drop embedding of JS/CSS files in ace.js. May result in a little performance drop but makes code much smaller

This commit is contained in:
Matthias Bartelmeß 2012-02-19 15:02:54 +01:00
parent 7e7646b517
commit 9ede14a546
2 changed files with 56 additions and 176 deletions

View File

@ -213,72 +213,6 @@ function _handle(req, res, jsFilename, jsFiles) {
} }
} }
// find all includes in ace.js and embed them.
function getAceFile(callback) {
fs.readFile(JS_DIR + 'ace.js', "utf8", function(err, data) {
if(ERR(err, callback)) return;
// Find all includes in ace.js and embed them
var founds = data.match(/\$\$INCLUDE_[a-zA-Z_]+\([a-zA-Z0-9.\/_"-]+\)/gi);
if (!settings.minify) {
founds = [];
}
founds.push('$$INCLUDE_JS("../static/js/require-kernel.js")');
data += ';\n';
data += 'Ace2Editor.EMBEDED = Ace2Editor.EMBEDED || {};\n';
//go trough all includes
async.forEach(founds, function (item, callback) {
var filename = item.match(/"([^"]*)"/)[1];
var type = item.match(/INCLUDE_([A-Z]+)/)[1];
var shortFilename = (filename.match(/^..\/static\/js\/(.*)$/, '')||[])[1];
//read the included files
if (shortFilename) {
if (shortFilename == 'require-kernel.js') {
// the kernel isnt actually on the file system.
handleEmbed(null, requireDefinition());
} else {
var contents = '';
tarCode(tar[shortFilename] || shortFilename
, function (content) {
contents += content;
}
, function () {
handleEmbed(null, contents);
}
);
}
} else {
fs.readFile(ROOT_DIR + filename, "utf8", handleEmbed);
}
function handleEmbed(error, data_) {
if (error) {
return; // Don't bother to include it.
}
if (settings.minify) {
if (type == "JS") {
try {
data_ = compressJS([data_]);
} catch (e) {
// Ignore, include uncompresseed, which will break in browser.
}
} else {
data_ = compressCSS([data_]);
}
}
data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = '
+ JSON.stringify(data_) + ';\n';
callback();
}
}, function(error) {
callback(error, data);
});
});
}
exports.requireDefinition = requireDefinition; exports.requireDefinition = requireDefinition;
function requireDefinition() { function requireDefinition() {
return 'var require = ' + RequireKernel.kernelSource + ';\n'; return 'var require = ' + RequireKernel.kernelSource + ';\n';
@ -288,12 +222,8 @@ function tarCode(jsFiles, write, callback) {
write('require.define({'); write('require.define({');
var initialEntry = true; var initialEntry = true;
async.forEach(jsFiles, function (filename, callback){ async.forEach(jsFiles, function (filename, callback){
if (filename == 'ace.js') { fs.readFile(JS_DIR + filename, "utf8", handleFile);
getAceFile(handleFile);
} else {
fs.readFile(JS_DIR + filename, "utf8", handleFile);
}
function handleFile(err, data) { function handleFile(err, data) {
if(ERR(err, callback)) return; if(ERR(err, callback)) return;
var srcPath = JSON.stringify('/' + filename); var srcPath = JSON.stringify('/' + filename);

View File

@ -133,74 +133,6 @@ function Ace2Editor()
return info.ace_getUnhandledErrors(); return info.ace_getUnhandledErrors();
}; };
function sortFilesByEmbeded(files) {
var embededFiles = [];
var remoteFiles = [];
if (Ace2Editor.EMBEDED) {
for (var i = 0, ii = files.length; i < ii; i++) {
var file = files[i];
if (Object.prototype.hasOwnProperty.call(Ace2Editor.EMBEDED, file)) {
embededFiles.push(file);
} else {
remoteFiles.push(file);
}
}
} else {
remoteFiles = files;
}
return {embeded: embededFiles, remote: remoteFiles};
}
function pushRequireScriptTo(buffer) {
var KERNEL_SOURCE = '../static/js/require-kernel.js';
var KERNEL_BOOT = 'require.setRootURI("../minified/");\nrequire.setGlobalKeyPath("require");'
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
buffer.push('<script type="text/javascript">');
buffer.push(Ace2Editor.EMBEDED[KERNEL_SOURCE]);
buffer.push(KERNEL_BOOT);
buffer.push('<\/script>');
}
}
function pushScriptsTo(buffer) {
/* Folling is for packaging regular expression. */
/* $$INCLUDE_JS("../static/js/ace2_inner.js"); */
var ACE_SOURCE = '../static/js/ace2_inner.js';
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[ACE_SOURCE]) {
buffer.push('<script type="text/javascript">');
buffer.push(Ace2Editor.EMBEDED[ACE_SOURCE]);
buffer.push('require("/ace2_inner");');
buffer.push('<\/script>');
} else {
file = ACE_SOURCE;
file = file.replace(/^\.\.\/static\/js\//, '../minified/');
buffer.push('<script type="application/javascript" src="' + file + '"><\/script>');
buffer.push('<script type="text/javascript">');
buffer.push('require("/ace2_inner");');
buffer.push('<\/script>');
}
}
function pushStyleTagsFor(buffer, files) {
var sorted = sortFilesByEmbeded(files);
var embededFiles = sorted.embeded;
var remoteFiles = sorted.remote;
if (embededFiles.length > 0) {
buffer.push('<style type="text/css">');
for (var i = 0, ii = embededFiles.length; i < ii; i++) {
var file = embededFiles[i];
buffer.push(Ace2Editor.EMBEDED[file].replace(/<\//g, '<\\/'));
}
buffer.push('<\/style>');
}
for (var i = 0, ii = remoteFiles.length; i < ii; i++) {
var file = remoteFiles[i];
buffer.push('<link rel="stylesheet" type="text/css" href="' + file + '"\/>');
}
}
editor.destroy = pendingInit(function() editor.destroy = pendingInit(function()
{ {
info.ace_dispose(); info.ace_dispose();
@ -208,7 +140,9 @@ function Ace2Editor()
delete ace2.registry[info.id]; delete ace2.registry[info.id];
info = null; // prevent IE 6 closure memory leaks info = null; // prevent IE 6 closure memory leaks
}); });
editor.init = function(containerId, initialCode, doneFunc) editor.init = function(containerId, initialCode, doneFunc)
{ {
@ -220,7 +154,8 @@ function Ace2Editor()
doActionsPendingInit(); doActionsPendingInit();
doneFunc(); doneFunc();
}; };
// This function builds the DOM structure of the editor which consists of two nested iFrames
(function() (function()
{ {
var doctype = "<!doctype html>"; var doctype = "<!doctype html>";
@ -240,50 +175,64 @@ function Ace2Editor()
for (var i = 0, ii = iframeHTML.length; i < ii; i++) { for (var i = 0, ii = iframeHTML.length; i < ii; i++) {
iframeHTML[i] = JSON.parse(iframeHTML[i]); iframeHTML[i] = JSON.parse(iframeHTML[i]);
} }
// Build HTML of editable iFrame
// Add Stylesheets to iFrame
iframeHTML.push('<link rel="stylesheet" type="text/css" href="../static/css/iframe_editor.css">');
iframeHTML.push('<link rel="stylesheet" type="text/css" href="../static/css/pad.css">');
iframeHTML.push('<link rel="stylesheet" type="text/css" href="../static/custom/pad.css">');
// Include Require Kernel and ace2_innner.js in iFrame;
iframeHTML.push('<script type="text/javascript" src="../static/js/require-kernel.js"></script>');
iframeHTML.push('<script type="text/javascript">');
// calls to these functions ($$INCLUDE_...) are replaced when this file is processed // Configure reqire
// and compressed, putting the compressed code from the named file directly into the iframeHTML.push('require.setRootURI("../minified/");');
// source here. iframeHTML.push('require.setGlobalKeyPath("require");');
// these lines must conform to a specific format because they are passed by the build script:
var includedCSS = [];
var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
$$INCLUDE_CSS("../static/css/iframe_editor.css");
$$INCLUDE_CSS("../static/css/pad.css");
$$INCLUDE_CSS("../static/custom/pad.css");
pushStyleTagsFor(iframeHTML, includedCSS);
var includedJS = [];
var $$INCLUDE_JS = function(filename) {includedJS.push(filename)};
pushRequireScriptTo(iframeHTML);
// Inject my plugins into my child. // Inject my plugins into my child.
iframeHTML.push('\ iframeHTML.push('require.define("/plugins", null);');
<script type="text/javascript">\ iframeHTML.push('require.define("/plugins.js", function (require, exports, module) {');
require.define("/plugins", null);\n\ iframeHTML.push('module.exports = parent.parent.require("/plugins");');
require.define("/plugins.js", function (require, exports, module) {\ iframeHTML.push('});');
module.exports = parent.parent.require("/plugins");\ iframeHTML.push('<\/script>');
});\
</script>\ // Require ace2
'); iframeHTML.push('<script type="text/javascript" src="../minified/ace2_inner.js"></script>');
pushScriptsTo(iframeHTML); iframeHTML.push('<script type="text/javascript">');
iframeHTML.push('require("/ace2_inner");');
iframeHTML.push('<\/script>');
iframeHTML.push('<style type="text/css" title="dynamicsyntax"></style>'); iframeHTML.push('<style type="text/css" title="dynamicsyntax"></style>');
iframeHTML.push('</head><body id="innerdocbody" class="syntax" spellcheck="false">&nbsp;</body></html>'); iframeHTML.push('</head><body id="innerdocbody" class="syntax" spellcheck="false">&nbsp;</body></html>');
editor.iframeHTML = iframeHTML.join('\n');
// Expose myself to global for my child frame. // Expose myself to global for my child frame.
var thisFunctionsName = "ChildAccessibleAce2Editor"; var thisFunctionsName = "ChildAccessibleAce2Editor";
(function () {return this}())[thisFunctionsName] = Ace2Editor; (function () {return this}())[thisFunctionsName] = Ace2Editor;
var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' +
'window.onload = function()' +
'{ window.onload = null; setTimeout' + '(function() ' +
'{ var iframe = document.createElement("IFRAME"); ' +
'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' +
'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE
'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' +
'iframe.ace_outerWin = window; ' +
'var doc = iframe.contentWindow.document; doc.open();doc.write(editorInfo.editor.iframeHTML); doc.close();'+
'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; };' +
'}, 0); }';
// Build HTML of editor iFrame;
var outerHTML = [doctype, '<html><head>'];
outerHTML.push('<link rel="stylesheet" type="text/css" href="../static/css/iframe_editor.css">');
outerHTML.push('<link rel="stylesheet" type="text/css" href="../static/css/pad.css">');
outerHTML.push('<link rel="stylesheet" type="text/css" href="../static/custom/pad.css"');
var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + 'window.onload = function() ' + '{ window.onload = null; setTimeout' + '(function() ' + '{ var iframe = document.createElement("IFRAME"); ' + 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE
'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + 'iframe.ace_outerWin = window; ' + 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; ' + 'var doc = iframe.contentWindow.document; doc.open(); var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');doc.write(text); doc.close(); ' + '}, 0); }';
var outerHTML = [doctype, '<html><head>']
var includedCSS = [];
var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
$$INCLUDE_CSS("../static/css/iframe_editor.css");
$$INCLUDE_CSS("../static/css/pad.css");
$$INCLUDE_CSS("../static/custom/pad.css");
pushStyleTagsFor(outerHTML, includedCSS);
// bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
// (throbs busy while typing) // (throbs busy while typing)
@ -295,6 +244,7 @@ function Ace2Editor()
document.getElementById(containerId).appendChild(outerFrame); document.getElementById(containerId).appendChild(outerFrame);
var editorDocument = outerFrame.contentWindow.document; var editorDocument = outerFrame.contentWindow.document;
editorDocument.open(); editorDocument.open();
editorDocument.write(outerHTML.join('')); editorDocument.write(outerHTML.join(''));