LogReader.js revision bbe9e42b22a395653f030d199e93f445d52d6f69
var CLASS_CONTAINER = 'container',
CLASS_HD = 'hd',
CLASS_CONSOLE = 'console',
CLASS_FT = 'ft',
CLASS_HIDE_FT = 'hide-ft',
CLASS_CONTROLS = 'controls',
CLASS_BUTTON = 'button',
CLASS_LABEL = 'label',
CLASS_CHECKBOX = 'checkbox',
CLASS_EXPAND = 'expand',
CLASS_ACTIVE = 'active',
CLASS_CLEAR = 'clear',
CLASS_CAT_CHECKS = 'categories',
CLASS_SRC_CHECKS = 'sources',
CLASS_FILTER = 'filter',
CLASS_CATEGORY = 'category',
CLASS_SOURCE = 'source',
CLASS_ENTRY = 'entry',
CLASS_VERBOSE = 'verbose',
CLASS_ENTRY_META = 'entry-meta',
CLASS_ENTRY_CAT = 'entry-cat',
CLASS_ENTRY_SRC = 'entry-src',
CLASS_ENTRY_TIME = 'entry-time',
CLASS_ENTRY_TYPE = 'entry-type',
CLASS_HIDE_BASE = 'hide',
CLASS_ENTRY_TYPE_BASE = 'entry-type',
HAS_CLASS = 'hasClass',
ADD_CLASS = 'addClass',
REMOVE_CLASS = 'removeClass',
GET_CLASS_NAME = 'getClassName';
/**
* Creates a log output console
*/
function LogReader() {
}
NAME : 'logreader',
VERBOSE : 'verbose',
BASIC : 'basic',
ATTRS : {
strings : {
value : {
COLLAPSE : "Collapse",
EXPAND : "Expand",
ACTIVE : "Active",
CLEAR : "Clear"
}
},
title : {
value : "Log Console"
},
// accept messages
enabled : {
value : true
},
// display messages received
active : {
value : true
},
defaultCategory : {
value : 'info'
},
defaultSource : {
value : 'global'
},
entryTypes : {
value : {
category : {
info : true,
warn : true,
error: true,
time : true
},
source : {
global : true
}
}
},
templates : {
value : {
verbose : null,
basic : null
}
},
defaultTemplate : {
value : 'verbose'
},
entryWriters : {
value: {
entry : '_entryFromTemplate'
}
},
defaultWriter : {
value : 'entry'
},
printTimeout : {
value : 100,
},
consoleLimit : {
value : 500
},
footerEnabled : {
value : true
},
// convenience attrib for managing defaultTemplate
verbose : {
value: true,
this.set('defaultTemplate',
return !!val;
}
},
newestOnTop : {
value : true
},
collapsed : {
value : false
},
startTime : {
value : new Date()
},
lastTime : {
value : new Date()
}
}
});
_head : null,
_title : null,
_console : null,
_foot : null,
_catChecks : null,
_srcChecks : null,
_timeout : null,
buffer : null,
initializer : function (cfg) {
this.buffer = [];
// HACK: AttributeProvider should clone object values but doesn't yet
this._initObjectAttributes();
this._initTemplates();
// bind to self a few instance methods for ease of use later
},
// HACK: AttributeProvider should clone object attribute values
_initObjectAttributes : function () {
for (;i>=0;--i) {
}
},
_initTemplates : function () {
// For verbose log entries
this.set('templates.verbose',
'<p>'+
'<span class="'+
'{label}</span>'+
'<span class="'+
' {totalTime}ms (+{elapsedTime}) {localTime}:'+
'</span>'+
'</p>'+
'{sourceAndDetail}'+
'</p>'+
'</div>'+
'<p>{message}</p>'+
'</pre>');
// For basic log entries
this.set('templates.basic',
'<p>'+
'<span class="'+
'{label}</span>'+
'<span class="'+
' {totalTime}ms (+{elapsedTime}) {localTime}:'+
'</span>'+
'<span class="'+
' {sourceAndDetail}'+
'</span>:'+
'</span>'+
' {message}'+
'</p>'+
'</pre>');
},
renderUI : function () {
if (!this.get('rendered')) {
this._renderHead();
this._renderConsole();
this._renderFoot();
}
},
_renderHead : function () {
var S = this.getStrings(),
n = this.get('contentBox');
'<input type="button" class="'+
'<input type="button" class="'+
'</div>'+
'</div>');
},
_renderConsole : function () {
this._foot || null);
},
_renderFoot : function () {
var S = this.getStrings(),
entryTypes,t;
'<input type="checkbox" class="'+
S.ACTIVE+
'</label>'+
'<input type="button" class="'+
'</div>');
'<div class="'+
'<div class="'+
// Add the category entryType checks
for (t in entryTypes) {
if (entryTypes.hasOwnProperty(t)) {
this._catChecks.appendChild(
}
}
// Add the source entryType checks
for (t in entryTypes) {
if (entryTypes.hasOwnProperty(t)) {
this._srcChecks.appendChild(
}
}
},
syncUI : function () {
var entryTypes;
// Set active check
// Set the collapsed class state
// Category entryType checks
function (check) {
});
// Source entryType checks
function (check) {
});
},
bindUI : function () {
// UI control click events
// (collapse, expand, active, clear, categories, sources)
// move to queryAll(..).on('click',..)
for (;i>=0;--i) {
}
// Attribute changes
// HACK: will point to this._setEntryType or something like that
},
_handleControlClick : function (e) {
var t = e.target;
this.set('collapsed', true);
this.set('collapsed', false);
this.clearConsole();
this.set('entryTypes.' +
t.get('value'),
t.get('checked'));
}
},
_setTitle : function (v) {
v = typeof v == 'object' ? v.newVal : v;
},
_setActive : function (b) {
b = typeof b == 'object' ? b.newVal : b;
// TODO: this should be this._head.queryAll(..).set('checked',!!b)
'input[type=checkbox].'+
this[GET_CLASS_NAME](CLASS_ACTIVE)),
for (;i>=0;--i) {
}
if (b) {
this._schedulePrint();
} else if (this._timeout) {
clearTimeout(this._timeout);
this._timeout = null;
}
},
_setCollapsed : function (b) {
b = typeof b == 'object' ? b.newVal : b;
this[GET_CLASS_NAME](CLASS_COLLAPSE));
},
_setConsoleLimit : function (v) {
v = typeof v === 'object' ? v.newVal : v;
this._trimOldEntries(v);
},
clearConsole : function () {
// TODO: clear event listeners from console contents
if (this._timeout) {
clearTimeout(this._timeout);
this._timeout = null;
}
this.buffer = [];
},
reset : function () {
this.clearConsole();
this.set('startTime',new Date());
this.set('enabled',true);
this.set('active',true);
this.fire('reset');
},
if (this.get('enabled')) {
if (m) {
// New category?
this.createCategory(m.category,true);
}
// New source?
this.createSource(m.source,true);
}
// buffer the output
this._schedulePrint();
}
}
},
var m = {
time : new Date(),
source : null,
label : null,
localTime : null,
elapsedTime : null,
totalTime : null
};
// Extract m.source "Foo" from m.sourceAndDetail "Foo bar baz"
RegExp.$1 : m.sourceAndDetail;
return m;
},
_schedulePrint : function () {
this._timeout = setTimeout(
this.printBuffer,
this.get('printTimeout'));
}
},
printBuffer: function () {
// Called from timeout, so calls to Y.log will not be caught by the
// recursion protection in event. Turn off logging while printing.
Y.debug = false;
clearTimeout(this._timeout);
this._timeout = null;
this.buffer = [];
// TODO: use doc frag?
for (;i<l;++i) {
this.printLogEntry(messages[i]);
this._trimOldEntries();
}
}
},
printLogEntry : function (m) {
if (output) {
if (this.get('newestOnTop')) {
this._console.insertBefore(
} else {
}
}
},
_entryFromTemplate : function (m) {
m = this._htmlEscapeMessage(m);
return n;
},
_htmlEscapeMessage : function (m) {
function esc(s) {
return s.replace(/&/g,'&').
replace(/</g,'<').
replace(/>/g,'>');
}
m = Y.clone(m);
return m;
},
_trimOldEntries : function (max) {
if (this._console) {
if (i > 0) {
if (this.get('newestOnTop')) {
}
} else {
for (;i>=0;--i) {
}
}
}
}
},
// Log entry display filtering methods
hideEntries : function (name) {
for (t in entryTypes) {
if (entryTypes.hasOwnProperty(t) &&
}
}
},
showEntries : function (name) {
for (t in entryTypes) {
if (entryTypes.hasOwnProperty(t) &&
}
}
},
// TODO: should be this._foot.queryAll(..).set('checked',checked)
for (;i>=0;--i) {
}
},
// add or remove the filter class from the root node
},
_setFooterEnabled : function (show) {
this[GET_CLASS_NAME](CLASS_HIDE_FT));
},
},
},
name+
'</label>'),
return label;
},
_handleEntryTypesChange : function (e) {
// We have to determine all terminal paths that have changed in case
// a branch node in the obj structure was changed.
// Build a list of paths to compare against the previous value
var buildPaths = function (o) {
var paths = [];
function drill(o,p) {
if (typeof o === 'object') {
for (var k in o) {
if (o.hasOwnProperty(k)) {
}
}
} else if (p) {
}
}
drill(o,[]);
return paths;
},
val = function (o,p) {
var v = o,
i = 0, l = p.length;
for (;i<l && v !== undefined; ++i) {
v = v[p[i]];
}
return v;
},
done = {},
for (;i<l;++i) {
// TODO: this does not handle deletions
// Change to existing entryType bool
}
}
// New entryType check
this._catChecks.appendChild(
this._createEntryType(
} else {
this._srcChecks.appendChild(
this._createEntryType(
}
}
}
}
});