Skip to content

Commit cea5c5a

Browse files
author
Andrew Start
committed
Added support for grouping.
1 parent ccec782 commit cea5c5a

File tree

2 files changed

+156
-60
lines changed

2 files changed

+156
-60
lines changed

src/springroll/remote/RemoteTrace.js

Lines changed: 128 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@
3939
* @property {jquery} output
4040
*/
4141
this.output = $("#trace");
42+
43+
/**
44+
* A stack of jquery elements representing log groups, so that logs can be
45+
* added to the proper groups.
46+
* @property {Array} groupStack
47+
*/
48+
this.groupStack = [];
49+
50+
/**
51+
* The next id for a group to ensure unique ids for each one.
52+
* @property {Number} nextGroupId
53+
*/
54+
this.nextGroupId = 0;
4255

4356
/**
4457
* Clear the output on a new session
@@ -132,6 +145,9 @@
132145
this.setFilters(filters ? filters.split(',') : allFilters);
133146

134147
this.clear();
148+
149+
if(DEBUG)
150+
window.RemoteTrace = this;
135151
};
136152

137153
// Reference to the prototype
@@ -245,6 +261,7 @@
245261
p.clear = function()
246262
{
247263
this.output.empty();
264+
this.groupStack.length = 0;
248265
this.saveButton.addClass('disabled');
249266
this.clearButton.addClass('disabled');
250267
};
@@ -314,8 +331,13 @@
314331

315332
result = JSON.parse(result);
316333

317-
var level = (result.level || "GENERAL").toLowerCase();
318-
var now = (new Date()).toLocaleString();
334+
var level = (result.level || "GENERAL").toLowerCase(),
335+
stack = result.stack;
336+
337+
var now = new Date();
338+
if(result.time)
339+
now.setTime(result.time);
340+
now = now.toLocaleString();
319341

320342
this.saveButton.removeClass('disabled');
321343
this.clearButton.removeClass('disabled');
@@ -326,57 +348,36 @@
326348
}
327349
else if(level == "clear")
328350
{
351+
this.clear();
329352
}
330-
else if(level == "group")
331-
{
332-
}
333-
else if(level == "groupCollapsed")
353+
else if(level == "group" || level == "groupcollapsed")
334354
{
355+
var log = this.prepareAndLogMessage(now, result.message, "general", stack),
356+
groupId = "group_" + this.nextGroupId++;
357+
var chevron = $("<span class='groupToggle' data-toggle='collapse' data-target='#" + groupId + "'></span>");
358+
chevron.append(
359+
$("<span class='glyphicon glyphicon-chevron-right right'></span>"),
360+
$("<span class='glyphicon glyphicon-chevron-down down'></span>")
361+
);
362+
log.prepend(chevron);
363+
364+
var group = $("<div class='group log collapse in' id='" + groupId + "'></div>");
365+
this.getLogParent().append(group);
366+
this.groupStack.push(group);
367+
368+
if(level == "groupcollapsed")
369+
{
370+
chevron.addClass("collapsed");
371+
group.collapse("hide");//.removeClass("in");
372+
}
335373
}
336-
else if(level == "groupEnd")
374+
else if(level == "groupend")
337375
{
376+
this.groupStack.pop();
338377
}
339378
else if (Array.isArray(result.message))
340379
{
341-
var message, i, j, tokens, token, sub;
342-
343-
for (i = 0; i < result.message.length; i++)
344-
{
345-
message = result.message[i];
346-
347-
// Ignore non-strings
348-
if (typeof message == "string")
349-
{
350-
tokens = message.match(/%[sdifoObxec]/g);
351-
352-
if (tokens)
353-
{
354-
for (j = 0; j < tokens.length; j++)
355-
{
356-
token = tokens[j];
357-
sub = result.message[++i];
358-
359-
// CSS substitution check
360-
if (token == "%c")
361-
{
362-
sub = '<span style="'+ sub + '">';
363-
message += '</span>';
364-
}
365-
// Do object substitution
366-
else if (token == "%o" || token == "%O")
367-
{
368-
sub = JSON.stringify(sub, null, "\t");
369-
}
370-
else if(token == "%d" || token == "%i")
371-
{
372-
sub = parseInt(sub);
373-
}
374-
message = message.replace(token, String(sub));
375-
}
376-
}
377-
}
378-
this.logMessage(now, message, level);
379-
}
380+
this.prepareAndLogMessage(now, result.message, level, stack);
380381
}
381382

382383
if (this.maxLogs)
@@ -390,29 +391,98 @@
390391
this.output.scrollTop(this.output[0].scrollHeight);
391392
}
392393
};
394+
395+
p.prepareAndLogMessage = function(now, messages, level, stack)
396+
{
397+
if(!messages || !messages.length)
398+
{
399+
return this.logMessage(now, [""], level, stack);
400+
}
401+
402+
var message, j, tokens, token, sub;
403+
404+
message = messages[0];
405+
406+
//if the first message is a string, then check it for string formatting tokens
407+
if (typeof message == "string")
408+
{
409+
tokens = message.match(/%[sdifoObxec]/g);
410+
411+
if (tokens)
412+
{
413+
for (j = 0; j < tokens.length; j++)
414+
{
415+
token = tokens[j];
416+
sub = messages[1];
417+
418+
// CSS substitution check
419+
if (token == "%c")
420+
{
421+
sub = '<span style="'+ sub + '">';
422+
message += '</span>';
423+
}
424+
// Do object substitution
425+
else if (token == "%o" || token == "%O")
426+
{
427+
sub = JSON.stringify(sub, null, "\t");
428+
}
429+
else if(token == "%d" || token == "%i")
430+
{
431+
sub = parseInt(sub);
432+
}
433+
message = message.replace(token, String(sub));
434+
435+
messages.splice(1, 1);
436+
}
437+
}
438+
messages[0] = message;
439+
}
440+
return this.logMessage(now, messages, level, stack);
441+
};
393442

394443
/**
395444
* Log a new message
396445
* @method logMessage
397446
* @param {String} now The current time name
398-
* @param {String} message The message to log
447+
* @param {Array} messages The message to log
399448
* @param {String} level The level to use
449+
* @param {Array} [stack] The stack trace for the log.
400450
*/
401-
p.logMessage = function(now, message, level)
451+
p.logMessage = function(now, messages, level, stack)
402452
{
403-
if (typeof message === "object")
453+
var message = "";
454+
for(var i = 0; i < messages.length; ++i)
404455
{
405-
message = JSON.stringify(message, null, "\t");
456+
if(i > 0)
457+
message += " ";
458+
if (typeof message === "object")
459+
{
460+
message += JSON.stringify(messages[i], null, "\t");
461+
}
462+
else
463+
message += messages[i];
406464
}
407-
this.output.append(
408-
$("<div class='log'></div>")
409-
.addClass(level)
410-
.append(
411-
$("<span class='type'></span>").text(level.toUpperCase()),
412-
$("<span class='timestamp'></span>").text(now),
413-
$("<span class='message'></span>").html(message)
414-
)
465+
var log = $("<div class='log'></div>")
466+
.addClass(level)
467+
.append(
468+
$("<span class='type'></span>").text(level.toUpperCase()),
469+
$("<span class='timestamp'></span>").text(now),
470+
$("<span class='message'></span>").html(message)
415471
);
472+
this.getLogParent().append(log);
473+
return log;
474+
};
475+
476+
/**
477+
* Gets the JQuery element that logs should be added to.
478+
* @method getLogParent
479+
* @return {jquery} The div to add logs to.
480+
*/
481+
p.getLogParent = function()
482+
{
483+
if(this.groupStack.length)
484+
return this.groupStack[this.groupStack.length - 1];
485+
return this.output;
416486
};
417487

418488
/**

src/springroll/remote/less/trace.less

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
.user-deselect() {
2+
-webkit-user-select:none;
3+
-moz-user-select:none;
4+
-o-user-select:none;
5+
-ms-user-select:none;
6+
user-select:none;
7+
}
8+
19
#trace {
210
overflow: auto;
311
position:absolute;
@@ -7,9 +15,9 @@
715
right:0;
816
padding:10px;
917

10-
.error,
18+
.error,
1119
.warning,
12-
.info,
20+
.info,
1321
.debug,
1422
.general {
1523
display:none;
@@ -22,6 +30,12 @@
2230
&.show-general .general {
2331
display: block;
2432
}
33+
34+
.group {
35+
padding-left:20px;
36+
display: block;
37+
overflow: hidden;
38+
}
2539

2640
.log {
2741
margin-bottom:5px;
@@ -48,6 +62,18 @@
4862
}
4963
.message {
5064
}
65+
66+
.groupToggle {
67+
.user-deselect();
68+
cursor:pointer;
69+
padding-right: 5px;
70+
.down { display:inline }
71+
.right { display:none }
72+
&.collapsed {
73+
.down { display:none}
74+
.right { display:inline }
75+
}
76+
}
5177
}
5278
// Options for the trace
5379
&.wrap .log {

0 commit comments

Comments
 (0)