
I need to work more on the problem that this commit tried to resolve
This reverts commit 84660db9d2
.
1076 lines
27 KiB
JavaScript
1076 lines
27 KiB
JavaScript
var Log = function() {
|
|
this.autoCloseFold = true;
|
|
this.listeners = [];
|
|
this.renderer = new Log.Renderer;
|
|
this.children = new Log.Nodes(this);
|
|
this.parts = {};
|
|
this.folds = new Log.Folds(this);
|
|
this.times = new Log.Times(this);
|
|
return this;
|
|
};
|
|
|
|
Log.extend = function(one, other) {
|
|
var name;
|
|
for (name in other) {
|
|
one[name] = other[name];
|
|
}
|
|
return one;
|
|
};
|
|
|
|
Log.extend(Log, {
|
|
DEBUG: true,
|
|
SLICE: 500,
|
|
TIMEOUT: 25,
|
|
FOLD: /fold:(start|end):([\w_\-\.]+)/,
|
|
TIME: /time:(start|end):([\w_\-\.]+):?([\w_\-\.\=\,]*)/,
|
|
create: function(options) {
|
|
var listener, log, _i, _len, _ref;
|
|
options || (options = {});
|
|
log = new Log();
|
|
if (options.limit) {
|
|
log.listeners.push(log.limit = new Log.Limit(options.limit));
|
|
}
|
|
_ref = options.listeners || [];
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
listener = _ref[_i];
|
|
log.listeners.push(listener);
|
|
}
|
|
return log;
|
|
}
|
|
});
|
|
|
|
var newLineAtTheEndRegexp, newLineRegexp, rRegexp, removeCarriageReturns;
|
|
|
|
Log.Node = function(id, num) {
|
|
this.id = id;
|
|
this.num = num;
|
|
this.key = Log.Node.key(this.id);
|
|
this.children = new Log.Nodes(this);
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Node, {
|
|
key: function(id) {
|
|
if (id) {
|
|
return id.split('-').map(function(i) {
|
|
return '000000'.concat(i).slice(-6);
|
|
}).join('');
|
|
}
|
|
}
|
|
});
|
|
|
|
Log.extend(Log.Node.prototype, {
|
|
addChild: function(node) {
|
|
return this.children.add(node);
|
|
},
|
|
remove: function() {
|
|
this.log.remove(this.element);
|
|
return this.parent.children.remove(this);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Node.prototype, 'log', {
|
|
get: function() {
|
|
var _ref;
|
|
return this._log || (this._log = ((_ref = this.parent) != null ? _ref.log : void 0) || this.parent);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Node.prototype, 'firstChild', {
|
|
get: function() {
|
|
return this.children.first;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Node.prototype, 'lastChild', {
|
|
get: function() {
|
|
return this.children.last;
|
|
}
|
|
});
|
|
|
|
Log.Nodes = function(parent) {
|
|
if (parent) {
|
|
this.parent = parent;
|
|
}
|
|
this.items = [];
|
|
this.index = {};
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Nodes.prototype, {
|
|
add: function(item) {
|
|
var ix, next, prev, _ref, _ref1;
|
|
ix = this.position(item) || 0;
|
|
this.items.splice(ix, 0, item);
|
|
if (this.parent) {
|
|
item.parent = this.parent;
|
|
}
|
|
prev = function(item) {
|
|
while (item && !item.children.last) {
|
|
item = item.prev;
|
|
}
|
|
return item != null ? item.children.last : void 0;
|
|
};
|
|
next = function(item) {
|
|
while (item && !item.children.first) {
|
|
item = item.next;
|
|
}
|
|
return item != null ? item.children.first : void 0;
|
|
};
|
|
if (item.prev = this.items[ix - 1] || prev((_ref = this.parent) != null ? _ref.prev : void 0)) {
|
|
item.prev.next = item;
|
|
}
|
|
if (item.next = this.items[ix + 1] || next((_ref1 = this.parent) != null ? _ref1.next : void 0)) {
|
|
item.next.prev = item;
|
|
}
|
|
return item;
|
|
},
|
|
remove: function(item) {
|
|
this.items.splice(this.items.indexOf(item), 1);
|
|
if (item.next) {
|
|
item.next.prev = item.prev;
|
|
}
|
|
if (item.prev) {
|
|
item.prev.next = item.next;
|
|
}
|
|
if (this.items.length === 0) {
|
|
return this.parent.remove();
|
|
}
|
|
},
|
|
position: function(item) {
|
|
var ix, _i, _ref;
|
|
for (ix = _i = _ref = this.items.length - 1; _i >= 0; ix = _i += -1) {
|
|
if (this.items[ix].key < item.key) {
|
|
return ix + 1;
|
|
}
|
|
}
|
|
},
|
|
indexOf: function() {
|
|
return this.items.indexOf.apply(this.items, arguments);
|
|
},
|
|
slice: function() {
|
|
return this.items.slice.apply(this.items, arguments);
|
|
},
|
|
each: function(func) {
|
|
return this.items.slice().forEach(func);
|
|
},
|
|
map: function(func) {
|
|
return this.items.map(func);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Nodes.prototype, 'first', {
|
|
get: function() {
|
|
return this.items[0];
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Nodes.prototype, 'last', {
|
|
get: function() {
|
|
return this.items[this.length - 1];
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Nodes.prototype, 'length', {
|
|
get: function() {
|
|
return this.items.length;
|
|
}
|
|
});
|
|
|
|
Log.Part = function(id, num, string) {
|
|
Log.Node.apply(this, arguments);
|
|
this.string = string || '';
|
|
this.string = this.string.replace(/\033\[1000D/gm, '\r');
|
|
this.string = this.string.replace(/\r+\n/gm, '\n');
|
|
this.strings = this.string.split(/^/gm) || [];
|
|
this.slices = ((function() {
|
|
var _results;
|
|
_results = [];
|
|
while (this.strings.length > 0) {
|
|
_results.push(this.strings.splice(0, Log.SLICE));
|
|
}
|
|
return _results;
|
|
}).call(this));
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Part, {
|
|
create: function(log, num, string) {
|
|
var part;
|
|
part = new Log.Part(num.toString(), num, string);
|
|
log.addChild(part);
|
|
return part.process(0, -1);
|
|
}
|
|
});
|
|
|
|
Log.Part.prototype = Log.extend(new Log.Node, {
|
|
remove: function() {},
|
|
process: function(slice, num) {
|
|
var node, span, spans, string, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4,
|
|
_this = this;
|
|
_ref = this.slices[slice] || [];
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
string = _ref[_i];
|
|
if ((_ref1 = this.log.limit) != null ? _ref1.limited : void 0) {
|
|
return;
|
|
}
|
|
spans = [];
|
|
_ref2 = Log.Deansi.apply(string);
|
|
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
|
node = _ref2[_j];
|
|
span = Log.Span.create(this, "" + this.id + "-" + (num += 1), num, node.text, node["class"]);
|
|
span.render();
|
|
spans.push(span);
|
|
}
|
|
if ((_ref3 = spans[0]) != null ? (_ref4 = _ref3.line) != null ? _ref4.cr : void 0 : void 0) {
|
|
spans[0].line.clear();
|
|
}
|
|
}
|
|
if (!(slice >= this.slices.length - 1)) {
|
|
return setTimeout((function() {
|
|
return _this.process(slice + 1, num);
|
|
}), Log.TIMEOUT);
|
|
}
|
|
}
|
|
});
|
|
|
|
newLineAtTheEndRegexp = new RegExp("\n$");
|
|
|
|
newLineRegexp = new RegExp("\n");
|
|
|
|
rRegexp = new RegExp("\r");
|
|
|
|
removeCarriageReturns = function(string) {
|
|
var index;
|
|
index = string.lastIndexOf("\r");
|
|
if (index === -1) {
|
|
return string;
|
|
}
|
|
return string.substr(index + 1);
|
|
};
|
|
|
|
Log.Span = function(id, num, text, classes) {
|
|
var fold, time, _ref;
|
|
Log.Node.apply(this, arguments);
|
|
if (fold = text.match(Log.FOLD)) {
|
|
this.fold = true;
|
|
this.event = fold[1];
|
|
this.text = this.name = fold[2];
|
|
} else if (time = text.match(Log.TIME)) {
|
|
this.time = true;
|
|
this.event = time[1];
|
|
this.name = time[2];
|
|
this.stats = time[3];
|
|
} else {
|
|
this.text = text;
|
|
this.text = removeCarriageReturns(this.text);
|
|
this.text = this.text.replace(newLineAtTheEndRegexp, '');
|
|
this.nl = !!((_ref = text[text.length - 1]) != null ? _ref.match(newLineRegexp) : void 0);
|
|
this.cr = !!text.match(rRegexp);
|
|
this["class"] = this.cr && ['clears'] || classes;
|
|
}
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Span, {
|
|
create: function(parent, id, num, text, classes) {
|
|
var span;
|
|
span = new Log.Span(id, num, text, classes);
|
|
parent.addChild(span);
|
|
return span;
|
|
},
|
|
render: function(parent, id, num, text, classes) {
|
|
var span;
|
|
span = this.create(parent, id, num, text, classes);
|
|
return span.render();
|
|
}
|
|
});
|
|
|
|
Log.Span.prototype = Log.extend(new Log.Node, {
|
|
render: function() {
|
|
var tail;
|
|
if (this.time && this.event === 'end' && this.prev) {
|
|
if (Log.DEBUG) {
|
|
console.log("S.0 insert " + this.id + " after prev " + this.prev.id);
|
|
}
|
|
this.nl = this.prev.nl;
|
|
this.log.insert(this.data, {
|
|
after: this.prev.element
|
|
});
|
|
this.line = this.prev.line;
|
|
} else if (!this.fold && this.prev && !this.prev.fold && !this.prev.nl) {
|
|
if (Log.DEBUG) {
|
|
console.log("S.1 insert " + this.id + " after prev " + this.prev.id);
|
|
}
|
|
this.log.insert(this.data, {
|
|
after: this.prev.element
|
|
});
|
|
this.line = this.prev.line;
|
|
} else if (!this.fold && this.next && !this.next.fold && !this.next.time) {
|
|
if (Log.DEBUG) {
|
|
console.log("S.2 insert " + this.id + " before next " + this.next.id);
|
|
}
|
|
this.log.insert(this.data, {
|
|
before: this.next.element
|
|
});
|
|
this.line = this.next.line;
|
|
} else {
|
|
this.line = Log.Line.create(this.log, [this]);
|
|
this.line.render();
|
|
}
|
|
if (this.nl && (tail = this.tail).length > 0) {
|
|
this.split(tail);
|
|
}
|
|
if (this.time) {
|
|
return this.log.times.add(this);
|
|
}
|
|
},
|
|
remove: function() {
|
|
Log.Node.prototype.remove.apply(this);
|
|
if (this.line) {
|
|
return this.line.remove(this);
|
|
}
|
|
},
|
|
split: function(spans) {
|
|
var line, span, _i, _len;
|
|
if (Log.DEBUG) {
|
|
console.log("S.4 split [" + (spans.map(function(span) {
|
|
return span.id;
|
|
}).join(', ')) + "]");
|
|
}
|
|
for (_i = 0, _len = spans.length; _i < _len; _i++) {
|
|
span = spans[_i];
|
|
this.log.remove(span.element);
|
|
}
|
|
line = Log.Line.create(this.log, spans);
|
|
line.render();
|
|
if (line.cr) {
|
|
return line.clear();
|
|
}
|
|
},
|
|
clear: function() {
|
|
if (this.prev && this.isSibling(this.prev) && this.isSequence(this.prev)) {
|
|
this.prev.clear();
|
|
return this.prev.remove();
|
|
}
|
|
},
|
|
isSequence: function(other) {
|
|
return this.parent.num - other.parent.num === this.log.children.indexOf(this.parent) - this.log.children.indexOf(other.parent);
|
|
},
|
|
isSibling: function(other) {
|
|
var _ref, _ref1;
|
|
return ((_ref = this.element) != null ? _ref.parentNode : void 0) === ((_ref1 = other.element) != null ? _ref1.parentNode : void 0);
|
|
},
|
|
siblings: function(type) {
|
|
var siblings, span;
|
|
siblings = [];
|
|
while ((span = (span || this)[type]) && this.isSibling(span)) {
|
|
siblings.push(span);
|
|
}
|
|
return siblings;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Span.prototype, 'data', {
|
|
get: function() {
|
|
return {
|
|
id: this.id,
|
|
type: 'span',
|
|
text: this.text,
|
|
"class": this["class"],
|
|
time: this.time
|
|
};
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Span.prototype, 'line', {
|
|
get: function() {
|
|
return this._line;
|
|
},
|
|
set: function(line) {
|
|
if (this.line) {
|
|
this.line.remove(this);
|
|
}
|
|
this._line = line;
|
|
if (this.line) {
|
|
return this.line.add(this);
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Span.prototype, 'element', {
|
|
get: function() {
|
|
return document.getElementById(this.id);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Span.prototype, 'head', {
|
|
get: function() {
|
|
return this.siblings('prev').reverse();
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Span.prototype, 'tail', {
|
|
get: function() {
|
|
return this.siblings('next');
|
|
}
|
|
});
|
|
|
|
Log.Line = function(log) {
|
|
this.log = log;
|
|
this.spans = [];
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Line, {
|
|
create: function(log, spans) {
|
|
var line, span, _i, _len;
|
|
if ((span = spans[0]) && span.fold) {
|
|
line = new Log.Fold(log, span.event, span.name);
|
|
} else {
|
|
line = new Log.Line(log);
|
|
}
|
|
for (_i = 0, _len = spans.length; _i < _len; _i++) {
|
|
span = spans[_i];
|
|
span.line = line;
|
|
}
|
|
return line;
|
|
}
|
|
});
|
|
|
|
Log.extend(Log.Line.prototype, {
|
|
add: function(span) {
|
|
var ix;
|
|
if (span.cr) {
|
|
this.cr = true;
|
|
}
|
|
if (this.spans.indexOf(span) > -1) {
|
|
|
|
} else if ((ix = this.spans.indexOf(span.prev)) > -1) {
|
|
return this.spans.splice(ix + 1, 0, span);
|
|
} else if ((ix = this.spans.indexOf(span.next)) > -1) {
|
|
return this.spans.splice(ix, 0, span);
|
|
} else {
|
|
return this.spans.push(span);
|
|
}
|
|
},
|
|
remove: function(span) {
|
|
var ix;
|
|
if ((ix = this.spans.indexOf(span)) > -1) {
|
|
return this.spans.splice(ix, 1);
|
|
}
|
|
},
|
|
render: function() {
|
|
var fold;
|
|
if ((fold = this.prev) && fold.event === 'start' && fold.active) {
|
|
if (this.next && !this.next.fold) {
|
|
if (Log.DEBUG) {
|
|
console.log("L.0 insert " + this.id + " before next " + this.next.id);
|
|
}
|
|
return this.element = this.log.insert(this.data, {
|
|
before: this.next.element
|
|
});
|
|
} else {
|
|
if (Log.DEBUG) {
|
|
console.log("L.0 insert " + this.id + " into fold " + fold.id);
|
|
}
|
|
fold = this.log.folds.folds[fold.name].fold;
|
|
return this.element = this.log.insert(this.data, {
|
|
into: fold
|
|
});
|
|
}
|
|
} else if (this.prev) {
|
|
if (Log.DEBUG) {
|
|
console.log("L.1 insert " + this.spans[0].id + " after prev " + this.prev.id);
|
|
}
|
|
return this.element = this.log.insert(this.data, {
|
|
after: this.prev.element
|
|
});
|
|
} else if (this.next) {
|
|
if (Log.DEBUG) {
|
|
console.log("L.2 insert " + this.spans[0].id + " before next " + this.next.id);
|
|
}
|
|
return this.element = this.log.insert(this.data, {
|
|
before: this.next.element
|
|
});
|
|
} else {
|
|
if (Log.DEBUG) {
|
|
console.log("L.3 insert " + this.spans[0].id + " into #log");
|
|
}
|
|
return this.element = this.log.insert(this.data);
|
|
}
|
|
},
|
|
clear: function() {
|
|
var cr, _i, _len, _ref, _results;
|
|
_ref = this.crs;
|
|
_results = [];
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
cr = _ref[_i];
|
|
_results.push(cr.clear());
|
|
}
|
|
return _results;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'id', {
|
|
get: function() {
|
|
var _ref;
|
|
return (_ref = this.spans[0]) != null ? _ref.id : void 0;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'data', {
|
|
get: function() {
|
|
return {
|
|
type: 'paragraph',
|
|
nodes: this.nodes
|
|
};
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'nodes', {
|
|
get: function() {
|
|
return this.spans.map(function(span) {
|
|
return span.data;
|
|
});
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'prev', {
|
|
get: function() {
|
|
var _ref;
|
|
return (_ref = this.spans[0].prev) != null ? _ref.line : void 0;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'next', {
|
|
get: function() {
|
|
var _ref;
|
|
return (_ref = this.spans[this.spans.length - 1].next) != null ? _ref.line : void 0;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Line.prototype, 'crs', {
|
|
get: function() {
|
|
return this.spans.filter(function(span) {
|
|
return span.cr;
|
|
});
|
|
}
|
|
});
|
|
|
|
Log.Fold = function(log, event, name) {
|
|
Log.Line.apply(this, arguments);
|
|
this.fold = true;
|
|
this.event = event;
|
|
this.name = name;
|
|
return this;
|
|
};
|
|
|
|
Log.Fold.prototype = Log.extend(new Log.Line, {
|
|
render: function() {
|
|
var element, _ref;
|
|
if (this.prev && this.prev.element) {
|
|
if (Log.DEBUG) {
|
|
console.log("F.1 insert " + this.id + " after prev " + this.prev.id);
|
|
}
|
|
element = this.prev.element;
|
|
this.element = this.log.insert(this.data, {
|
|
after: element
|
|
});
|
|
} else if (this.next) {
|
|
if (Log.DEBUG) {
|
|
console.log("F.2 insert " + this.id + " before next " + this.next.id);
|
|
}
|
|
element = this.next.element || this.next.element.parentNode;
|
|
this.element = this.log.insert(this.data, {
|
|
before: element
|
|
});
|
|
} else {
|
|
if (Log.DEBUG) {
|
|
console.log("F.3 insert " + this.id);
|
|
}
|
|
this.element = this.log.insert(this.data);
|
|
}
|
|
if (this.span.next && ((_ref = this.span.prev) != null ? _ref.isSibling(this.span.next) : void 0)) {
|
|
this.span.prev.split([this.span.next].concat(this.span.next.tail));
|
|
}
|
|
return this.active = this.log.folds.add(this.data);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Fold.prototype, 'id', {
|
|
get: function() {
|
|
return "fold-" + this.event + "-" + this.name;
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Fold.prototype, 'span', {
|
|
get: function() {
|
|
return this.spans[0];
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Fold.prototype, 'data', {
|
|
get: function() {
|
|
return {
|
|
type: 'fold',
|
|
id: this.id,
|
|
event: this.event,
|
|
name: this.name
|
|
};
|
|
}
|
|
});
|
|
|
|
Log.prototype = Log.extend(new Log.Node, {
|
|
set: function(num, string) {
|
|
if (this.parts[num]) {
|
|
return console.log("part " + num + " exists");
|
|
} else {
|
|
this.parts[num] = true;
|
|
return Log.Part.create(this, num, string);
|
|
}
|
|
},
|
|
insert: function(data, pos) {
|
|
this.trigger('insert', data, pos);
|
|
return this.renderer.insert(data, pos);
|
|
},
|
|
remove: function(node) {
|
|
this.trigger('remove', node);
|
|
return this.renderer.remove(node);
|
|
},
|
|
hide: function(node) {
|
|
this.trigger('hide', node);
|
|
return this.renderer.hide(node);
|
|
},
|
|
trigger: function() {
|
|
var args, ix, listener, _i, _len, _ref, _results;
|
|
args = [this].concat(Array.prototype.slice.apply(arguments));
|
|
_ref = this.listeners;
|
|
_results = [];
|
|
for (ix = _i = 0, _len = _ref.length; _i < _len; ix = ++_i) {
|
|
listener = _ref[ix];
|
|
_results.push(listener.notify.apply(listener, args));
|
|
}
|
|
return _results;
|
|
}
|
|
});
|
|
|
|
Log.Listener = function() {};
|
|
|
|
Log.extend(Log.Listener.prototype, {
|
|
notify: function(log, event) {
|
|
if (this[event]) {
|
|
return this[event].apply(this, [log].concat(Array.prototype.slice.call(arguments, 2)));
|
|
}
|
|
}
|
|
});
|
|
|
|
Log.Folds = function(log) {
|
|
this.log = log;
|
|
this.folds = {};
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Folds.prototype, {
|
|
add: function(data) {
|
|
var fold, _base, _name;
|
|
fold = (_base = this.folds)[_name = data.name] || (_base[_name] = new Log.Folds.Fold);
|
|
fold.receive(data, {
|
|
autoCloseFold: this.log.autoCloseFold
|
|
});
|
|
return fold.active;
|
|
}
|
|
});
|
|
|
|
Log.Folds.Fold = function() {
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Folds.Fold.prototype, {
|
|
receive: function(data, options) {
|
|
this[data.event] = data.id;
|
|
if (this.start && this.end && !this.active) {
|
|
return this.activate(options);
|
|
}
|
|
},
|
|
activate: function(options) {
|
|
var fragment, nextSibling, node, parentNode, toRemove, _i, _len, _ref;
|
|
options || (options = {});
|
|
if (Log.DEBUG) {
|
|
console.log("F.n - activate " + this.start);
|
|
}
|
|
toRemove = this.fold.parentNode;
|
|
parentNode = toRemove.parentNode;
|
|
nextSibling = toRemove.nextSibling;
|
|
parentNode.removeChild(toRemove);
|
|
fragment = document.createDocumentFragment();
|
|
_ref = this.nodes;
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
node = _ref[_i];
|
|
fragment.appendChild(node);
|
|
}
|
|
this.fold.appendChild(fragment);
|
|
parentNode.insertBefore(toRemove, nextSibling);
|
|
this.fold.setAttribute('class', this.classes(options['autoCloseFold']));
|
|
return this.active = true;
|
|
},
|
|
classes: function(autoCloseFold) {
|
|
var classes;
|
|
classes = this.fold.getAttribute('class').split(' ');
|
|
classes.push('fold');
|
|
if (!autoCloseFold) {
|
|
classes.push('open');
|
|
}
|
|
if (this.fold.childNodes.length > 2) {
|
|
classes.push('active');
|
|
}
|
|
return classes.join(' ');
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Folds.Fold.prototype, 'fold', {
|
|
get: function() {
|
|
return this._fold || (this._fold = document.getElementById(this.start));
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Folds.Fold.prototype, 'nodes', {
|
|
get: function() {
|
|
var node, nodes;
|
|
node = this.fold;
|
|
nodes = [];
|
|
while ((node = node.nextSibling) && node.id !== this.end) {
|
|
nodes.push(node);
|
|
}
|
|
return nodes;
|
|
}
|
|
});
|
|
|
|
Log.Times = function(log) {
|
|
this.log = log;
|
|
this.times = {};
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Times.prototype, {
|
|
add: function(node) {
|
|
var time, _base, _name;
|
|
time = (_base = this.times)[_name = node.name] || (_base[_name] = new Log.Times.Time);
|
|
return time.receive(node);
|
|
},
|
|
duration: function(name) {
|
|
if (this.times[name]) {
|
|
return this.times[name].duration;
|
|
}
|
|
}
|
|
});
|
|
|
|
Log.Times.Time = function() {
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Times.Time.prototype, {
|
|
receive: function(node) {
|
|
this[node.event] = node;
|
|
if (Log.DEBUG) {
|
|
console.log("T.0 - " + node.event + " " + node.name);
|
|
}
|
|
if (this.start && this.end) {
|
|
return this.finish();
|
|
}
|
|
},
|
|
finish: function() {
|
|
var element;
|
|
if (Log.DEBUG) {
|
|
console.log("T.1 - finish " + this.start.name);
|
|
}
|
|
element = document.getElementById(this.start.id);
|
|
if (element) {
|
|
return this.update(element);
|
|
}
|
|
},
|
|
update: function(element) {
|
|
element.setAttribute('class', 'duration');
|
|
element.setAttribute('title', "This command finished after " + this.duration + " seconds.");
|
|
return element.lastChild.nodeValue = "" + this.duration + "s";
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Times.Time.prototype, 'duration', {
|
|
get: function() {
|
|
var duration;
|
|
duration = this.stats.duration / 1000 / 1000 / 1000;
|
|
return duration.toFixed(2);
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Times.Time.prototype, 'stats', {
|
|
get: function() {
|
|
var stat, stats, _i, _len, _ref;
|
|
if (!(this.end && this.end.stats)) {
|
|
return {};
|
|
}
|
|
stats = {};
|
|
_ref = this.end.stats.split(',');
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
stat = _ref[_i];
|
|
stat = stat.split('=');
|
|
stats[stat[0]] = stat[1];
|
|
}
|
|
return stats;
|
|
}
|
|
});
|
|
|
|
Log.Deansi = {
|
|
CLEAR_ANSI: /(?:\033)(?:\[0?c|\[[0356]n|\[7[lh]|\[\?25[lh]|\(B|H|\[(?:\d+(;\d+){,2})?G|\[(?:[12])?[JK]|[DM]|\[0K)/gm,
|
|
apply: function(string) {
|
|
var nodes,
|
|
_this = this;
|
|
if (!string) {
|
|
return [];
|
|
}
|
|
string = string.replace(this.CLEAR_ANSI, '');
|
|
nodes = ansiparse(string).map(function(part) {
|
|
return _this.node(part);
|
|
});
|
|
return nodes;
|
|
},
|
|
node: function(part) {
|
|
var classes, node;
|
|
node = {
|
|
type: 'span',
|
|
text: part.text
|
|
};
|
|
if (classes = this.classes(part)) {
|
|
node["class"] = classes.join(' ');
|
|
}
|
|
return node;
|
|
},
|
|
classes: function(part) {
|
|
var result;
|
|
result = [];
|
|
result = result.concat(this.colors(part));
|
|
if (result.length > 0) {
|
|
return result;
|
|
}
|
|
},
|
|
colors: function(part) {
|
|
var colors;
|
|
colors = [];
|
|
if (part.foreground) {
|
|
colors.push(part.foreground);
|
|
}
|
|
if (part.background) {
|
|
colors.push("bg-" + part.background);
|
|
}
|
|
if (part.bold) {
|
|
colors.push('bold');
|
|
}
|
|
if (part.italic) {
|
|
colors.push('italic');
|
|
}
|
|
if (part.underline) {
|
|
colors.push('underline');
|
|
}
|
|
return colors;
|
|
},
|
|
hidden: function(part) {
|
|
if (part.text.match(/\r/)) {
|
|
part.text = part.text.replace(/^.*\r/gm, '');
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
Log.Limit = function(max_lines) {
|
|
this.max_lines = max_lines || 1000;
|
|
return this;
|
|
};
|
|
|
|
Log.Limit.prototype = Log.extend(new Log.Listener, {
|
|
count: 0,
|
|
insert: function(log, node, pos) {
|
|
if (node.type === 'paragraph' && !node.hidden) {
|
|
return this.count += 1;
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Limit.prototype, 'limited', {
|
|
get: function() {
|
|
return this.count >= this.max_lines;
|
|
}
|
|
});
|
|
|
|
Log.Renderer = function() {
|
|
this.frag = document.createDocumentFragment();
|
|
this.para = this.createParagraph();
|
|
this.span = this.createSpan();
|
|
this.text = document.createTextNode('');
|
|
this.fold = this.createFold();
|
|
return this;
|
|
};
|
|
|
|
Log.extend(Log.Renderer.prototype, {
|
|
insert: function(data, pos) {
|
|
var after, before, into, node;
|
|
node = this.render(data);
|
|
if (into = pos != null ? pos.into : void 0) {
|
|
if (typeof into === 'String') {
|
|
into = document.getElementById(pos != null ? pos.into : void 0);
|
|
}
|
|
if (pos != null ? pos.prepend : void 0) {
|
|
this.prependTo(node, into);
|
|
} else {
|
|
this.appendTo(node, into);
|
|
}
|
|
} else if (after = pos != null ? pos.after : void 0) {
|
|
if (typeof after === 'String') {
|
|
after = document.getElementById(pos);
|
|
}
|
|
this.insertAfter(node, after);
|
|
} else if (before = pos != null ? pos.before : void 0) {
|
|
if (typeof before === 'String') {
|
|
before = document.getElementById(pos != null ? pos.before : void 0);
|
|
}
|
|
this.insertBefore(node, before);
|
|
} else {
|
|
this.insertBefore(node);
|
|
}
|
|
return node;
|
|
},
|
|
hide: function(node) {
|
|
node.setAttribute('class', this.addClass(node.getAttribute('class'), 'hidden'));
|
|
return node;
|
|
},
|
|
remove: function(node) {
|
|
if (node) {
|
|
node.parentNode.removeChild(node);
|
|
}
|
|
return node;
|
|
},
|
|
render: function(data) {
|
|
var frag, node, type, _i, _len;
|
|
if (data instanceof Array) {
|
|
frag = this.frag.cloneNode(true);
|
|
for (_i = 0, _len = data.length; _i < _len; _i++) {
|
|
node = data[_i];
|
|
node = this.render(node);
|
|
if (node) {
|
|
frag.appendChild(node);
|
|
}
|
|
}
|
|
return frag;
|
|
} else {
|
|
data.type || (data.type = 'paragraph');
|
|
type = data.type[0].toUpperCase() + data.type.slice(1);
|
|
return this["render" + type](data);
|
|
}
|
|
},
|
|
renderParagraph: function(data) {
|
|
var node, para, type, _i, _len, _ref;
|
|
para = this.para.cloneNode(true);
|
|
if (data.id) {
|
|
para.setAttribute('id', data.id);
|
|
}
|
|
if (data.hidden) {
|
|
para.setAttribute('style', 'display: none;');
|
|
}
|
|
_ref = data.nodes || [];
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
node = _ref[_i];
|
|
type = node.type[0].toUpperCase() + node.type.slice(1);
|
|
node = this["render" + type](node);
|
|
para.appendChild(node);
|
|
}
|
|
return para;
|
|
},
|
|
renderFold: function(data) {
|
|
var fold;
|
|
fold = this.fold.cloneNode(true);
|
|
fold.setAttribute('id', data.id || ("fold-" + data.event + "-" + data.name));
|
|
fold.setAttribute('class', "fold-" + data.event);
|
|
if (data.event === 'start') {
|
|
fold.lastChild.lastChild.nodeValue = data.name;
|
|
} else {
|
|
fold.removeChild(fold.lastChild);
|
|
}
|
|
return fold;
|
|
},
|
|
renderSpan: function(data) {
|
|
var span;
|
|
span = this.span.cloneNode(true);
|
|
if (data.id) {
|
|
span.setAttribute('id', data.id);
|
|
}
|
|
if (data["class"]) {
|
|
span.setAttribute('class', data["class"]);
|
|
}
|
|
span.lastChild.nodeValue = data.text || '';
|
|
return span;
|
|
},
|
|
renderText: function(data) {
|
|
var text;
|
|
text = this.text.cloneNode(true);
|
|
text.nodeValue = data.text;
|
|
return text;
|
|
},
|
|
createParagraph: function() {
|
|
var para;
|
|
para = document.createElement('p');
|
|
para.appendChild(document.createElement('a'));
|
|
return para;
|
|
},
|
|
createFold: function() {
|
|
var fold;
|
|
fold = document.createElement('div');
|
|
fold.appendChild(this.createSpan());
|
|
fold.lastChild.setAttribute('class', 'fold-name');
|
|
return fold;
|
|
},
|
|
createSpan: function() {
|
|
var span;
|
|
span = document.createElement('span');
|
|
span.appendChild(document.createTextNode(' '));
|
|
return span;
|
|
},
|
|
insertBefore: function(node, other) {
|
|
var log;
|
|
if (other) {
|
|
return other.parentNode.insertBefore(node, other);
|
|
} else {
|
|
log = document.getElementById('log');
|
|
return log.insertBefore(node, log.firstChild);
|
|
}
|
|
},
|
|
insertAfter: function(node, other) {
|
|
if (other.nextSibling) {
|
|
return this.insertBefore(node, other.nextSibling);
|
|
} else {
|
|
return this.appendTo(node, other.parentNode);
|
|
}
|
|
},
|
|
prependTo: function(node, other) {
|
|
if (other.firstChild) {
|
|
return other.insertBefore(node, other.firstChild);
|
|
} else {
|
|
return appendTo(node, other);
|
|
}
|
|
},
|
|
appendTo: function(node, other) {
|
|
return other.appendChild(node);
|
|
},
|
|
addClass: function(classes, string) {
|
|
if (classes != null ? classes.indexOf(string) : void 0) {
|
|
return;
|
|
}
|
|
if (classes) {
|
|
return "" + classes + " " + string;
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|
|
});
|
|
|
|
window.Log = Log;
|