mirror of
https://github.com/jsbin/jsbin.git
synced 2026-02-01 16:46:05 +00:00
Filthy little hack: when the live preview is open, any calls to console.* will switch the context to the jsbin preview - NOT the actual current window. Note that this only works in Chrome due to the way the argument.callee call stack is exposed.
This commit is contained in:
parent
46f73fbd51
commit
6a4492e1be
53
js/render/consoleContext.js
Normal file
53
js/render/consoleContext.js
Normal file
@ -0,0 +1,53 @@
|
||||
function ConsoleContext(context) {
|
||||
var self = this;
|
||||
this.context = context;
|
||||
this.executable = typeof context == 'function';
|
||||
|
||||
this.active = false;
|
||||
this.original = window.top.console;
|
||||
|
||||
// yeah, lame, but we've no way to detect the console arguments support, because
|
||||
// it can only be tested from the /actual/ console.
|
||||
this.supported = /chrome/i.test(navigator.userAgent);
|
||||
}
|
||||
|
||||
ConsoleContext.prototype = {
|
||||
hijack: function (method, args) {
|
||||
var context = this.executable ? this.context() : this.context;
|
||||
var re = new RegExp('console\.' + method + '\\((.*?)\\)');
|
||||
if (!/renderLivePreview/.test(arguments.callee.caller.caller.toString()) && context) {
|
||||
context.eval('console.' + method + '(' + arguments.callee.caller.caller.arguments[0].toString().match(re)[1] + ')');
|
||||
} else {
|
||||
this.original[method].apply(this.original, args);
|
||||
}
|
||||
},
|
||||
log: function () {
|
||||
this.hijack('log', [].slice.call(arguments));
|
||||
},
|
||||
debug: function () {
|
||||
this.hijack('debug', [].slice.call(arguments));
|
||||
},
|
||||
dir: function () {
|
||||
this.hijack('dir', [].slice.call(arguments));
|
||||
},
|
||||
warn: function () {
|
||||
this.hijack('warn', [].slice.call(arguments));
|
||||
},
|
||||
error: function () {
|
||||
this.hijack('error', [].slice.call(arguments));
|
||||
},
|
||||
activate: function () {
|
||||
if (this.supported) {
|
||||
window.top.console = this;
|
||||
if (console == this) this.original.log('--- console context switched to jsbin ---');
|
||||
this.active = true;
|
||||
}
|
||||
},
|
||||
deactivate: function () {
|
||||
if (this.supported) {
|
||||
this.active = false;
|
||||
if (console == this) this.original.log('--- console context switched back to original ---');
|
||||
window.top.console = this.original;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -2,6 +2,11 @@ var $live = $('#live'),
|
||||
$bin = $('#bin'),
|
||||
throttledPreview = throttle(renderLivePreview, 100);
|
||||
|
||||
//= require "consoleContext"
|
||||
var hijackedConsole = new ConsoleContext(function () {
|
||||
return $('#live iframe').length ? $('#live iframe')[0].contentWindow : null;
|
||||
});
|
||||
|
||||
// could chain - but it's more readable like this
|
||||
$live.bind('show', function () {
|
||||
$bin.addClass('live');
|
||||
@ -11,10 +16,12 @@ $live.bind('show', function () {
|
||||
// start timer
|
||||
$(document).bind('codeChange.live', throttledPreview);
|
||||
renderLivePreview();
|
||||
hijackedConsole.activate();
|
||||
}).bind('hide', function () {
|
||||
$(document).unbind('codeChange.live');
|
||||
localStorage && localStorage.removeItem('livepreview');
|
||||
$bin.removeClass('live');
|
||||
hijackedConsole.deactivate();
|
||||
}).bind('toggle', function () {
|
||||
$live.trigger($bin.is('.live') ? 'hide' : 'show');
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user