core/api/soft/ace/ace-master/Makefile.dryice.js

938 lines
31 KiB
JavaScript
Raw Normal View History

2023-08-14 09:15:58 +05:00
#!/usr/bin/env node
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
/*global Buffer, setImmediate*/
var fs = require("fs");
var path = require("path");
var copy = require('architect-build/copy');
var build = require('architect-build/build');
var ACE_HOME = __dirname;
var BUILD_DIR = ACE_HOME + "/build";
var CACHE = {};
function generateAmdModules() {
var root = ACE_HOME + "/";
function iterate(dir) {
var filenames = fs.readdirSync(root + dir);
filenames.forEach(function(name) {
var path = dir + name;
var stat = fs.statSync(root + path);
var newPath = path.replace("src", "lib/ace");
if (stat.isDirectory()) {
try {
fs.mkdirSync(root + newPath);
} catch(e) {}
iterate(path + "/");
} else if (/\.js/.test(name) && !/worker_client\.js$/.test(name)) {
transform(path, newPath);
}
});
}
function transform(path, newPath) {
var data = fs.readFileSync(root + path, "utf-8");
data = "define(function(require, exports, module){"
+ compileTypescript(data)
+"\n});";
fs.writeFileSync(root + newPath, data, "utf-8");
}
function compileTypescript(code) {
var ts = require("typescript");
return ts.transpileModule(code, {
compilerOptions: {
newLine: "lf",
downlevelIteration: true,
suppressExcessPropertyErrors: true,
module: ts.ModuleKind.CommonJS,
removeComments: false,
sourceMap: false,
inlineSourceMap: false,
target: "ES5"
},
fileName: ""
}).outputText;
}
iterate("src/");
}
function main(args) {
if (args.indexOf("updateModes") !== -1) {
return updateModes();
}
var type = "minimal";
args = args.map(function(x) {
if (x[0] == "-" && x[1] != "-")
return "-" + x;
return x;
}).filter(Boolean);
if (args[2] && (args[2][0] != "-" || args[2].indexOf("h") != -1))
type = args[2];
var i = args.indexOf("--target");
if (i != -1 && args[i+1])
BUILD_DIR = args[i+1];
if (args.indexOf("--h") != -1 || args.indexOf("-h") != -1 || args.indexOf("--help") != -1) {
return showHelp();
}
if (type == "css") {
return extractCss();
}
if (type == "nls") {
return extractNls();
}
if (args.indexOf("--reuse") === -1) {
console.log("updating files in lib/ace");
generateAmdModules();
}
if (type == "minimal") {
buildAce({
compress: args.indexOf("--m") != -1,
noconflict: args.indexOf("--nc") != -1,
shrinkwrap: args.indexOf("--s") != -1
});
} else if (type == "normal") {
ace();
} else if (type == "demo") {
demo();
} else if (type == "full") {
ace();
demo();
} else if (type == "highlighter") {
// TODO
}
}
function showHelp(type) {
console.log("--- Ace Dryice Build Tool ---");
console.log("");
console.log("Options:");
console.log(" minimal Places necessary Ace files out in build dir; uses configuration flags below [default]");
console.log(" normal Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min");
console.log(" demo Runs demo build of Ace");
console.log(" full all of above");
console.log(" highlighter ");
console.log(" css extract css files");
console.log(" nls extract nls messages");
console.log("args:");
console.log(" --target ./path path to build folder");
console.log("flags:");
console.log(" --h print this help");
console.log(" --m minify");
console.log(" --nc namespace require");
console.log(" --s shrinkwrap (combines all output files into one)");
console.log("");
if (type)
console.log(" output for " + type + " generated in " + BUILD_DIR);
}
function ace() {
console.log('# ace License | Readme | Changelog ---------');
copy.file(ACE_HOME + "/build_support/editor.html", BUILD_DIR + "/editor.html");
copy.file(ACE_HOME + "/LICENSE", BUILD_DIR + "/LICENSE");
copy.file(ACE_HOME + "/CHANGELOG.md", BUILD_DIR + "/CHANGELOG.md");
console.log('# ace ---------');
for (var i = 0; i < 4; i++) {
buildAce({compress: i & 2, noconflict: i & 1, check: true});
}
}
function buildTypes() {
var aceCodeModeDefinitions = '/// <reference path="./ace-modes.d.ts" />';
// ace-builds package has different structure and can't use mode types defined for the ace-code.
// ace-builds modes are declared along with other modules in the ace-modules.d.ts file below.
var definitions = fs.readFileSync(ACE_HOME + '/ace.d.ts', 'utf8').replace(aceCodeModeDefinitions, '');
var paths = fs.readdirSync(BUILD_DIR + '/src-noconflict');
var moduleRef = '/// <reference path="./ace-modules.d.ts" />';
fs.readdirSync(BUILD_DIR + '/src-noconflict/snippets').forEach(function(path) {
paths.push("snippets/" + path);
});
var moduleNameRegex = /^(mode|theme|ext|keybinding)-|^snippets\//;
var pathModules = [
"declare module 'ace-builds/webpack-resolver';",
"declare module 'ace-builds/esm-resolver';",
"declare module 'ace-builds/src-noconflict/ace';"
].concat(paths.map(function(path) {
if (moduleNameRegex.test(path)) {
var moduleName = path.split('.')[0];
return "declare module 'ace-builds/src-noconflict/" + moduleName + "';";
}
}).filter(Boolean)).join("\n") + "\n";
fs.writeFileSync(BUILD_DIR + '/ace.d.ts', moduleRef + '\n' + definitions);
fs.writeFileSync(BUILD_DIR + '/ace-modules.d.ts', pathModules);
var esmUrls = [];
var loader = paths.map(function(path) {
if (/\.js$/.test(path) && !/^ace\.js$/.test(path)) {
var moduleName = path.split('.')[0].replace(/-/, "/");
if (/^worker/.test(moduleName))
moduleName = "mode" + moduleName.slice(6) + "_worker";
moduleName = moduleName.replace(/keybinding/, "keyboard");
esmUrls.push("ace.config.setModuleLoader('ace/" + moduleName + "', () => import('./src-noconflict/" + path + "'));");
return "ace.config.setModuleUrl('ace/" + moduleName + "', require('file-loader?esModule=false!./src-noconflict/" + path + "'));";
}
}).join('\n');
var esmLoader = esmUrls.join('\n');
fs.writeFileSync(BUILD_DIR + '/webpack-resolver.js', loader, "utf8");
fs.writeFileSync(BUILD_DIR + '/esm-resolver.js', esmLoader, "utf8");
}
function demo() {
console.log('# kitchen sink ---------');
var version = "", ref = "";
try {
version = JSON.parse(fs.readFileSync(ACE_HOME + "/package.json")).version;
ref = fs.readFileSync(ACE_HOME + "/.git-ref").toString();
} catch(e) {}
function changeComments(data) {
return (data
.replace("doc/site/images/ace-logo.png", "demo/kitchen-sink/ace-logo.png")
.replace(/<!\-\-DEVEL[\d\D]*?DEVEL\-\->/g, "")
.replace(/PACKAGE\-\->|<!\-\-PACKAGE/g, "")
.replace(/\/\*DEVEL[\d\D]*?DEVEL\*\//g, "")
.replace(/PACKAGE\*\/|\/\*PACKAGE/g, "")
.replace("%version%", version)
.replace("%commit%", ref)
);
}
copy(ACE_HOME +"/demo/kitchen-sink/docs/", BUILD_DIR + "/demo/kitchen-sink/docs/");
copy.file(ACE_HOME + "/demo/kitchen-sink/logo.png", BUILD_DIR + "/demo/kitchen-sink/logo.png");
copy.file(ACE_HOME + "/demo/kitchen-sink/styles.css", BUILD_DIR + "/demo/kitchen-sink/styles.css");
copy.file(ACE_HOME + "/kitchen-sink.html", BUILD_DIR + "/kitchen-sink.html", changeComments);
buildSubmodule({}, {
require: ["kitchen-sink/demo"],
projectType: "demo"
}, BUILD_DIR + "/demo/kitchen-sink/demo");
copy(ACE_HOME + "/demo/", BUILD_DIR + "/demo/", {
shallow: true,
exclude: /\s|requirejs/,
include: /\.(js|html)$/,
replace: function(source) {
if (!/^\s*</.test(source))
return source;
var removeRequireJS;
source = source.replace(/<script src="kitchen-sink\/require.js"[\s\S]+?require\(\[([^\]]+).*/, function(e, m) {
removeRequireJS = true;
var scripts = m.split(/,\s*/);
var result = [];
function comment(str) {result.push("<!-- " + str + " -->");}
function script(str) {result.push('<script src="../src/' + str + '.js"></script>');}
scripts.forEach(function(s) {
s = s.replace(/"/g, "");
if (s == "ace/ace") {
comment("load ace");
script("ace");
} else {
var extName = s.match(/[^/]*$/)[0];
comment("load ace " + extName + " extension");
script("ext-" + extName);
}
});
result.push("<script>");
return result.join("\n");
});
if (removeRequireJS)
source = source.replace(/\s*\}\);?\s*(<\/script>)/, "\n$1");
source = source.replace(/"\.\.\/build\//g, function(e) {
console.log(e); return '"../';
});
return source;
}
});
}
function jsFileList(path, filter) {
path = ACE_HOME + "/" + path;
if (!filter)
filter = /_test/;
return fs.readdirSync(path).map(function(x) {
if (x.slice(-3) == ".js" && !filter.test(x) && !/\s|BASE|(\b|_)dummy(\b|_)|[\-\.]css\.js$/.test(x))
return x.slice(0, -3);
}).filter(Boolean);
}
function searchFiles(dir, fn) {
var files = fs.readdirSync(dir);
files.forEach(function(name) {
var path = dir + "/" + name;
try {
var stat = fs.statSync(path);
} catch (e) {
return;
}
if (stat.isFile() && /\.js$/.test(path)) {
fn(path);
} else if (stat.isDirectory()) {
if (/node_modules|[#\s]/.test(name)) return;
searchFiles(path, fn);
}
});
}
function workers(path) {
return jsFileList(path).map(function(x) {
if (x.slice(-7) == "_worker")
return x.slice(0, -7);
}).filter(function(x) { return !!x; });
}
function modeList(path) {
path = path || "lib/ace/mode";
return jsFileList(path, /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/);
}
function buildAceModule(opts, callback) {
// calling buildAceModuleInternal many times in parallel is slow, so we use queue
if (!buildAceModule.queue) {
buildAceModule.queue = [];
buildAceModule.dequeue = function() {
if (buildAceModule.running) return;
var call = buildAceModule.queue.shift();
buildAceModule.running = call;
if (call) {
setImmediate(function() {
buildAceModuleInternal.apply(null, call);
});
}
};
}
buildAceModule.queue.push([opts, function(err, result) {
callback && callback(err, result);
buildAceModule.running = null;
buildAceModule.dequeue();
}]);
if (!buildAceModule.running) {
buildAceModule.dequeue();
} else {
process.nextTick(buildAceModule.dequeue);
}
}
function buildAceModuleInternal(opts, callback) {
var cache = opts.cache == undefined ? CACHE : opts.cache;
var key = opts.require + "|" + opts.projectType;
if (cache && cache.configs && cache.configs[key])
return write(null, cache.configs[key]);
var pathConfig = {
paths: {
ace: ACE_HOME + "/lib/ace",
"kitchen-sink": ACE_HOME + "/demo/kitchen-sink",
build_support: ACE_HOME + "/build_support"
},
root: ACE_HOME
};
function write(err, result) {
if (cache && key && !(cache.configs && cache.configs[key])) {
cache.configs = cache.configs || Object.create(null);
cache.configs[key] = result;
result.sources = result.sources.map(function(pkg) {
return {deps: pkg.deps};
});
}
if (!opts.outputFile)
return callback(err, result);
var code = result.code;
if (opts.compress) {
if (!result.codeMin)
result.codeMin = compress(result.code);
code = result.codeMin;
}
var targetDir = getTargetDir(opts);
var to = /^([\\/]|\w:)/.test(opts.outputFile)
? opts.outputFile
: path.join(opts.outputFolder || targetDir, opts.outputFile);
var filters = [];
var ns = opts.ns || "ace";
if (opts.filters)
filters = filters.concat(opts.filters);
if (opts.noconflict)
filters.push(namespace(ns));
var projectType = opts.projectType;
if (projectType !== "worker") {
filters.push(exportAce(ns, opts.require[0],
opts.noconflict ? ns : "", projectType !== "main"));
}
filters.push(normalizeLineEndings);
filters.forEach(function(f) { code = f(code); });
build.writeToFile({code: code}, {
outputFolder: path.dirname(to),
outputFile: path.basename(to)
}, function() {});
callback && callback(err, result);
}
build(opts.require, {
cache: cache,
quiet: opts.quiet,
pathConfig: pathConfig,
additional: opts.additional,
enableBrowser: true,
keepDepArrays: opts.noconflict || opts.projectType == "worker" ? "" : "all",
noArchitect: true,
compress: false,
ignore: opts.ignore || [],
withRequire: false,
basepath: ACE_HOME,
transforms: [wrapCJS, normalizeLineEndings, includeLoader],
afterRead: [optimizeTextModules]
}, write);
}
function buildCore(options, extra, callback) {
options = extend(extra, options);
options.additional = [{
id: "build_support/mini_require",
order: -1000,
literal: true
}];
options.require =["ace/ace", "ace/loader_build"];
options.projectType = "main";
options.ns = "ace";
buildAceModule(options, callback);
}
function buildSubmodule(options, extra, file, callback) {
options = extend(extra, options);
getLoadedFileList(options, function(coreFiles) {
options.outputFile = file + ".js";
options.ignore = options.ignore || coreFiles;
options.quiet = true;
buildAceModule(options, callback);
});
}
function buildAce(options, callback) {
var snippetFiles = jsFileList("lib/ace/snippets");
var modeNames = modeList();
buildCore(options, {outputFile: "ace.js"}, addCb());
// modes
modeNames.forEach(function(name) {
buildSubmodule(options, {
projectType: "mode",
require: ["ace/mode/" + name]
}, "mode-" + name, addCb());
});
// snippets
modeNames.forEach(function(name) {
buildSubmodule(options, {
require: ["ace/snippets/" + name]
}, "snippets/" + name, addCb());
});
// themes
jsFileList("lib/ace/theme").forEach(function(name) {
buildSubmodule(options, {
projectType: "theme",
require: ["ace/theme/" + name]
}, "theme-" + name, addCb());
});
// keybindings
["vim", "emacs", "sublime", "vscode"].forEach(function(name) {
buildSubmodule(options, {
projectType: "keybinding",
require: ["ace/keyboard/" + name ]
}, "keybinding-" + name, addCb());
});
// extensions
jsFileList("lib/ace/ext").forEach(function(name) {
buildSubmodule(options, {
projectType: "ext",
require: ["ace/ext/" + name]
}, "ext-" + name, addCb());
});
// workers
workers("lib/ace/mode").forEach(function(name) {
buildSubmodule(options, {
projectType: "worker",
require: ["ace/mode/" + name + "_worker"],
ignore: [],
additional: [{
id: "ace/worker/worker",
transforms: [wrapCJS],
order: -1000
}]
}, "worker-" + name, addCb());
});
// worker base
buildSubmodule(options, {
projectType: "worker",
require: ["ace/worker/mirror"],
ignore: [],
additional: [{
id: "ace/worker/worker",
transforms: [wrapCJS],
order: -1000
}]
}, "worker-base", addCb());
//
function addCb() {
addCb.count = (addCb.count || 0) + 1;
return done;
}
function done() {
if (--addCb.count > 0)
return;
if (options.check)
sanityCheck(options, callback);
if (options.noconflict && !options.compress)
buildTypes();
// call extractCss only once during a build
if (cssUpdated) {
console.log("Finished building " + getTargetDir(options));
return;
} else {
cssUpdated = true;
extractCss(function() {
if (callback)
return callback();
console.log("Finished building " + getTargetDir(options));
});
}
}
}
var cssUpdated = false;
function extractCss(callback) {
var images = {};
var cssImports = {};
var fileName = "";
var extensions = jsFileList("src/ext");
var keybinding = jsFileList("src/keyboard");
var themes = jsFileList("src/theme");
var dom = require("./src/lib/dom");
var index = 0;
dom.importCssString = function(value, id) {
if (!id) id = fileName + (index++);
cssImports[id] = value;
};
var loadFile = function(path) {
fileName = path;
require(path);
};
themes.forEach(function(name) {
cssImports = {};
loadFile("./src/theme/" + name);
delete require.cache[require.resolve("./src/theme/" + name)];
var themeCss = "";
for (var i in cssImports) {
themeCss += cssImports[i];
}
themeCss = extractImages(themeCss, name, "..");
build.writeToFile({code: themeCss}, {
outputFolder: BUILD_DIR + "/css/theme",
outputFile: name + ".css"
}, function() {});
});
cssImports = {};
loadFile("./src/ace");
extensions.forEach(function(name) {
loadFile("./src/ext/" + name);
});
keybinding.forEach(function(name) {
loadFile("./src/keyboard/" + name);
});
var css = "";
for (var i in cssImports) {
css += "\n/*" + i + "*/";
css += "\n" + cssImports[i];
}
css = extractImages(css, "main", ".").replace(/^\s*/gm, "");
build.writeToFile({code: css}, {
outputFolder: BUILD_DIR + "/css",
outputFile: "ace.css"
}, function() {
saveImages();
callback && callback();
});
function extractImages(css, name, directory) {
var imageCounter = 0;
return css.replace(
/url\(\s*"data:([^"\\]|\\.)+"\s*\)|url\(\s*'data:([^'\\]|\\.)+'\s*\)|url\(data:[^)]+\)/g,
function(url) {
var data = url.slice(4, -1).trim();
if (/["']/.test(data[0])) {
data = data.slice(1, -1).replace(/\\(.)/g, "$1");
}
data = data.slice(5);
var i = data.indexOf(",");
if (i == -1) {
console.error(url);
return url;
}
var buffer = Buffer.from(data.slice(i + 1), "base64");
imageCounter++;
var imageName;
if (/^image\/svg\+xml/.test(data))
imageName = name + "-" + imageCounter + ".svg";
else
imageName = name + "-" + imageCounter + ".png";
images[imageName] = buffer;
console.log("url(\"" + directory + "/" + imageName + "\")");
return "url(\"" + directory + "/" + imageName + "\")";
}
);
}
function saveImages() {
for (var imageName in images) {
fs.writeFileSync(BUILD_DIR + "/css/" + imageName, images[imageName]);
}
}
}
function extractNls() {
var allMessages = {};
searchFiles(__dirname + "/src", function(path) {
if (/_test/.test(path)) return;
var text = fs.readFileSync(path, "utf8");
var matches = text.match(/nls\s*\(\s*("([^"\\]|\\.)+"|'([^'\\]|\\.)+')/g);
matches && matches.forEach(function(m) {
var eng = m.replace(/^nls\s*\(\s*["']|["']$/g, "");
allMessages[eng] = "";
});
});
fs.readdirSync(__dirname + "/translations").forEach(function(x) {
if (!/\.json$/.test(x)) return;
var path = __dirname + "/translations/" + x;
var existingStr = fs.readFileSync(path, "utf8");
var existing = JSON.parse(existingStr);
var newData = {$id: existing.$id};
for (var i in allMessages) {
newData[i] = existing[i] || "";
}
fs.writeFileSync(path, JSON.stringify(newData, null, 4), "utf8");
console.log("Saved " + x);
});
}
function getLoadedFileList(options, callback, result) {
if (!result) {
return buildCore({}, {}, function(e, result) {
getLoadedFileList(options, callback, result);
});
}
var deps = Object.create(null);
result.sources.forEach(function(pkg) {
pkg.deps && pkg.deps.forEach(function(p) {
if (!deps[p]) deps[p] = 1;
});
});
if (options.projectType == "theme")
delete deps["ace/theme/textmate"];
deps["ace/ace"] = 1;
callback(Object.keys(deps));
}
function normalizeLineEndings(module) {
if (typeof module == "string")
module = {source: module};
return module.source = module.source.replace(/\r\n/g, "\n");
}
function includeLoader(module) {
var pattern = '"include loader_build";';
if (module.source && module.source.indexOf(pattern) != -1) {
module.deps.push("ace/loader_build");
module.source = module.source.replace(pattern, 'require("./loader_build")(exports)');
}
}
function optimizeTextModules(sources) {
var textModules = {};
return sources.filter(function(pkg) {
if (!pkg.id) {
return true;
}
else if (pkg.id.indexOf("text!") > -1) {
detectTextModules(pkg);
return false;
}
else {
pkg.source = rewriteTextImports(pkg.source, pkg.deps);
return true;
}
}).map(function(pkg) {
if (pkg && pkg.deps) {
pkg.deps = pkg.deps && pkg.deps.filter(function(p) {
return p.indexOf("text!") == -1;
});
}
return pkg;
});
function rewriteTextImports(text, deps) {
return text.replace(/ require\(['"](?:ace|[.\/]+)\/requirejs\/text!(.*?)['"]\)/g, function(_, call) {
if (call) {
var dep;
deps.some(function(d) {
if (d.split("/").pop() == call.split("/").pop()) {
dep = d;
return true;
}
});
call = textModules[dep];
if (call)
return " " + call;
}
});
}
function detectTextModules(pkg) {
var input = pkg.source.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
if (/\.css$/.test(pkg.id)) {
// remove unnecessary whitespace from css
input = input.replace(/\n\s+/g, "\n");
input = '"' + input.replace(/\n/g, '\\\n') + '"';
} else {
// but don't break other files!
input = '"' + input.replace(/\n/g, '\\n\\\n') + '"';
}
textModules[pkg.id] = input;
}
}
function namespace(ns) {
return function(text) {
text = text
.toString()
.replace(/ACE_NAMESPACE\s*=\s*""/, 'ACE_NAMESPACE = "' + ns +'"')
.replace(/\bdefine\(/g, function(def, index, source) {
if (/(^|[;}),])\s*$/.test(source.slice(0, index)))
return ns + "." + def;
return def;
});
return text;
};
}
function exportAce(ns, modules, requireBase, extModules) {
requireBase = requireBase || "window";
return function(text) {
/*globals REQUIRE_NS, MODULES*/
var template = function() {
(function() {
REQUIRE_NS.require(MODULES, function(a) {
if (a) {
a.config.init(true);
a.define = REQUIRE_NS.define;
}
if (!window.NS)
window.NS = a;
for (var key in a) if (a.hasOwnProperty(key))
window.NS[key] = a[key];
window.NS["default"] = window.NS;
if (typeof module == "object" && typeof exports == "object" && module) {
module.exports = window.NS;
}
});
})();
};
if (extModules) {
template = function() {
(function() {
REQUIRE_NS.require(MODULES, function(m) {
if (typeof module == "object" && typeof exports == "object" && module) {
module.exports = m;
}
});
})();
};
}
text = text.replace(/function init\(packaged\) {/, "init(true);$&\n");
if (typeof modules == "string")
modules = [modules];
return (text.replace(/;\s*$/, "") + ";" + template
.toString()
.replace(/MODULES/g, JSON.stringify(modules))
.replace(/REQUIRE_NS/g, requireBase)
.replace(/NS/g, ns)
.slice(13, -1)
);
};
}
function updateModes() {
modeList().forEach(function(m) {
var filepath = __dirname + "/lib/ace/mode/" + m + ".js";
var source = fs.readFileSync(filepath, "utf8");
if (!/this.\$id\s*=\s*"/.test(source))
source = source.replace(/\n([ \t]*)(\}\).call\(\w*Mode.prototype\))/, '\n$1 this.$id = "";\n$1$2');
source = source.replace(/(this.\$id\s*=\s*)"[^"]*"/, '$1"ace/mode/' + m + '"');
fs.writeFileSync(filepath, source, "utf8");
});
}
function generateThemesModule(themes) {
var themelist = [
'define(function(require, exports, module) {',
'\n\nmodule.exports.themes = ' + JSON.stringify(themes, null, ' '),
';\n\n});'
].join('');
fs.writeFileSync(__dirname + '/lib/ace/ext/themelist_utils/themes.js', themelist, 'utf8');
}
function wrapCJS(module) {
if (module.loaderModule || module.noRequire || module.literal) return;
module.source = module.source.replace(/^#.*\n/, "");
if (!isCJS(module.source)) return;
module.source = `define(function(require, exports, module) {${module.source}\n});`;
}
function isCJS(source) {
var firstDefineCall = source.match(/define\(\s*[^)]*/);
if (firstDefineCall) {
// check if it is a normal define or some crazy umd trick
if (/define\(\s*(function\s*\(|{)/.test(firstDefineCall[0])) return;
if (/define\(\s*\[[^\]]*\],\s*\(?function\(/.test(firstDefineCall[0])) return;
if (/typeof define/.test(source)) return;
}
if (/"no use strict"/.test(source)) return;
return true;
}
function compress(text) {
var uglify = require("dryice").copy.filter.uglifyjs;
uglify.options.mangle_toplevel = {except: ["ACE_NAMESPACE", "requirejs"]};
uglify.options.beautify = {ascii_only: true, inline_script: true};
return asciify(uglify(text));
// copy.filter.uglifyjs.options.ascii_only = true; doesn't work with some uglify.js versions
function asciify(text) {
return text.replace(/[\x00-\x08\x0b\x0c\x0e\x19\x80-\uffff]/g, function(c) {
c = c.charCodeAt(0).toString(16);
if (c.length == 1)
return "\\x0" + c;
if (c.length == 2)
return "\\x" + c;
if (c.length == 3)
return "\\u0" + c;
return "\\u" + c;
});
}
}
function extend(base, extra) {
Object.keys(extra).forEach(function(k) {
base[k] = extra[k];
});
return base;
}
function getTargetDir(opts) {
var targetDir = BUILD_DIR + "/src";
if (opts.compress)
targetDir += "-min";
if (opts.noconflict)
targetDir += "-noconflict";
return targetDir;
}
function sanityCheck(opts, callback) {
var targetDir = getTargetDir(opts);
require("child_process").execFile(process.execPath, ["-e", "(" + function() {
window = global;
require("./ace");
if (typeof ace.edit != "function")
process.exit(1);
require("fs").readdirSync(".").forEach(function(p) {
if (!/ace\.js$/.test(p) && /\.js$/.test(p))
require("./" + p);
});
process.exit(0);
} + ")()"], {
cwd: targetDir
}, function(err, stdout) {
if (callback) return callback(err, stdout);
if (err)
throw err;
});
}
if (!module.parent)
main(process.argv);
else {
exports.buildAce = buildAce;
exports.jsFileList = jsFileList;
exports.modeList = modeList;
}