mirror of
https://github.com/jsbin/jsbin.git
synced 2026-01-25 15:38:56 +00:00
108 lines
3.4 KiB
JavaScript
108 lines
3.4 KiB
JavaScript
/** =========================================================================
|
||
* Processor
|
||
* Modify the prepared source ready to be written to an iframe
|
||
* ========================================================================== */
|
||
|
||
var processor = (function () {
|
||
|
||
var processor = {};
|
||
|
||
processor.blockingMethods = {
|
||
kill: '<script>try{window.open=function(){};window.print=function(){};window.alert=function(){};window.prompt=function(){};window.confirm=function(){};}catch(e){}</script>',
|
||
// RS: the empty comment in the end of the harness, ensures any
|
||
// open comments are closed, and will ensure the harness is hidden
|
||
// from the user.
|
||
restore: '<!--jsbin live harness--><script>try{delete window.print;delete window.alert;delete window.prompt;delete window.confirm;delete window.open;}catch(e){}</script>'
|
||
};
|
||
|
||
/**
|
||
* Grab the doctype from a string.
|
||
*
|
||
* Returns an object with doctype and tail keys.
|
||
*/
|
||
processor.getDoctype = (function () {
|
||
// Cached regex
|
||
// [\s\S] matches multiline doctypes
|
||
var regex = /<!doctype [\s\S]*?>/i;
|
||
return function (str) {
|
||
var doctype = (str.match(regex) || [''])[0],
|
||
tail = str.substr(doctype.length);
|
||
return {
|
||
doctype: doctype,
|
||
tail: tail
|
||
};
|
||
};
|
||
}());
|
||
|
||
/**
|
||
* Replace HTML characters with encoded equivatents for debug mode.
|
||
*/
|
||
processor.debug = function (source) {
|
||
return '<pre>' + source.replace(/[<>&]/g, function (m) {
|
||
if (m == '<') return '<';
|
||
if (m == '>') return '>';
|
||
if (m == '&') return '&';
|
||
}) + '</pre>';
|
||
};
|
||
|
||
/**
|
||
* Render – build the final source code to be written to the iframe. Takes
|
||
* the original source and an options object.
|
||
*/
|
||
processor.render = function (source, options) {
|
||
|
||
options = options || [];
|
||
source = source || '';
|
||
|
||
var combinedSource = [],
|
||
realtime = (options.requested !== true),
|
||
noRealtimeJs = (options.includeJsInRealtime === false);
|
||
|
||
// If the render was realtime and we don't want javascript in realtime
|
||
// renders – Auto-run JS is unchecked – then strip out the Javascript
|
||
if (realtime && noRealtimeJs) {
|
||
source = source.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
||
}
|
||
|
||
// Strip autofocus from the markup, preventing the focus switching out of
|
||
// the editable area.
|
||
source = source.replace(/(<.*?\s)(autofocus)/g, '$1');
|
||
|
||
// Make sure the doctype is the first thing in the source
|
||
var doctypeObj = processor.getDoctype(source),
|
||
doctype = doctypeObj.doctype;
|
||
source = doctypeObj.tail;
|
||
combinedSource.push(doctype);
|
||
|
||
// Kill the blocking functions
|
||
// IE requires that this is done in the script, rather than off the window
|
||
// object outside of the doc.write.
|
||
if (realtime && options.includeJsInRealtime) {
|
||
combinedSource.push(processor.blockingMethods.kill);
|
||
}
|
||
|
||
// Push the source, split from the doctype above.
|
||
combinedSource.push(source);
|
||
|
||
// Restore the blocking functions
|
||
if (realtime && options.includeJsInRealtime) {
|
||
combinedSource.push(processor.blockingMethods.restore);
|
||
}
|
||
|
||
// In debug mode return an escaped version
|
||
if (options.debug) {
|
||
return processor.debug(combinedSource.join('\n'));
|
||
}
|
||
|
||
return combinedSource.join('\n');
|
||
|
||
};
|
||
|
||
return processor;
|
||
|
||
}());
|
||
|
||
if (typeof exports !== 'undefined') {
|
||
module.exports = processor;
|
||
}
|