+ //<debug>
+ function dumpObject (object) {
+ var member, members = [];
+
+ // Cannot use Ext.encode since it can recurse endlessly (if we're lucky)
+ // ...and the data could be prettier!
+ Ext.Object.each(object, function (name, value) {
+ if (typeof(value) === "function") {
+ return;
+ }
+
+ if (!Ext.isDefined(value) || value === null ||
+ Ext.isDate(value) ||
+ Ext.isString(value) || (typeof(value) == "number") ||
+ Ext.isBoolean(value)) {
+ member = Ext.encode(value);
+ } else if (Ext.isArray(value)) {
+ member = '[ ]';
+ } else if (Ext.isObject(value)) {
+ member = '{ }';
+ } else {
+ member = 'undefined';
+ }
+ members.push(Ext.encode(name) + ': ' + member);
+ });
+
+ if (members.length) {
+ return ' \nData: {\n ' + members.join(',\n ') + '\n}';
+ }
+ return '';
+ }
+
+ function log (message) {
+ var options, dump,
+ con = Ext.global.console,
+ level = 'log',
+ indent = log.indent || 0,
+ stack;
+
+ log.indent = indent;
+
+ if (!Ext.isString(message)) {
+ options = message;
+ message = options.msg || '';
+ level = options.level || level;
+ dump = options.dump;
+ stack = options.stack;
+
+ if (options.indent) {
+ ++log.indent;
+ } else if (options.outdent) {
+ log.indent = indent = Math.max(indent - 1, 0);
+ }
+
+ if (dump && !(con && con.dir)) {
+ message += dumpObject(dump);
+ dump = null;
+ }
+ }
+
+ if (arguments.length > 1) {
+ message += Array.prototype.slice.call(arguments, 1).join('');
+ }
+
+ message = indent ? Ext.String.repeat(' ', indent) + message : message;
+ // w/o console, all messages are equal, so munge the level into the message:
+ if (level != 'log') {
+ message = '[' + level.charAt(0).toUpperCase() + '] ' + message;
+ }
+
+ // Not obvious, but 'console' comes and goes when Firebug is turned on/off, so
+ // an early test may fail either direction if Firebug is toggled.
+ //
+ if (con) { // if (Firebug-like console)
+ if (con[level]) {
+ con[level](message);
+ } else {
+ con.log(message);
+ }
+
+ if (dump) {
+ con.dir(dump);
+ }
+
+ if (stack && con.trace) {
+ // Firebug's console.error() includes a trace already...
+ if (!con.firebug || level != 'error') {
+ con.trace();
+ }
+ }
+ } else {
+ if (Ext.isOpera) {
+ opera.postError(message);
+ } else {
+ var out = log.out,
+ max = log.max;
+
+ if (out.length >= max) {
+ // this formula allows out.max to change (via debugger), where the
+ // more obvious "max/4" would not quite be the same
+ Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); // keep newest 75%
+ }
+
+ out.push(message);
+ }
+ }
+
+ // Mostly informational, but the Ext.Error notifier uses them:
+ ++log.count;
+ ++log.counters[level];
+ }
+
+ log.count = 0;
+ log.counters = { error: 0, warn: 0, info: 0, log: 0 };
+ log.out = [];
+ log.max = 250;
+ log.show = function () {
+ window.open('','extlog').document.write([
+ '<html><head><script type="text/javascript">',
+ 'var lastCount = 0;',
+ 'function update () {',
+ 'var ext = window.opener.Ext,',
+ 'extlog = ext && ext.log;',
+ 'if (extlog && extlog.out && lastCount != extlog.count) {',
+ 'lastCount = extlog.count;',
+ 'var s = "<tt>" + extlog.out.join("<br>").replace(/[ ]/g, "&nbsp;") + "</tt>";',
+ 'document.body.innerHTML = s;',
+ '}',
+ 'setTimeout(update, 1000);',
+ '}',
+ 'setTimeout(update, 1000);',
+ '</script></head><body></body></html>'].join(''));
+ };
+ //</debug>
+
+ Ext.setVersion('extjs', '4.0.7');