diff --git a/build.js b/build.js index 36596107..7f64186e 100644 --- a/build.js +++ b/build.js @@ -29,44 +29,44 @@ "ace/document", "ace/undomanager", "ace/virtual_renderer", - + "ace/mode/javascript", "ace/theme/textmate" ], includeRequire: false }, - - { - name: "ace/theme/eclipse", + + { + name: "ace/theme/eclipse", exclude: [ - "ace/lib/lang", - "ace/lib/dom", - "ace/lib/oop" + "pilot/lang", + "pilot/dom", + "pilot/oop" ] }, - { + { name: "ace/mode/xml", exclude: [ - "ace/lib/oop", + "pilot/oop", "ace/tokenizer", - "ace/mode/text" + "ace/mode/text" ] }, - { + { name: "ace/mode/css", exclude: [ - "ace/lib/oop", - "ace/lib/lang", + "pilot/oop", + "pilot/lang", "ace/tokenizer", "ace/range", - "ace/mode/text" + "ace/mode/text" ] }, - { + { name: "ace/mode/html", exclude: [ - "ace/lib/oop", - "ace/lib/lang", + "pilot/oop", + "pilot/lang", "ace/tokenizer", "ace/range", "ace/mode/text", diff --git a/demo/boot.js b/demo/boot.js new file mode 100644 index 00000000..8cb3e6e3 --- /dev/null +++ b/demo/boot.js @@ -0,0 +1,129 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// TODO: Yuck! A global function +var setupPlugins = function(config, callback) { + config = config || {}; + if (!config.pluginDirs) { + config.pluginDirs = {}; + } + // config.pluginDirs["../lib"] = { + // packages: ["ace"] + // }; + config.pluginDirs["../plugins"] = { + packages: ["pilot", "cockpit"] + }; + + var knownPlugins = []; + + var pluginPackageInfo = { + "../lib": [ + { + name: "ace", + lib: "." + } + ] + }; + + var paths = {}; + var i; + var location; + + // we need to ensure that the core plugin directory is loaded first + var pluginDirs = []; + var pluginDir; + for (pluginDir in config.pluginDirs) { + pluginDirs.push(pluginDir); + } + pluginDirs.sort(function(a, b) { + if (a == "../plugins") { + return -1; + } else if (b == "../plugins") { + return 1; + } else if (a < b) { + return -1; + } else if (b < a) { + return 1; + } else { + return 0; + } + }); + + // set up RequireJS to know that our plugins all have a main module called "index" + for (var dirNum = 0; dirNum < pluginDirs.length; dirNum++) { + pluginDir = pluginDirs[dirNum]; + var dirInfo = config.pluginDirs[pluginDir]; + if (dirInfo.packages) { + location = pluginPackageInfo[pluginDir]; + if (location === undefined) { + pluginPackageInfo[pluginDir] = location = []; + } + var packages = dirInfo.packages; + for (i = 0; i < packages.length; i++) { + location.push({ + name: packages[i], + main: "index" + }); + knownPlugins.push(packages[i]); + } + } + if (dirInfo.singleFiles) { + for (i = 0; i < dirInfo.singleFiles.length; i++) { + var pluginName = dirInfo.singleFiles[i]; + paths[pluginName] = pluginDir + "/" + pluginName; + knownPlugins.push(pluginName); + } + } + } +console.log(JSON.stringify({ + packagePaths: pluginPackageInfo, + paths: paths + })); + require({ + packagePaths: pluginPackageInfo, + paths: paths + }); + require(["pilot/plugin_manager", "pilot/settings"], function() { + var pluginsModule = require("pilot/plugin_manager"); + var settings = require("pilot/settings").settings; + var catalog = pluginsModule.catalog; + catalog.registerPlugins(knownPlugins); + if (callback) { + callback(pluginsModule, settings); + } + }); +}; diff --git a/demo/demo_startup.js b/demo/demo_startup.js new file mode 100644 index 00000000..9ce6b585 --- /dev/null +++ b/demo/demo_startup.js @@ -0,0 +1,199 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +define(function(require, exports, module) { + +exports.launch = function(env) { + + var event = require("pilot/event").event; + var Editor = require("ace/editor").Editor; + var Renderer = require("ace/virtual_renderer").VirtualRenderer; + var theme = require("ace/theme/textmate"); + var Document = require("ace/document").Document; + var JavaScriptMode = require("ace/mode/javascript").JavaScript; + var CssMode = require("ace/mode/css").Css; + var HtmlMode = require("ace/mode/html").Html; + var XmlMode = require("ace/mode/xml").Xml; + var TextMode = require("ace/mode/text").Text; + var UndoManager = require("ace/undomanager").UndoManager; + + var docs = {}; + + docs.js = new Document(document.getElementById("jstext").innerHTML); + docs.js.setMode(new JavaScriptMode()); + docs.js.setUndoManager(new UndoManager()); + + docs.css = new Document(document.getElementById("csstext").innerHTML); + docs.css.setMode(new CssMode()); + docs.css.setUndoManager(new UndoManager()); + + docs.html = new Document(document.getElementById("htmltext").innerHTML); + docs.html.setMode(new HtmlMode()); + docs.html.setUndoManager(new UndoManager()); + + var docEl = document.getElementById("doc"); + + var container = document.getElementById("editor"); + env.editor = new Editor(new Renderer(container, theme)); + + function onDocChange() { + var doc = getDoc(); + env.editor.setDocument(doc); + + var mode = doc.getMode(); + if (mode instanceof JavaScriptMode) { + modeEl.value = "javascript"; + } + else if (mode instanceof CssMode) { + modeEl.value = "css"; + } + else if (mode instanceof HtmlMode) { + modeEl.value = "html"; + } + else if (mode instanceof XmlMode) { + modeEl.value = "xml"; + } + else { + modeEl.value = "text"; + } + + env.editor.focus(); + } + docEl.onchange = onDocChange; + + function getDoc() { + return docs[docEl.value]; + } + + var modeEl = document.getElementById("mode"); + modeEl.onchange = function() { + env.editor.getDocument().setMode(modes[modeEl.value] || modes.text); + }; + + var modes = { + text: new TextMode(), + xml: new XmlMode(), + html: new HtmlMode(), + css: new CssMode(), + javascript: new JavaScriptMode() + }; + + function getMode() { + return modes[modeEl.value]; + } + + var themeEl = document.getElementById("theme"); + themeEl.onchange = function() { + env.editor.setTheme(themeEl.value); + }; + + var selectEl = document.getElementById("select_style"); + selectEl.onchange = function() { + if (selectEl.checked) { + env.editor.setSelectionStyle("line"); + } else { + env.editor.setSelectionStyle("text"); + } + }; + + var activeEl = document.getElementById("highlight_active"); + activeEl.onchange = function() { + env.editor.setHighlightActiveLine(!!activeEl.checked); + }; + + onDocChange(); + + window.jump = function() { + var jump = document.getElementById("jump"); + var cursor = env.editor.getCursorPosition(); + var pos = env.editor.renderer.textToScreenCoordinates(cursor.row, cursor.column); + jump.style.left = pos.pageX + "px"; + jump.style.top = pos.pageY + "px"; + jump.style.display = "block"; + }; + + function onResize() { + container.style.width = (document.documentElement.clientWidth - 4) + "px"; + container.style.height = (document.documentElement.clientHeight - 55 - 4 - 23) + "px"; + env.editor.resize(); + }; + + window.onresize = onResize; + onResize(); + + event.addListener(container, "dragover", function(e) { + return event.preventDefault(e); + }); + + event.addListener(container, "drop", function(e) { + try { + var file = e.dataTransfer.files[0]; + } catch(e) { + return event.stopEvent(); + } + + if (window.FileReader) { + var reader = new FileReader(); + reader.onload = function(e) { + env.editor.getSelection().selectAll(); + + var mode = "text"; + if (/^.*\.js$/i.test(file.name)) { + mode = "javascript"; + } else if (/^.*\.xml$/i.test(file.name)) { + mode = "xml"; + } else if (/^.*\.html$/i.test(file.name)) { + mode = "html"; + } else if (/^.*\.css$/i.test(file.name)) { + mode = "css"; + } + + env.editor.onTextInput(reader.result); + + modeEl.value = mode; + env.editor.getDocument().setMode(modes[mode]); + }; + reader.readAsText(file); + } + + return event.preventDefault(e); + }); +}; + +}); diff --git a/demo/editor-build.html b/demo/editor-build.html deleted file mode 100644 index 8ebcdf9e..00000000 --- a/demo/editor-build.html +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - Editor - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- -
-
- - - - - - - - - - - - - \ No newline at end of file diff --git a/demo/editor.html b/demo/editor.html deleted file mode 100644 index e5bdd247..00000000 --- a/demo/editor.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - Editor - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- -
-
- - - - - - - - - - - - - \ No newline at end of file diff --git a/demo/require.js b/demo/require.js index 29462455..1f94622e 100644 --- a/demo/require.js +++ b/demo/require.js @@ -13,16 +13,20 @@ setInterval: false, importScripts: false, jQuery: false */ var require, define; (function () { //Change this version number for each release. - var version = "0.14.5", + var version = "0.14.5+", empty = {}, s, i, defContextName = "_", contextLoads = [], scripts, script, rePkg, src, m, dataMain, cfg = {}, setReadyState, - readyRegExp = /^(complete|loaded)$/, commentRegExp = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, - cjsRequireRegExp = /require\(["']([\w-_\.\/]+)["']\)/g, + cjsRequireRegExp = /require\(["']([\w\!\-_\.\/]+)["']\)/g, main, isBrowser = !!(typeof window !== "undefined" && navigator && document), isWebWorker = !isBrowser && typeof importScripts !== "undefined", + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is "loading", "loaded", execution, + // then "complete". The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, ostring = Object.prototype.toString, ap = Array.prototype, aps = ap.slice, scrollIntervalId, req, baseElement, @@ -882,12 +886,12 @@ var require, define; } contextName = contextName || s.ctxName; - var ret, context = s.contexts[contextName]; + var ret, context = s.contexts[contextName], nameProps; //Normalize module name, if it contains . or .. - moduleName = req.normalizeName(moduleName, relModuleName, context); + nameProps = req.splitPrefix(moduleName, relModuleName, context); - ret = context.defined[moduleName]; + ret = context.defined[nameProps.name]; if (ret === undefined) { req.onError(new Error("require: module name '" + moduleName + @@ -940,7 +944,7 @@ var require, define; } }; - req.jsExtRegExp = /\.js$/; + req.jsExtRegExp = /^\/|:|\?|\.js$/; /** * Given a relative module name, like ./something, normalize it to @@ -955,37 +959,44 @@ var require, define; //Adjust any relative paths. var part; if (name.charAt(0) === ".") { - if (!baseName) { - req.onError(new Error("Cannot normalize module name: " + - name + - ", no relative module name available.")); - } - - if (context.config.packages[baseName]) { - //If the baseName is a package name, then just treat it as one - //name to concat the name with. - baseName = [baseName]; - } else { - //Convert baseName to array, and lop off the last part, - //so that . matches that "directory" and not name of the baseName's - //module. For instance, baseName of "one/two/three", maps to - //"one/two/three.js", but we want the directory, "one/two" for - //this normalization. - baseName = baseName.split("/"); - baseName = baseName.slice(0, baseName.length - 1); - } - - name = baseName.concat(name.split("/")); - for (i = 0; (part = name[i]); i++) { - if (part === ".") { - name.splice(i, 1); - i -= 1; - } else if (part === "..") { - name.splice(i - 1, 2); - i -= 2; + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + if (context.config.packages[baseName]) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + baseName = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that "directory" and not name of the baseName's + //module. For instance, baseName of "one/two/three", maps to + //"one/two/three.js", but we want the directory, "one/two" for + //this normalization. + baseName = baseName.split("/"); + baseName = baseName.slice(0, baseName.length - 1); } + + name = baseName.concat(name.split("/")); + for (i = 0; (part = name[i]); i++) { + if (part === ".") { + name.splice(i, 1); + i -= 1; + } else if (part === "..") { + if (i === 1) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for '..'. + break; + } else if (i > 1) { + name.splice(i - 1, 2); + i -= 2; + } + } + } + name = name.join("/"); } - name = name.join("/"); } return name; }; @@ -1035,7 +1046,7 @@ var require, define; //If a colon is in the URL, it indicates a protocol is used and it is just //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file. //The slash is important for protocol-less URLs as well as full paths. - if (moduleName.indexOf(":") !== -1 || moduleName.charAt(0) === '/' || req.jsExtRegExp.test(moduleName)) { + if (req.jsExtRegExp.test(moduleName)) { //Just a plain path, not module name lookup, so just return it. //Add extension if it is included. This is a bit wonky, only non-.js things pass //an extension, this method probably needs to be reworked. @@ -1078,6 +1089,11 @@ var require, define; config.urlArgs) : url; }; + //In async environments, checkLoaded can get called a few times in the same + //call stack. Allow only one to do the finishing work. Set to false + //for sync environments. + req.blockCheckLoaded = true; + /** * Checks if all modules for a context are loaded, and if so, evaluates the * new ones in right dependency order. @@ -1119,7 +1135,7 @@ var require, define; //by calling a waiting callback that then calls require and then this function //should not proceed. At the end of this function, if there are still things //waiting, then checkLoaded will be called again. - context.isCheckLoaded = true; + context.isCheckLoaded = req.blockCheckLoaded; //Grab waiting and loaded lists here, since it could have changed since //this function was first called. @@ -2477,4 +2493,4 @@ var require, define; }()); //Target build file for a require.js that has all of require's functionality, -//and includes specific plugins: i18n and text. \ No newline at end of file +//and includes specific plugins: i18n and text. diff --git a/editor.html b/editor.html new file mode 100644 index 00000000..ba91335a --- /dev/null +++ b/editor.html @@ -0,0 +1,163 @@ + + + + + + Editor + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/lib/ace/background_tokenizer.js b/lib/ace/background_tokenizer.js index d3d6828f..811eeb8d 100644 --- a/lib/ace/background_tokenizer.js +++ b/lib/ace/background_tokenizer.js @@ -37,8 +37,8 @@ define(function(require, exports, module) { -var oop = require("./lib/oop"); -var MEventEmitter = require("./event_emitter"); +var oop = require("pilot/oop").oop; +var EventEmitter = require("pilot/event_emitter").EventEmitter; var BackgroundTokenizer = function(tokenizer, editor) { this.running = false; @@ -82,7 +82,7 @@ var BackgroundTokenizer = function(tokenizer, editor) { (function(){ - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.setTokenizer = function(tokenizer) { this.tokenizer = tokenizer; @@ -103,7 +103,7 @@ var BackgroundTokenizer = function(tokenizer, editor) { first: firstRow, last: lastRow }; - this.$dispatchEvent("update", {data: data}); + this._dispatchEvent("update", {data: data}); }; this.start = function(startRow) { @@ -164,5 +164,5 @@ var BackgroundTokenizer = function(tokenizer, editor) { }).call(BackgroundTokenizer.prototype); -return BackgroundTokenizer; +exports.BackgroundTokenizer = BackgroundTokenizer; }); diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 8d6a221a..4e7d66b1 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -37,158 +37,211 @@ define(function(require, exports, module) { -var PluginManager = require("../plugin_manager"); +var canon = require("pilot/canon"); -PluginManager.registerCommand("selectall", function(editor, selection) { - selection.selectAll(); +canon.addCommand({ + name: "selectall", + exec: function(env, args, request) { env.selection.selectAll(); } }); -PluginManager.registerCommand("removeline", function(editor, selection) { - editor.removeLines(); +canon.addCommand({ + name: "removeline", + exec: function(env, args, request) { env.editor.removeLines(); } }); -PluginManager.registerCommand("gotoline", function(editor, selection) { - var line = parseInt(prompt("Enter line number:")); - if (!isNaN(line)) { - editor.gotoLine(line); +canon.addCommand({ + name: "gotoline", + exec: function(env, args, request) { + var line = parseInt(prompt("Enter line number:")); + if (!isNaN(line)) { + env.editor.gotoLine(line); + } } }); -PluginManager.registerCommand("togglecomment", function(editor, selection) { - editor.toggleCommentLines(); +canon.addCommand({ + name: "togglecomment", + exec: function(env, args, request) { env.editor.toggleCommentLines(); } }); -PluginManager.registerCommand("findnext", function(editor, selection) { - editor.findNext(); +canon.addCommand({ + name: "findnext", + exec: function(env, args, request) { env.editor.findNext(); } }); -PluginManager.registerCommand("findprevious", function(editor, selection) { - editor.findPrevious(); +canon.addCommand({ + name: "findprevious", + exec: function(env, args, request) { env.editor.findPrevious(); } }); -PluginManager.registerCommand("find", function(editor, selection) { - var needle = prompt("Find:"); - editor.find(needle); +canon.addCommand({ + name: "find", + exec: function(env, args, request) { + var needle = prompt("Find:"); + env.editor.find(needle); + } }); -PluginManager.registerCommand("undo", function(editor, selection) { - editor.undo(); +canon.addCommand({ + name: "undo", + exec: function(env, args, request) { env.editor.undo(); } }); -PluginManager.registerCommand("redo", function(editor, selection) { - editor.redo(); +canon.addCommand({ + name: "redo", + exec: function(env, args, request) { env.editor.redo(); } }); -PluginManager.registerCommand("redo", function(editor, selection) { - editor.redo(); +canon.addCommand({ + name: "redo", + exec: function(env, args, request) { env.editor.redo(); } }); -PluginManager.registerCommand("overwrite", function(editor, selection) { - editor.toggleOverwrite(); +canon.addCommand({ + name: "overwrite", + exec: function(env, args, request) { env.editor.toggleOverwrite(); } }); -PluginManager.registerCommand("copylinesup", function(editor, selection) { - editor.copyLinesUp(); +canon.addCommand({ + name: "copylinesup", + exec: function(env, args, request) { env.editor.copyLinesUp(); } }); -PluginManager.registerCommand("movelinesup", function(editor, selection) { - editor.moveLinesUp(); +canon.addCommand({ + name: "movelinesup", + exec: function(env, args, request) { env.editor.moveLinesUp(); } }); -PluginManager.registerCommand("selecttostart", function(editor, selection) { - selection.selectFileStart(); +canon.addCommand({ + name: "selecttostart", + exec: function(env, args, request) { env.selection.selectFileStart(); } }); -PluginManager.registerCommand("gotostart", function(editor, selection) { - editor.navigateFileStart(); +canon.addCommand({ + name: "gotostart", + exec: function(env, args, request) { env.editor.navigateFileStart(); } }); -PluginManager.registerCommand("selectup", function(editor, selection) { - selection.selectUp(); +canon.addCommand({ + name: "selectup", + exec: function(env, args, request) { env.selection.selectUp(); } }); -PluginManager.registerCommand("golineup", function(editor, selection) { - editor.navigateUp(); +canon.addCommand({ + name: "golineup", + exec: function(env, args, request) { env.editor.navigateUp(); } }); -PluginManager.registerCommand("copylinesdown", function(editor, selection) { - editor.copyLinesDown(); +canon.addCommand({ + name: "copylinesdown", + exec: function(env, args, request) { env.editor.copyLinesDown(); } }); -PluginManager.registerCommand("movelinesdown", function(editor, selection) { - editor.moveLinesDown(); +canon.addCommand({ + name: "movelinesdown", + exec: function(env, args, request) { env.editor.moveLinesDown(); } }); -PluginManager.registerCommand("selecttoend", function(editor, selection) { - selection.selectFileEnd(); +canon.addCommand({ + name: "selecttoend", + exec: function(env, args, request) { env.selection.selectFileEnd(); } }); -PluginManager.registerCommand("gotoend", function(editor, selection) { - editor.navigateFileEnd(); +canon.addCommand({ + name: "gotoend", + exec: function(env, args, request) { env.editor.navigateFileEnd(); } }); -PluginManager.registerCommand("selectdown", function(editor, selection) { - selection.selectDown(); +canon.addCommand({ + name: "selectdown", + exec: function(env, args, request) { env.selection.selectDown(); } }); -PluginManager.registerCommand("godown", function(editor, selection) { - editor.navigateDown(); +canon.addCommand({ + name: "godown", + exec: function(env, args, request) { env.editor.navigateDown(); } }); -PluginManager.registerCommand("selectwordleft", function(editor, selection) { - selection.selectWordLeft(); +canon.addCommand({ + name: "selectwordleft", + exec: function(env, args, request) { env.selection.selectWordLeft(); } }); -PluginManager.registerCommand("gotowordleft", function(editor, selection) { - editor.navigateWordLeft(); +canon.addCommand({ + name: "gotowordleft", + exec: function(env, args, request) { env.editor.navigateWordLeft(); } }); -PluginManager.registerCommand("selecttolinestart", function(editor, selection) { - selection.selectLineStart(); +canon.addCommand({ + name: "selecttolinestart", + exec: function(env, args, request) { env.selection.selectLineStart(); } }); -PluginManager.registerCommand("gotolinestart", function(editor, selection) { - editor.navigateLineStart(); +canon.addCommand({ + name: "gotolinestart", + exec: function(env, args, request) { env.editor.navigateLineStart(); } }); -PluginManager.registerCommand("selectleft", function(editor, selection) { - selection.selectLeft(); +canon.addCommand({ + name: "selectleft", + exec: function(env, args, request) { env.selection.selectLeft(); } }); -PluginManager.registerCommand("gotoleft", function(editor, selection) { - editor.navigateLeft(); +canon.addCommand({ + name: "gotoleft", + exec: function(env, args, request) { env.editor.navigateLeft(); } }); -PluginManager.registerCommand("selectwordright", function(editor, selection) { - selection.selectWordRight(); +canon.addCommand({ + name: "selectwordright", + exec: function(env, args, request) { env.selection.selectWordRight(); } }); -PluginManager.registerCommand("gotowordright", function(editor, selection) { - editor.navigateWordRight(); +canon.addCommand({ + name: "gotowordright", + exec: function(env, args, request) { env.editor.navigateWordRight(); } }); -PluginManager.registerCommand("selecttolineend", function(editor, selection) { - selection.selectLineEnd(); +canon.addCommand({ + name: "selecttolineend", + exec: function(env, args, request) { env.selection.selectLineEnd(); } }); -PluginManager.registerCommand("gotolineend", function(editor, selection) { - editor.navigateLineEnd(); +canon.addCommand({ + name: "gotolineend", + exec: function(env, args, request) { env.editor.navigateLineEnd(); } }); -PluginManager.registerCommand("selectright", function(editor, selection) { - selection.selectRight(); +canon.addCommand({ + name: "selectright", + exec: function(env, args, request) { env.selection.selectRight(); } }); -PluginManager.registerCommand("gotoright", function(editor, selection) { - editor.navigateRight(); +canon.addCommand({ + name: "gotoright", + exec: function(env, args, request) { env.editor.navigateRight(); } }); -PluginManager.registerCommand("selectpagedown", function(editor, selection) { - editor.selectPageDown(); +canon.addCommand({ + name: "selectpagedown", + exec: function(env, args, request) { env.editor.selectPageDown(); } }); -PluginManager.registerCommand("pagedown", function(editor, selection) { - editor.scrollPageDown(); +canon.addCommand({ + name: "pagedown", + exec: function(env, args, request) { env.editor.scrollPageDown(); } }); -PluginManager.registerCommand("gotopagedown", function(editor, selection) { - editor.gotoPageDown(); +canon.addCommand({ + name: "gotopagedown", + exec: function(env, args, request) { env.editor.gotoPageDown(); } }); -PluginManager.registerCommand("selectpageup", function(editor, selection) { - editor.selectPageUp(); +canon.addCommand({ + name: "selectpageup", + exec: function(env, args, request) { env.editor.selectPageUp(); } }); -PluginManager.registerCommand("pageup", function(editor, selection) { - editor.scrollPageUp(); +canon.addCommand({ + name: "pageup", + exec: function(env, args, request) { env.editor.scrollPageUp(); } }); -PluginManager.registerCommand("gotopageup", function(editor, selection) { - editor.gotoPageUp(); +canon.addCommand({ + name: "gotopageup", + exec: function(env, args, request) { env.editor.gotoPageUp(); } }); -PluginManager.registerCommand("selectlinestart", function(editor, selection) { - selection.selectLineStart(); +canon.addCommand({ + name: "selectlinestart", + exec: function(env, args, request) { env.selection.selectLineStart(); } }); -PluginManager.registerCommand("gotolinestart", function(editor, selection) { - editor.navigateLineStart(); +canon.addCommand({ + name: "gotolinestart", + exec: function(env, args, request) { env.editor.navigateLineStart(); } }); -PluginManager.registerCommand("selectlineend", function(editor, selection) { - selection.selectLineEnd(); +canon.addCommand({ + name: "selectlineend", + exec: function(env, args, request) { env.selection.selectLineEnd(); } }); -PluginManager.registerCommand("gotolineend", function(editor, selection) { - editor.navigateLineEnd(); +canon.addCommand({ + name: "gotolineend", + exec: function(env, args, request) { env.editor.navigateLineEnd(); } }); -PluginManager.registerCommand("del", function(editor, selection) { - editor.removeRight(); +canon.addCommand({ + name: "del", + exec: function(env, args, request) { env.editor.removeRight(); } }); -PluginManager.registerCommand("backspace", function(editor, selection) { - editor.removeLeft(); +canon.addCommand({ + name: "backspace", + exec: function(env, args, request) { env.editor.removeLeft(); } }); -PluginManager.registerCommand("outdent", function(editor, selection) { - editor.blockOutdent(); +canon.addCommand({ + name: "outdent", + exec: function(env, args, request) { env.editor.blockOutdent(); } }); -PluginManager.registerCommand("indent", function(editor, selection) { - editor.indent(); +canon.addCommand({ + name: "indent", + exec: function(env, args, request) { env.editor.indent(); } }); -}); \ No newline at end of file +}); diff --git a/lib/ace/conf/keybindings/default_mac.js b/lib/ace/conf/keybindings/default_mac.js index d027d031..788ed577 100644 --- a/lib/ace/conf/keybindings/default_mac.js +++ b/lib/ace/conf/keybindings/default_mac.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -return { +exports.bindings = { "selectall": "Command-A", "removeline": "Command-D", "gotoline": "Command-L", diff --git a/lib/ace/conf/keybindings/default_win.js b/lib/ace/conf/keybindings/default_win.js index b752d0b1..3ae134b9 100644 --- a/lib/ace/conf/keybindings/default_win.js +++ b/lib/ace/conf/keybindings/default_win.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -return { +exports.bindings = { "selectall": "Ctrl-A", "removeline": "Ctrl-D", "gotoline": "Ctrl-L", diff --git a/lib/ace/document.js b/lib/ace/document.js index ab8071d7..671244f2 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -37,12 +37,12 @@ define(function(require, exports, module) { -var oop = require("./lib/oop"); -var lang = require("./lib/lang"); -var MEventEmitter = require("./event_emitter"); -var Selection = require("./selection"); -var TextMode = require("./mode/text"); -var Range = require("./range"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var EventEmitter = require("pilot/event_emitter").EventEmitter; +var Selection = require("ace/selection").Selection; +var TextMode = require("ace/mode/text").Text; +var Range = require("ace/range").Range; var Document = function(text, mode) { @@ -66,7 +66,7 @@ var Document = function(text, mode) { (function() { - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.$undoManager = null; @@ -74,13 +74,13 @@ var Document = function(text, mode) { return text.split(/\r\n|\r|\n/); }; - this.setValue = function(text) { - var args = [0, this.lines.length]; - args.push.apply(args, this.$split(text)); - this.lines.splice.apply(this.lines, args); - this.modified = true; - this.fireChangeEvent(0); - }; + this.setValue = function(text) { + var args = [0, this.lines.length]; + args.push.apply(args, this.$split(text)); + this.lines.splice.apply(this.lines, args); + this.modified = true; + this.fireChangeEvent(0); + }; this.toString = function() { return this.lines.join(this.$getNewLineCharacter()); @@ -95,7 +95,7 @@ var Document = function(text, mode) { firstRow: firstRow, lastRow: lastRow }; - this.$dispatchEvent("change", { data: data}); + this._dispatchEvent("change", { data: data}); }; this.setUndoManager = function(undoManager) { @@ -154,7 +154,7 @@ var Document = function(text, mode) { this.modified = true; this.$tabSize = tabSize; - this.$dispatchEvent("changeTabSize"); + this._dispatchEvent("changeTabSize"); }; this.getTabSize = function() { @@ -170,22 +170,22 @@ var Document = function(text, mode) { for (var i=0; i= 0; --i) this.$tryReplace(ranges[i], replacement); if (ranges[0] !== null) @@ -1041,5 +1041,5 @@ var Editor =function(renderer, doc) { }).call(Editor.prototype); -return Editor; +exports.Editor = Editor; }); diff --git a/lib/ace/keybinding.js b/lib/ace/keybinding.js index 1adc4886..31df2ee3 100644 --- a/lib/ace/keybinding.js +++ b/lib/ace/keybinding.js @@ -37,12 +37,12 @@ define(function(require, exports, module) { -var core = require("./lib/core"); -var event = require("./lib/event"); -var default_mac = require("./conf/keybindings/default_mac"); -var default_win = require("./conf/keybindings/default_win"); -var PluginManager = require("./plugin_manager"); -require("./commands/default_commands"); +var core = require("pilot/core").core; +var event = require("pilot/event").event; +var default_mac = require("ace/conf/keybindings/default_mac").bindings; +var default_win = require("ace/conf/keybindings/default_win").bindings; +var canon = require("pilot/canon"); +require("ace/commands/default_commands"); var KeyBinding = function(element, editor, config) { this.setConfig(config); @@ -55,10 +55,9 @@ var KeyBinding = function(element, editor, config) { var commandName = (_self.config.reverse[hashId] || {})[(key || String.fromCharCode(e.keyCode)).toLowerCase()]; - var command = PluginManager.commands[commandName]; - if (command) { - command(editor, editor.getSelection()); + var success = canon.exec(commandName); + if (success) { return event.stopEvent(e); } }); @@ -149,5 +148,5 @@ var KeyBinding = function(element, editor, config) { }).call(KeyBinding.prototype); -return KeyBinding; +exports.KeyBinding = KeyBinding; }); diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index f1f99916..57ffc7f7 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var dom = require("../lib/dom"); +var dom = require("pilot/dom").dom; var Cursor = function(parentEl) { this.element = document.createElement("div"); @@ -120,7 +120,7 @@ var Cursor = function(parentEl) { this.update = function(config) { if (!this.position) return; - + this.config = config; var cursorLeft = Math.round(this.position.column * config.characterWidth); @@ -145,5 +145,6 @@ var Cursor = function(parentEl) { }).call(Cursor.prototype); -return Cursor; +exports.Cursor = Cursor; + }); diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index 87db1632..4202772f 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -81,5 +81,6 @@ var Gutter = function(parentEl) { }).call(Gutter.prototype); -return Gutter; +exports.Gutter = Gutter; + }); diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index 0c304915..06422bd5 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var Range = require("../range"); +var Range = require("ace/range").Range; var Marker = function(parentEl) { this.element = document.createElement("div"); @@ -181,5 +181,6 @@ var Marker = function(parentEl) { }).call(Marker.prototype); -return Marker; +exports.Marker = Marker; + }); diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 08f3670a..9ba67f43 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -37,9 +37,9 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var dom = require("../lib/dom"); -var MEventEmitter = require("../event_emitter"); +var oop = require("pilot/oop").oop; +var dom = require("pilot/dom").dom; +var EventEmitter = require("pilot/event_emitter").EventEmitter; var Text = function(parentEl) { this.element = document.createElement("div"); @@ -52,7 +52,7 @@ var Text = function(parentEl) { (function() { - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.EOF_CHAR = "¶"; this.EOL_CHAR = "¬"; @@ -77,7 +77,7 @@ var Text = function(parentEl) { var size = self.$measureSizes(); if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { self.$characterSize = size; - self.$dispatchEvent("changeCharaterSize", {data: size}); + self._dispatchEvent("changeCharaterSize", {data: size}); } }, 500); }; @@ -155,7 +155,7 @@ var Text = function(parentEl) { this.tokenizer.getTokens(first, last, function(tokens) { for ( var i = first; i <= last; i++) { var lineElement = lineElements[i - layerConfig.firstRow]; - if (!lineElement) + if (!lineElement) continue; var html = []; @@ -299,5 +299,6 @@ var Text = function(parentEl) { }).call(Text.prototype); -return Text; +exports.Text = Text; + }); diff --git a/lib/ace/mode/css.js b/lib/ace/mode/css.js index 91819a91..4c6bd198 100644 --- a/lib/ace/mode/css.js +++ b/lib/ace/mode/css.js @@ -37,11 +37,11 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextMode = require("./text"); -var Tokenizer = require("../tokenizer"); -var CssHighlightRules = require("./css_highlight_rules"); -var MatchingBraceOutdent = require("./matching_brace_outdent"); +var oop = require("pilot/oop").oop; +var TextMode = require("ace/mode/text").Text; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var CssHighlightRules = require("ace/mode/css_highlight_rules").CssHighlightRules; +var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; var Css = function() { this.$tokenizer = new Tokenizer(new CssHighlightRules().getRules()); @@ -78,5 +78,6 @@ oop.inherits(Css, TextMode); }).call(Css.prototype); -return Css; -}); \ No newline at end of file +exports.Css = Css; + +}); diff --git a/lib/ace/mode/css_highlight_rules.js b/lib/ace/mode/css_highlight_rules.js index 938b9bca..a4445f41 100644 --- a/lib/ace/mode/css_highlight_rules.js +++ b/lib/ace/mode/css_highlight_rules.js @@ -37,9 +37,9 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var TextHighlightRules = require("./text_highlight_rules"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var CssHighlightRules = function() { @@ -229,5 +229,6 @@ var CssHighlightRules = function() { oop.inherits(CssHighlightRules, TextHighlightRules); -return CssHighlightRules; +exports.CssHighlightRules = CssHighlightRules; + }); diff --git a/lib/ace/mode/doc_comment_highlight_rules.js b/lib/ace/mode/doc_comment_highlight_rules.js index 5db3a5d1..48812aed 100644 --- a/lib/ace/mode/doc_comment_highlight_rules.js +++ b/lib/ace/mode/doc_comment_highlight_rules.js @@ -37,8 +37,8 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules"); +var oop = require("pilot/oop").oop; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var DocCommentHighlightRules = function() { @@ -77,5 +77,6 @@ oop.inherits(DocCommentHighlightRules, TextHighlightRules); }).call(DocCommentHighlightRules.prototype); -return DocCommentHighlightRules; -}); \ No newline at end of file +exports.DocCommentHighlightRules = DocCommentHighlightRules; + +}); diff --git a/lib/ace/mode/html.js b/lib/ace/mode/html.js index 8694b00a..f6587676 100644 --- a/lib/ace/mode/html.js +++ b/lib/ace/mode/html.js @@ -37,12 +37,12 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextMode = require("./text"); -var JavaScriptMode = require("./javascript"); -var CssMode = require("./css"); -var Tokenizer = require("../tokenizer"); -var HtmlHighlightRules = require("./html_highlight_rules"); +var oop = require("pilot/oop").oop; +var TextMode = require("ace/mode/text").Text; +var JavaScriptMode = require("ace/mode/javascript").JavaScript; +var CssMode = require("ace/mode/css").Css; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var HtmlHighlightRules = require("ace/mode/html_highlight_rules").HtmlHighlightRules; var Html = function() { this.$tokenizer = new Tokenizer(new HtmlHighlightRules().getRules()); @@ -97,5 +97,5 @@ oop.inherits(Html, TextMode); }).call(Html.prototype); -return Html; +exports.Html = Html; }); diff --git a/lib/ace/mode/html_highlight_rules.js b/lib/ace/mode/html_highlight_rules.js index c914b112..be441552 100644 --- a/lib/ace/mode/html_highlight_rules.js +++ b/lib/ace/mode/html_highlight_rules.js @@ -37,10 +37,10 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var CssHighlightRules = require("./css_highlight_rules"); -var JavaScriptHighlightRules = require("./javascript_highlight_rules"); -var TextHighlightRules = require("./text_highlight_rules"); +var oop = require("pilot/oop").oop; +var CssHighlightRules = require("ace/mode/css_highlight_rules").CssHighlightRules; +var JavaScriptHighlightRules = require("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var HtmlHighlightRules = function() { @@ -178,5 +178,5 @@ var HtmlHighlightRules = function() { oop.inherits(HtmlHighlightRules, TextHighlightRules); -return HtmlHighlightRules; +exports.HtmlHighlightRules = HtmlHighlightRules; }); diff --git a/lib/ace/mode/javascript.js b/lib/ace/mode/javascript.js index 0310a16e..e8bc67a6 100644 --- a/lib/ace/mode/javascript.js +++ b/lib/ace/mode/javascript.js @@ -37,12 +37,12 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextMode = require("./text"); -var Tokenizer = require("../tokenizer"); -var JavaScriptHighlightRules = require("./javascript_highlight_rules"); -var MatchingBraceOutdent = require("./matching_brace_outdent"); -var Range = require("../range"); +var oop = require("pilot/oop").oop; +var TextMode = require("ace/mode/text").Text; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var JavaScriptHighlightRules = require("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules; +var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var Range = require("ace/range").Range; var JavaScript = function() { this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules()); @@ -123,5 +123,5 @@ oop.inherits(JavaScript, TextMode); }).call(JavaScript.prototype); -return JavaScript; +exports.JavaScript = JavaScript; }); diff --git a/lib/ace/mode/javascript_highlight_rules.js b/lib/ace/mode/javascript_highlight_rules.js index 039422c4..0cbad802 100644 --- a/lib/ace/mode/javascript_highlight_rules.js +++ b/lib/ace/mode/javascript_highlight_rules.js @@ -37,10 +37,10 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var lang = require("../lib/lang"); -var DocCommentHighlightRules = require("./doc_comment_highlight_rules"); -var TextHighlightRules = require("./text_highlight_rules"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; JavaScriptHighlightRules = function() { @@ -159,5 +159,5 @@ JavaScriptHighlightRules = function() { oop.inherits(JavaScriptHighlightRules, TextHighlightRules); -return JavaScriptHighlightRules; -}); \ No newline at end of file +exports.JavaScriptHighlightRules = JavaScriptHighlightRules; +}); diff --git a/lib/ace/mode/matching_brace_outdent.js b/lib/ace/mode/matching_brace_outdent.js index 82777425..6f4896aa 100644 --- a/lib/ace/mode/matching_brace_outdent.js +++ b/lib/ace/mode/matching_brace_outdent.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var Range = require("../range"); +var Range = require("ace/range").Range; var MatchingBraceOutdent = function() {}; @@ -78,5 +78,5 @@ var MatchingBraceOutdent = function() {}; }).call(MatchingBraceOutdent.prototype); -return MatchingBraceOutdent; +exports.MatchingBraceOutdent = MatchingBraceOutdent; }); diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index 7cf04cb8..1a73194f 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -37,8 +37,8 @@ define(function(require, exports, module) { -var Tokenizer = require("../tokenizer"); -var TextHighlightRules = require("./text_highlight_rules"); +var Tokenizer = require("ace/tokenizer").Tokenizer; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var Text = function() { this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules()); @@ -76,5 +76,5 @@ var Text = function() { }).call(Text.prototype); -return Text; -}); \ No newline at end of file +exports.Text = Text; +}); diff --git a/lib/ace/mode/text_highlight_rules.js b/lib/ace/mode/text_highlight_rules.js index c5331061..3f5351ce 100644 --- a/lib/ace/mode/text_highlight_rules.js +++ b/lib/ace/mode/text_highlight_rules.js @@ -73,5 +73,5 @@ var TextHighlightRules = function() { }).call(TextHighlightRules.prototype); -return TextHighlightRules; -}); \ No newline at end of file +exports.TextHighlightRules = TextHighlightRules; +}); diff --git a/lib/ace/mode/xml.js b/lib/ace/mode/xml.js index a64eeac7..0a83adb1 100644 --- a/lib/ace/mode/xml.js +++ b/lib/ace/mode/xml.js @@ -37,10 +37,10 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextMode = require("./text"); -var Tokenizer = require("../tokenizer"); -var XmlHighlightRules = require("./xml_highlight_rules"); +var oop = require("pilot/oop").oop; +var TextMode = require("ace/mode/text").Text; +var Tokenizer = require("ace/tokenizer").Tokenizer; +var XmlHighlightRules = require("ace/mode/xml_highlight_rules").XmlHighlightRules; var Xml = function() { this.$tokenizer = new Tokenizer(new XmlHighlightRules().getRules()); @@ -56,5 +56,5 @@ oop.inherits(Xml, TextMode); }).call(Xml.prototype); -return Xml; -}); \ No newline at end of file +exports.Xml = Xml; +}); diff --git a/lib/ace/mode/xml_highlight_rules.js b/lib/ace/mode/xml_highlight_rules.js index 69e7b691..b1c6e874 100644 --- a/lib/ace/mode/xml_highlight_rules.js +++ b/lib/ace/mode/xml_highlight_rules.js @@ -37,8 +37,8 @@ define(function(require, exports, module) { -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules"); +var oop = require("pilot/oop").oop; +var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; var XmlHighlightRules = function() { @@ -114,5 +114,5 @@ var XmlHighlightRules = function() { oop.inherits(XmlHighlightRules, TextHighlightRules); -return XmlHighlightRules; -}); \ No newline at end of file +exports.XmlHighlightRules = XmlHighlightRules; +}); diff --git a/lib/ace/range.js b/lib/ace/range.js index 31e4ecae..a818617a 100644 --- a/lib/ace/range.js +++ b/lib/ace/range.js @@ -152,5 +152,5 @@ Range.fromPoints = function(start, end) { return new Range(start.row, start.column, end.row, end.column); }; -return Range; -}) +exports.Range = Range; +}); diff --git a/lib/ace/renderloop.js b/lib/ace/renderloop.js index 9a8ea34f..20fa21fb 100644 --- a/lib/ace/renderloop.js +++ b/lib/ace/renderloop.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var event = require("./lib/event") +var event = require("pilot/event").event; var RenderLoop = function(onRender) { this.onRender = onRender; @@ -62,11 +62,11 @@ var RenderLoop = function(onRender) { }) } }; - + if (window.postMessage) { - + this.messageName = "zero-timeout-message"; - + this.setTimeoutZero = function(callback) { if (!this.attached) { var _self = this; @@ -81,15 +81,15 @@ var RenderLoop = function(onRender) { this.callback = callback; window.postMessage(this.messageName, "*"); } - + } else { - + this.setTimeoutZero = function(callback) { setTimeout(callback, 0); } } - + }).call(RenderLoop.prototype); -return RenderLoop; -}); \ No newline at end of file +exports.RenderLoop = RenderLoop; +}); diff --git a/lib/ace/scrollbar.js b/lib/ace/scrollbar.js index 576b5ab4..8ff25a14 100644 --- a/lib/ace/scrollbar.js +++ b/lib/ace/scrollbar.js @@ -37,11 +37,11 @@ define(function(require, exports, module) { -var oop = require("./lib/oop"); -var lang = require("./lib/lang"); -var dom = require("./lib/dom"); -var event = require("./lib/event"); -var MEventEmitter = require("./event_emitter"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var dom = require("pilot/dom").dom; +var event = require("pilot/event").event; +var EventEmitter = require("pilot/event_emitter").EventEmitter; var ScrollBar = function(parent) { this.element = document.createElement("div"); @@ -59,7 +59,7 @@ var ScrollBar = function(parent) { }; (function() { - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.onScroll = function() { this.$dispatchEvent("scroll", {data: this.element.scrollTop}); @@ -83,5 +83,5 @@ var ScrollBar = function(parent) { }).call(ScrollBar.prototype); -return ScrollBar; +exports.ScrollBar = ScrollBar; }); diff --git a/lib/ace/search.js b/lib/ace/search.js index e3f040c4..3ea5eba0 100644 --- a/lib/ace/search.js +++ b/lib/ace/search.js @@ -37,9 +37,9 @@ define(function(require, exports, module) { -var lang = require("./lib/lang"); -var oop = require("./lib/oop"); -var Range = require("./range"); +var lang = require("pilot/lang").lang; +var oop = require("pilot/oop").oop; +var Range = require("ace/range").Range; var Search = function() { this.$options = { @@ -317,5 +317,5 @@ Search.SELECTION = 2; }).call(Search.prototype); -return Search; +exports.Search = Search; }); diff --git a/lib/ace/selection.js b/lib/ace/selection.js index 7af93630..3b551667 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -37,10 +37,10 @@ define(function(require, exports, module) { -var oop = require("./lib/oop"); -var lang = require("./lib/lang"); -var MEventEmitter = require("./event_emitter"); -var Range = require("./range"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var EventEmitter = require("pilot/event_emitter").EventEmitter; +var Range = require("ace/range").Range; var Selection = function(doc) { this.doc = doc; @@ -54,7 +54,7 @@ var Selection = function(doc) { (function() { - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.isEmpty = function() { return (!this.selectionAnchor || @@ -79,11 +79,11 @@ var Selection = function(doc) { if (!this.selectionAnchor) { this.selectionAnchor = anchor; - this.$dispatchEvent("changeSelection", {}); + this._dispatchEvent("changeSelection", {}); } else if (this.selectionAnchor.row !== anchor.row || this.selectionAnchor.column !== anchor.column) { this.selectionAnchor = anchor; - this.$dispatchEvent("changeSelection", {}); + this._dispatchEvent("changeSelection", {}); } }; @@ -142,7 +142,7 @@ var Selection = function(doc) { this.clearSelection = function() { if (this.selectionAnchor) { this.selectionAnchor = null; - this.$dispatchEvent("changeSelection", {}); + this._dispatchEvent("changeSelection", {}); } }; @@ -181,7 +181,7 @@ var Selection = function(doc) { } if (changed) - this.$dispatchEvent("changeSelection", {}); + this._dispatchEvent("changeSelection", {}); }; this.selectTo = function(row, column) { @@ -381,7 +381,7 @@ var Selection = function(doc) { // only dispatch change if the cursor actually changed if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) { this.selectionLead = cursor; - this.$dispatchEvent("changeCursor", { data: this.getCursor() }); + this._dispatchEvent("changeCursor", { data: this.getCursor() }); } }; @@ -417,5 +417,5 @@ var Selection = function(doc) { }).call(Selection.prototype); -return Selection; +exports.Selection = Selection; }); diff --git a/lib/ace/test/all.js b/lib/ace/test/all.js index be6a4ffa..297c69a4 100644 --- a/lib/ace/test/all.js +++ b/lib/ace/test/all.js @@ -1,3 +1,40 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + require({ paths: { "ace": "../src/ace" diff --git a/lib/ace/test/assertions.js b/lib/ace/test/assertions.js index 9075823b..1bccf3da 100644 --- a/lib/ace/test/assertions.js +++ b/lib/ace/test/assertions.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { diff --git a/lib/ace/test/change_document_test.js b/lib/ace/test/change_document_test.js index a78fe5ee..90ca741f 100644 --- a/lib/ace/test/change_document_test.js +++ b/lib/ace/test/change_document_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -30,11 +59,11 @@ var Test = { this.doc2 = new Document(["ghi", "jkl"].join("\n")); this.editor = new Editor(new MockRenderer()); }, - + "test: change document" : function() { this.editor.setDocument(this.doc1); assert.equal(this.editor.getDocument(), this.doc1); - + this.editor.setDocument(this.doc2); assert.equal(this.editor.getDocument(), this.doc2); }, @@ -134,4 +163,4 @@ var Test = { module.exports = require("async/test").testcase(Test); if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/document_test.js b/lib/ace/test/document_test.js index 4575b6e9..6ae725da 100644 --- a/lib/ace/test/document_test.js +++ b/lib/ace/test/document_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); diff --git a/lib/ace/test/event_emitter_test.js b/lib/ace/test/event_emitter_test.js index b8f96f1e..8b6b6a26 100644 --- a/lib/ace/test/event_emitter_test.js +++ b/lib/ace/test/event_emitter_test.js @@ -1,21 +1,49 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); var oop = require("../lib/oop"); MEventEmitter = require("../event_emitter"), assert = require("./assertions"); - - + var EventEmitter = function() {}; -oop.implement(EventEmitter.prototype, MEventEmitter); +oop.implement(EventEmitter.prototype, EventEmitter); var Test = { "test: dispatch event with no data" : function() { @@ -35,4 +63,4 @@ var Test = { module.exports = require("async/test").testcase(Test) if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/mockrenderer.js b/lib/ace/test/mockrenderer.js index 40367ee1..6a3f51a1 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { diff --git a/lib/ace/test/mode/css_test.js b/lib/ace/test/mode/css_test.js index 0660ad56..3fc588ea 100644 --- a/lib/ace/test/mode/css_test.js +++ b/lib/ace/test/mode/css_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/Document", @@ -13,10 +42,11 @@ require.def([ ], function( Document, Range, - CssMode + cssMod ) { - var CssTest = new TestCase("mode.CssTest", { +var CssMode = cssMod.Css; +var CssTest = new TestCase("mode.CssTest", { setUp : function() { this.mode = new CssMode(); diff --git a/lib/ace/test/mode/css_tokenizer_test.js b/lib/ace/test/mode/css_tokenizer_test.js index d6200751..7baedfab 100644 --- a/lib/ace/test/mode/css_tokenizer_test.js +++ b/lib/ace/test/mode/css_tokenizer_test.js @@ -1,17 +1,47 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/mode/Css" ], function( - CssMode + cssMod ) { +var CssMode = cssMod.Css; var CssTest = new TestCase("mode.CssTest", { setUp : function() { diff --git a/lib/ace/test/mode/html_test.js b/lib/ace/test/mode/html_test.js index d809315f..ae80f579 100644 --- a/lib/ace/test/mode/html_test.js +++ b/lib/ace/test/mode/html_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/Document", @@ -13,9 +42,10 @@ require.def([ ], function( Document, Range, - HtmlMode + htmlMod ) { +var HtmlMode = htmlMod.Html; var HtmlTest = new TestCase("mode.HtmlTest", { setUp : function() { diff --git a/lib/ace/test/mode/html_tokenizer_test.js b/lib/ace/test/mode/html_tokenizer_test.js index b538e4c4..b95bbe4e 100644 --- a/lib/ace/test/mode/html_tokenizer_test.js +++ b/lib/ace/test/mode/html_tokenizer_test.js @@ -1,17 +1,47 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/mode/Html" ], function( - HtmlMode + htmlMod ) { +var HtmlMode = htmlMod.Html; var HtmlTest = new TestCase("mode.HtmlTest", { setUp : function() { diff --git a/lib/ace/test/mode/javascript_test.js b/lib/ace/test/mode/javascript_test.js index 8f61d55a..2374edde 100644 --- a/lib/ace/test/mode/javascript_test.js +++ b/lib/ace/test/mode/javascript_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/Document", @@ -15,9 +44,10 @@ require.def([ Document, Range, Tokenizer, - JavaScriptMode + jsMod ) { +var JavaScriptMode = jsMod.JavaScript; var JavaScriptTest = new TestCase("mode.JavaScriptTest", { setUp : function() { diff --git a/lib/ace/test/mode/javascript_tokenizer_test.js b/lib/ace/test/mode/javascript_tokenizer_test.js index 65f40f21..a80bcdd5 100644 --- a/lib/ace/test/mode/javascript_tokenizer_test.js +++ b/lib/ace/test/mode/javascript_tokenizer_test.js @@ -1,17 +1,47 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/mode/JavaScript" ], function( - JavaScriptMode + jsMod ) { +var JavaScriptMode = jsMod.JavaScript; var JavaScriptTokenizerTest = new TestCase("mode.JavaScriptTokenizerTest", { setUp : function() { diff --git a/lib/ace/test/mode/text_test.js b/lib/ace/test/mode/text_test.js index 252b867e..9ca3880f 100644 --- a/lib/ace/test/mode/text_test.js +++ b/lib/ace/test/mode/text_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/Document", @@ -13,9 +42,10 @@ require.def([ ], function( Document, Range, - TextMode + textMod ) { +var TextMode = textMod.Text; var TextTest = new TestCase("mode.TextTest", { setUp : function() { diff --git a/lib/ace/test/mode/xml_test.js b/lib/ace/test/mode/xml_test.js index 8c8e7f92..f94f4a13 100644 --- a/lib/ace/test/mode/xml_test.js +++ b/lib/ace/test/mode/xml_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/Document", @@ -15,9 +44,10 @@ require.def([ Document, Range, Tokenizer, - XmlMode + xmlMod ) { +var XmlMode = xmlMod.Xml; var XmlTest = new TestCase("mode.XmlTest", { setUp : function() { diff --git a/lib/ace/test/mode/xml_tokenizer_test.js b/lib/ace/test/mode/xml_tokenizer_test.js index 3963fa70..ada2ea38 100644 --- a/lib/ace/test/mode/xml_tokenizer_test.js +++ b/lib/ace/test/mode/xml_tokenizer_test.js @@ -1,17 +1,47 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require.def([ "ace/mode/Xml" ], function( - XmlMode + xmlMod ) { +var XmlMode = xmlMod.Xml; var XmlTest = new TestCase("mode.XmlTest", { setUp : function() { diff --git a/lib/ace/test/navigation_test.js b/lib/ace/test/navigation_test.js index f05acd79..63e519e8 100644 --- a/lib/ace/test/navigation_test.js +++ b/lib/ace/test/navigation_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -132,4 +161,4 @@ var Test = { module.exports = require("async/test").testcase(Test) if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/range_test.js b/lib/ace/test/range_test.js index 3e8989c9..3aa1cc72 100644 --- a/lib/ace/test/range_test.js +++ b/lib/ace/test/range_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -121,4 +150,4 @@ var Test = { module.exports = require("async/test").testcase(Test); if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/search_test.js b/lib/ace/test/search_test.js index 9f4255fc..ba9b6e10 100644 --- a/lib/ace/test/search_test.js +++ b/lib/ace/test/search_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -318,4 +347,4 @@ var Test = { module.exports = require("async/test").testcase(Test) if (module === require.main) - module.exports.exec(); \ No newline at end of file + module.exports.exec(); diff --git a/lib/ace/test/selection_test.js b/lib/ace/test/selection_test.js index 539c146d..407fd3bf 100644 --- a/lib/ace/test/selection_test.js +++ b/lib/ace/test/selection_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -264,4 +293,4 @@ var Test = { module.exports = require("async/test").testcase(Test); if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/text_edit_test.js b/lib/ace/test/text_edit_test.js index 7dd20a19..c8d40c7b 100644 --- a/lib/ace/test/text_edit_test.js +++ b/lib/ace/test/text_edit_test.js @@ -1,10 +1,39 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ require("../../../support/paths"); @@ -18,11 +47,11 @@ global.navigator = browser.navigator; global.location = browser.location; var Document = require("../document"), - Editor = require("../editor"), - JavaScriptMode = require("../mode/javascript"), + Editor = require("../editor"), + JavaScriptMode = require("../mode/javascript").JavaScript, MockRenderer = require("./mockrenderer"), assert = require("./assertions"); - + var Test = { "test: delete line from the middle" : function() { var doc = new Document(["a", "b", "c", "d"].join("\n")); @@ -317,4 +346,4 @@ var Test = { module.exports = require("async/test").testcase(Test); if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/test/virtual_renderer_test.js b/lib/ace/test/virtual_renderer_test.js index 3f4a5ca3..776d8bab 100644 --- a/lib/ace/test/virtual_renderer_test.js +++ b/lib/ace/test/virtual_renderer_test.js @@ -1,13 +1,42 @@ -/** - * Ajax.org Code Editor (ACE) +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ - + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + require("../../../support/paths"); - + var Document = "../document", VirtualRenderer = "../virtual_renderer", assert = "../assertions"; @@ -45,4 +74,4 @@ var Test = { module.exports = require("async/test").testcase(Test); if (module === require.main) - module.exports.exec() \ No newline at end of file + module.exports.exec() diff --git a/lib/ace/textinput.js b/lib/ace/textinput.js index 4bcf479f..d4abdc96 100644 --- a/lib/ace/textinput.js +++ b/lib/ace/textinput.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var event = require("./lib/event"); +var event = require("pilot/event").event; var TextInput = function(parentNode, host) { @@ -146,5 +146,5 @@ var TextInput = function(parentNode, host) { }; }; -return TextInput; -}); \ No newline at end of file +exports.TextInput = TextInput; +}); diff --git a/lib/ace/theme/clouds.js b/lib/ace/theme/clouds.js index 9489d9ea..6f1fa494 100644 --- a/lib/ace/theme/clouds.js +++ b/lib/ace/theme/clouds.js @@ -1,6 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); + var dom = require("pilot/dom").dom; var cssText = ".ace-clouds .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -150,11 +187,9 @@ var dom = require("../lib/dom"); .ace-clouds .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-clouds" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-clouds"; +}); diff --git a/lib/ace/theme/clouds_mignight.js b/lib/ace/theme/clouds_mignight.js index 93c3f99d..d73350f2 100644 --- a/lib/ace/theme/clouds_mignight.js +++ b/lib/ace/theme/clouds_mignight.js @@ -1,6 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); + var dom = require("pilot/dom").dom; var cssText = ".ace-clouds-midnight .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -151,11 +188,9 @@ background-color:#E92E2E;\ .ace-clouds-midnight .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-clouds-midnight" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-clouds-midnight"; +}); diff --git a/lib/ace/theme/cobalt.js b/lib/ace/theme/cobalt.js index def66f11..5ae45ca1 100644 --- a/lib/ace/theme/cobalt.js +++ b/lib/ace/theme/cobalt.js @@ -1,7 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); - + var dom = require("pilot/dom").dom; var cssText = ".ace-cobalt .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -153,11 +189,9 @@ color:#0088FF;\ .ace-cobalt .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-cobalt" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-cobalt"; +}); diff --git a/lib/ace/theme/dawn.js b/lib/ace/theme/dawn.js index 247336da..02a46140 100644 --- a/lib/ace/theme/dawn.js +++ b/lib/ace/theme/dawn.js @@ -1,6 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); + var dom = require("pilot/dom").dom; var cssText = ".ace-dawn .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -156,11 +193,9 @@ color:#5A525F;\ .ace-dawn .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-dawn" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-dawn"; +}); diff --git a/lib/ace/theme/eclipse.js b/lib/ace/theme/eclipse.js index 8cee6e9e..9545a5eb 100644 --- a/lib/ace/theme/eclipse.js +++ b/lib/ace/theme/eclipse.js @@ -1,12 +1,47 @@ -define(["require", "exports", "module", "text!ace/theme/eclipse.css", "../lib/dom"], - function(require, exports, module, cssText) { +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + var dom = require("pilot/dom").dom; + var cssText = require("text!ace/theme/eclipse.css"); - var dom = require("../lib/dom"); - // import CSS once dom.importCssString(cssText); - return { - cssClass: "ace-eclipse" - }; -}) \ No newline at end of file + exports.cssClass = "ace-eclipse"; +}); diff --git a/lib/ace/theme/idle_fingers.js b/lib/ace/theme/idle_fingers.js index 6975a87d..c0e3733a 100644 --- a/lib/ace/theme/idle_fingers.js +++ b/lib/ace/theme/idle_fingers.js @@ -1,7 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); - + var dom = require("pilot/dom").dom; var cssText = ".ace-idle-fingers .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -153,11 +189,9 @@ color:#BC9458;\ .ace-idle-fingers .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-idle-fingers" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-idle-fingers"; +}); diff --git a/lib/ace/theme/kr_theme.js b/lib/ace/theme/kr_theme.js index 406f159b..164232d7 100644 --- a/lib/ace/theme/kr_theme.js +++ b/lib/ace/theme/kr_theme.js @@ -1,7 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); - + var dom = require("pilot/dom").dom; var cssText = ".ace-kr-theme .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -153,11 +189,9 @@ color:#706D5B;\ .ace-kr-theme .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-kr-theme" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-kr-theme"; +}); diff --git a/lib/ace/theme/mono_industrial.js b/lib/ace/theme/mono_industrial.js index 842f7ec3..20a0efbb 100644 --- a/lib/ace/theme/mono_industrial.js +++ b/lib/ace/theme/mono_industrial.js @@ -1,7 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); - + var dom = require("pilot/dom").dom; var cssText = ".ace-mono-industrial .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -153,11 +189,9 @@ background-color:#151C19;\ .ace-mono-industrial .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-mono-industrial" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-mono-industrial"; +}); diff --git a/lib/ace/theme/monokai.js b/lib/ace/theme/monokai.js index d20ac5d5..3e116bc6 100644 --- a/lib/ace/theme/monokai.js +++ b/lib/ace/theme/monokai.js @@ -1,7 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); - + var dom = require("pilot/dom").dom; var cssText = ".ace-monokai .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -153,11 +189,9 @@ background-color:#AE81FF;\ .ace-monokai .ace_xml_pe {\ \ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-monokai" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-monokai"; +}); diff --git a/lib/ace/theme/textmate.js b/lib/ace/theme/textmate.js index a28c2d6e..19d65d27 100644 --- a/lib/ace/theme/textmate.js +++ b/lib/ace/theme/textmate.js @@ -1,12 +1,47 @@ -define(["require", "exports", "module", "text!ace/theme/tm.css", "../lib/dom"], - function(require, exports, module, cssText) { +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ - var dom = require("../lib/dom"); +define(function(require, exports, module) { + + var dom = require("pilot/dom").dom; + var cssText = require("text!ace/theme/tm.css"); // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-tm" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-tm"; +}); diff --git a/lib/ace/theme/twilight.js b/lib/ace/theme/twilight.js index 1f3d61d5..dba0f7a4 100644 --- a/lib/ace/theme/twilight.js +++ b/lib/ace/theme/twilight.js @@ -1,6 +1,43 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org Services B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + define(function(require, exports, module) { -var dom = require("../lib/dom"); + var dom = require("pilot/dom").dom; var cssText = ".ace-twilight .ace_editor {\ border: 2px solid rgb(159, 159, 159);\ @@ -154,11 +191,9 @@ color:#5F5A60;\ .ace-twilight .ace_xml_pe {\ color:#494949;\ }"; - + // import CSS once dom.importCssString(cssText); - - return { - cssClass: "ace-twilight" - }; -}) \ No newline at end of file + + exports.cssClass = "ace-twilight"; +}); diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index 79e9082d..c5cdf964 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -128,5 +128,5 @@ var Tokenizer = function(rules) { }).call(Tokenizer.prototype); -return Tokenizer; -}); \ No newline at end of file +exports.Tokenizer = Tokenizer; +}); diff --git a/lib/ace/undomanager.js b/lib/ace/undomanager.js index 79a4ad7b..4ef90fef 100644 --- a/lib/ace/undomanager.js +++ b/lib/ace/undomanager.js @@ -73,5 +73,5 @@ var UndoManager = function() { }).call(UndoManager.prototype); -return UndoManager; -}); \ No newline at end of file +exports.UndoManager = UndoManager; +}); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 910e1467..08155d9c 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -35,22 +35,20 @@ * * ***** END LICENSE BLOCK ***** */ -define(["require", "exports", "module", "text!ace/css/editor.css", "./lib/oop", "./lib/oop", - "./lib/event", "./layer/gutter", "./layer/marker", "./layer/text", - "./layer/cursor", "./scrollbar", "./renderloop", "./event_emitter"], - function(require, exports, module, editorCss) { +define(function(require, exports, module) { -var oop = require("./lib/oop"); -var lang = require("./lib/lang"); -var dom = require("./lib/dom"); -var event = require("./lib/event"); -var GutterLayer = require("./layer/gutter"); -var MarkerLayer = require("./layer/marker"); -var TextLayer = require("./layer/text"); -var CursorLayer = require("./layer/cursor"); -var ScrollBar = require("./scrollbar"); -var RenderLoop = require("./renderloop"); -var MEventEmitter = require("./event_emitter"); +var oop = require("pilot/oop").oop; +var lang = require("pilot/lang").lang; +var dom = require("pilot/dom").dom; +var event = require("pilot/event").event; +var GutterLayer = require("ace/layer/gutter").Gutter; +var MarkerLayer = require("ace/layer/marker").Marker; +var TextLayer = require("ace/layer/text").Text; +var CursorLayer = require("ace/layer/cursor").Cursor; +var ScrollBar = require("ace/scrollbar").ScrollBar; +var RenderLoop = require("ace/renderloop").RenderLoop; +var EventEmitter = require("pilot/event_emitter").EventEmitter; +var editorCss = require("text!ace/css/editor.css"); // import CSS once dom.importCssString(editorCss); @@ -115,7 +113,7 @@ var VirtualRenderer = function(container, theme) { this.$loop = new RenderLoop(lang.bind(this.$renderChanges, this)); this.$loop.schedule(this.CHANGE_FULL); - + this.$updatePrintMargin(); this.setPadding(4); }; @@ -133,7 +131,7 @@ var VirtualRenderer = function(container, theme) { this.CHANGE_SIZE = 64; this.CHANGE_FULL = 128; - oop.implement(this, MEventEmitter); + oop.implement(this, EventEmitter); this.setDocument = function(doc) { this.lines = doc.lines; @@ -225,7 +223,7 @@ var VirtualRenderer = function(container, theme) { var pageX = event.getDocumentX(e); var pageY = event.getDocumentY(e); - this.$dispatchEvent("gutter" + e.type, { + this._dispatchEvent("gutter" + e.type, { row: this.screenToTextCoordinates(pageX, pageY).row, htmlEvent: e }); @@ -262,7 +260,7 @@ var VirtualRenderer = function(container, theme) { this.getPrintMarginColumn = function() { return this.$printMarginColumn; }; - + this.setShowGutter = function(show){ this.$gutter.style.display = show ? "block" : "none"; this.showGutter = show; @@ -295,18 +293,18 @@ var VirtualRenderer = function(container, theme) { this.getFirstVisibleRow = function() { return (this.layerConfig || {}).firstRow || 0; }; - + this.getFirstFullyVisibleRow = function(){ if (!this.layerConfig) return 0; - + return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); } this.getLastFullyVisibleRow = function() { if (!this.layerConfig) return 0; - + var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); return this.layerConfig.firstRow - 1 + flint; } @@ -374,7 +372,7 @@ var VirtualRenderer = function(container, theme) { } else if (changes & this.CHANGE_LINES) { this.$updateLines(); - this.$updateScrollBar(); + this.$updateScrollBar(); } if (changes & this.CHANGE_GUTTER) { this.showGutter && this.$gutterLayer.update(this.layerConfig); } @@ -470,17 +468,17 @@ var VirtualRenderer = function(container, theme) { this.$markerLayer.removeMarker(markerId); this.$loop.schedule(this.CHANGE_MARKER); }; - + this.addGutterDecoration = function(row, className){ this.$gutterLayer.addGutterDecoration(row, className); this.$loop.schedule(this.CHANGE_GUTTER); } - + this.removeGutterDecoration = function(row, className){ this.$gutterLayer.removeGutterDecoration(row, className); this.$loop.schedule(this.CHANGE_GUTTER); } - + this.setBreakpoints = function(rows) { this.$gutterLayer.setBreakpoints(rows); this.$loop.schedule(this.CHANGE_GUTTER); @@ -528,7 +526,7 @@ var VirtualRenderer = function(container, theme) { this.getScrollTop = function() { return this.scrollTop; }; - + this.getScrollLeft = function() { return this.scroller.scrollLeft; }; @@ -550,7 +548,7 @@ var VirtualRenderer = function(container, theme) { this.$loop.schedule(this.CHANGE_SCROLL); } }; - + this.scrollToX = function(scrollLeft) { if (scrollLeft <= this.$padding) scrollLeft = 0; @@ -579,10 +577,10 @@ var VirtualRenderer = function(container, theme) { this.textToScreenCoordinates = function(row, column) { var canvasPos = this.scroller.getBoundingClientRect(); - + var x = this.padding + Math.round(this.doc.documentToScreenColumn(row, column) * this.characterWidth); var y = row * this.lineHeight; - + return { pageX: canvasPos.left + x - this.getScrollLeft(), pageY: canvasPos.top + y - this.getScrollTop() @@ -637,5 +635,5 @@ var VirtualRenderer = function(container, theme) { }).call(VirtualRenderer.prototype); -return VirtualRenderer; -}); \ No newline at end of file +exports.VirtualRenderer = VirtualRenderer; +}); diff --git a/plugins/cockpit/lib/cli.js b/plugins/cockpit/lib/cli.js new file mode 100644 index 00000000..027ba9f8 --- /dev/null +++ b/plugins/cockpit/lib/cli.js @@ -0,0 +1,821 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var console = require('pilot/console'); +var util = require('pilot/util'); +var oop = require('pilot/oop').oop; +var EventEmitter = require('pilot/event_emitter').EventEmitter; + +//var keyboard = require('keyboard/keyboard'); +var types = require('pilot/types'); +var Status = require('pilot/types').Status; +var Conversion = require('pilot/types').Conversion; +var canon = require('pilot/canon'); + + +/** + * The information required to tell the user there is a problem with their + * input. + */ +function Hint(status, message, start, end) { + this.status = status; + this.message = message; + + if (typeof start === 'number') { + this.start = start; + this.end = end; + } + else { + var arg = start; + this.start = arg.start; + this.end = arg.end; + } +} +Hint.prototype = { +}; +exports.Hint = Hint; + +/** + * A Hint that arose as a result of a Conversion + */ +function ConversionHint(conversion, arg) { + this.status = conversion.status; + this.message = conversion.message; + if (arg) { + this.start = arg.start; + this.end = arg.end; + } + else { + this.start = 0; + this.end = 0; + } + this.predictions = conversion.predictions; +}; +oop.inherits(ConversionHint, Hint); + + +/** + * We record where in the input string an argument comes so we can report errors + * against those string positions. + * @constructor + */ +function Argument(text, start, end, priorSpace) { + this.setText(text); + this.start = start; + this.end = end; + this.priorSpace = priorSpace; +} +Argument.prototype = { + /** + * Return the result of merging these arguments + */ + merge: function(following) { + return new Argument( + this.text + following.priorSpace + following.text, + this.start, following.end, + this.priorSpace); + }, + + setText: function(text) { + if (text == null) { + throw new Error('Illegal text for Argument: ' + text); + } + this.text = text; + } +}; +/** + * Merge an array of arguments into a single argument. + */ +Argument.merge = function(argArray, start, end) { + start = (start === undefined) ? 0 : start; + end = (end === undefined) ? argArray.length : end; + + var joined; + for (var i = start; i < end; i++) { + var arg = argArray[i]; + if (!joined) { + joined = arg; + } + else { + joined = joined.merge(arg); + } + } + return joined; +}; + + +/** + * A link between a parameter and the data for that parameter. + * The data for the parameter is available as in the preferred type and as + * an Argument for the CLI. + *

We also record validity information where applicable. + *

For values, null and undefined have distinct definitions. null means + * that a value has been provided, undefined means that it has not. + * Thus, null is a valid default value, and common because it identifies an + * parameter that is optional. undefined means there is no value from + * the command line. + * @constructor + */ +function Assignment(param) { + this.param = param; + this.setValue(param.defaultValue); +}; +Assignment.prototype = { + /** + * The parameter that we are assigning to + * @readonly + */ + param: undefined, + + /** + * The current value (i.e. not the string representation) + * Use setValue() to mutate + */ + value: undefined, + setValue: function(value) { + if (this.value === value) { + return; + } + if (value === undefined) { + value = this.param.defaultValue; + } + this.value = value; + + var text = (value == null) ? '' : this.param.type.stringify(value); + if (this.arg) { + this.arg.setText(text); + } + + this.conversion = undefined; + //this._dispatchEvent('change', { assignment: this }); + }, + + /** + * The textual representation of the current value + * Use setValue() to mutate + */ + arg: undefined, + setArgument: function(arg) { + if (this.arg === arg) { + return; + } + this.arg = arg; + this.conversion = this.param.type.parse(arg.text); + this.value = this.conversion.value; + //this._dispatchEvent('change', { assignment: this }); + }, + + /** + * Create a list of this hints associated with this parameter assignment + */ + getHints: function() { + var hints = []; + if (this.conversion != null && + (this.conversion.status !== Status.VALID || + this.conversion.message)) { + hints.push(new ConversionHint(this.conversion, this.arg)); + } + + var argProvided = this.arg != null && this.arg.text !== ''; + var dataProvided = this.value !== undefined || argProvided; + + if (this.param.defaultValue === undefined && !dataProvided) { + // If the there is no data provided, we have no start/end. Use -1 + hints.push(new Hint(Status.INVALID, + 'Argument for ' + param.name + ' is required' + -1, -1)); + } + return hints; + }, + + /** + * Report on the status of the last parse() conversion. + * @see types.Conversion + */ + conversion: undefined +}; +oop.implement(Assignment, EventEmitter); +exports.Assignment = Assignment; + + +/** + * A Requisition collects the information needed to execute a command. + * There is no point in a requisition for parameter-less commands because there + * is no information to collect. A Requisition is a collection of assignments + * of values to parameters, each handled by an instance of Assignment. + * CliRequisition adds functions for parsing input from a command line to this + * class + * @constructor + */ +function Requisition() { +} +Requisition.prototype = { + /** + * The command that we are about to execute. + * @readonly + */ + command: undefined, + + /** + * The count of assignments + * @readonly + */ + assignmentCount: undefined, + + /** + * Set a new command. We make no attempt to convert the args in the old + * command to args in the new command. The assignments need to be + * re-entered. + */ + setCommand: function(command) { + if (this.command === command) { + return; + } + + this.command = command; + this._assignments = {}; + + if (command) { + command.params.forEach(function(param) { + this._assignments[param.name] = new Assignment(param); + }, this); + } + + this.assignmentCount = Object.keys(this._assignments); + }, + + /** + * Assignments have an order, so we need to store them in an array. + * But we also need named access ... + */ + getAssignment: function(nameOrNumber) { + var name = (typeof nameOrNumber === 'string') ? + nameOrNumber : + Object.keys(this._assignments)[nameOrNumber]; + return this._assignments[name]; + }, + + /** + * Where parameter name == assignment names - they are the same. + */ + getParameterNames: function() { + return Object.keys(this._assignments); + }, + + /** + * A *shallow* clone of the assignments. + * This is useful for systems that wish to go over all the assignments + * finding values one way or another and wish to trim an array as they go. + */ + cloneAssignments: function() { + return Object.keys(this._assignments).map(function(name) { + return this._assignments[name]; + }, this); + }, + + /** + * Collect the statuses from the Assignments + */ + getHints: function() { + var hints = []; + Object.keys(this._assignments).map(function(name) { + // Append the assignments hints to our list + hints.push.apply(hints, this._assignments[name].getHints()); + }, this); + return hints; + }, + + /** + * Extract the names and values of all the assignments, and return as + * an object. + */ + getArgs: function() { + var args = {}; + Object.keys(this._assignments).forEach(function(name) { + args[name] = this.getAssignment(name).value; + }, this); + return args; + }, + + /** + * Reset all the assignments to their default values + */ + setDefaultValues: function() { + Object.keys(this._assignments).forEach(function(name) { + this._assignments[name].setValue(undefined); + }, this); + }, + + /** + * Helper to call canon.exec + */ + exec: function() { + canon.exec(this.command, this.getArgs()); + } +}; +exports.Requisition = Requisition; + + +/** + * An object used during command line parsing to hold the various intermediate + * data steps. + *

The 'output' of the update is held in 2 objects: input.hints which is an + * array of hints to display to the user. In the future this will become a + * single value. + *

The other output value is input.requisition which gives access to an + * args object for use in executing the final command. + * + *

The majority of the functions in this class are called in sequence by the + * constructor. Their task is to add to hints fill out the requisition. + *

The general sequence is:

    + *
  • _tokenize(): convert _typed into _parts + *
  • _split(): convert _parts into _command and _unparsedArgs + *
  • _assign(): convert _unparsedArgs into requisition + *
+ * + * @param typed {string} The instruction as typed by the user so far + * @param options {object} A list of optional named parameters. Can be any of: + * flags: Flags for us to check against the predicates specified with the + * commands. Defaulted to keyboard.buildFlags({ }); + * if not specified. + * @constructor + */ +function CliRequisition(options) { + if (options && options.flags) { + /** + * TODO: We were using a default of keyboard.buildFlags({ }); + * This allowed us to have commands that only existed in certain contexts + * - i.e. Javascript specific commands. + */ + this.flags = options.flags; + } +} +oop.inherits(CliRequisition, Requisition); +(function() { + /** + * + */ + CliRequisition.prototype.update = function(input) { + this.hints = []; + + if (util.none(input.typed)) { + this.setCommand(null); + return; + } + + var args = _tokenize(input.typed); + if (args.length === 0) { + // We would like to put some initial help here, but for anyone but + // a complete novice a 'type help' message is very annoying, so we + // need to find a way to only display this message once, or for + // until the user click a 'close' button or similar + this._addHint(Status.INCOMPLETE, '', 0, 0); + this.setCommand(null); + return; + } + + var command = _split(args); + if (!command) { + // No command found - bail helpfully. + var commandType = types.getType('command'); + var conversion = commandType.parse(input.typed); + var arg = Argument.merge(args); + this._addHint(new ConversionHint(conversion, arg)); + + this.setCommand(null); + } + else { + // The user hasn't started to type any arguments + if (args.length === 0) { + var message = documentCommand(command); + this._addHint(Status.VALID, message, 0, input.typed.length); + } + + this.setCommand(command); + this._assign(args); + this._addHint(CliRequisition.super_.getHints.call(this)); + } + + // Not knowing about cursor positioning, the requisition and assignments + // can't know this, but anything they mark as INCOMPLETE is actually + // INVALID unless the cursor is actually inside that argument. + var c = input.cursor; + this.hints.forEach(function(hint) { + var startInHint = c.start >= hint.start && c.start <= hint.end; + var endInHint = c.end >= hint.start && c.end <= hint.end; + var inHint = startInHint || endInHint; + if (!inHint && hint.status === Status.INCOMPLETE) { + hint.status = Status.INVALID; + } + }, this); + + return; + }; + + CliRequisition.prototype.getHints = function() { + return this.hints; + }; + + /** + * Some sugar around: 'this.hints.push(new Hint(...));', but you can also + * pass in an array of Hints or the parameters to create a hint + */ + CliRequisition.prototype._addHint = function(status, message, start, end) { + if (status == null) { + return; + } + if (status instanceof Hint) { + this.hints.push(status); + } + else if (Array.isArray(status)) { + this.hints.push.apply(this.hints, status); + } + else { + this.hints.push(new Hint(status, message, start, end)); + } + }; + + /** + * Work out which arguments are applicable to which parameters. + *

This takes #_command.params and #_unparsedArgs and creates a map of + * param names to 'assignment' objects, which have the following properties: + *

    + *
  • param - The matching parameter. + *
  • index - Zero based index into where the match came from on the input + *
  • value - The matching input + *
+ */ + CliRequisition.prototype._assign = function(args) { + if (args.length === 0) { + this.setDefaultValues(); + return; + } + + // Create an error if the command does not take parameters, but we have + // been given them ... + if (this.assignmentCount === 0) { + // TODO: previously we were doing some extra work to avoid this if + // we determined that we had args that were all whitespace, but + // probably given our tighter tokenize() this won't be an issue? + this._addHint(Status.INVALID, + this.command.name + ' does not take any parameters', + Argument.merge(args)); + return; + } + + // Special case: if there is only 1 parameter, and that's of type + // text we put all the params into the first param + if (this.assignmentCount == 1) { + var assignment = this.getAssignment(0); + if (assignment.param.type.name === 'text') { + assignment.setArgument(Argument.merge(args)); + return; + } + } + + var assignments = this.cloneAssignments(); + var names = this.getParameterNames(); + + // Extract all the named parameters + var used = []; + assignments.forEach(function(assignment) { + var namedArgText = '--' + assignment.name; + + var i = 0; + while (true) { + var arg = args[i]; + if (namedArgText !== arg.text) { + i++; + if (i >= args.length) { + break; + } + continue; + } + + // boolean parameters don't have values, default to false + if (assignment.param.type.name === 'boolean') { + assignment.setValue(true); + } + else { + if (i + 1 < args.length) { + // Missing value portion of this named param + this._addHint(Status.INCOMPLETE, + 'Missing value for: ' + namedArgText, + args[i]); + } + else { + args.splice(i + 1, 1); + assignment.setArgument(args[i + 1]); + } + } + + util.arrayRemove(names, assignment.name); + args.splice(i, 1); + // We don't need to i++ if we splice + } + }, this); + + // What's left are positional parameters assign in order + names.forEach(function(name) { + var assignment = this.getAssignment(name); + if (args.length === 0) { + // No more values + assignment.setValue(undefined); // i.e. default + } + else { + var arg = args[0]; + args.splice(0, 1); + assignment.setArgument(arg); + } + }, this); + + if (args.length > 0) { + var remaining = Argument.merge(args); + this._addHint(Status.INVALID, + 'Input \'' + remaining.text + '\' makes no sense.', + remaining); + } + }; + +})(); +exports.CliRequisition = CliRequisition; + +/** + * Split up the input taking into account ' and " + */ +function _tokenize(typed) { + var OUTSIDE = 1; // The last character was whitespace + var IN_SIMPLE = 2; // The last character was part of a parameter + var IN_SINGLE_Q = 3; // We're inside a single quote: ' + var IN_DOUBLE_Q = 4; // We're inside double quotes: " + + var mode = OUTSIDE; + + // First we un-escape. This list was taken from: + // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Unicode + // We are generally converting to their real values except for \', \" + // and '\ ' which we are converting to unicode private characters so we + // can distinguish them from ', " and ' ', which have special meaning. + // They need swapping back post-split - see unescape() + typed = typed + .replace(/\\\\/g, '\\') + .replace(/\\b/g, '\b') + .replace(/\\f/g, '\f') + .replace(/\\n/g, '\n') + .replace(/\\r/g, '\r') + .replace(/\\t/g, '\t') + .replace(/\\v/g, '\v') + .replace(/\\n/g, '\n') + .replace(/\\r/g, '\r') + .replace(/\\ /g, '\uF000') + .replace(/\\'/g, '\uF001') + .replace(/\\"/g, '\uF002'); + + function unescape(str) { + return str + .replace(/\uF000/g, ' ') + .replace(/\uF001/g, '\'') + .replace(/\uF002/g, '"'); + } + + var i = 0; + var start = 0; // Where did this section start? + var priorSpace = ''; + var args = []; + + while (true) { + if (i >= typed.length) { + // There is no more - tidy up + if (mode !== OUTSIDE) { + var str = unescape(typed.substring(start, i)); + args.push(new Argument(str, start, i, priorSpace)); + } + break; + } + + var c = typed[i]; + switch (mode) { + case OUTSIDE: + if (c === '\'') { + priorSpace = typed.substring(start, i); + mode = IN_SINGLE_Q; + start = i + 1; + } + else if (c === '"') { + priorSpace = typed.substring(start, i); + mode = IN_DOUBLE_Q; + start = i + 1; + } + else if (/ /.test(c)) { + // Still whitespace, do nothing + } + else { + priorSpace = typed.substring(start, i); + mode = IN_SIMPLE; + start = i; + } + break; + + case IN_SIMPLE: + // There is an edge case of xx'xx which we are assuming to be + // a single parameter (and same with ") + if (c === ' ') { + var str = unescape(typed.substring(start, i)); + args.push(new Argument(str, start, i, priorSpace)); + mode = OUTSIDE; + start = i; + priorSpace = ''; + } + break; + + case IN_SINGLE_Q: + if (c === '\'') { + var str = unescape(typed.substring(start, i)); + args.push(new Argument(str, start, i, priorSpace)); + mode = OUTSIDE; + start = i + 1; + priorSpace = ''; + } + break; + + case IN_DOUBLE_Q: + if (c === '"') { + var str = unescape(typed.substring(start, i)); + args.push(new Argument(str, start, i, priorSpace)); + mode = OUTSIDE; + start = i + 1; + priorSpace = ''; + } + break; + } + + i++; + } + + return args; +} +exports._tokenize = _tokenize; + +/** + * Looks in the canon for a command extension that matches what has been + * typed at the command line. + */ +function _split(args) { + if (args.length === 0) { + return undefined; + } + + var argsUsed = 0; + var lookup = ''; + var command; + + while (true) { + argsUsed++; + lookup += args.map(function(arg) { + return arg.text; + }).slice(0, argsUsed).join(' '); + command = canon.getCommand(lookup); + + if (!command) { + // Not found. break with command == null + return undefined; + } + + /* + // Previously we needed a way to hide commands depending context. + // We have not resurrected that feature yet. + if (!keyboard.flagsMatch(command.predicates, this.flags)) { + // If the predicates say 'no match' then go LA LA LA + command = null; + break; + } + */ + + if (command.exec) { + // Valid command, break with command valid + break; + } + + // command, but no exec - this must be a sub-command + lookup += ' '; + } + + // Remove the used args + for (var i = 0; i < argsUsed; i++) { + args.shift(); + } + + return command; +} +exports._split = _split; + + +/** + * Provide some documentation for a command. + * TODO: this should return a hint + */ +function documentCommand(command) { + var docs = []; + docs.push('

' + command.name + '

'); + docs.push('

Summary

'); + docs.push('

' + command.description + '

'); + + if (command.manual) { + docs.push('

Description

'); + docs.push('

' + command.description + '

'); + } + + if (command.params && command.params.length > 0) { + docs.push('

Synopsis

'); + docs.push('
');
+        docs.push(command.name);
+        var optionalParamCount = 0;
+        command.params.forEach(function(param) {
+            if (param.defaultValue === undefined) {
+                docs.push(' ');
+                docs.push(param.name);
+                docs.push('');
+            }
+            else if (param.defaultValue === null) {
+                docs.push(' [');
+                docs.push(param.name);
+                docs.push(']');
+            }
+            else {
+                optionalParamCount++;
+            }
+        }, this);
+        if (optionalParamCount > 3) {
+            docs.push(' [options]');
+        } else if (optionalParamCount > 0) {
+            command.params.forEach(function(param) {
+                if (param.defaultValue) {
+                    docs.push(' [--');
+                    docs.push(param.name);
+                    if (param.type.name === 'boolean') {
+                        docs.push('');
+                    }
+                    else {
+                        docs.push(' ' + param.type.name);
+                    }
+                    docs.push(']');
+                }
+            }, this);
+        }
+        docs.push('
'); + + docs.push('

Parameters

'); + command.params.forEach(function(param) { + docs.push('

' + param.name + '

'); + docs.push('

' + param.description + '

'); + if (param.type.defaultValue) { + docs.push('

Default: ' + param.type.defaultValue + '

'); + } + }, this); + } + + return docs.join(''); +}; +exports.documentCommand = documentCommand; + + + + +}); diff --git a/plugins/cockpit/lib/index.js b/plugins/cockpit/lib/index.js new file mode 100644 index 00000000..beacc28f --- /dev/null +++ b/plugins/cockpit/lib/index.js @@ -0,0 +1,59 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.startup = function(data, reason) { + + window.testCli = require('cockpit/test/testCli'); + + var plain = require('cockpit/ui/plain'); + plain.startup(data, reason); + +}; + +/* +exports.shutdown(data, reason) { + deps.forEach(function(dep) { + var module = require(dep); + if (typeof module.shutdown === "function") { + module.shutdown(data, reason); + } + }); +}; +*/ +}); diff --git a/plugins/cockpit/lib/test/assert.js b/plugins/cockpit/lib/test/assert.js new file mode 100644 index 00000000..d0d1b93a --- /dev/null +++ b/plugins/cockpit/lib/test/assert.js @@ -0,0 +1,317 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var test = { + + success: function(message) { + console.log(message); + }, + + fail: function(message) { + test._recordThrow("fail", arguments); + }, + + assertTrue: function(value) { + if (!value) { + test._recordThrow("assertTrue", arguments); + } + }, + + verifyTrue: function(value) { + if (!value) { + test._recordTrace("verifyTrue", arguments); + } + }, + + assertFalse: function(value) { + if (value) { + test._recordThrow("assertFalse", arguments); + } + }, + + verifyFalse: function(value) { + if (value) { + test._recordTrace("verifyFalse", arguments); + } + }, + + assertNull: function(value) { + if (value !== null) { + test._recordThrow("assertNull", arguments); + } + }, + + verifyNull: function(value) { + if (value !== null) { + test._recordTrace("verifyNull", arguments); + } + }, + + assertNotNull: function(value) { + if (value === null) { + test._recordThrow("assertNotNull", arguments); + } + }, + + verifyNotNull: function(value) { + if (value === null) { + test._recordTrace("verifyNotNull", arguments); + } + }, + + assertUndefined: function(value) { + if (value !== undefined) { + test._recordThrow("assertUndefined", arguments); + } + }, + + verifyUndefined: function(value) { + if (value !== undefined) { + test._recordTrace("verifyUndefined", arguments); + } + }, + + assertNotUndefined: function(value) { + if (value === undefined) { + test._recordThrow("assertNotUndefined", arguments); + } + }, + + verifyNotUndefined: function(value) { + if (value === undefined) { + test._recordTrace("verifyNotUndefined", arguments); + } + }, + + assertNaN: function(value) { + if (!isNaN(value)) { + test._recordThrow("assertNaN", arguments); + } + }, + + verifyNaN: function(value) { + if (!isNaN(value)) { + test._recordTrace("verifyNaN", arguments); + } + }, + + assertNotNaN: function(value) { + if (isNaN(value)) { + test._recordThrow("assertNotNaN", arguments); + } + }, + + verifyNotNaN: function(value) { + if (isNaN(value)) { + test._recordTrace("verifyNotNaN", arguments); + } + }, + + assertEqual: function(expected, actual) { + if (!test._isEqual(expected, actual)) { + test._recordThrow("assertEqual", arguments); + } + }, + + verifyEqual: function(expected, actual) { + if (!test._isEqual(expected, actual)) { + test._recordTrace("verifyEqual", arguments); + } + }, + + assertNotEqual: function(expected, actual) { + if (test._isEqual(expected, actual)) { + test._recordThrow("assertNotEqual", arguments); + } + }, + + verifyNotEqual: function(expected, actual) { + if (test._isEqual(expected, actual)) { + test._recordTrace("verifyNotEqual", arguments); + } + }, + + assertSame: function(expected, actual) { + if (expected !== actual) { + test._recordThrow("assertSame", arguments); + } + }, + + verifySame: function(expected, actual) { + if (expected !== actual) { + test._recordTrace("verifySame", arguments); + } + }, + + assertNotSame: function(expected, actual) { + if (expected !== actual) { + test._recordThrow("assertNotSame", arguments); + } + }, + + verifyNotSame: function(expected, actual) { + if (expected !== actual) { + test._recordTrace("verifyNotSame", arguments); + } + }, + + _recordTrace: function() { + test._record.apply(this, arguments); + console.trace(); + }, + + _recordThrow: function() { + test._record.apply(this, arguments); + throw new Error(); + }, + + _record: function() { + console.error(arguments); + var message = arguments[0] + "("; + var data = arguments[1]; + if (typeof data == "string") { + message += data; + } + else { + for (var i = 0; i < data.length; i++) { + if (i != 0){message += ", ";} + message += data[i]; + } + } + message += ")"; + console.log(message); + }, + + _isEqual: function(expected, actual, depth) { + if (!depth){depth = 0;} + // Rather than failing we assume that it works! + if (depth > 10) { + return true; + } + + if (expected == null) { + if (actual != null) { + console.log("expected: null, actual non-null: ", actual); + return false; + } + return true; + } + + if (typeof(expected) == "number" && isNaN(expected)) { + if (!(typeof(actual) == "number" && isNaN(actual))) { + console.log("expected: NaN, actual non-NaN: ", actual); + return false; + } + return true; + } + + if (actual == null) { + if (expected != null) { + console.log("actual: null, expected non-null: ", expected); + return false; + } + return true; // we wont get here of course ... + } + + if (typeof expected == "object") { + if (!(typeof actual == "object")) { + console.log("expected object, actual not an object"); + return false; + } + + var actualLength = 0; + for (var prop in actual) { + if (typeof actual[prop] != "function" || + typeof expected[prop] != "function") { + var nest = test._isEqual(actual[prop], expected[prop], depth + 1); + if (typeof nest != "boolean" || !nest) { + console.log("element '" + prop + "' does not match: " + nest); + return false; + } + } + actualLength++; + } + + // need to check length too + var expectedLength = 0; + for (prop in expected) expectedLength++; + if (actualLength != expectedLength) { + console.log("expected object size = " + expectedLength + + ", actual object size = " + actualLength); + return false; + } + return true; + } + + if (actual != expected) { + console.log("expected = " + expected + " (type=" + typeof expected + "), " + + "actual = " + actual + " (type=" + typeof actual + ")"); + return false; + } + + if (expected instanceof Array) { + if (!(actual instanceof Array)) { + console.log("expected array, actual not an array"); + return false; + } + if (actual.length != expected.length) { + console.log("expected array length = " + expected.length + + ", actual array length = " + actual.length); + return false; + } + for (var i = 0; i < actual.length; i++) { + var inner = test._isEqual(actual[i], expected[i], depth + 1); + if (typeof inner != "boolean" || !inner) { + console.log("element " + i + " does not match: " + inner); + return false; + } + } + + return true; + } + + return true; + } +}; + + +exports.test = test; + + +}); diff --git a/plugins/cockpit/lib/test/testCli.js b/plugins/cockpit/lib/test/testCli.js new file mode 100644 index 00000000..bace956e --- /dev/null +++ b/plugins/cockpit/lib/test/testCli.js @@ -0,0 +1,279 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var test = require('cockpit/test/assert').test; +var Status = require('pilot/types').Status; +var settings = require('pilot/settings').settings; +var tokenize = require('cockpit/cli')._tokenize; +var split = require('cockpit/cli')._split; +var CliRequisition = require('cockpit/cli').CliRequisition; + + +exports.testAll = function() { + exports.testTokenize(); + exports.testSplit(); + exports.testCli(); + return "testAll Completed"; +}; + +exports.testTokenize = function() { + var args = tokenize(''); + test.verifyEqual(0, args.length); + + args = tokenize('s'); + test.verifyEqual(1, args.length); + test.verifyEqual('s', args[0].text); + test.verifyEqual(0, args[0].start); + test.verifyEqual(1, args[0].end); + test.verifyEqual('', args[0].priorSpace); + + args = tokenize('s s'); + test.verifyEqual(2, args.length); + test.verifyEqual('s', args[0].text); + test.verifyEqual(0, args[0].start); + test.verifyEqual(1, args[0].end); + test.verifyEqual('', args[0].priorSpace); + test.verifyEqual('s', args[1].text); + test.verifyEqual(2, args[1].start); + test.verifyEqual(3, args[1].end); + test.verifyEqual(' ', args[1].priorSpace); + + args = tokenize(' 1234 \'12 34\''); + test.verifyEqual(2, args.length); + test.verifyEqual('1234', args[0].text); + test.verifyEqual(1, args[0].start); + test.verifyEqual(5, args[0].end); + test.verifyEqual(' ', args[0].priorSpace); + test.verifyEqual('12 34', args[1].text); + test.verifyEqual(8, args[1].start); + test.verifyEqual(13, args[1].end); + test.verifyEqual(' ', args[1].priorSpace); + + args = tokenize('12\'34 "12 34" \\'); // 12'34 "12 34" \ + test.verifyEqual(3, args.length); + test.verifyEqual('12\'34', args[0].text); + test.verifyEqual(0, args[0].start); + test.verifyEqual(5, args[0].end); + test.verifyEqual('', args[0].priorSpace); + test.verifyEqual('12 34', args[1].text); + test.verifyEqual(7, args[1].start); + test.verifyEqual(12, args[1].end); + test.verifyEqual(' ', args[1].priorSpace); + test.verifyEqual('\\', args[2].text); + test.verifyEqual(14, args[2].start); + test.verifyEqual(15, args[2].end); + test.verifyEqual(' ', args[2].priorSpace); + + args = tokenize('a\\ b \\t\\n\\r \\\'x\\\" \'d'); // a_b \t\n\r \'x\" 'd + test.verifyEqual(4, args.length); + test.verifyEqual('a b', args[0].text); + test.verifyEqual(0, args[0].start); + test.verifyEqual(3, args[0].end); + test.verifyEqual('', args[0].priorSpace); + test.verifyEqual('\t\n\r', args[1].text); + test.verifyEqual(4, args[1].start); + test.verifyEqual(7, args[1].end); + test.verifyEqual(' ', args[1].priorSpace); + test.verifyEqual('\'x"', args[2].text); + test.verifyEqual(8, args[2].start); + test.verifyEqual(11, args[2].end); + test.verifyEqual(' ', args[2].priorSpace); + test.verifyEqual('d', args[3].text); + test.verifyEqual(13, args[3].start); + test.verifyEqual(14, args[3].end); + test.verifyEqual(' ', args[3].priorSpace); + + return "testTokenize Completed"; +}; + +exports.testSplit = function() { + var args = tokenize('s'); + var command = split(args); + test.verifyEqual(1, args.length); + test.verifyEqual('s', args[0].text); + test.verifyUndefined(command); + + var args = tokenize('set'); + var command = split(args); + test.verifyEqual([], args); + test.verifyEqual('set', command.name); + + var args = tokenize('set a b'); + var command = split(args); + test.verifyEqual('set', command.name); + test.verifyEqual(2, args.length); + test.verifyEqual('a', args[0].text); + test.verifyEqual('b', args[1].text); + + // TODO: add tests for sub commands + return "testSplit Completed"; +}; + +exports.testCli = function() { + var hints; + var hint0; + var settingAssignment; + var valueAssignment; + var cli = new CliRequisition(); + + function update(input) { + cli.update(input); + hints = cli.getHints(); + hint0 = (hints.length !== 0) ? hints[0] : undefined; + if (cli.command && cli.command.name === 'set') { + settingAssignment = cli.getAssignment('setting'); + valueAssignment = cli.getAssignment('value'); + } + else { + settingAssignment = undefined; + valueAssignment = undefined; + } + } + + var historyLengthSetting = settings.getSetting('historyLength'); + + update({ typed: '', cursor: { start: 0, end: 0 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INCOMPLETE, hint0.status); + test.verifyEqual(0, hint0.start); + test.verifyEqual(0, hint0.end); + test.verifyNull(cli.command); + + update({ typed: 's', cursor: { start: 1, end: 1 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INCOMPLETE, hint0.status); + test.verifyNotEqual(-1, hint0.message.indexOf('possibilities')); + test.verifyEqual(0, hint0.start); + test.verifyEqual(1, hint0.end); + test.verifyTrue(hint0.predictions.length > 0); + // This is slightly fragile because it depends on the configuration + test.verifyTrue(hint0.predictions.length < 20); + test.verifyNotEqual(-1, hint0.predictions.indexOf('set')); + test.verifyNull(cli.command); + + update({ typed: 'set', cursor: { start: 3, end: 3 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.VALID, hint0.status); + test.verifyEqual(0, hint0.start); + test.verifyEqual(3, hint0.end); + test.verifyEqual('set', cli.command.name); + + update({ typed: 'set ', cursor: { start: 4, end: 4 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.VALID, hint0.status); + test.verifyEqual(0, hint0.start); + // Technically the command ends at 3, but we're returning 4 currently. + // This is caused by us using the whole input to determine the length. + // Maybe one day we should fix this? + //test.verifyEqual(3, hint0.end); + test.verifyEqual('set', cli.command.name); + + update({ typed: 'set h', cursor: { start: 5, end: 5 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INCOMPLETE, hint0.status); + test.verifyTrue(hint0.predictions.length > 0); + test.verifyEqual(4, hint0.start); + test.verifyEqual(5, hint0.end); + test.verifyNotEqual(-1, hint0.predictions.indexOf('historyLength')); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('h', settingAssignment.arg.text); + test.verifyEqual(undefined, settingAssignment.value); + + update({ typed: 'set historyLengt', cursor: { start: 16, end: 16 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INCOMPLETE, hint0.status); + test.verifyEqual(1, hint0.predictions.length); + test.verifyEqual(4, hint0.start); + test.verifyEqual(16, hint0.end); + test.verifyEqual('historyLength', hint0.predictions[0]); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLengt', settingAssignment.arg.text); + test.verifyEqual(undefined, settingAssignment.value); + + update({ typed: 'set historyLengt', cursor: { start: 1, end: 1 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INVALID, hint0.status); + test.verifyEqual(4, hint0.start); + test.verifyEqual(16, hint0.end); + test.verifyEqual(1, hint0.predictions.length); + test.verifyEqual('historyLength', hint0.predictions[0]); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLengt', settingAssignment.arg.text); + test.verifyEqual(undefined, settingAssignment.value); + + update({ typed: 'set historyLengt ', cursor: { start: 17, end: 17 } }); + test.verifyEqual(1, hints.length); + test.verifyEqual(Status.INVALID, hint0.status); + test.verifyEqual(4, hint0.start); + test.verifyEqual(16, hint0.end); + test.verifyEqual(1, hint0.predictions.length); + test.verifyEqual('historyLength', hint0.predictions[0]); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLengt', settingAssignment.arg.text); + test.verifyEqual(undefined, settingAssignment.value); + + update({ typed: 'set historyLength', cursor: { start: 17, end: 17 } }); + test.verifyEqual(0, hints.length); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLength', settingAssignment.arg.text); + test.verifyEqual(historyLengthSetting, settingAssignment.value); + + update({ typed: 'set historyLength ', cursor: { start: 18, end: 18 } }); + test.verifyEqual(0, hints.length); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLength', settingAssignment.arg.text); + test.verifyEqual(historyLengthSetting, settingAssignment.value); + + update({ typed: 'set historyLength 6', cursor: { start: 19, end: 19 } }); + test.verifyEqual(0, hints.length); + test.verifyEqual('set', cli.command.name); + test.verifyEqual('historyLength', settingAssignment.arg.text); + test.verifyEqual(historyLengthSetting, settingAssignment.value); + test.verifyEqual('6', valueAssignment.arg.text); + test.verifyEqual(6, valueAssignment.value); + test.verifyEqual('number', typeof valueAssignment.value); + + // TODO: Add test to see that a command without mandatory param causes INVALID + + return "testCli Completed"; +}; + + +}); diff --git a/lib/ace/plugin_manager.js b/plugins/cockpit/lib/test/testNothing.js similarity index 84% rename from lib/ace/plugin_manager.js rename to plugins/cockpit/lib/test/testNothing.js index 2bd5abc6..567b575a 100644 --- a/lib/ace/plugin_manager.js +++ b/plugins/cockpit/lib/test/testNothing.js @@ -11,15 +11,15 @@ * for the specific language governing rights and limitations under the * License. * - * The Original Code is Ajax.org Code Editor (ACE). + * The Original Code is Skywriter. * * The Initial Developer of the Original Code is - * Ajax.org Services B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Fabian Jakobs + * Joe Walker (jwalker@mozilla.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -37,13 +37,4 @@ define(function(require, exports, module) { -var PluginManager = { - commands : {}, - - registerCommand : function(name, command) { - this.commands[name] = command; - } -}; - -return PluginManager; -}); \ No newline at end of file +}); diff --git a/plugins/cockpit/lib/ui/plain.css b/plugins/cockpit/lib/ui/plain.css new file mode 100644 index 00000000..85c55ff1 --- /dev/null +++ b/plugins/cockpit/lib/ui/plain.css @@ -0,0 +1,2 @@ + +#cockpit { color: red; } diff --git a/plugins/cockpit/lib/ui/plain.js b/plugins/cockpit/lib/ui/plain.js new file mode 100644 index 00000000..445a7864 --- /dev/null +++ b/plugins/cockpit/lib/ui/plain.js @@ -0,0 +1,98 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var editorCss = require("text!cockpit/ui/plain.css"); +var dom = require("pilot/dom").dom; +dom.importCssString(editorCss); + +var CliRequisition = require('cockpit/cli').CliRequisition; +var keyutil = require('pilot/keyboard/keyutil'); + +exports.startup = function(data, reason) { + // TODO: we should have a better way to specify command lines??? + this.input = document.getElementById('cockpit'); + if (!this.input) { + console.log('No element with an id of cockpit. Bailing on plain cli'); + return; + } + + var cli = new CliRequisition(); + + /* + // All this does is to kill TABs normal use. I wonder if we can train + // people to use right arrow? Probably not? but ... + keyutil.addKeyDownListener(input, function(ev) { + // env.commandLine = this; + // var handled = keyboardManager.processKeyEvent(ev, this, { + // isCommandLine: true, isKeyUp: false + // }); + if (ev.keyCode === keyutil.KeyHelper.KEY.TAB) { + return true; + } + //return handled; + }.bind(this)); + */ + + this.input.addEventListener('keyup', function(ev) { + /* + var handled = keyboardManager.processKeyEvent(ev, this, { + isCommandLine: true, isKeyUp: true + }); + */ + + if (ev.keyCode === keyutil.KeyHelper.KEY.RETURN) { + cli.exec(); + this.input.value = ''; + } else { + cli.update({ + typed: this.input.value, + cursor: { + start: this.input.selectionStart, + end: this.input.selectionEnd + } + }); + console.log(JSON.stringify(cli.getHints())); + } + + // return handled; + }.bind(this), true); +}; + + +}); diff --git a/plugins/pilot/lib/canon.js b/plugins/pilot/lib/canon.js new file mode 100644 index 00000000..aa308f49 --- /dev/null +++ b/plugins/pilot/lib/canon.js @@ -0,0 +1,329 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var console = require('pilot/console'); +var Trace = require('pilot/stacktrace').Trace; +var oop = require('pilot/oop').oop; +var EventEmitter = require('pilot/event_emitter').EventEmitter; +var catalog = require('pilot/catalog'); +var Status = require('pilot/types').Status; +var types = require('pilot/types'); + +/* +// TODO: this doesn't belong here - or maybe anywhere? +var dimensionsChangedExtensionSpec = { + name: 'dimensionsChanged', + description: 'A dimensionsChanged is a way to be notified of ' + + 'changes to the dimension of Skywriter' +}; +exports.startup = function(data, reason) { + catalog.addExtensionSpec(commandExtensionSpec); +}; +exports.shutdown = function(data, reason) { + catalog.removeExtensionSpec(commandExtensionSpec); +}; +*/ + +var commandExtensionSpec = { + name: 'command', + description: 'A command is a bit of functionality with optional ' + + 'typed arguments which can do something small like moving ' + + 'the cursor around the screen, or large like cloning a ' + + 'project from VCS.', + indexOn: 'name' +}; + +var env; + +exports.startup = function(data, reason) { + // TODO: this is probably all kinds of evil, but we need something working + env = data.env; + catalog.addExtensionSpec(commandExtensionSpec); +}; + +exports.shutdown = function(data, reason) { + catalog.removeExtensionSpec(commandExtensionSpec); +}; + +/** + * Manage a list of commands in the current canon + */ + +/** + * A Command is a discrete action optionally with a set of ways to customize + * how it happens. This is here for documentation purposes. + * TODO: Document better + */ +var thingCommand = { + name: 'thing', + description: 'thing is an example command', + params: [{ + name: 'param1', + description: 'an example parameter', + type: 'text', + defaultValue: null + }], + exec: function(env, args, request) { + thing(); + } +}; + +var commands = {}; + +/** + * This registration method isn't like other Ace registration methods because + * it doesn't return a decorated command because there is no functional + * decoration to be done. + * TODO: Are we sure that in the future there will be no such decoration? + */ +exports.addCommand = function(command) { + if (!command.name) { + throw new Error('All registered commands must have a name'); + } + if (command.params == null) { + command.params = []; + } + if (!Array.isArray(command.params)) { + throw new Error('command.params must be an array in ' + command.name); + } + // Replace the type + command.params.forEach(function(param) { + if (!param.name) { + throw new Error('In ' + command.name + ': all params must have a name'); + } + var lookup = param.type; + param.type = types.getType(lookup); + if (param.type == null) { + throw new Error('In ' + command.name + '/' + param.name + + ': can\'t find type for: ' + JSON.stringify(lookup)); + } + }, this); + commands[command.name] = command; +}; + +exports.removeCommand = function(command) { + if (typeof command === 'string') { + delete commands[command]; + } + else { + delete commands[command.name]; + } +}; + +exports.getCommand = function(name) { + return commands[name]; +}; + +exports.getCommandNames = function() { + return Object.keys(commands); +}; + +/** + * Entry point for keyboard accelerators or anything else that knows + * everything it needs to about the command params + * @param command Either a command, or the name of one + */ +exports.exec = function(command, args) { + if (typeof command === 'string') { + command = commands[command]; + } + if (!command) { + // TODO: Should we complain more than returning false? + return false; + } + + // TODO: Ugg. really? + env.selection = env.editor.getSelection(); + var request = new Request(); + command.exec(env, args || {}, request); + return true; +}; + +/** + * We publish a 'addedRequestOutput' event whenever new command begins output + * TODO: make this more obvious + */ +oop.implement(exports, EventEmitter); + + +/** + * Current requirements are around displaying the command line, and provision + * of a 'history' command and cursor up|down navigation of history. + *

Future requirements could include: + *

    + *
  • Multiple command lines + *
  • The ability to recall key presses (i.e. requests with no output) which + * will likely be needed for macro recording or similar + *
  • The ability to store the command history either on the server or in the + * browser local storage. + *
+ *

The execute() command doesn't really live here, except as part of that + * last future requirement, and because it doesn't really have anywhere else to + * live. + */ + +/** + * The array of requests that wish to announce their presence + */ +exports.requests = []; + +/** + * How many requests do we store? + */ +var maxRequestLength = 100; + +/** + * Called by Request instances when some output (or a cell to async() happens) + */ +exports.addRequestOutput = function(request) { + exports.requests.push(request); + // This could probably be optimized with some maths, but 99.99% of the + // time we will only be off by one, and I'm feeling lazy. + while (exports.requests.length > maxRequestLength) { + exports.requests.shiftObject(); + } + + exports._dispatchEvent('addedRequestOutput', { request: request }); +}; + +/** + * To create an invocation, you need to do something like this (all the ctor + * args are optional): + *

+ * var request = new Request({
+ *     command: command,
+ *     commandExt: commandExt,
+ *     args: args,
+ *     typed: typed
+ * });
+ * 
+ * @constructor + */ +function Request(options) { + options = options || {}; + + // Will be used in the keyboard case and the cli case + this.command = options.command; + this.commandExt = options.commandExt; + + // Will be used only in the cli case + this.args = options.args; + this.typed = options.typed; + + // Have we been initialized? + this._begunOutput = false; + + this.start = new Date(); + this.end = null; + this.completed = false; + this.error = false; +}; + +oop.implement(Request.prototype, EventEmitter); + +/** + * Lazy init to register with the history should only be done on output. + * init() is expensive, and won't be used in the majority of cases + */ +Request.prototype._beginOutput = function() { + this._begunOutput = true; + this.outputs = []; + + exports.addRequestOutput(this); +}; + +/** + * Sugar for: + *
request.error = true; request.done(output);
+ */ +Request.prototype.doneWithError = function(content) { + this.error = true; + this.done(content); +}; + +/** + * Declares that this function will not be automatically done when + * the command exits + */ +Request.prototype.async = function() { + if (!this._begunOutput) { + this._beginOutput(); + } +}; + +/** + * Complete the currently executing command with successful output. + * @param output Either DOM node, an SproutCore element or something that + * can be used in the content of a DIV to create a DOM node. + */ +Request.prototype.output = function(content) { + if (!this._begunOutput) { + this._beginOutput(); + } + + if (typeof content !== 'string' && !(content instanceof Node)) { + content = content.toString(); + } + + this.outputs.push(content); + this._dispatchEvent('changed', {}); + + return this; +}; + +/** + * All commands that do output must call this to indicate that the command + * has finished execution. + */ +Request.prototype.done = function(content) { + this.completed = true; + this.end = new Date(); + this.duration = this.end.getTime() - this.start.getTime(); + + if (content) { + this.output(content); + } + + this._dispatchEvent('changed', {}); +}; +exports.Request = Request; + + +}); diff --git a/plugins/pilot/lib/catalog.js b/plugins/pilot/lib/catalog.js new file mode 100644 index 00000000..5acb69e5 --- /dev/null +++ b/plugins/pilot/lib/catalog.js @@ -0,0 +1,65 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Julian Viereck (jviereck@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var extensionSpecs = {}; + +exports.addExtensionSpec = function(extensionSpec) { + extensionSpecs[extensionSpec.name] = extensionSpec; +}; + +exports.removeExtensionSpec = function(extensionSpec) { + if (typeof extensionSpec === "string") { + delete extensionSpecs[extensionSpec]; + } + else { + delete extensionSpecs[extensionSpec.name]; + } +}; + +exports.getExtensionSpec = function(name) { + return extensionSpecs[name]; +}; + +exports.getExtensionSpecs = function() { + return Object.keys(extensionSpecs); +}; + + +}); diff --git a/plugins/pilot/lib/commands/settings.js b/plugins/pilot/lib/commands/settings.js new file mode 100644 index 00000000..f2b6100b --- /dev/null +++ b/plugins/pilot/lib/commands/settings.js @@ -0,0 +1,146 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Skywriter Team (skywriter@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var setCommandSpec = { + name: 'set', + params: [ + { + name: 'setting', + type: 'setting', + description: 'The name of the setting to display or alter', + defaultValue: null + }, + { + name: 'value', + type: 'settingValue', + description: 'The new value for the chosen setting', + defaultValue: null + } + ], + description: 'define and show settings', + exec: function(env, args, request) { + var html; + if (!args.setting) { + // 'set' by itself lists all the settings + var settingsList = env.settings._list(); + html = ''; + // first sort the settingsList based on the key + settingsList.sort(function(a, b) { + if (a.key < b.key) { + return -1; + } else if (a.key == b.key) { + return 0; + } else { + return 1; + } + }); + var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' + + setting.key; + settingsList.forEach(function(setting) { + html += '' + + setting.key + + ' = ' + + setting.value + + '
'; + }); + } else { + var setting = env.settings.get(args.setting); + if (!setting) { + request.doneWithError('No setting with the name ' + + setting.name + '.'); + return; + } + + // set with only a setting, shows the value for that setting + if (args.value === undefined) { + html = '' + setting.name + ' = ' + + setting.get(); + } else { + // Actually change the setting + setting.set(args.value); + html = 'Setting: ' + setting.name + ' = ' + + setting.get(); + } + } + request.done(html); + } +}; + +var unsetCommandSpec = { + name: 'unset', + params: [ + { + name: 'setting', + type: 'setting', + description: 'The name of the setting to return to defaults' + } + ], + description: 'unset a setting entirely', + exec: function(env, args, request) { + var setting = env.settings.get(args.setting); + if (!setting) { + request.doneWithError('No setting with the name ' + + args.setting + '.'); + return; + } + + setting.reset(); + request.done('Reset ' + setting.name + ' to default: ' + + env.settings.get(args.setting)); + } +}; + +var canon = require('pilot/canon'); + +exports.startup = function(data, reason) { + canon.addCommand(setCommandSpec); + canon.addCommand(unsetCommandSpec); +}; + +exports.shutdown = function(data, reason) { + canon.removeCommand(setCommandSpec); + canon.removeCommand(unsetCommandSpec); +}; + + +}); diff --git a/plugins/pilot/lib/console.js b/plugins/pilot/lib/console.js new file mode 100644 index 00000000..b1fe5190 --- /dev/null +++ b/plugins/pilot/lib/console.js @@ -0,0 +1,76 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * Patrick Walton (pwalton@mozilla.com) + * Julian Viereck (jviereck@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +define(function(require, exports, module) { + +/** + * This object represents a "safe console" object that forwards debugging + * messages appropriately without creating a dependency on Firebug in Firefox. + */ + +var noop = function() {}; + +// These are the functions that are available in Chrome 4/5, Safari 4 +// and Firefox 3.6. Don't add to this list without checking browser support +var NAMES = [ + "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", + "info", "log", "profile", "profileEnd", "time", "timeEnd", "trace", "warn" +]; + +if (typeof(window) === 'undefined') { + // We're in a web worker. Forward to the main thread so the messages + // will show up. + NAMES.forEach(function(name) { + exports[name] = function() { + var args = Array.prototype.slice.call(arguments); + var msg = { op: 'log', method: name, args: args }; + postMessage(JSON.stringify(msg)); + }; + }); +} else { + // For each of the console functions, copy them if they exist, stub if not + NAMES.forEach(function(name) { + if (window.console && window.console[name]) { + exports[name] = window.console[name].bind(window.console); + } else { + exports[name] = noop; + } + }); +} + +}); diff --git a/lib/ace/lib/core.js b/plugins/pilot/lib/core.js similarity index 98% rename from lib/ace/lib/core.js rename to plugins/pilot/lib/core.js index 295be086..29aacf9e 100644 --- a/lib/ace/lib/core.js +++ b/plugins/pilot/lib/core.js @@ -58,6 +58,6 @@ define(function(require, exports, module) { } }; - return core; + exports.core = core; -}); \ No newline at end of file +}); diff --git a/lib/ace/lib/dom.js b/plugins/pilot/lib/dom.js similarity index 98% rename from lib/ace/lib/dom.js rename to plugins/pilot/lib/dom.js index 86cd1e4b..f1021241 100644 --- a/lib/ace/lib/dom.js +++ b/plugins/pilot/lib/dom.js @@ -37,7 +37,7 @@ define(function(require, exports, module) { -var lang = require("./lang"); + var lang = require("pilot/lang").lang; var dom = {}; @@ -137,5 +137,5 @@ var lang = require("./lang"); return noScrollbar-withScrollbar; }; - return dom; -}); \ No newline at end of file + exports.dom = dom; +}); diff --git a/lib/ace/lib/event.js b/plugins/pilot/lib/event.js similarity index 96% rename from lib/ace/lib/event.js rename to plugins/pilot/lib/event.js index 33176db2..c2f6be72 100644 --- a/lib/ace/lib/event.js +++ b/plugins/pilot/lib/event.js @@ -37,8 +37,7 @@ define(function(require, exports, module) { - -var core = require("./core"); + var core = require("pilot/core").core; var event = {}; event.addListener = function(elem, type, callback) { @@ -49,7 +48,7 @@ var core = require("./core"); var wrapper = function() { callback(window.event); }; - callback.$$wrapper = wrapper; + callback._wrapper = wrapper; elem.attachEvent("on" + type, wrapper); } }; @@ -59,7 +58,7 @@ var core = require("./core"); return elem.removeEventListener(type, callback, false); } if (elem.detachEvent) { - elem.detachEvent("on" + type, callback.$$wrapper || callback); + elem.detachEvent("on" + type, callback._wrapper || callback); } }; @@ -111,10 +110,10 @@ var core = require("./core"); } // old IE else { - return Math.max(e.button - 1, 2) + return Math.max(e.button - 1, 2); } }; - + if (document.documentElement.setCapture) { event.capture = function(el, eventHandler, releaseCaptureHandler) { function onMouseMove(e) { @@ -202,7 +201,7 @@ var core = require("./core"); }, timeout || 600); } - if (event.getButton(e) != button + if (event.getButton(e) != button || Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5) clicks = 0; @@ -238,5 +237,6 @@ var core = require("./core"); } }; - return event; -}); \ No newline at end of file + exports.event = event; + +}); diff --git a/lib/ace/event_emitter.js b/plugins/pilot/lib/event_emitter.js similarity index 58% rename from lib/ace/event_emitter.js rename to plugins/pilot/lib/event_emitter.js index ee73b3c1..c7ddf1cd 100644 --- a/lib/ace/event_emitter.js +++ b/plugins/pilot/lib/event_emitter.js @@ -37,49 +37,50 @@ define(function(require, exports, module) { - var lang = require("./lib/lang"); +var lang = require('pilot/lang').lang; - var MEventEmitter = {} +var EventEmitter = {}; - MEventEmitter.$dispatchEvent = function(eventName, e) { - this.$eventRegistry = this.$eventRegistry || {}; +EventEmitter._dispatchEvent = function(eventName, e) { + this._eventRegistry = this._eventRegistry || {}; - var listeners = this.$eventRegistry[eventName]; - if (!listeners || !listeners.length) return; + var listeners = this._eventRegistry[eventName]; + if (!listeners || !listeners.length) return; - var e = e || {}; - e.type = eventName; + var e = e || {}; + e.type = eventName; - for (var i=0; i + // This is necessary for the French keyboard. On that keyboard, + // you have to hold down the shift key to access the number + // characters. + if (code > 47 && code < 58) { + allowShift = evt.altKey; + } + } + + if (ret) { + if (evt.altKey) { + modifiers += 'alt_'; + } + if (evt.ctrlKey) { + modifiers += 'ctrl_'; + } + if (evt.metaKey) { + modifiers += 'meta_'; + } + } else if (evt.ctrlKey || evt.metaKey) { + return false; + } + } + + // otherwise just go get the right key. + if (!ret) { + code = evt.which; + key = ret = String.fromCharCode(code); + lowercase = ret.toLowerCase(); + + if (evt.metaKey) { + modifiers = 'meta_'; + ret = lowercase; + + } else ret = null; + } + + if (evt.shiftKey && ret && allowShift) { + modifiers += 'shift_'; + } + + if (ret) { + ret = modifiers + ret; + } + + if (!dontIgnoreMeta && ret) { + ret = ret.replace(/ctrl_meta|meta/,'ctrl'); + } + + return [ret, key]; +}; + +// Note: Most of the following code is taken from SproutCore with a few changes. + +/** + * Firefox sends a few key events twice: the first time to the keydown event + * and then later again to the keypress event. To handle them correct, they + * should be processed only once. Due to this, we will skip these events + * in keydown and handle them then in keypress. + */ +exports.addKeyDownListener = function(element, boundFunction) { + + var handleBoundFunction = function(ev) { + var handled = boundFunction(ev); + // If the boundFunction returned true, then stop the event. + if (handled) { + util.stopEvent(ev); + } + return handled; + }; + + element.addEventListener('keydown', function(ev) { + if (util.isMozilla) { + // Check for function keys (like DELETE, TAB, LEFT, RIGHT...) + if (exports.KeyHelper.FUNCTION_KEYS[ev.keyCode]) { + return true; + // Check for command keys (like ctrl_c, ctrl_z...) + } else if ((ev.ctrlKey || ev.metaKey) && + exports.KeyHelper.PRINTABLE_KEYS[ev.keyCode]) { + return true; + } + } + + if (isFunctionOrNonPrintableKey(ev)) { + return handleBoundFunction(ev); + } + + return true; + }, false); + + element.addEventListener('keypress', function(ev) { + if (util.isMozilla) { + // If this is a function key, we have to use the keyCode. + if (exports.KeyHelper.FUNCTION_KEYS[ev.keyCode]) { + return handleBoundFunction(ev); + } else if ((ev.ctrlKey || ev.metaKey) && + exports.KeyHelper.PRINTABLE_KEYS_CHARCODE[ev.charCode]){ + // Check for command keys (like ctrl_c, ctrl_z...). + // For command keys have to convert the charCode to a keyCode + // as it has been sent from the keydown event to be in line + // with the other browsers implementations. + + // FF does not allow let you change the keyCode or charCode + // property. Store to a custom keyCode/charCode variable. + // The getCommandCodes() function takes care of these + // special variables. + ev._keyCode = exports.KeyHelper.PRINTABLE_KEYS_CHARCODE[ev.charCode]; + ev._charCode = 0; + return handleBoundFunction(ev); + } + } + + // normal processing: send keyDown for printable keys. + if (ev.charCode !== undefined && ev.charCode === 0) { + return true; + } + + return handleBoundFunction(ev); + }, false); +}; + +}); diff --git a/plugins/pilot/lib/keyboard/tests/testKeyboard.js b/plugins/pilot/lib/keyboard/tests/testKeyboard.js new file mode 100644 index 00000000..17918935 --- /dev/null +++ b/plugins/pilot/lib/keyboard/tests/testKeyboard.js @@ -0,0 +1,99 @@ +require.def(['require', 'exports', 'module', + 'keyboard/keyboard', + 'keyboard/tests/plugindev' +], function(require, exports, module, + keyboard, + t +) { + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Skywriter Team (skywriter@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + + + +exports.testKeyMatching = function() { + var km = keyboard.keyboardManager; + var command = {}; + t.equal(km._commandMatches(command, 'meta_z', {}), false, + 'no keymapping means false'); + + command = { + key: 'meta_z' + }; + t.equal(km._commandMatches(command, 'meta_z', {}), true, + 'matching keys, simple string'); + t.equal(km._commandMatches(command, 'meta_a', {}), false, + 'not matching key, simple string'); + + command = { + key: {key: 'meta_z', predicates: {isGreen: true}} + }; + t.equal(km._commandMatches(command, 'meta_z', {}), false, + 'object with not matching predicate'); + t.equal(km._commandMatches(command, 'meta_z', {isGreen: true}), true, + 'object with matching key and predicate'); + t.equal(km._commandMatches(command, 'meta_a', {isGreen: true}), false, + 'object with not matching key'); + t.equal(km._commandMatches(command, 'meta_a', {isGreen: false}), false, + 'object with neither matching'); + t.equal(km._commandMatches(command, 'meta_z', {isGreen: false}), false, + 'object with matching key and but different predicate'); + + command = { + key: ['meta_b', {key: 'meta_z', predicates: {isGreen: true}}, + {key: 'meta_c'}] + }; + t.equal(km._commandMatches(command, 'meta_z', {}), false, + 'list: object with not matching predicate'); + t.equal(km._commandMatches(command, 'meta_z', {isGreen: true}), true, + 'list: object with matching key and predicate'); + t.equal(km._commandMatches(command, 'meta_a', {isGreen: true}), false, + 'list: object with not matching key'); + t.equal(km._commandMatches(command, 'meta_a', {isGreen: false}), false, + 'list: object with neither matching'); + t.equal(km._commandMatches(command, 'meta_z', {isGreen: false}), false, + 'list: object with matching key and but different predicate'); + t.equal(km._commandMatches(command, 'meta_b'), true, + 'list: simple key match'); + t.equal(km._commandMatches(command, 'meta_c'), true, + 'list: object without predicate match'); + t.equal(km._commandMatches(command, 'meta_c', {isGreen: false}), true, + 'list: flags don\'t matter without predicates'); +}; + +}); diff --git a/lib/ace/lib/lang.js b/plugins/pilot/lib/lang.js similarity index 97% rename from lib/ace/lib/lang.js rename to plugins/pilot/lib/lang.js index 2a9ff350..f99d7a04 100644 --- a/lib/ace/lib/lang.js +++ b/plugins/pilot/lib/lang.js @@ -37,6 +37,7 @@ define(function(require, exports, module) { + var lang = {}; lang.stringReverse = function(string) { @@ -44,9 +45,9 @@ define(function(require, exports, module) { }; lang.stringRepeat = function (string, count) { - return new Array(count + 1).join(string); - } - + return new Array(count + 1).join(string); + }; + if (Array.prototype.indexOf) { lang.arrayIndexOf = function(array, searchElement) { return array.indexOf(searchElement); @@ -121,5 +122,5 @@ define(function(require, exports, module) { }; }; - return lang; + exports.lang = lang; }); diff --git a/lib/ace/lib/oop.js b/plugins/pilot/lib/oop.js similarity index 98% rename from lib/ace/lib/oop.js rename to plugins/pilot/lib/oop.js index 8a825a27..eaf2cc73 100644 --- a/lib/ace/lib/oop.js +++ b/plugins/pilot/lib/oop.js @@ -57,5 +57,5 @@ define(function(require, exports, module) { oop.mixin(proto, mixin); }; - return oop; -}); \ No newline at end of file + exports.oop = oop; +}); diff --git a/plugins/pilot/lib/plugin_manager.js b/plugins/pilot/lib/plugin_manager.js new file mode 100644 index 00000000..79b5b4cc --- /dev/null +++ b/plugins/pilot/lib/plugin_manager.js @@ -0,0 +1,137 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var Promise = require("pilot/promise").Promise; + +exports.REASONS = { + APP_STARTUP: 1, + APP_SHUTDOWN: 2, + PLUGIN_ENABLE: 3, + PLUGIN_DISABLE: 4, + PLUGIN_INSTALL: 5, + PLUGIN_UNINSTALL: 6, + PLUGIN_UPGRADE: 7, + PLUGIN_DOWNGRADE: 8 +}; + +exports.Plugin = function(name) { + this.name = name; + this.status = this.INSTALLED; +}; + +exports.Plugin.prototype = { + /** + * constants for the state + */ + NEW: 0, + INSTALLED: 1, + STARTED: 2, + SHUTDOWN: 3, + + install: function(data, reason) { + var pr = new Promise(); + if (this.status > this.NEW) { + pr.resolve(this); + return pr; + } + require([this.name], function(pluginModule) { + if (pluginModule.install) { + pluginModule.install(data, reason); + } + this.status = this.INSTALLED; + pr.resolve(this); + }.bind(this)); + return pr; + }, + + startup: function(data, reason) { + var pr = new Promise(); + if (this.status != this.INSTALLED) { + pr.resolve(this); + return pr; + } + require([this.name], function(pluginModule) { + if (pluginModule.startup) { + pluginModule.startup(data, reason); + } + this.status = this.STARTED; + pr.resolve(this); + }.bind(this)); + return pr; + }, + + shutdown: function(data, reason) { + if (this.status != this.STARTED) { + return; + } + pluginModule = require(this.name); + if (pluginModule.shutdown) { + pluginModule.shutdown(data, reason); + } + } +}; + +exports.PluginCatalog = function() { + this.plugins = {}; +}; + +exports.PluginCatalog.prototype = { + registerPlugins: function(pluginList) { + pluginList.forEach(function(pluginName) { + var plugin = this.plugins[pluginName]; + if (plugin === undefined) { + plugin = new exports.Plugin(pluginName); + this.plugins[pluginName] = plugin; + } + }.bind(this)); + }, + + startupPlugins: function(data, reason) { + var startupPromises = []; + for (var pluginName in this.plugins) { + var plugin = this.plugins[pluginName]; + startupPromises.push(plugin.startup(data, reason)); + } + return Promise.group(startupPromises); + } +}; + +exports.catalog = new exports.PluginCatalog(); + +}); diff --git a/plugins/pilot/lib/promise.js b/plugins/pilot/lib/promise.js new file mode 100644 index 00000000..8bd9f971 --- /dev/null +++ b/plugins/pilot/lib/promise.js @@ -0,0 +1,264 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var console = require("pilot/console"); +var Trace = require('pilot/stacktrace').Trace; + +/** + * A promise can be in one of 2 states. + * The ERROR and SUCCESS states are terminal, the PENDING state is the only + * start state. + */ +var ERROR = -1; +var PENDING = 0; +var SUCCESS = 1; + +/** + * We give promises and ID so we can track which are outstanding + */ +var _nextId = 0; + +/** + * Debugging help if 2 things try to complete the same promise. + * This can be slow (especially on chrome due to the stack trace unwinding) so + * we should leave this turned off in normal use. + */ +var _traceCompletion = false; + +/** + * Outstanding promises. Handy list for debugging only. + */ +var _outstanding = []; + +/** + * Recently resolved promises. Also for debugging only. + */ +var _recent = []; + +/** + * Create an unfulfilled promise + */ +Promise = function () { + this._status = PENDING; + this._value = undefined; + this._onSuccessHandlers = []; + this._onErrorHandlers = []; + + // Debugging help + this._id = _nextId++; + //this._createTrace = new Trace(new Error()); + _outstanding[this._id] = this; +}; + +/** + * Yeay for RTTI. + */ +Promise.prototype.isPromise = true; + +/** + * Have we either been resolve()ed or reject()ed? + */ +Promise.prototype.isComplete = function() { + return this._status != PENDING; +}; + +/** + * Have we resolve()ed? + */ +Promise.prototype.isResolved = function() { + return this._status == SUCCESS; +}; + +/** + * Have we reject()ed? + */ +Promise.prototype.isRejected = function() { + return this._status == ERROR; +}; + +/** + * Take the specified action of fulfillment of a promise, and (optionally) + * a different action on promise rejection. + */ +Promise.prototype.then = function(onSuccess, onError) { + if (typeof onSuccess === 'function') { + if (this._status === SUCCESS) { + onSuccess.call(null, this._value); + } else if (this._status === PENDING) { + this._onSuccessHandlers.push(onSuccess); + } + } + + if (typeof onError === 'function') { + if (this._status === ERROR) { + onError.call(null, this._value); + } else if (this._status === PENDING) { + this._onErrorHandlers.push(onError); + } + } + + return this; +}; + +/** + * Like then() except that rather than returning this we return + * a promise which + */ +Promise.prototype.chainPromise = function(onSuccess) { + var chain = new Promise(); + chain._chainedFrom = this; + this.then(function(data) { + try { + chain.resolve(onSuccess(data)); + } catch (ex) { + chain.reject(ex); + } + }, function(ex) { + chain.reject(ex); + }); + return chain; +}; + +/** + * Supply the fulfillment of a promise + */ +Promise.prototype.resolve = function(data) { + return this._complete(this._onSuccessHandlers, SUCCESS, data, 'resolve'); +}; + +/** + * Renege on a promise + */ +Promise.prototype.reject = function(data) { + return this._complete(this._onErrorHandlers, ERROR, data, 'reject'); +}; + +/** + * Internal method to be called on resolve() or reject(). + * @private + */ +Promise.prototype._complete = function(list, status, data, name) { + // Complain if we've already been completed + if (this._status != PENDING) { + console.group('Promise already closed'); + console.error('Attempted ' + name + '() with ', data); + console.error('Previous status = ', this._status, + ', previous value = ', this._value); + console.trace(); + + if (this._completeTrace) { + console.error('Trace of previous completion:'); + this._completeTrace.log(5); + } + console.groupEnd(); + return this; + } + + if (_traceCompletion) { + this._completeTrace = new Trace(new Error()); + } + + this._status = status; + this._value = data; + + // Call all the handlers, and then delete them + list.forEach(function(handler) { + handler.call(null, this._value); + }, this); + this._onSuccessHandlers.length = 0; + this._onErrorHandlers.length = 0; + + // Remove the given {promise} from the _outstanding list, and add it to the + // _recent list, pruning more than 20 recent promises from that list. + delete _outstanding[this._id]; + _recent.push(this); + while (_recent.length > 20) { + _recent.shift(); + } + + return this; +}; + +/** + * Takes an array of promises and returns a promise that that is fulfilled once + * all the promises in the array are fulfilled + * @param group The array of promises + * @return the promise that is fulfilled when all the array is fulfilled + */ +Promise.group = function(promiseList) { + if (!(promiseList instanceof Array)) { + promiseList = Array.prototype.slice.call(arguments); + } + + // If the original array has nothing in it, return now to avoid waiting + if (promiseList.length === 0) { + return new Promise().resolve([]); + } + + var groupPromise = new Promise(); + var results = []; + var fulfilled = 0; + + var onSuccessFactory = function(index) { + return function(data) { + results[index] = data; + fulfilled++; + // If the group has already failed, silently drop extra results + if (groupPromise._status !== ERROR) { + if (fulfilled === promiseList.length) { + groupPromise.resolve(results); + } + } + }; + }; + + promiseList.forEach(function(promise, index) { + var onSuccess = onSuccessFactory(index); + var onError = groupPromise.reject.bind(groupPromise); + promise.then(onSuccess, onError); + }); + + return groupPromise; +}; + +exports.Promise = Promise; +exports._outstanding = _outstanding; +exports._recent = _recent; + +}); diff --git a/plugins/pilot/lib/proxy.js b/plugins/pilot/lib/proxy.js new file mode 100644 index 00000000..88d76a54 --- /dev/null +++ b/plugins/pilot/lib/proxy.js @@ -0,0 +1,83 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Julian Viereck (jviereck@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var Promise = require('pilot/promise').Promise; + +exports.xhr = function(method, url, async, beforeSendCallback) { + var pr = new Promise(); + + if (!skywriter.proxy || !skywriter.proxy.xhr) { + var req = new XMLHttpRequest(); + req.onreadystatechange = function() { + if (req.readyState !== 4) { + return; + } + + var status = req.status; + if (status !== 0 && status !== 200) { + var error = new Error(req.responseText + ' (Status ' + req.status + ")"); + error.xhr = req; + pr.reject(error); + return; + } + + pr.resolve(req.responseText); + }.bind(this); + + req.open("GET", url, async); + if (beforeSendCallback) { + beforeSendCallback(req); + } + req.send(); + } else { + skywriter.proxy.xhr.call(this, method, url, async, beforeSendCallback, pr); + } + + return pr; +}; + +exports.Worker = function(url) { + if (!skywriter.proxy || !skywriter.proxy.worker) { + return new Worker(url); + } else { + return new skywriter.proxy.worker(url); + } +}; + +}); diff --git a/plugins/pilot/lib/rangeutils.js b/plugins/pilot/lib/rangeutils.js new file mode 100644 index 00000000..b4714f7b --- /dev/null +++ b/plugins/pilot/lib/rangeutils.js @@ -0,0 +1,185 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Patrick Walton (pwalton@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var util = require("util/util"); + +/** + * Returns the result of adding the two positions. + */ +exports.addPositions = function(a, b) { + return { row: a.row + b.row, col: a.col + b.col }; +}; + +/** Returns a copy of the given range. */ +exports.cloneRange = function(range) { + var oldStart = range.start, oldEnd = range.end; + var newStart = { row: oldStart.row, col: oldStart.col }; + var newEnd = { row: oldEnd.row, col: oldEnd.col }; + return { start: newStart, end: newEnd }; +}; + +/** + * Given two positions a and b, returns a negative number if a < b, 0 if a = b, + * or a positive number if a > b. + */ +exports.comparePositions = function(positionA, positionB) { + var rowDiff = positionA.row - positionB.row; + return rowDiff === 0 ? positionA.col - positionB.col : rowDiff; +}; + +/** + * Returns true if the two ranges are equal and false otherwise. + */ +exports.equal = function(rangeA, rangeB) { + return (exports.comparePositions(rangeA.start, rangeB.start) === 0 && + exports.comparePositions(rangeA.end, rangeB.end) === 0); +}; + +exports.extendRange = function(range, delta) { + var end = range.end; + return { + start: range.start, + end: { + row: end.row + delta.row, + col: end.col + delta.col + } + }; +}; + +/** + * Given two sets of ranges, returns the ranges of characters that exist in one + * of the sets but not both. + */ +exports.intersectRangeSets = function(setA, setB) { + var stackA = util.clone(setA), stackB = util.clone(setB); + var result = []; + while (stackA.length > 0 && stackB.length > 0) { + var rangeA = stackA.shift(), rangeB = stackB.shift(); + var startDiff = exports.comparePositions(rangeA.start, rangeB.start); + var endDiff = exports.comparePositions(rangeA.end, rangeB.end); + + if (exports.comparePositions(rangeA.end, rangeB.start) < 0) { + // A is completely before B + result.push(rangeA); + stackB.unshift(rangeB); + } else if (exports.comparePositions(rangeB.end, rangeA.start) < 0) { + // B is completely before A + result.push(rangeB); + stackA.unshift(rangeA); + } else if (startDiff < 0) { // A starts before B + result.push({ start: rangeA.start, end: rangeB.start }); + stackA.unshift({ start: rangeB.start, end: rangeA.end }); + stackB.unshift(rangeB); + } else if (startDiff === 0) { // A and B start at the same place + if (endDiff < 0) { // A ends before B + stackB.unshift({ start: rangeA.end, end: rangeB.end }); + } else if (endDiff > 0) { // A ends after B + stackA.unshift({ start: rangeB.end, end: rangeA.end }); + } + } else if (startDiff > 0) { // A starts after B + result.push({ start: rangeB.start, end: rangeA.start }); + stackA.unshift(rangeA); + stackB.unshift({ start: rangeA.start, end: rangeB.end }); + } + } + return result.concat(stackA, stackB); +}; + +exports.isZeroLength = function(range) { + return range.start.row === range.end.row && + range.start.col === range.end.col; +}; + +/** + * Returns the greater of the two positions. + */ +exports.maxPosition = function(a, b) { + return exports.comparePositions(a, b) > 0 ? a : b; +}; + +/** + * Converts a range with swapped 'end' and 'start' values into one with the + * values in the correct order. + * + * TODO: Unit test. + */ +exports.normalizeRange = function(range) { + return this.comparePositions(range.start, range.end) < 0 ? range : + { start: range.end, end: range.start }; +}; + +/** + * Returns a single range that spans the entire given set of ranges. + */ +exports.rangeSetBoundaries = function(rangeSet) { + return { + start: rangeSet[0].start, + end: rangeSet[rangeSet.length - 1].end + }; +}; + +exports.toString = function(range) { + var start = range.start, end = range.end; + return '[ ' + start.row + ', ' + start.col + ' ' + end.row + ',' + + end.col +' ]'; +}; + +/** + * Returns the union of the two ranges. + */ +exports.unionRanges = function(a, b) { + return { + start: a.start.row < b.start.row || + (a.start.row === b.start.row && a.start.col < b.start.col) ? + a.start : b.start, + end: a.end.row > b.end.row || + (a.end.row === b.end.row && a.end.col > b.end.col) ? + a.end : b.end + }; +}; + +exports.isPosition = function(pos) { + return !util.none(pos) && !util.none(pos.row) && !util.none(pos.col); +}; + +exports.isRange = function(range) { + return (!util.none(range) && exports.isPosition(range.start) && + exports.isPosition(range.end)); +}; + +}); \ No newline at end of file diff --git a/plugins/pilot/lib/settings.js b/plugins/pilot/lib/settings.js new file mode 100644 index 00000000..fbe8b2ab --- /dev/null +++ b/plugins/pilot/lib/settings.js @@ -0,0 +1,298 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * Julian Viereck (jviereck@mozilla.com) + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +/** + * This plug-in manages settings. + */ + +var console = require('pilot/console'); +var oop = require('pilot/oop').oop; +var types = require('pilot/types'); +var EventEmitter = require('pilot/event_emitter').EventEmitter; +var catalog = require('pilot/catalog'); + +var settingExtensionSpec = { + name: 'setting', + description: 'A setting is something that the application offers as a ' + + 'way to customize how it works', + register: 'env.settings.addSetting', + indexOn: 'name' +}; + +exports.startup = function(data, reason) { + catalog.addExtensionSpec(settingExtensionSpec); +}; + +exports.shutdown = function(data, reason) { + catalog.removeExtensionSpec(settingExtensionSpec); +}; + + +/** + * Create a new setting. + * @param settingSpec An object literal that looks like this: + * { + * name: 'thing', + * description: 'Thing is an example setting', + * type: 'string', + * defaultValue: 'something' + * } + */ +function Setting(settingSpec, settings) { + this._settings = settings; + + Object.keys(settingSpec).forEach(function(key) { + this[key] = settingSpec[key]; + }, this); + + this.type = types.getType(this.type); + if (this.type == null) { + throw new Error('In ' + this.name + + ': can\'t find type for: ' + JSON.stringify(settingSpec.type)); + } + + if (!this.name) { + throw new Error('Setting.name == undefined. Ignoring.', this); + } + + if (!this.defaultValue === undefined) { + throw new Error('Setting.defaultValue == undefined', this); + } + + this.value = this.defaultValue; +} +Setting.prototype = { + get: function() { + return this.value; + }, + + set: function(value) { + if (this.value === value) { + return; + } + + this.value = value; + if (this._settings.persister) { + this._settings.persister.persistValue(this._settings, this.name, value); + } + + this._dispatchEvent('change', { setting: this, value: value }); + }, + + /** + * Reset the value of the key setting to it's default + */ + resetValue: function() { + this.set(this.defaultValue); + } +}; +oop.implement(Setting.prototype, EventEmitter); + + +/** + * A base class for all the various methods of storing settings. + *

Usage: + *

+ * // Create manually, or require 'settings' from the container.
+ * // This is the manual version:
+ * var settings = plugins.catalog.getObject('settings');
+ * // Add a new setting
+ * settings.addSetting({ name:'foo', ... });
+ * // Display the default value
+ * alert(settings.get('foo'));
+ * // Alter the value, which also publishes the change etc.
+ * settings.set('foo', 'bar');
+ * // Reset the value to the default
+ * settings.resetValue('foo');
+ * 
+ * @constructor + */ +function Settings(persister) { + /** + * Storage for deactivated values + */ + this._deactivated = {}; + + this._settings = {}; + + if (persister) { + this.setPersister(persister); + } +}; + +Settings.prototype = { + /** + * Function to add to the list of available settings. + *

Example usage: + *

+     * var settings = plugins.catalog.getObject('settings');
+     * settings.addSetting({
+     *     name: 'tabsize', // For use in settings.get('X')
+     *     type: 'number',  // To allow value checking.
+     *     defaultValue: 4  // Default value for use when none is directly set
+     * });
+     * 
+ * @param {object} settingSpec Object containing name/type/defaultValue members. + */ + addSetting: function(settingSpec) { + var setting = new Setting(settingSpec, this); + this._settings[setting.name] = setting; + }, + + removeSetting: function(name) { + delete this._settings[name]; + }, + + getSettingNames: function() { + return Object.keys(this._settings); + }, + + getSetting: function(name) { + return this._settings[name]; + }, + + /** + * A Persister is able to store settings. It is an object that defines + * two functions: + * loadInitialValues(settings) and persistValue(settings, key, value). + */ + setPersister: function(persister) { + this._persister = persister; + if (persister) { + persister.loadInitialValues(this); + } + }, + + resetAll: function() { + this.getSettingNames().forEach(function(key) { + this.resetValue(key); + }.bind(this)); + }, + + /** + * Retrieve a list of the known settings and their values + */ + _list: function() { + var reply = []; + this.getSettingNames().forEach(function(setting) { + reply.push({ + 'key': setting, + 'value': this.get(setting) + }); + }.bind(this)); + return reply; + }, + + /** + * Prime the local cache with the defaults. + */ + _loadDefaultValues: function() { + this._loadFromObject(this._getDefaultValues()); + }, + + /** + * Utility to load settings from an object + */ + _loadFromObject: function(data) { + // We iterate over data rather than keys so we don't forget values + // which don't have a setting yet. + for (var key in data) { + if (data.hasOwnProperty(key)) { + var setting = this._settings[key]; + if (setting) { + var value = setting.type.parse(data[key]); + this.set(key, value); + } else { + this.set(key, data[key]); + } + } + } + }, + + /** + * Utility to grab all the settings and export them into an object + */ + _saveToObject: function() { + return this.getSettingNames().map(function(key) { + return this._settings[key].type.stringify(this.get(key)); + }.bind(this)); + }, + + /** + * The default initial settings + */ + _getDefaultValues: function() { + return this.getSettingNames().map(function(key) { + return this._settings[key].spec.defaultValue; + }.bind(this)); + } +}; +exports.settings = new Settings(); + +/** + * Save the settings in a cookie + * This code has not been tested since reboot + * @constructor + */ +function CookiePersister() { +}; + +CookiePersister.prototype = { + loadInitialValues: function(settings) { + settings._loadDefaultValues(); + var data = cookie.get('settings'); + settings._loadFromObject(JSON.parse(data)); + }, + + persistValue: function(settings, key, value) { + try { + var stringData = JSON.stringify(settings._saveToObject()); + cookie.set('settings', stringData); + } catch (ex) { + console.error('Unable to JSONify the settings! ' + ex); + return; + } + } +}; + +exports.CookiePersister = CookiePersister; + +}); diff --git a/plugins/pilot/lib/settings/canon.js b/plugins/pilot/lib/settings/canon.js new file mode 100644 index 00000000..5ad36d50 --- /dev/null +++ b/plugins/pilot/lib/settings/canon.js @@ -0,0 +1,57 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + +var historyLengthSetting = { + name: "historyLength", + description: "How many typed commands do we recall for reference?", + type: "number", + defaultValue: 50 +}; + +exports.startup = function(data, reason) { + data.env.settings.addSetting(historyLengthSetting); +}; + +exports.shutdown = function(data, reason) { + data.env.settings.removeSetting(historyLengthSetting); +}; + + +}); diff --git a/plugins/pilot/lib/stacktrace.js b/plugins/pilot/lib/stacktrace.js new file mode 100644 index 00000000..961d88cc --- /dev/null +++ b/plugins/pilot/lib/stacktrace.js @@ -0,0 +1,332 @@ +define(function(require, exports, module) { + +var util = require("pilot/util"); +var console = require('pilot/console'); + +// Changed to suit the specific needs of running within Skywriter + +// Domain Public by Eric Wendelin http://eriwen.com/ (2008) +// Luke Smith http://lucassmith.name/ (2008) +// Loic Dachary (2008) +// Johan Euphrosine (2008) +// Øyvind Sean Kinsey http://kinsey.no/blog +// +// Information and discussions +// http://jspoker.pokersource.info/skin/test-printstacktrace.html +// http://eriwen.com/javascript/js-stack-trace/ +// http://eriwen.com/javascript/stacktrace-update/ +// http://pastie.org/253058 +// http://browsershots.org/http://jspoker.pokersource.info/skin/test-printstacktrace.html +// + +// +// guessFunctionNameFromLines comes from firebug +// +// Software License Agreement (BSD License) +// +// Copyright (c) 2007, Parakey Inc. +// All rights reserved. +// +// Redistribution and use of this software 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 Parakey Inc. nor the names of its +// contributors may be used to endorse or promote products +// derived from this software without specific prior +// written permission of Parakey Inc. +// +// 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 THE COPYRIGHT OWNER OR +// CONTRIBUTORS 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. + + + +/** + * Different browsers create stack traces in different ways. + * Feature Browser detection baby ;). + */ +var mode = (function() { + + // We use SC's browser detection here to avoid the "break on error" + // functionality provided by Firebug. Firebug tries to do the right + // thing here and break, but it happens every time you load the page. + // bug 554105 + if (util.isMozilla) { + return 'firefox'; + } else if (util.isOpera) { + return 'opera'; + } else if (util.isSafari) { + return 'other'; + } + + // SC doesn't do any detection of Chrome at this time. + + // this is the original feature detection code that is used as a + // fallback. + try { + (0)(); + } catch (e) { + if (e.arguments) { + return 'chrome'; + } + if (e.stack) { + return 'firefox'; + } + if (window.opera && !('stacktrace' in e)) { //Opera 9- + return 'opera'; + } + } + return 'other'; +})(); + +/** + * + */ +function stringifyArguments(args) { + for (var i = 0; i < args.length; ++i) { + var argument = args[i]; + if (typeof argument == 'object') { + args[i] = '#object'; + } else if (typeof argument == 'function') { + args[i] = '#function'; + } else if (typeof argument == 'string') { + args[i] = '"' + argument + '"'; + } + } + return args.join(','); +} + +/** + * Extract a stack trace from the format emitted by each browser. + */ +var decoders = { + chrome: function(e) { + var stack = e.stack; + if (!stack) { + console.log(e); + return []; + } + return stack.replace(/^.*?\n/, ''). + replace(/^.*?\n/, ''). + replace(/^.*?\n/, ''). + replace(/^[^\(]+?[\n$]/gm, ''). + replace(/^\s+at\s+/gm, ''). + replace(/^Object.\s*\(/gm, '{anonymous}()@'). + split('\n'); + }, + + firefox: function(e) { + var stack = e.stack; + if (!stack) { + console.log(e); + return []; + } + // stack = stack.replace(/^.*?\n/, ''); + stack = stack.replace(/(?:\n@:0)?\s+$/m, ''); + stack = stack.replace(/^\(/gm, '{anonymous}('); + return stack.split('\n'); + }, + + // Opera 7.x and 8.x only! + opera: function(e) { + var lines = e.message.split('\n'), ANON = '{anonymous}', + lineRE = /Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i, i, j, len; + + for (i = 4, j = 0, len = lines.length; i < len; i += 2) { + if (lineRE.test(lines[i])) { + lines[j++] = (RegExp.$3 ? RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 : ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) + + ' -- ' + + lines[i + 1].replace(/^\s+/, ''); + } + } + + lines.splice(j, lines.length - j); + return lines; + }, + + // Safari, Opera 9+, IE, and others + other: function(curr) { + var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, stack = [], j = 0, fn, args; + + var maxStackSize = 10; + while (curr && stack.length < maxStackSize) { + fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON; + args = Array.prototype.slice.call(curr['arguments']); + stack[j++] = fn + '(' + stringifyArguments(args) + ')'; + + //Opera bug: if curr.caller does not exist, Opera returns curr (WTF) + if (curr === curr.caller && window.opera) { + //TODO: check for same arguments if possible + break; + } + curr = curr.caller; + } + return stack; + } +}; + +/** + * + */ +function NameGuesser() { +} + +NameGuesser.prototype = { + + sourceCache: {}, + + ajax: function(url) { + var req = this.createXMLHTTPObject(); + if (!req) { + return; + } + req.open('GET', url, false); + req.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); + req.send(''); + return req.responseText; + }, + + createXMLHTTPObject: function() { + // Try XHR methods in order and store XHR factory + var xmlhttp, XMLHttpFactories = [ + function() { + return new XMLHttpRequest(); + }, function() { + return new ActiveXObject('Msxml2.XMLHTTP'); + }, function() { + return new ActiveXObject('Msxml3.XMLHTTP'); + }, function() { + return new ActiveXObject('Microsoft.XMLHTTP'); + } + ]; + for (var i = 0; i < XMLHttpFactories.length; i++) { + try { + xmlhttp = XMLHttpFactories[i](); + // Use memoization to cache the factory + this.createXMLHTTPObject = XMLHttpFactories[i]; + return xmlhttp; + } catch (e) {} + } + }, + + getSource: function(url) { + if (!(url in this.sourceCache)) { + this.sourceCache[url] = this.ajax(url).split('\n'); + } + return this.sourceCache[url]; + }, + + guessFunctions: function(stack) { + for (var i = 0; i < stack.length; ++i) { + var reStack = /{anonymous}\(.*\)@(\w+:\/\/([-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/; + var frame = stack[i], m = reStack.exec(frame); + if (m) { + var file = m[1], lineno = m[4]; //m[7] is character position in Chrome + if (file && lineno) { + var functionName = this.guessFunctionName(file, lineno); + stack[i] = frame.replace('{anonymous}', functionName); + } + } + } + return stack; + }, + + guessFunctionName: function(url, lineNo) { + try { + return this.guessFunctionNameFromLines(lineNo, this.getSource(url)); + } catch (e) { + return 'getSource failed with url: ' + url + ', exception: ' + e.toString(); + } + }, + + guessFunctionNameFromLines: function(lineNo, source) { + var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/; + var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/; + // Walk backwards from the first line in the function until we find the line which + // matches the pattern above, which is the function definition + var line = '', maxLines = 10; + for (var i = 0; i < maxLines; ++i) { + line = source[lineNo - i] + line; + if (line !== undefined) { + var m = reGuessFunction.exec(line); + if (m) { + return m[1]; + } + else { + m = reFunctionArgNames.exec(line); + } + if (m && m[1]) { + return m[1]; + } + } + } + return '(?)'; + } +}; + +var guesser = new NameGuesser(); + +var frameIgnorePatterns = [ + /http:\/\/localhost:4020\/sproutcore.js:/ +]; + +exports.ignoreFramesMatching = function(regex) { + frameIgnorePatterns.push(regex); +}; + +/** + * Create a stack trace from an exception + * @param ex {Error} The error to create a stacktrace from (optional) + * @param guess {Boolean} If we should try to resolve the names of anonymous functions + */ +exports.Trace = function Trace(ex, guess) { + this._ex = ex; + this._stack = decoders[mode](ex); + + if (guess) { + this._stack = guesser.guessFunctions(this._stack); + } +}; + +/** + * Log to the console a number of lines (default all of them) + * @param lines {number} Maximum number of lines to wrote to console + */ +exports.Trace.prototype.log = function(lines) { + if (lines <= 0) { + // You aren't going to have more lines in your stack trace than this + // and it still fits in a 32bit integer + lines = 999999999; + } + + var printed = 0; + for (var i = 0; i < this._stack.length && printed < lines; i++) { + var frame = this._stack[i]; + var display = true; + frameIgnorePatterns.forEach(function(regex) { + if (regex.test(frame)) { + display = false; + } + }); + if (display) { + console.debug(frame); + printed++; + } + } +}; + +}); diff --git a/plugins/pilot/lib/tests/testRangeutils.js b/plugins/pilot/lib/tests/testRangeutils.js new file mode 100644 index 00000000..d96c43a4 --- /dev/null +++ b/plugins/pilot/lib/tests/testRangeutils.js @@ -0,0 +1,163 @@ +require.def(['require', 'exports', 'module', + 'rangeutils/tests/plugindev', + 'rangeutils/tests/utils/range' +], function(require, exports, module, + t, + Range +) { + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Skywriter Team (skywriter@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + + + +exports.testAddPositions = function() { + t.deepEqual(Range.addPositions({ row: 0, col: 0 }, + { row: 0, col: 0 }), { row: 0, col: 0 }, '0,0 + 0,0 and 0,0'); + t.deepEqual(Range.addPositions({ row: 1, col: 0 }, + { row: 2, col: 0 }), { row: 3, col: 0 }, '1,0 + 2,0 and 3,0'); + t.deepEqual(Range.addPositions({ row: 0, col: 1 }, + { row: 0, col: 1 }), { row: 0, col: 2 }, '0,1 + 0,1 and 0,2'); + t.deepEqual(Range.addPositions({ row: 1, col: 2 }, + { row: -1, col: -2 }), { row: 0, col: 0 }, '1,2 + -1,-2 and 0,0'); +}; + +exports.testCloneRange = function() { + var oldRange = { start: { row: 1, col: 2 }, end: { row: 3, col: 4 } }; + var newRange = Range.cloneRange(oldRange); + t.deepEqual(oldRange, newRange, "the old range and the new range"); + t.ok(oldRange.start !== newRange.start, "the old range's start position " + + "is distinct from the new range's start position"); + t.ok(oldRange.end !== newRange.end, "the old range's end position is " + + "distinct from the new range's end position"); + t.ok(oldRange !== newRange, "the old range is distinct from the new " + + "range"); +}; + +exports.testComparePositions = function() { + t.equal(Range.comparePositions({ row: 0, col: 0 }, + { row: 0, col: 0 }), 0, '0,0 = 0,0'); + t.ok(Range.comparePositions({ row: 0, col: 0 }, + { row: 1, col: 0 }) < 0, '0,0 < 1,0'); + t.ok(Range.comparePositions({ row: 0, col: 0 }, + { row: 0, col: 1 }) < 0, '0,0 < 0,1'); + t.ok(Range.comparePositions({ row: 1, col: 0 }, + { row: 0, col: 0 }) > 0, '1,0 > 0,0'); + t.ok(Range.comparePositions({ row: 0, col: 1 }, + { row: 0, col: 0 }) > 0, '0,1 > 0,0'); +}; + +exports.testExtendRange = function() { + t.deepEqual(Range.extendRange({ + start: { row: 1, col: 2 }, + end: { row: 3, col: 4 } + }, { row: 5, col: 6 }), { + start: { row: 1, col: 2 }, + end: { row: 8, col: 10 } + }, '[ 1,2 3,4 ] extended by 5,6 = [ 1,2 8,10 ]'); + t.deepEqual(Range.extendRange({ + start: { row: 7, col: 8 }, + end: { row: 9, col: 10 } + }, { row: 0, col: 0 }), { + start: { row: 7, col: 8 }, + end: { row: 9, col: 10 } + }, '[ 7,8 9,10 ] extended by 0,0 remains the same'); +}; + +exports.testMaxPosition = function() { + t.deepEqual(Range.maxPosition({ row: 0, col: 0 }, + { row: 0, col: 0 }), { row: 0, col: 0 }, 'max(0,0 0,0) = 0,0'); + t.deepEqual(Range.maxPosition({ row: 0, col: 0 }, + { row: 1, col: 0 }), { row: 1, col: 0 }, 'max(0,0 1,0) = 1,0'); + t.deepEqual(Range.maxPosition({ row: 0, col: 0 }, + { row: 0, col: 1 }), { row: 0, col: 1 }, 'max(0,0 0,1) = 0,1'); + t.deepEqual(Range.maxPosition({ row: 1, col: 0 }, + { row: 0, col: 0 }), { row: 1, col: 0 }, 'max(1,0 0,0) = 1,0'); + t.deepEqual(Range.maxPosition({ row: 0, col: 1 }, + { row: 0, col: 0 }), { row: 0, col: 1 }, 'max(0,1 0,0) = 0,1'); +}; + +exports.testNormalizeRange = function() { + t.deepEqual(Range.normalizeRange({ + start: { row: 0, col: 0 }, + end: { row: 0, col: 0 } + }), { + start: { row: 0, col: 0 }, + end: { row: 0, col: 0 } + }, 'normalize(0,0 0,0) and (0,0 0,0)'); + t.deepEqual(Range.normalizeRange({ + start: { row: 1, col: 2 }, + end: { row: 3, col: 4 } + }), { + start: { row: 1, col: 2 }, + end: { row: 3, col: 4 } + }, 'normalize(1,2 3,4) and (1,2 3,4)'); + t.deepEqual(Range.normalizeRange({ + start: { row: 4, col: 3 }, + end: { row: 2, col: 1 } + }), { + start: { row: 2, col: 1 }, + end: { row: 4, col: 3 } + }, 'normalize(4,3 2,1) and (2,1 4,3)'); +}; + +exports.testUnionRanges = function() { + t.deepEqual(Range.unionRanges({ + start: { row: 1, col: 2 }, + end: { row: 3, col: 4 } + }, { + start: { row: 5, col: 6 }, + end: { row: 7, col: 8 } + }), { + start: { row: 1, col: 2 }, + end: { row: 7, col: 8 } + }, '[ 1,2 3,4 ] union [ 5,6 7,8 ] = [ 1,2 7,8 ]'); + t.deepEqual(Range.unionRanges({ + start: { row: 4, col: 4 }, + end: { row: 5, col: 5 } + }, { + start: { row: 3, col: 3 }, + end: { row: 4, col: 5 } + }), { + start: { row: 3, col: 3 }, + end: { row: 5, col: 5 } + }, '[ 4,4 5,5 ] union [ 3,3 4,5 ] = [ 3,3 5,5 ]'); +}; + + +}); diff --git a/plugins/pilot/lib/types.js b/plugins/pilot/lib/types.js new file mode 100644 index 00000000..0452b0a6 --- /dev/null +++ b/plugins/pilot/lib/types.js @@ -0,0 +1,238 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +/** + * Some types can detect validity, that is to say they can distinguish between + * valid and invalid values. + * TODO: Change these constants to be numbers for more performance? + */ +var Status = { + /** + * The conversion process worked without any problem, and the value is + * valid. There are a number of failure states, so the best way to check + * for failure is (x !== Status.VALID) + */ + VALID: 'VALID', + + /** + * The conversion process did not work like Status.INVALID, however it was + * noted that the string provided to 'parse()' could be VALID by the + * addition of more characters, so the typing may not be actually incorrect + * yet, just unfinished. + * @see Status.INVALID + */ + INCOMPLETE: 'INCOMPLETE', + + /** + * The conversion process did not work, the value should be null and a + * reason for failure should have been provided. In addition some completion + * values may be available. + * @see Status.INCOMPLETE + */ + INVALID: 'INVALID', + + /** + * A combined status is the worser of the provided statuses + */ + combine: function(statuses) { + var combined = Status.VALID; + for (var i = 0; i < arguments; i++) { + if (arguments[i] > combined) { + combined = arguments[i]; + } + } + return combined; + } +}; +exports.Status = Status; + +/** + * The type.parse() method returns a Conversion to inform the user about not + * only the result of a Conversion but also about what went wrong. + * We could use an exception, and throw if the conversion failed, but that + * seems to violate the idea that exceptions should be exceptional. Typos are + * not. Also in order to store both a status and a message we'd still need + * some sort of exception type... + */ +function Conversion(value, status, message, predictions) { + /** + * The result of the conversion process. Will be null if status != VALID + */ + this.value = value; + + /** + * The status of the conversion. + * @see Status + */ + this.status = status || Status.VALID; + + /** + * A message to go with the conversion. This could be present for any status + * including VALID in the case where we want to note a warning for example. + * I18N: On the one hand this nasty and un-internationalized, however with + * a command line it is hard to know where to start. + */ + this.message = message; + + /** + * A array of strings which are the systems best guess at better inputs than + * the one presented. + * We generally expect there to be about 7 predictions (to match human list + * comprehension ability) however it is valid to provide up to about 20, + * or less. It is the job of the predictor to decide a smart cut-off. + * For example if there are 4 very good matches and 4 very poor ones, + * probably only the 4 very good matches should be presented. + */ + this.predictions = predictions || []; +} +exports.Conversion = Conversion; + +/** + * Most of our types are 'static' e.g. there is only one type of 'text', however + * some types like 'selection' and 'deferred' are customizable. The basic + * Type type isn't useful, but does provide documentation about what types do. + * + */ +function Type() { +}; +Type.prototype = { + /** + * Convert the given value to a string representation. + * Where possible, there should be round-tripping between values and their + * string representations. + */ + stringify: function(value) { throw new Error("not implemented"); }, + + /** + * Convert the given str to an instance of this type. + * Where possible, there should be round-tripping between values and their + * string representations. + * @return Conversion + */ + parse: function(str) { throw new Error("not implemented"); }, + + /** + * The plug-in system, and other things need to know what this type is + * called. The name alone is not enough to fully specify a type. Types like + * 'selection' and 'deferred' need extra data, however this function returns + * only the name, not the extra data. + *

In old bespin, equality was based on the name. This may turn out to be + * important in Ace too. + */ + name: undefined +}; +exports.Type = Type; + +/** + * Private registry of types + * Invariant: types[name] = type.name + */ +var types = {}; + +/** + * Add a new type to the list available to the system. + * You can pass 2 things to this function - either an instance of Type, in + * which case we return this instance when #getType() is called with a 'name' + * that matches type.name. + * Also you can pass in a constructor (i.e. function) in which case when + * #getType() is called with a 'name' that matches Type.prototype.name we will + * pass the typeSpec into this constructor. See #reconstituteType(). + */ +exports.registerType = function(type) { + if (typeof type === 'object') { + if (type instanceof Type) { + if (!type.name) { + throw new Error('All registered types must have a name'); + } + types[type.name] = type; + } + else { + throw new Error('Can\'t registerType using: ' + type); + } + } + else if (typeof type === 'function') { + if (!type.prototype.name) { + throw new Error('All registered types must have a name'); + } + types[type.prototype.name] = type; + } + else { + throw new Error('Unknown type: ' + type); + } +}; + +/** + * Remove a type from the list available to the system + */ +exports.deregisterType = function(type) { + delete types[type.name]; +}; + +/** + * See description of #exports.registerType() + */ +function reconstituteType(name, typeSpec) { + var type = types[name]; + if (typeof type === 'function') { + // TODO: should we complain if typeSpec is a string? + type = new type(typeSpec); + } + return type; +} + +/** + * Find a type, previously registered using #registerType() + */ +exports.getType = function(typeSpec) { + if (typeof typeSpec === 'string') { + return reconstituteType(typeSpec, typeSpec); + } + + if (typeof typeSpec == 'object') { + if (!typeSpec.name) { + throw new Error('Missing \'name\' member to typeSpec'); + } + return reconstituteType(typeSpec.name, typeSpec); + } + + throw new Error('Can\'t extract type from ' + typeSpec); +}; + + +}); diff --git a/plugins/pilot/lib/types/basic.js b/plugins/pilot/lib/types/basic.js new file mode 100644 index 00000000..8e7e5ebc --- /dev/null +++ b/plugins/pilot/lib/types/basic.js @@ -0,0 +1,238 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var types = require("pilot/types"); +var Type = types.Type; +var Conversion = types.Conversion; +var Status = types.Status; + +/** + * These are the basic types that we accept. They are vaguely based on the + * Jetpack settings system (https://wiki.mozilla.org/Labs/Jetpack/JEP/24) + * although clearly more restricted. + * + *

In addition to these types, Jetpack also accepts range, member, password + * that we are thinking of adding. + * + *

This module probably should not be accessed directly, but instead used + * through types.js + */ + +/** + * 'text' is the default if no type is given. + */ +var text = new Type(); + +text.stringify = function(value) { + return value; +}; + +text.parse = function(value) { + if (typeof value != 'string') { + throw new Error('non-string passed to text.parse()'); + } + return new Conversion(value); +}; + +text.name = 'text'; + +/** + * We don't currently plan to distinguish between integers and floats + */ +var number = new Type(); + +number.stringify = function(value) { + if (!value) { + return null; + } + return '' + value; +}; + +number.parse = function(value) { + if (typeof value != 'string') { + throw new Error('non-string passed to number.parse()'); + } + + var reply = new Conversion(parseInt(value, 10)); + if (isNaN(reply.value)) { + reply.status = Status.INVALID; + reply.message = 'Can\'t convert "' + value + '" to a number.'; + } + + return reply; +}; + +number.name = 'number'; + +/** + * One of a known set of options + */ +function SelectionType(typeSpec) { + if (!Array.isArray(typeSpec.data) && typeof typeSpec.data !== 'function') { + throw new Error('instances of SelectionType need typeSpec.data to be an array or function that returns an array:' + JSON.stringify(typeSpec)); + } + Object.keys(typeSpec).forEach(function(key) { + this[key] = typeSpec[key]; + }, this); +}; + +SelectionType.prototype = new Type(); + +SelectionType.prototype.stringify = function(value) { + return value; +}; + +SelectionType.prototype.parse = function(value) { + if (typeof value != 'string') { + throw new Error('non-string passed to parse()'); + } + if (!this.data) { + throw new Error('Missing data on selection type extension.'); + } + var data = (typeof(this.data) === "function") ? this.data() : this.data; + + var match = false; + var completions = []; + data.forEach(function(option) { + if (value == option) { + match = true; + } + else if (option.indexOf(value) === 0) { + completions.push(option); + } + }); + + if (match) { + return new Conversion(value); + } + else { + var status = completions.length > 0 ? Status.INCOMPLETE : Status.INVALID; + + // TODO: better error message - include options? + // TODO: better completions - we're just using the extensions + return new Conversion(null, + status, + 'Can\'t convert \'' + value + '\' to a selection.', + completions); + } +}; + +SelectionType.prototype.name = 'selection'; + +/** + * SelectionType is a base class for other types + */ +exports.SelectionType = SelectionType; + +/** + * true/false values + */ +var bool = new SelectionType({ + name: 'bool', + data: [ 'true', 'false' ], + stringify: function(value) { + return '' + value; + }, + parse: function(value) { + var conversion = SelectionType.prototype.parse(value); + + if (conversion.value === 'true') { + conversion.value = true; + } + if (conversion.value === 'false') { + conversion.value = false; + } + + return conversion; + } +}); + + +/** + * One of a known set of options + */ +function DeferredType(typeSpec) { + if (typeof typeSpec.defer !== 'function') { + throw new Error('Instances of DeferredType need typeSpec.defer to be a function that returns a type'); + } + Object.keys(typeSpec).forEach(function(key) { + this[key] = typeSpec[key]; + }, this); +}; + +DeferredType.prototype = new Type(); + +DeferredType.prototype.stringify = function(value) { + return this.defer().stringify(value); +}; + +DeferredType.prototype.parse = function(value) { + console.log(this.defer); + return this.defer().parse(value); +}; + +DeferredType.prototype.name = 'deferred'; + +/** + * DeferredType is a base class for other types + */ +exports.DeferredType = DeferredType; + +/** + * Registration and de-registration. + */ +exports.startup = function() { + types.registerType(text); + types.registerType(number); + types.registerType(bool); + types.registerType(SelectionType); + types.registerType(DeferredType); +}; + +exports.shutdown = function() { + types.unregisterType(text); + types.unregisterType(number); + types.unregisterType(bool); + types.unregisterType(SelectionType); + types.unregisterType(DeferredType); +}; + + +}); diff --git a/plugins/pilot/lib/types/command.js b/plugins/pilot/lib/types/command.js new file mode 100644 index 00000000..b53fc19d --- /dev/null +++ b/plugins/pilot/lib/types/command.js @@ -0,0 +1,82 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var canon = require("pilot/canon"); +var SelectionType = require("pilot/types/basic").SelectionType; +var types = require("pilot/types"); + + +/** + * Select from the available commands + */ +var command = new SelectionType({ + name: 'command', + data: function() { + return canon.getCommandNames(); + }, + stringify: function(command) { + return command.name; + }, + parse: function(value) { + var conversion = SelectionType.prototype.parse.call(this, value); + if (conversion.value) { + conversion.value = canon.getCommand(conversion.value); + } + else { + conversion.message = 'Several possibilities for \'' + value + '\''; + } + return conversion; + } +}); + + +/** + * Registration and de-registration. + */ +exports.startup = function() { + types.registerType(command); +}; + +exports.shutdown = function() { + types.unregisterType(command); +}; + + +}); diff --git a/plugins/pilot/lib/types/settings.js b/plugins/pilot/lib/types/settings.js new file mode 100644 index 00000000..587a1df7 --- /dev/null +++ b/plugins/pilot/lib/types/settings.js @@ -0,0 +1,109 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Joe Walker (jwalker@mozilla.com) + * Kevin Dangoor (kdangoor@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var SelectionType = require('pilot/types/basic').SelectionType; +var DeferredType = require('pilot/types/basic').DeferredType; +var types = require('pilot/types'); +var settings = require('pilot/settings').settings; + + +/** + * EVIL: This relies on us using settingValue in the same event as setting + * The alternative is to have some central place where we store the current + * command line, but this might be a lesser evil for now. + */ +var lastSetting; + +/** + * Select from the available settings + */ +var setting = new SelectionType({ + name: 'setting', + data: function() { + return env.settings.getSettingNames(); + }, + stringify: function(setting) { + lastSetting = setting; + return setting.name; + }, + parse: function(text) { + lastSetting = text; + + var conversion = SelectionType.prototype.parse.call(this, text); + if (conversion.value) { + conversion.value = settings.getSetting(conversion.value); + } + else { + conversion.message = 'Several possibilities for \'' + text + '\''; + } + return conversion; + } +}); + +/** + * Something of a hack to allow the set command to give a clearer definition + * of the type to the command line. + */ +var settingValue = new DeferredType({ + name: 'settingValue', + defer: function() { + return env.settings.getSetting(lastSetting).type; + } +}); + +var env; + +/** + * Registration and de-registration. + */ +exports.startup = function(data, reason) { + // TODO: this is probably all kinds of evil, but we need something working + env = data.env; + types.registerType(setting); + types.registerType(settingValue); +}; + +exports.shutdown = function(data, reason) { + types.unregisterType(setting); + types.unregisterType(settingValue); +}; + + +}); diff --git a/plugins/pilot/lib/util.js b/plugins/pilot/lib/util.js new file mode 100644 index 00000000..e0cd4bb3 --- /dev/null +++ b/plugins/pilot/lib/util.js @@ -0,0 +1,671 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Skywriter. + * + * The Initial Developer of the Original Code is + * Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Skywriter Team (skywriter@mozilla.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +/** + * Create an object representing a de-serialized query section of a URL. + * Query keys with multiple values are returned in an array. + *

Example: The input "foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&" + * Produces the output object: + *

{
+ *   foo: [ "bar", "baz" ],
+ *   thinger: " spaces =blah",
+ *   zonk: "blarg"
+ * }
+ * 
+ *

Note that spaces and other urlencoded entities are correctly handled + * @see dojo.queryToObject() + * While dojo.queryToObject() is mainly for URL query strings, this version + * allows to specify a separator character + */ +exports.queryToObject = function(str, seperator) { + var ret = {}; + var qp = str.split(seperator || "&"); + var dec = decodeURIComponent; + qp.forEach(function(item) { + if (item.length) { + var parts = item.split("="); + var name = dec(parts.shift()); + var val = dec(parts.join("=")); + if (exports.isString(ret[name])){ + ret[name] = [ret[name]]; + } + if (Array.isArray(ret[name])){ + ret[name].push(val); + } else { + ret[name] = val; + } + } + }); + return ret; +}; + +/** + * Takes a name/value mapping object and returns a string representing a + * URL-encoded version of that object for use in a GET request + *

For example, given the input: + * { blah: "blah", multi: [ "thud", "thonk" ] } + * The following string would be returned: + * "blah=blah&multi=thud&multi=thonk" + * @param map {Object} The object to convert + * @return {string} A URL-encoded version of the input + */ +exports.objectToQuery = function(map) { + // FIXME: need to implement encodeAscii!! + var enc = encodeURIComponent; + var pairs = []; + var backstop = {}; + for (var name in map) { + var value = map[name]; + if (value != backstop[name]) { + var assign = enc(name) + "="; + if (value.isArray) { + for (var i = 0; i < value.length; i++) { + pairs.push(assign + enc(value[i])); + } + } else { + pairs.push(assign + enc(value)); + } + } + } + return pairs.join("&"); +}; + +/** + * Holds the count to keep a unique value for setTimeout + * @private See rateLimit() + */ +var nextRateLimitId = 0; + +/** + * Holds the timeouts so they can be cleared later + * @private See rateLimit() + */ +var rateLimitTimeouts = {}; + +/** + * Delay calling some function to check that it's not called again inside a + * maxRate. The real function is called after maxRate ms unless the return + * value of this function is called before, in which case the clock is restarted + */ +exports.rateLimit = function(maxRate, scope, func) { + if (maxRate) { + var rateLimitId = nextRateLimitId++; + + return function() { + if (rateLimitTimeouts[rateLimitId]) { + clearTimeout(rateLimitTimeouts[rateLimitId]); + } + + rateLimitTimeouts[rateLimitId] = setTimeout(function() { + func.apply(scope, arguments); + delete rateLimitTimeouts[rateLimitId]; + }, maxRate); + }; + } +}; + +/** + * Return true if it is a String + */ +exports.isString = function(it) { + return (typeof it == "string" || it instanceof String); +}; + +/** + * Returns true if it is a Boolean. + */ +exports.isBoolean = function(it) { + return (typeof it == 'boolean'); +}; + +/** + * Returns true if it is a Number. + */ +exports.isNumber = function(it) { + return (typeof it == 'number' && isFinite(it)); +}; + +/** + * Hack copied from dojo. + */ +exports.isObject = function(it) { + return it !== undefined && + (it === null || typeof it == "object" || + Array.isArray(it) || exports.isFunction(it)); +}; + +/** + * Is the passed object a function? + * From dojo.isFunction() + */ +exports.isFunction = (function() { + var _isFunction = function(it) { + var t = typeof it; // must evaluate separately due to bizarre Opera bug. See #8937 + //Firefox thinks object HTML element is a function, so test for nodeType. + return it && (t == "function" || it instanceof Function) && !it.nodeType; // Boolean + }; + + return exports.isSafari ? + // only slow this down w/ gratuitious casting in Safari (not WebKit) + function(/*anything*/ it) { + if (typeof it == "function" && it == "[object NodeList]") { + return false; + } + return _isFunction(it); // Boolean + } : _isFunction; +})(); + +/** + * A la Prototype endsWith(). Takes a regex excluding the '$' end marker + */ +exports.endsWith = function(str, end) { + if (!str) { + return false; + } + return str.match(new RegExp(end + "$")); +}; + +/** + * A la Prototype include(). + */ +exports.include = function(array, item) { + return array.indexOf(item) > -1; +}; + +/** + * Like include, but useful when you're checking for a specific + * property on each object in the list... + * + * Returns null if the item is not in the list, otherwise + * returns the index of the item. + */ +exports.indexOfProperty = function(array, propertyName, item) { + for (var i = 0; i < array.length; i++) { + if (array[i][propertyName] == item) { + return i; + } + } + return null; +}; + +/** + * A la Prototype last(). + */ +exports.last = function(array) { + if (Array.isArray(array)) { + return array[array.length - 1]; + } +}; + +/** + * Knock off any undefined items from the end of an array + */ +exports.shrinkArray = function(array) { + var newArray = []; + + var stillAtBeginning = true; + array.reverse().forEach(function(item) { + if (stillAtBeginning && item === undefined) { + return; + } + + stillAtBeginning = false; + + newArray.push(item); + }); + + return newArray.reverse(); +}; + +/** + * Create an array + * @param number The size of the new array to create + * @param character The item to put in the array, defaults to ' ' + */ +exports.makeArray = function(number, character) { + if (number < 1) { + return []; // give us a normal number please! + } + if (!character){character = ' ';} + + var newArray = []; + for (var i = 0; i < number; i++) { + newArray.push(character); + } + return newArray; +}; + +/** + * Repeat a string a given number of times. + * @param string String to repeat + * @param repeat Number of times to repeat + */ +exports.repeatString = function(string, repeat) { + var newstring = ''; + + for (var i = 0; i < repeat; i++) { + newstring += string; + } + + return newstring; +}; + +/** + * Given a row, find the number of leading spaces. + * E.g. an array with the string " aposjd" would return 2 + * @param row The row to hunt through + */ +exports.leadingSpaces = function(row) { + var numspaces = 0; + for (var i = 0; i < row.length; i++) { + if (row[i] == ' ' || row[i] == '' || row[i] === undefined) { + numspaces++; + } else { + return numspaces; + } + } + return numspaces; +}; + +/** + * Given a row, find the number of leading tabs. + * E.g. an array with the string " aposjd" would return 2 + * @param row The row to hunt through + */ +exports.leadingTabs = function(row) { + var numtabs = 0; + for (var i = 0; i < row.length; i++) { + if (row[i] == ' ' || row[i] == '' || row[i] === undefined) { + numtabs++; + } else { + return numtabs; + } + } + return numtabs; +}; + +/** + * Given a row, extract a copy of the leading spaces or tabs. + * E.g. an array with the string " aposjd" would return an array with the + * string " ". + * @param row The row to hunt through + */ +exports.leadingWhitespace = function(row) { + var leading = []; + for (var i = 0; i < row.length; i++) { + if (row[i] == ' ' || row[i] == ' ' || row[i] == '' || row[i] === undefined) { + leading.push(row[i]); + } else { + return leading; + } + } + return leading; +}; + +/** + * Given a camelCaseWord convert to "Camel Case Word" + */ +exports.englishFromCamel = function(camel) { + camel.replace(/([A-Z])/g, function(str) { + return " " + str.toLowerCase(); + }).trim(); +}; + +/** + * I hate doing this, but we need some way to determine if the user is on a Mac + * The reason is that users have different expectations of their key combinations. + * + * Take copy as an example, Mac people expect to use CMD or APPLE + C + * Windows folks expect to use CTRL + C + */ +exports.OS = { + LINUX: 'LINUX', + MAC: 'MAC', + WINDOWS: 'WINDOWS' +}; + +var ua = navigator.userAgent; +var av = navigator.appVersion; + +/** Is the user using a browser that identifies itself as Linux */ +exports.isLinux = av.indexOf("Linux") >= 0; + +/** Is the user using a browser that identifies itself as Windows */ +exports.isWindows = av.indexOf("Win") >= 0; + +/** Is the user using a browser that identifies itself as WebKit */ +exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; + +/** Is the user using a browser that identifies itself as Chrome */ +exports.isChrome = parseFloat(ua.split("Chrome/")[1]) || undefined; + +/** Is the user using a browser that identifies itself as Mac OS */ +exports.isMac = av.indexOf("Macintosh") >= 0; + +/* Is this Firefox or related? */ +exports.isMozilla = av.indexOf('Gecko/') >= 0; + +if (ua.indexOf("AdobeAIR") >= 0) { + exports.isAIR = 1; +} + +/** + * Is the user using a browser that identifies itself as Safari + * See also: + * - http://developer.apple.com/internet/safari/faq.html#anchor2 + * - http://developer.apple.com/internet/safari/uamatrix.html + */ +var index = Math.max(av.indexOf("WebKit"), av.indexOf("Safari"), 0); +if (index && !exports.isChrome) { + // try to grab the explicit Safari version first. If we don't get + // one, look for less than 419.3 as the indication that we're on something + // "Safari 2-ish". + exports.isSafari = parseFloat(av.split("Version/")[1]); + if (!exports.isSafari || parseFloat(av.substr(index + 7)) <= 419.3) { + exports.isSafari = 2; + } +} + +if (ua.indexOf("Gecko") >= 0 && !exports.isWebKit) { + exports.isMozilla = parseFloat(av); +} + +/** + * Return a exports.OS constant + */ +exports.getOS = function() { + if (exports.isMac) { + return exports.OS['MAC']; + } else if (exports.isLinux) { + return exports.OS['LINUX']; + } else { + return exports.OS['WINDOWS']; + } +}; + +/** Returns true if the DOM element "b" is inside the element "a". */ +if (typeof(document) !== 'undefined' && document.compareDocumentPosition) { + exports.contains = function(a, b) { + return a.compareDocumentPosition(b) & 16; + }; +} else { + exports.contains = function(a, b) { + return a !== b && (a.contains ? a.contains(b) : true); + }; +} + +/** + * Prevents propagation and clobbers the default action of the passed event + */ +exports.stopEvent = function(ev) { + ev.preventDefault(); + ev.stopPropagation(); +}; + +/** + * Create a random password of the given length (default 16 chars) + */ +exports.randomPassword = function(length) { + length = length || 16; + var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + var pass = ""; + for (var x = 0; x < length; x++) { + var charIndex = Math.floor(Math.random() * chars.length); + pass += chars.charAt(charIndex); + } + return pass; +}; + +/** + * Is the passed object free of members, i.e. are there any enumerable + * properties which the objects claims as it's own using hasOwnProperty() + */ +exports.isEmpty = function(object) { + for (var x in object) { + if (object.hasOwnProperty(x)) { + return false; + } + } + return true; +}; + +/** + * Does the name of a project indicate that it is owned by someone else + * TODO: This is a major hack. We really should have a File object that include + * separate owner information. + */ +exports.isMyProject = function(project) { + return project.indexOf("+") == -1; +}; + +/** + * Format a date as dd MMM yyyy + */ +exports.formatDate = function (date) { + if (!date) { + return "Unknown"; + } + return date.getDate() + " " + + exports.formatDate.shortMonths[date.getMonth()] + " " + + date.getFullYear(); +}; + +/** + * Month data for exports.formatDate + */ +exports.formatDate.shortMonths = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; + +/** + * Add a CSS class to the list of classes on the given node + */ +exports.addClass = function(node, className) { + var parts = className.split(/\s+/); + var cls = " " + node.className + " "; + for (var i = 0, len = parts.length, c; i < len; ++i) { + c = parts[i]; + if (c && cls.indexOf(" " + c + " ") < 0) { + cls += c + " "; + } + } + node.className = cls.trim(); +}; + +/** + * Remove a CSS class from the list of classes on the given node + */ +exports.removeClass = function(node, className) { + var cls; + if (className !== undefined) { + var parts = className.split(/\s+/); + cls = " " + node.className + " "; + for (var i = 0, len = parts.length; i < len; ++i) { + cls = cls.replace(" " + parts[i] + " ", " "); + } + cls = cls.trim(); + } else { + cls = ""; + } + if (node.className != cls) { + node.className = cls; + } +}; + +/** + * Add or remove a CSS class from the list of classes on the given node + * depending on the value of include + */ +exports.setClass = function(node, className, include) { + if (include) { + exports.addClass(node, className); + } else { + exports.removeClass(node, className); + } +}; + +/** + * Is the passed object either null or undefined (using ===) + */ +exports.none = function(obj) { + return obj === null || obj === undefined; +}; + +/** + * Creates a clone of the passed object. This function can take just about + * any type of object and create a clone of it, including primitive values + * (which are not actually cloned because they are immutable). + * If the passed object implements the clone() method, then this function + * will simply call that method and return the result. + * + * @param object {Object} the object to clone + * @param deep {Boolean} do a deep clone? + * @returns {Object} the cloned object + */ +exports.clone = function(object, deep) { + if (Array.isArray(object) && !deep) { + return object.slice(); + } + + if (typeof object === 'object' || Array.isArray(object)) { + if (object === null) { + return null; + } + + var reply = (Array.isArray(object) ? [] : {}); + for (var key in object) { + if (deep && (typeof object[key] === 'object' + || Array.isArray(object[key]))) { + reply[key] = exports.clone(object[key], true); + } else { + reply[key] = object[key]; + } + } + return reply; + } + + if (object && typeof(object.clone) === 'function') { + return object.clone(); + } + + // That leaves numbers, booleans, undefined. Doesn't it? + return object; +}; + + +/** + * Helper method for extending one object with another + * Copies all properties from source to target. Returns the extended target + * object. + * Taken from John Resig, http://ejohn.org/blog/javascript-getters-and-setters/. + */ +exports.mixin = function(a, b) { + for (var i in b) { + var g = b.__lookupGetter__(i); + var s = b.__lookupSetter__(i); + + if (g || s) { + if (g) { + a.__defineGetter__(i, g); + } + if (s) { + a.__defineSetter__(i, s); + } + } else { + a[i] = b[i]; + } + } + + return a; +}; + +/** + * Basically taken from Sproutcore. + * Replaces the count items from idx with objects. + */ +exports.replace = function(arr, idx, amt, objects) { + return arr.slice(0, idx).concat(objects).concat(arr.slice(idx + amt)); +}; + +/** + * Return true if the two frames match. You can also pass only points or sizes. + * @param r1 {Rect} the first rect + * @param r2 {Rect} the second rect + * @param delta {Float} an optional delta that allows for rects that do not match exactly. Defaults to 0.1 + * @returns {Boolean} true if rects match + */ +exports.rectsEqual = function(r1, r2, delta) { + if (!r1 || !r2) { + return r1 == r2; + } + + if (!delta && delta !== 0) { + delta = 0.1; + } + + if ((r1.y != r2.y) && (Math.abs(r1.y - r2.y) > delta)) { + return false; + } + + if ((r1.x != r2.x) && (Math.abs(r1.x - r2.x) > delta)) { + return false; + } + + if ((r1.width != r2.width) && (Math.abs(r1.width - r2.width) > delta)) { + return false; + } + + if ((r1.height != r2.height) && (Math.abs(r1.height - r2.height) > delta)) { + return false; + } + + return true; +}; + +/** + * splice out of 'array' anything that === 'value' + */ +exports.arrayRemove = function(array, value) { + for (var i = 0; i <= array.length; i++) { + if (value === array[i]) { + array.splice(i, 1); + } + } +}; + + +}); diff --git a/support/requirejs b/support/requirejs index 819c4e7b..0095dc02 160000 --- a/support/requirejs +++ b/support/requirejs @@ -1 +1 @@ -Subproject commit 819c4e7b9b1e6e5f99696b5c9f2805891a9e7cfd +Subproject commit 0095dc028d0e6f3d40587071fa67622930aa880e diff --git a/tool/theme.tmpl.js b/tool/theme.tmpl.js index b4eed087..38a23553 100644 --- a/tool/theme.tmpl.js +++ b/tool/theme.tmpl.js @@ -1,10 +1,10 @@ define(function(require, exports, module) { - var dom = require("./lib/dom"); + var dom = require("pilot/dom"); var cssText = %css%; - + // import CSS once dom.importCssString(cssText); - + return { cssClass: "%cssClass%" };