Created
May 28, 2016 09:58
-
-
Save spiralx/614f01111bf3effb873e25f1f4e1c984 to your computer and use it in GitHub Desktop.
console.message library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
var cssNumbers = { | |
columnCount: true, | |
fillOpacity: true, | |
flexGrow: true, | |
flexShrink: true, | |
fontWeight: true, | |
lineHeight: true, | |
opacity: true, | |
order: true, | |
orphans: true, | |
widows: true, | |
zIndex: true, | |
zoom: true | |
}; | |
var support = (function () { | |
// Taken from https://github.com/jquery/jquery-migrate/blob/master/src/core.js | |
function uaMatch(ua) { | |
ua = ua.toLowerCase(); | |
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || | |
/(webkit)[ \/]([\w.]+)/.exec(ua) || | |
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || | |
/(msie) ([\w.]+)/.exec(ua) || | |
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; | |
return { | |
browser: match[1] || "", | |
version: match[2] || "0" | |
}; | |
} | |
var browserData = uaMatch(navigator.userAgent); | |
return { | |
isIE: browserData.browser == 'msie' || (browserData.browser == 'mozilla' && parseInt(browserData.version, 10) == 11) | |
}; | |
})(); | |
function ConsoleMessage() { | |
if (!ConsoleMessage.prototype.isPrototypeOf(this)) { | |
return new ConsoleMessage(); | |
} | |
this._rootSpan = { | |
styles: {}, | |
children: [], | |
parent: null | |
}; | |
this._currentSpan = this._rootSpan; | |
this._waiting = 0; | |
this._readyCallback = null; | |
} | |
ConsoleMessage.prototype = { | |
/** | |
* Begins a group. By default the group is expanded. Provide false if you want the group to be collapsed. | |
* @param {boolean} [expanded = true] - | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
group: function (expanded) { | |
this._currentSpan.children.push({ | |
type: expanded === false ? 'groupCollapsed' : 'group', | |
parent: this._currentSpan | |
}); | |
return this; | |
}, | |
/** | |
* Ends the group and returns to writing to the parent message. | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
groupEnd: function () { | |
this._currentSpan.children.push({ | |
type: 'groupEnd', | |
parent: this._currentSpan | |
}); | |
return this; | |
}, | |
/** | |
* Starts a span with particular style and all appended text after it will use the style. | |
* @param {Object} styles - The CSS styles to be applied to all text until endSpan() is called | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
span: function (styles) { | |
var span = { | |
type: 'span', | |
styles: apply(styles || {}, this._currentSpan.styles), | |
children: [], | |
parent: this._currentSpan | |
}; | |
this._currentSpan.children.push(span); | |
this._currentSpan = span; | |
return this; | |
}, | |
/** | |
* Ends the current span styles and backs to the previous styles or the root if there are no other parents. | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
spanEnd: function () { | |
this._currentSpan = this._currentSpan.parent || this._currentSpan; | |
return this; | |
}, | |
/** | |
* Appends a text to the current message. All styles in the current span are applied. | |
* @param {string} text - The text to be appended | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
text: function (text, styles) { | |
this.span(styles); | |
this._currentSpan.children.push({ | |
type: 'text', | |
message: text, | |
parent: this._currentSpan | |
}); | |
return this.spanEnd(); | |
}, | |
/** | |
* Adds a new line to the output. | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
line: function (type) { | |
this._currentSpan.children.push({ | |
type: type || 'log', | |
parent: this._currentSpan | |
}); | |
return this; | |
}, | |
/** | |
* Adds an interactive DOM element to the output. | |
* @param {HTMLElement} element - The DOM element to be added. | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
element: function (element) { | |
this._currentSpan.children.push({ | |
type: 'element', | |
element: element, | |
parent: this._currentSpan | |
}); | |
return this; | |
}, | |
/** | |
* Adds an interactive object tree to the output. | |
* @param {*} object - A value to be added to the output. | |
* @returns {ConsoleMessage} - Returns the message object itself to allow chaining. | |
*/ | |
object: function (object) { | |
this._currentSpan.children.push({ | |
type: 'object', | |
object: object, | |
parent: this._currentSpan | |
}); | |
return this; | |
}, | |
/** | |
* Prints the message to the console. | |
* Until print() is called there will be no result to the console. | |
*/ | |
print: function () { | |
if (typeof console != 'undefined') { | |
var messages = [this._newMessage()]; | |
var message; | |
this._printSpan(this._rootSpan, messages); | |
for (var i = 0; i < messages.length; i++) { | |
message = messages[i]; | |
if (message.text && message.text != '%c' && console[message.type]) { | |
this._printMessage(message); | |
} | |
} | |
} | |
return new ConsoleMessage(); | |
}, | |
_printMessage: function (message) { | |
Function.prototype.apply.call( | |
console[message.type], | |
console, | |
[message.text].concat(message.args) | |
); | |
}, | |
_printSpan: function (span, messages) { | |
var children = span.children; | |
var message = messages[messages.length - 1]; | |
this._addSpanData(span, message); | |
for (var i = 0; i < children.length; i++) { | |
this._handleChild(children[i], messages); | |
} | |
}, | |
_handleChild: function (child, messages) { | |
var message = messages[messages.length - 1]; | |
switch (child.type) { | |
case 'group': | |
messages.push(this._newMessage('group')); | |
break; | |
case 'groupCollapsed': | |
messages.push(this._newMessage('groupCollapsed')); | |
break; | |
case 'groupEnd': | |
message = this._newMessage('groupEnd'); | |
message.text = ' '; | |
messages.push(message); | |
messages.push(this._newMessage()); | |
break; | |
case 'span': | |
this._printSpan(child, messages); | |
this._addSpanData(child, message); | |
this._addSpanData(child.parent, message); | |
break; | |
case 'text': | |
message.text += child.message; | |
break; | |
case 'element': | |
message.text += '%o'; | |
message.args.push(child.element); | |
break; | |
case 'object': | |
message.text += '%O'; | |
message.args.push(child.object); | |
break; | |
case 'log': | |
messages.push(this._newMessage(child.type)); | |
break; | |
} | |
}, | |
_addSpanData: function (span, message) { | |
if (!support.isIE) { | |
if (message.text.substring(message.text.length - 2) == '%c') { | |
message.args[message.args.length - 1] = this._stylesString(span.styles); | |
} else { | |
message.text += '%c'; | |
message.args.push(this._stylesString(span.styles)); | |
} | |
} | |
}, | |
_newMessage: function (type) { | |
return { | |
type: type || 'log', | |
text: '', | |
args: [] | |
}; | |
}, | |
_stylesString: function (styles) { | |
var result = ''; | |
var value; | |
var key; | |
for (key in styles) { | |
value = styles[key]; | |
key = this._fixCssStyleKey(key); | |
if (typeof value === 'number' && !cssNumbers[key]) { | |
value += 'px'; | |
} | |
result += this._toDashKey(key) + ':' + value + ';'; | |
} | |
return result; | |
}, | |
_fixCssStyleKey: function (key) { | |
return key.replace(/-\w/g, function (match) { | |
return match.charAt(1).toUpperCase(); | |
}); | |
}, | |
_toDashKey: function (key) { | |
return key.replace(/[A-Z]/g, function (match) { | |
return '-' + match.toLowerCase(); | |
}); | |
} | |
}; | |
function apply(options, object) { | |
for (var key in object) { | |
if (options[key] === undefined) { | |
options[key] = object[key]; | |
} | |
} | |
return options; | |
} | |
if (typeof window != 'undefined') { | |
if (!window.console) { | |
window.console = {}; | |
} | |
/** | |
* Creates a message object. | |
* @returns {ConsoleMessage} - The message object | |
*/ | |
window.console.message = ConsoleMessage; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From the GitHub repository...
API
text (text: string, styles: Object?)
Appends text to the current message in the current style if
styles
is not set, otherwisestyles
is used to override the current style just for this text.console.message()
.text('Error: ', { color: 'red' })
.text('this is more useful scenario')
.print()
object (object: Object)
Adds an interactive object tree to the output.
span (styles: Object)
spanEnd ()
Start a span with the CSS properties defined by the
styles
object, all appended text after will use this style until the nextspanEnd ()
:group (expanded: boolean = true)
groupEnd ()
Begins a group with
group ()
, which is then ended usinggroupEnd ()
. By default the group is expanded, passfalse
togroup ()
if you want the group to be collapsed.line ()
Adds a new line to the output.
print ()
Prints the message to the console. Every message chain should end with
print ()
otherwise no message will be displayed.