You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
5.5 KiB
219 lines
5.5 KiB
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
/**
|
|
* Js debug.
|
|
*/
|
|
var jsDump;
|
|
|
|
(function() {
|
|
var reName = /^function (\w+)/;
|
|
|
|
function quote(str) {
|
|
return '"' + str.toString().replace(/"/g, '\\"') + '"';
|
|
}
|
|
|
|
function literal(o) {
|
|
return o + '';
|
|
}
|
|
|
|
function join(pre, arr, post) {
|
|
var s = jsDump.separator(),
|
|
base = jsDump.indent();
|
|
inner = jsDump.indent(1);
|
|
|
|
if (arr.join) {
|
|
arr = arr.join(',' + s + inner);
|
|
}
|
|
if (!arr) {
|
|
return pre + post;
|
|
}
|
|
|
|
return [pre, inner + arr, base + post].join(s);
|
|
}
|
|
|
|
function array(arr) {
|
|
var i = arr.length, ret = Array(i);
|
|
|
|
this.up();
|
|
while (i--) {
|
|
ret[i] = this.parse(arr[i]);
|
|
}
|
|
this.down();
|
|
|
|
return join('[', ret, ']');
|
|
}
|
|
|
|
jsDump = {
|
|
quote: quote,
|
|
literal: literal,
|
|
join: join,
|
|
_depth_: 1,
|
|
HTML: false, // if true, entities are escaped ( <, >, \t, space and \n )
|
|
indentChar: ' ', // indentation unit
|
|
multiline: true, // if true, items in a collection, are separated by a \n, else just a space.
|
|
|
|
parse: function(obj, type) { // type is used mostly internally, you can fix a (custom) type in advance
|
|
var parser = this.parsers[type || this.typeOf(obj)];
|
|
type = typeof parser;
|
|
|
|
return type == 'function' ? parser.call(this, obj) : type == 'string' ? parser : this.parsers.error;
|
|
},
|
|
|
|
typeOf: function(obj) {
|
|
var type = typeof obj,
|
|
f = 'function'; // we'll use it 3 times, save it
|
|
|
|
return type != 'object' && type != f ? type :
|
|
!obj ? 'null' :
|
|
obj.exec ? 'regexp' : // some browsers (FF) consider regexps functions
|
|
obj.getHours ? 'date' :
|
|
obj.scrollBy ? 'window' :
|
|
obj.nodeName == '#document' ? 'document' :
|
|
obj.nodeName ? 'node' :
|
|
obj.item ? 'nodelist' : // Safari reports nodelists as functions
|
|
obj.callee ? 'arguments' :
|
|
obj.call || obj.constructor != Array && // an array would also fall on this hack
|
|
(obj + '').indexOf(f) != -1 ? f : // IE reports functions like alert, as objects
|
|
'length' in obj ? 'array' :
|
|
type;
|
|
},
|
|
|
|
separator: function() {
|
|
return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? ' ' : ' ';
|
|
},
|
|
|
|
indent: function (extra) { // extra can be a number, shortcut for increasing-calling-decreasing
|
|
if (!this.multiline) {
|
|
return '';
|
|
}
|
|
|
|
var chr = this.indentChar;
|
|
|
|
if (this.HTML) {
|
|
chr = chr.replace(/\t/g, ' ').replace(/ /g, ' ');
|
|
}
|
|
|
|
return Array(this._depth_ + (extra||0)).join(chr);
|
|
},
|
|
|
|
up: function(a) {
|
|
this._depth_ += a || 1;
|
|
},
|
|
|
|
down: function(a) {
|
|
this._depth_ -= a || 1;
|
|
},
|
|
|
|
setParser: function(name, parser) {
|
|
this.parsers[name] = parser;
|
|
},
|
|
|
|
// this is the list of parsers, to modify them, use jsdump.setparser
|
|
parsers: {
|
|
window: '[Window]',
|
|
document: '[Document]',
|
|
error: '[ERROR]', // when no parser is found, shouldn't happen
|
|
unknown: '[Unknown]',
|
|
'null': 'null',
|
|
undefined: 'undefined',
|
|
'function': function(fn) {
|
|
var ret = 'function',
|
|
name = 'name' in fn ? fn.name : (reName.exec(fn) || [])[1]; // functions never have name in IE
|
|
if (name) {
|
|
ret += ' ' + name;
|
|
}
|
|
ret += '(';
|
|
ret = [ret, this.parse(fn, 'functionArgs'), '){'].join('');
|
|
|
|
return join(ret, this.parse(fn, 'functionCode'), '}');
|
|
},
|
|
|
|
array: array,
|
|
nodelist: array,
|
|
arguments: array,
|
|
key: quote, // object calls it internally, the key part of an item in a map
|
|
functionCode: '[code]', // function calls it internally, it's the content of the function
|
|
attribute: quote, // onode calls it internally, it's an html attribute value
|
|
string: quote,
|
|
date: quote,
|
|
regexp: literal, // regex
|
|
number: literal,
|
|
'boolean': literal,
|
|
|
|
object: function(map) {
|
|
var ret = [];
|
|
this.up();
|
|
for (var key in map) {
|
|
ret.push(this.parse(key, 'key') + ': ' + this.parse(map[key]));
|
|
}
|
|
this.down();
|
|
|
|
return join('{', ret, '}');
|
|
},
|
|
|
|
node: function(node) {
|
|
var open = this.HTML ? '<' : '<',
|
|
close = this.HTML ? '>' : '>',
|
|
tag = node.nodeName.toLowerCase(),
|
|
ret = open + tag;
|
|
|
|
for (var a in this.DOMAttrs) {
|
|
var val = node[this.DOMAttrs[a]];
|
|
if (val) {
|
|
ret += ' ' + a + '=' + this.parse(val, 'attribute');
|
|
}
|
|
}
|
|
|
|
return ret + close + open + '/' + tag + close;
|
|
},
|
|
|
|
functionArgs: function(fn) { // function calls it internally, it's the arguments part of the function
|
|
var l = fn.length;
|
|
|
|
if (!l) {
|
|
return '';
|
|
}
|
|
|
|
var args = Array(l);
|
|
while (l--) {
|
|
args[l] = String.fromCharCode(97 + l); // 97 is 'a'
|
|
}
|
|
|
|
return ' ' + args.join(', ') + ' ';
|
|
}
|
|
},
|
|
|
|
DOMAttrs: { // attributes to dump from nodes, name => realName
|
|
id: 'id',
|
|
name: 'name',
|
|
'class': 'className'
|
|
}
|
|
};
|
|
})();
|
|
|
|
function cdump($obj) {
|
|
console.log(jsDump.parse($obj));
|
|
}
|
|
|
|
function cdumpts(timestamp) {
|
|
return new CDate(timestamp).getZBXDate();
|
|
}
|