Merge remote branch 'remotes/mozilla/master'

Conflicts:
	demo/editor-build.html
	demo/editor.html
This commit is contained in:
Fabian Jakobs 2010-12-10 16:54:14 +01:00
commit f7c217d7a4
108 changed files with 8340 additions and 1335 deletions

View file

@ -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",

129
demo/boot.js Normal file
View file

@ -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);
}
});
};

199
demo/demo_startup.js Normal file
View file

@ -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 <fabian AT ajax DOT org>
* 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);
});
};
});

View file

@ -1,329 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Editor</title>
<meta name="author" content="Fabian Jakobs">
<style type="text/css" media="screen">
html {
height: 100%;
overflow: hidden;
}
body {
overflow: hidden;
margin: 0;
padding: 0;
font: sans-serif;
height: 100%;
width: 100%;
font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana;
font-size: 12px;
background: rgb(14, 98, 165);
color: white;
}
#editor {
top: 55px;
left: 0px;
background: white;
}
#controls {
width: 100%;
height: 55px;
}
#jump {
position: absolute;
width: 10px;
height: 10px;
border: 1px solid red;
z-index: 10000;
display: none;
}
</style>
<script src="require.js" type="text/javascript" charset="utf-8"></script>
<script src="../build/ace/editor.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="jump"></div>
<table id="controls">
<tr>
<td>
<label for="doc">Document:</label>
<select id="doc" size="1">
<option value="js">JS Document</option>
<option value="html">HTML Document</option>
<option value="css">CSS Document</option>
<option value="python">Python Document</option>
</select>
</td>
<td>
<label for="mode">Mode:</label>
<select id="mode" size="1">
<option value="text">Plain Text</option>
<option value="javascript">JavaScript</option>
<option value="xml">XML</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="python">Python</option>
</select>
</td>
<td>
<label for="theme">Theme:</label>
<select id="theme" size="1">
<option value="ace/theme/textmate">TextMate</option>
<option value="ace/theme/eclipse">Eclipse</option>
<option value="ace/theme/dawn">Dawn</option>
<option value="ace/theme/idle_fingers">idleFingers</option>
<option value="ace/theme/twilight">Twilight</option>
</select>
</td>
<td>
<label for="select_style">Full line selections</label>
<input type="checkbox" name="select_style" id="select_style" checked>
</td>
<td>
<label for="highlight_active">Highlight active line</label>
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
</td>
<td align="right">
<img src="logo.png">
</td>
</tr>
</table>
<div id="editor">
</div>
<script type="text/editor" id="jstext">function foo(items) {
for (var i=0; i<items.length; i++) {
alert(items[i] + "juhu");
}
}</script>
<script type="text/editor" id="csstext">.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</script>
<script type="text/editor" id="htmltext"><html>
<head>
<style type="text/css">
.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</style>
</head>
<body>
<h1 style="color:red">Juhu Kinners</h1>
</body>
</html>
</script>
<script type="text/editor" id="pythontext">#!/usr/local/bin/python
import string, sys
# If no arguments were given, print a helpful message
if len(sys.argv)==1:
print 'Usage: celsius temp1 temp2 ...'
sys.exit(0)
# Loop over the arguments
for i in sys.argv[1:]:
try:
fahrenheit=float(string.atoi(i))
except string.atoi_error:
print repr(i), "not a numeric value"
else:
celsius=(fahrenheit-32)*5.0/9.0
print '%i\260F = %i\260C' % (int(fahrenheit), int(celsius+.5))
</script>
<script type="text/javascript" charset="utf-8">
require(
{baseUrl: "../lib"},
[
"ace/lib/event",
"ace/editor",
"ace/virtual_renderer",
"ace/theme/textmate",
"ace/document",
"ace/mode/javascript",
"ace/mode/css",
"ace/mode/html",
"ace/mode/xml",
"ace/mode/text",
"ace/mode/python",
"ace/undomanager"
], function(event, Editor, Renderer, theme, Document, JavaScriptMode, CssMode, HtmlMode, XmlMode, TextMode, PythonMode, 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());
docs.python = new Document(document.getElementById("pythontext").innerHTML);
docs.python.setMode(new PythonMode());
docs.python.setUndoManager(new UndoManager());
var docEl = document.getElementById("doc");
function onDocChange() {
var doc = getDoc();
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 if (mode instanceof PythonMode) {
modeEl.value = "python"
}
else {
modeEl.value = "text"
}
editor.focus();
}
docEl.onchange = onDocChange;
function getDoc() {
return docs[docEl.value];
}
var modeEl = document.getElementById("mode");
modeEl.onchange = function() {
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() {
editor.setTheme(themeEl.value);
};
var selectEl = document.getElementById("select_style");
selectEl.onchange = function() {
if (selectEl.checked) {
editor.setSelectionStyle("line");
} else {
editor.setSelectionStyle("text");
}
};
var activeEl = document.getElementById("highlight_active");
activeEl.onchange = function() {
editor.setHighlightActiveLine(!!activeEl.checked);
};
var container = document.getElementById("editor");
var editor = new Editor(new Renderer(container, theme));
onDocChange();
window.jump = function() {
var jump = document.getElementById("jump")
var cursor = editor.getCursorPosition()
var pos = 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) + "px";
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) {
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";
}
editor.onTextInput(reader.result);
modeEl.value = mode;
editor.getDocument().setMode(modes[mode]);
}
reader.readAsText(file);
}
return event.preventDefault(e);
});
});
</script>
</body>
</html>

View file

@ -1,328 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Editor</title>
<meta name="author" content="Fabian Jakobs">
<style type="text/css" media="screen">
html {
height: 100%;
overflow: hidden;
}
body {
overflow: hidden;
margin: 0;
padding: 0;
font: sans-serif;
height: 100%;
width: 100%;
font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana;
font-size: 12px;
background: rgb(14, 98, 165);
color: white;
}
#editor {
top: 55px;
left: 0px;
background: white;
}
#controls {
width: 100%;
height: 55px;
}
#jump {
position: absolute;
width: 10px;
height: 10px;
border: 1px solid red;
z-index: 10000;
display: none;
}
</style>
<script src="require.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="jump"></div>
<table id="controls">
<tr>
<td>
<label for="doc">Document:</label>
<select id="doc" size="1">
<option value="js">JS Document</option>
<option value="html">HTML Document</option>
<option value="css">CSS Document</option>
<option value="python">Python Document</option>
</select>
</td>
<td>
<label for="mode">Mode:</label>
<select id="mode" size="1">
<option value="text">Plain Text</option>
<option value="javascript">JavaScript</option>
<option value="xml">XML</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="python">Python</option>
</select>
</td>
<td>
<label for="theme">Theme:</label>
<select id="theme" size="1">
<option value="ace/theme/textmate">TextMate</option>
<option value="ace/theme/eclipse">Eclipse</option>
<option value="ace/theme/dawn">Dawn</option>
<option value="ace/theme/idle_fingers">idleFingers</option>
<option value="ace/theme/twilight">Twilight</option>
</select>
</td>
<td>
<label for="select_style">Full line selections</label>
<input type="checkbox" name="select_style" id="select_style" checked>
</td>
<td>
<label for="highlight_active">Highlight active line</label>
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
</td>
<td align="right">
<img src="logo.png">
</td>
</tr>
</table>
<div id="editor">
</div>
<script type="text/editor" id="jstext">function foo(items) {
for (var i=0; i<items.length; i++) {
alert(items[i] + "juhu");
}
}</script>
<script type="text/editor" id="csstext">.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</script>
<script type="text/editor" id="htmltext"><html>
<head>
<style type="text/css">
.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</style>
</head>
<body>
<h1 style="color:red">Juhu Kinners</h1>
</body>
</html>
</script>
<script type="text/editor" id="pythontext">#!/usr/local/bin/python
import string, sys
# If no arguments were given, print a helpful message
if len(sys.argv)==1:
print 'Usage: celsius temp1 temp2 ...'
sys.exit(0)
# Loop over the arguments
for i in sys.argv[1:]:
try:
fahrenheit=float(string.atoi(i))
except string.atoi_error:
print repr(i), "not a numeric value"
else:
celsius=(fahrenheit-32)*5.0/9.0
print '%i\260F = %i\260C' % (int(fahrenheit), int(celsius+.5))
</script>
<script type="text/javascript" charset="utf-8">
require(
{baseUrl: "../lib"},
[
"ace/lib/event",
"ace/editor",
"ace/virtual_renderer",
"ace/theme/textmate",
"ace/document",
"ace/mode/javascript",
"ace/mode/css",
"ace/mode/html",
"ace/mode/xml",
"ace/mode/text",
"ace/mode/python",
"ace/undomanager"
], function(event, Editor, Renderer, theme, Document, JavaScriptMode, CssMode, HtmlMode, XmlMode, TextMode, PythonMode, 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());
docs.python = new Document(document.getElementById("pythontext").innerHTML);
docs.python.setMode(new PythonMode());
docs.python.setUndoManager(new UndoManager());
var docEl = document.getElementById("doc");
function onDocChange() {
var doc = getDoc();
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 if (mode instanceof PythonMode) {
modeEl.value = "python"
}
else {
modeEl.value = "text"
}
editor.focus();
}
docEl.onchange = onDocChange;
function getDoc() {
return docs[docEl.value];
}
var modeEl = document.getElementById("mode");
modeEl.onchange = function() {
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() {
editor.setTheme(themeEl.value);
};
var selectEl = document.getElementById("select_style");
selectEl.onchange = function() {
if (selectEl.checked) {
editor.setSelectionStyle("line");
} else {
editor.setSelectionStyle("text");
}
};
var activeEl = document.getElementById("highlight_active");
activeEl.onchange = function() {
editor.setHighlightActiveLine(!!activeEl.checked);
};
var container = document.getElementById("editor");
var editor = new Editor(new Renderer(container, theme));
onDocChange();
window.jump = function() {
var jump = document.getElementById("jump")
var cursor = editor.getCursorPosition()
var pos = 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) + "px";
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) {
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";
}
editor.onTextInput(reader.result);
modeEl.value = mode;
editor.getDocument().setMode(modes[mode]);
}
reader.readAsText(file);
}
return event.preventDefault(e);
});
});
</script>
</body>
</html>

View file

@ -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.
//and includes specific plugins: i18n and text.

163
editor.html Normal file
View file

@ -0,0 +1,163 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Editor</title>
<meta name="author" content="Fabian Jakobs">
<style type="text/css" media="screen">
html {
height: 100%;
overflow: hidden;
}
body {
overflow: hidden;
margin: 0;
padding: 0;
font: sans-serif;
height: 100%;
width: 100%;
font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana;
font-size: 12px;
background: rgb(14, 98, 165);
color: white;
}
#editor {
top: 55px;
left: 0px;
background: white;
}
#controls {
width: 100%;
height: 55px;
}
#jump {
position: absolute;
width: 10px;
height: 10px;
border: 1px solid red;
z-index: 10000;
display: none;
}
#cockpit {
position: absolute;
width: 100%;
bottom: 0;
}
</style>
<script>
require = {
//urlArgs: "bust=" + (new Date()).getTime()
};
</script>
<script src="demo/require.js" type="text/javascript" charset="utf-8"></script>
<script src="demo/boot.js" type="text/javascript"></script>
<script>
setupPlugins({
pluginDirs: {
"../demo": {
singleFiles: ["demo_startup"]
}
}
}, function(plugin_manager, settings) {
var data = { env: { settings: settings } };
plugin_manager.catalog.startupPlugins(data, plugin_manager.REASONS.APP_STARTUP).then(function() {
var demo_startup = require("demo_startup");
demo_startup.launch(data.env);
});
});
</script>
</head>
<body>
<div id="jump"></div>
<table id="controls">
<tr>
<td>
<label for="doc">Document:</label>
<select id="doc" size="1">
<option value="js">JS Document</option>
<option value="html">HTML Document</option>
<option value="css">CSS Document</option>
</select>
</td>
<td>
<label for="mode">Mode:</label>
<select id="mode" size="1">
<option value="text">Plain Text</option>
<option value="javascript">JavaScript</option>
<option value="xml">XML</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
</select>
</td>
<td>
<label for="theme">Theme:</label>
<select id="theme" size="1">
<option value="ace/theme/textmate">TextMate</option>
<option value="ace/theme/eclipse">Eclipse</option>
<option value="ace/theme/dawn">Dawn</option>
<option value="ace/theme/idle_fingers">idleFingers</option>
<option value="ace/theme/twilight">Twilight</option>
</select>
</td>
<td>
<label for="select_style">Full line selections</label>
<input type="checkbox" name="select_style" id="select_style" checked>
</td>
<td>
<label for="highlight_active">Highlight active line</label>
<input type="checkbox" name="highlight_active" id="highlight_active" checked>
</td>
<td align="right">
<img src="demo/logo.png">
</td>
</tr>
</table>
<div id="editor">
</div>
<script type="text/editor" id="jstext">function foo(items) {
for (var i=0; i<items.length; i++) {
alert(items[i] + "juhu");
}
}</script>
<script type="text/editor" id="csstext">.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</script>
<script type="text/editor" id="htmltext"><html>
<head>
<style type="text/css">
.text-layer {
font-family: Monaco, "Courier New", monospace;
font-size: 12px;
cursor: text;
}
</style>
</head>
<body>
<h1 style="color:red">Juhu Kinners</h1>
</body>
</html>
</script>
<input id=cockpit type=text/>
</body>
</html>

View file

@ -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;
});

View file

@ -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(); }
});
});
});

View file

@ -37,7 +37,7 @@
define(function(require, exports, module) {
return {
exports.bindings = {
"selectall": "Command-A",
"removeline": "Command-D",
"gotoline": "Command-L",

View file

@ -37,7 +37,7 @@
define(function(require, exports, module) {
return {
exports.bindings = {
"selectall": "Ctrl-A",
"removeline": "Ctrl-D",
"gotoline": "Ctrl-L",

View file

@ -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<rows.length; i++) {
this.$breakpoints[rows[i]] = true;
}
this.$dispatchEvent("changeBreakpoint", {});
this._dispatchEvent("changeBreakpoint", {});
};
this.clearBreakpoints = function() {
this.$breakpoints = [];
this.$dispatchEvent("changeBreakpoint", {});
this._dispatchEvent("changeBreakpoint", {});
};
this.setBreakpoint = function(row) {
this.$breakpoints[row] = true;
this.$dispatchEvent("changeBreakpoint", {});
this._dispatchEvent("changeBreakpoint", {});
};
this.clearBreakpoint = function(row) {
delete this.$breakpoints[row];
this.$dispatchEvent("changeBreakpoint", {});
this._dispatchEvent("changeBreakpoint", {});
};
this.$detectNewLine = function(text) {
@ -261,7 +261,7 @@ var Document = function(text, mode) {
if (this.$mode === mode) return;
this.$mode = mode;
this.$dispatchEvent("changeMode");
this._dispatchEvent("changeMode");
};
this.getMode = function() {
@ -276,7 +276,7 @@ var Document = function(text, mode) {
if (this.$scrollTop === scrollTopRow) return;
this.$scrollTop = scrollTopRow;
this.$dispatchEvent("changeScrollTop");
this._dispatchEvent("changeScrollTop");
};
this.getScrollTopRow = function() {
@ -748,5 +748,5 @@ var Document = function(text, mode) {
}).call(Document.prototype);
return Document;
exports.Document = Document;
});

View file

@ -37,16 +37,16 @@
define(function(require, exports, module) {
var oop = require("./lib/oop");
var event = require("./lib/event");
var lang = require("./lib/lang");
var TextInput = require("./textinput");
var KeyBinding = require("./keybinding");
var Document = require("./document");
var Search = require("./search");
var BackgroundTokenizer = require("./background_tokenizer");
var Range = require("./range");
var MEventEmitter = require("./event_emitter");
var oop = require("pilot/oop").oop;
var event = require("pilot/event").event;
var lang = require("pilot/lang").lang;
var TextInput = require("ace/textinput").TextInput;
var KeyBinding = require("ace/keybinding").KeyBinding;
var Document = require("ace/document").Document;
var Search = require("ace/search").Search;
var BackgroundTokenizer = require("ace/background_tokenizer").BackgroundTokenizer;
var Range = require("ace/range").Range;
var EventEmitter = require("pilot/event_emitter").EventEmitter;
var Editor =function(renderer, doc) {
var container = renderer.getContainerElement();
@ -84,7 +84,7 @@ var Editor =function(renderer, doc) {
(function(){
oop.implement(this, MEventEmitter);
oop.implement(this, EventEmitter);
this.$forwardEvents = {
gutterclick: 1,
@ -301,7 +301,7 @@ var Editor =function(renderer, doc) {
var pos = this.renderer.screenToTextCoordinates(pageX, pageY);
pos.row = Math.max(0, Math.min(pos.row, this.doc.getLength()-1));
if (event.getButton(e) != 0) {
if (this.selection.isEmpty()) {
this.moveCursorToPosition(pos);
@ -436,7 +436,7 @@ var Editor =function(renderer, doc) {
return;
}
*/
_self.bgTokenizer.getState(cursor.row, function(lineState) {
// multi line insert
if (cursor.row !== end.row) {
@ -450,14 +450,14 @@ var Editor =function(renderer, doc) {
for (var i = 0; i < line.length; ++i)
if (line.charAt(i) == '\t')
indent += size;
else if (line.charAt(i) == ' ')
else if (line.charAt(i) == ' ')
indent += 1;
else
break;
if (/[^\s]/.test(line))
minIndent = Math.min(indent, minIndent);
}
for (var row = cursor.row + 1; row <= end.row; ++row) {
var outdent = minIndent;
@ -470,7 +470,7 @@ var Editor =function(renderer, doc) {
_self.doc.replace(new Range(row, 0, row, line.length), line.substr(i));
}
end.column += _self.doc.indentRows(
new Range(cursor.row + 1, 0, end.row, end.column),
new Range(cursor.row + 1, 0, end.row, end.column),
lineIndent);
} else {
if (shouldOutdent) {
@ -494,7 +494,7 @@ var Editor =function(renderer, doc) {
this.onCursorChange();
this.$blockScrolling = false;
this.$dispatchEvent("changeOverwrite", {data: overwrite});
this._dispatchEvent("changeOverwrite", {data: overwrite});
};
this.getOverwrite = function() {
@ -521,7 +521,7 @@ var Editor =function(renderer, doc) {
this.$selectionStyle = style;
this.onSelectionChange();
this.$dispatchEvent("changeSelectionStyle", {data: style});
this._dispatchEvent("changeSelectionStyle", {data: style});
};
@ -605,21 +605,21 @@ var Editor =function(renderer, doc) {
var doc = this.doc,
range = this.getSelectionRange();
if (range.start.row < range.end.row ||
range.start.column < range.end.column) {
var count = doc.indentRows(this.getSelectionRange(), "\t");
this.selection.shiftSelection(count);
} else {
var indentString;
if (this.doc.getUseSoftTabs()) {
var size = doc.getTabSize(),
position = this.getCursorPosition(),
column = doc.documentToScreenColumn(position.row, position.column),
count = (size - column % size);
indentString = lang.stringRepeat(" ", count);
} else
indentString = "\t";
@ -633,7 +633,7 @@ var Editor =function(renderer, doc) {
var selection = this.doc.getSelection(),
range = this.doc.outdentRows(selection.getRange());
selection.setSelectionRange(range, selection.isBackwards());
this.$updateDesiredColumn();
};
@ -797,7 +797,7 @@ var Editor =function(renderer, doc) {
var row = this.getPageDownRow(),
column = Math.min(this.getCursorPosition().column,
this.doc.getLine(row).length);
this.scrollToRow(row);
this.getSelection().moveCursorTo(row, column);
};
@ -806,7 +806,7 @@ var Editor =function(renderer, doc) {
var row = this.getPageUpRow(),
column = Math.min(this.getCursorPosition().column,
this.doc.getLine(row).length);
this.scrollToRow(row);
this.getSelection().moveCursorTo(row, column);
};
@ -850,7 +850,7 @@ var Editor =function(renderer, doc) {
this.gotoLine = function(lineNumber, row) {
this.selection.clearSelection();
this.$blockScrolling = true;
this.moveCursorTo(lineNumber-1, row || 0);
this.$blockScrolling = false;
@ -948,7 +948,7 @@ var Editor =function(renderer, doc) {
this.replace = function(replacement, options) {
if (options)
this.$search.set(options);
var range = this.$search.find(this.doc);
this.$tryReplace(range, replacement);
if (range !== null)
@ -965,9 +965,9 @@ var Editor =function(renderer, doc) {
if (!ranges.length)
return;
this.clearSelection();
this.selection.moveCursorTo(0, 0);
this.clearSelection();
this.selection.moveCursorTo(0, 0);
for (var i = ranges.length - 1; 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;
});

View file

@ -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;
});

View file

@ -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;
});

View file

@ -81,5 +81,6 @@ var Gutter = function(parentEl) {
}).call(Gutter.prototype);
return Gutter;
exports.Gutter = Gutter;
});

View file

@ -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;
});

View file

@ -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 = "&para;";
this.EOL_CHAR = "&not;";
@ -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;
});

View file

@ -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;
});
exports.Css = Css;
});

View file

@ -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;
});

View file

@ -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;
});
exports.DocCommentHighlightRules = DocCommentHighlightRules;
});

View file

@ -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;
});

View file

@ -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;
});

View file

@ -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;
});

View file

@ -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;
});
exports.JavaScriptHighlightRules = JavaScriptHighlightRules;
});

View file

@ -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;
});

View file

@ -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;
});
exports.Text = Text;
});

View file

@ -73,5 +73,5 @@ var TextHighlightRules = function() {
}).call(TextHighlightRules.prototype);
return TextHighlightRules;
});
exports.TextHighlightRules = TextHighlightRules;
});

View file

@ -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;
});
exports.Xml = Xml;
});

View file

@ -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;
});
exports.XmlHighlightRules = XmlHighlightRules;
});

View file

@ -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;
});

View file

@ -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;
});
exports.RenderLoop = RenderLoop;
});

View file

@ -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;
});

View file

@ -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;
});

View file

@ -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;
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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) {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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");

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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) {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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();

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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() {

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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();
module.exports.exec();

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
* 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 <fabian AT ajax DOT org>
*
* 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()
module.exports.exec()

View file

@ -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;
});
exports.TextInput = TextInput;
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-clouds";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-clouds-midnight";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-cobalt";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-dawn";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-eclipse";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-idle-fingers";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-kr-theme";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-mono-industrial";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-monokai";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-tm";
});

View file

@ -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 <fabian AT ajax DOT org>
*
* 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"
};
})
exports.cssClass = "ace-twilight";
});

View file

@ -128,5 +128,5 @@ var Tokenizer = function(rules) {
}).call(Tokenizer.prototype);
return Tokenizer;
});
exports.Tokenizer = Tokenizer;
});

View file

@ -73,5 +73,5 @@ var UndoManager = function() {
}).call(UndoManager.prototype);
return UndoManager;
});
exports.UndoManager = UndoManager;
});

View file

@ -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;
});
exports.VirtualRenderer = VirtualRenderer;
});

821
plugins/cockpit/lib/cli.js Normal file
View file

@ -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.
* <p>We also record validity information where applicable.
* <p>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.
* <p>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.
* <p>The other output value is input.requisition which gives access to an
* args object for use in executing the final command.
*
* <p>The majority of the functions in this class are called in sequence by the
* constructor. Their task is to add to <tt>hints</tt> fill out the requisition.
* <p>The general sequence is:<ul>
* <li>_tokenize(): convert _typed into _parts
* <li>_split(): convert _parts into _command and _unparsedArgs
* <li>_assign(): convert _unparsedArgs into requisition
* </ul>
*
* @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:
* <b>flags</b>: Flags for us to check against the predicates specified with the
* commands. Defaulted to <tt>keyboard.buildFlags({ });</tt>
* 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.
* <p>This takes #_command.params and #_unparsedArgs and creates a map of
* param names to 'assignment' objects, which have the following properties:
* <ul>
* <li>param - The matching parameter.
* <li>index - Zero based index into where the match came from on the input
* <li>value - The matching input
* </ul>
*/
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('<h1>' + command.name + '</h1>');
docs.push('<h2>Summary</h2>');
docs.push('<p>' + command.description + '</p>');
if (command.manual) {
docs.push('<h2>Description</h2>');
docs.push('<p>' + command.description + '</p>');
}
if (command.params && command.params.length > 0) {
docs.push('<h2>Synopsis</h2>');
docs.push('<pre>');
docs.push(command.name);
var optionalParamCount = 0;
command.params.forEach(function(param) {
if (param.defaultValue === undefined) {
docs.push(' <i>');
docs.push(param.name);
docs.push('</i>');
}
else if (param.defaultValue === null) {
docs.push(' <i>[');
docs.push(param.name);
docs.push(']</i>');
}
else {
optionalParamCount++;
}
}, this);
if (optionalParamCount > 3) {
docs.push(' [options]');
} else if (optionalParamCount > 0) {
command.params.forEach(function(param) {
if (param.defaultValue) {
docs.push(' [--<i>');
docs.push(param.name);
if (param.type.name === 'boolean') {
docs.push('</i>');
}
else {
docs.push('</i> ' + param.type.name);
}
docs.push(']');
}
}, this);
}
docs.push('</pre>');
docs.push('<h2>Parameters</h2>');
command.params.forEach(function(param) {
docs.push('<h3 class="cmd_body"><i>' + param.name + '</i></h3>');
docs.push('<p>' + param.description + '</p>');
if (param.type.defaultValue) {
docs.push('<p>Default: ' + param.type.defaultValue + '</p>');
}
}, this);
}
return docs.join('');
};
exports.documentCommand = documentCommand;
});

View file

@ -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);
}
});
};
*/
});

View file

@ -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;
});

View file

@ -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";
};
});

View file

@ -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 <fabian AT ajax DOT org>
* 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;
});
});

View file

@ -0,0 +1,2 @@
#cockpit { color: red; }

View file

@ -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);
};
});

329
plugins/pilot/lib/canon.js Normal file
View file

@ -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.
* <p>Future requirements could include:
* <ul>
* <li>Multiple command lines
* <li>The ability to recall key presses (i.e. requests with no output) which
* will likely be needed for macro recording or similar
* <li>The ability to store the command history either on the server or in the
* browser local storage.
* </ul>
* <p>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):
* <pre>
* var request = new Request({
* command: command,
* commandExt: commandExt,
* args: args,
* typed: typed
* });
* </pre>
* @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:
* <pre>request.error = true; request.done(output);</pre>
*/
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;
});

View file

@ -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);
};
});

View file

@ -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 += '<a class="setting" href="' + url +
'" title="View external documentation on setting: ' +
setting.key +
'" target="_blank">' +
setting.key +
'</a> = ' +
setting.value +
'<br/>';
});
} else {
var setting = env.settings.get(args.setting);
if (!setting) {
request.doneWithError('No setting with the name <strong>' +
setting.name + '</strong>.');
return;
}
// set with only a setting, shows the value for that setting
if (args.value === undefined) {
html = '<strong>' + setting.name + '</strong> = ' +
setting.get();
} else {
// Actually change the setting
setting.set(args.value);
html = 'Setting: <strong>' + setting.name + '</strong> = ' +
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 <strong>' +
args.setting + '</strong>.');
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);
};
});

View file

@ -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;
}
});
}
});

View file

@ -58,6 +58,6 @@ define(function(require, exports, module) {
}
};
return core;
exports.core = core;
});
});

View file

@ -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;
});
exports.dom = dom;
});

View file

@ -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;
});
exports.event = event;
});

View file

@ -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<listeners.length; i++) {
listeners[i](e);
}
};
for (var i=0; i<listeners.length; i++) {
listeners[i](e);
}
};
MEventEmitter.on =
MEventEmitter.addEventListener = function(eventName, callback) {
this.$eventRegistry = this.$eventRegistry || {};
EventEmitter.on =
EventEmitter.addEventListener = function(eventName, callback) {
this._eventRegistry = this._eventRegistry || {};
var listeners = this.$eventRegistry[eventName];
if (!listeners) {
var listeners = this.$eventRegistry[eventName] = [];
}
if (lang.arrayIndexOf(listeners, callback) == -1) {
listeners.push(callback);
}
};
var listeners = this._eventRegistry[eventName];
if (!listeners) {
var listeners = this._eventRegistry[eventName] = [];
}
if (lang.arrayIndexOf(listeners, callback) == -1) {
listeners.push(callback);
}
};
MEventEmitter.removeEventListener = function(eventName, callback) {
this.$eventRegistry = this.$eventRegistry || {};
EventEmitter.removeEventListener = function(eventName, callback) {
this._eventRegistry = this._eventRegistry || {};
var listeners = this.$eventRegistry[eventName];
if (!listeners) {
return;
}
var index = lang.arrayIndexOf(listeners, callback);
if (index !== -1) {
listeners.splice(index, 1);
}
};
var listeners = this._eventRegistry[eventName];
if (!listeners) {
return;
}
var index = lang.arrayIndexOf(listeners, callback);
if (index !== -1) {
listeners.splice(index, 1);
}
};
exports.EventEmitter = EventEmitter;
return MEventEmitter;
});

View file

@ -0,0 +1,147 @@
/* ***** 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) {
// Narwhal's shim for ES5 defineProperty
// ES5 15.2.3.6
if (!Object.defineProperty) {
Object.defineProperty = function(object, property, descriptor) {
var has = Object.prototype.hasOwnProperty;
if (typeof descriptor == "object" && object.__defineGetter__) {
if (has.call(descriptor, "value")) {
if (!object.__lookupGetter__(property) && !object.__lookupSetter__(property)) {
// data property defined and no pre-existing accessors
object[property] = descriptor.value;
}
if (has.call(descriptor, "get") || has.call(descriptor, "set")) {
// descriptor has a value property but accessor already exists
throw new TypeError("Object doesn't support this action");
}
}
// fail silently if "writable", "enumerable", or "configurable"
// are requested but not supported
/*
// alternate approach:
if ( // can't implement these features; allow false but not true
!(has.call(descriptor, "writable") ? descriptor.writable : true) ||
!(has.call(descriptor, "enumerable") ? descriptor.enumerable : true) ||
!(has.call(descriptor, "configurable") ? descriptor.configurable : true)
)
throw new RangeError(
"This implementation of Object.defineProperty does not " +
"support configurable, enumerable, or writable."
);
*/
else if (typeof descriptor.get == "function") {
object.__defineGetter__(property, descriptor.get);
}
if (typeof descriptor.set == "function") {
object.__defineSetter__(property, descriptor.set);
}
}
return object;
};
}
// ES5 15.2.3.7
if (!Object.defineProperties) {
Object.defineProperties = function(object, properties) {
for (var property in properties) {
if (Object.prototype.hasOwnProperty.call(properties, property)) {
Object.defineProperty(object, property, properties[property]);
}
}
return object;
};
}
/**
* Array detector.
* Firefox 3.5 and Safari 4 have this already. Chrome 4 however ...
* Note to Dojo - your isArray is still broken: instanceof doesn't work with
* Arrays taken from a different frame/window.
*/
if (!Array.isArray) {
Array.isArray = function(data) {
return data && Object.prototype.toString.call(data) === "[object Array]";
};
}
/**
* Retrieves the list of keys on an object.
*/
if (!Object.keys) {
Object.keys = function(obj) {
var k, ret = [];
for (k in obj) {
if (obj.hasOwnProperty(k)) {
ret.push(k);
}
}
return ret;
};
}
if (!Function.prototype.bind) {
// From Narwhal
Function.prototype.bind = function () {
var args = Array.prototype.slice.call(arguments);
var self = this;
var bound = function () {
return self.call.apply(
self,
args.concat(
Array.prototype.slice.call(arguments)
)
);
};
bound.name = this.name;
bound.displayName = this.displayName;
bound.length = this.length;
bound.unbound = self;
return bound;
};
}
exports.globalsLoaded = true;
};
});

View file

@ -0,0 +1,73 @@
/* ***** 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 ***** */
var deps = [
"pilot/fixoldbrowsers",
"pilot/types/basic",
"pilot/types/command",
"pilot/types/settings",
"pilot/commands/settings",
"pilot/settings/canon",
"pilot/canon"
];
var packages = deps.slice();
packages.unshift("require", "exports", "module");
define(packages, function(require, exports, module) {
console.log(packages);
exports.startup = function(data, reason) {
deps.forEach(function(dep) {
console.log("test startup for " + dep);
var module = require(dep);
if (typeof module.startup === "function") {
module.startup(data, reason);
}
});
};
/*
exports.shutdown(data, reason) {
deps.forEach(function(dep) {
var module = require(dep);
if (typeof module.shutdown === "function") {
module.shutdown(data, reason);
}
});
};
*/
});

View file

@ -0,0 +1,459 @@
/* ***** 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(request, exports, module) {
var console = require('pilot/console');
var Trace = require('pilot/stacktrace').Trace;
var keyutil = require('pilot/keyboard/keyutil');
var history = require('canon/history');
var Request = require('canon/request').Request;
var env = require('environment').env;
exports.keymappings = {};
exports.addKeymapping = function(mapping) {
exports.keymappings[mapping.name] = mapping;
};
exports.removeKeymapping = function(name) {
delete exports.keymapping[name];
};
exports.startup = function(data, reason) {
var settings = data.env.settings;
// TODO register this
// catalog.addExtensionSpec("keymapping", {
// "description": "A keymapping defines how keystrokes are interpreted.",
// "params": [
// {
// "name": "states",
// "required": true,
// "description":
// "Holds the states and all the informations about the keymapping. See docs: pluginguide/keymapping"
// }
// ]
// });
settings.settingChange.add({
match: "customKeymapping",
ref: exports.keyboardManager,
func: exports.keyboardManager._customKeymappingChanged
.bind(exports.keyboardManager)
});
};
exports.shutdown = function(data, reason) {
var settings = data.env.settings;
settings.settingChange.remove(exports.keyboardManager);
};
/*
* Things to do to sanitize this code:
* - 'no command' is a bizarre special value at the very least it should be a
* constant to make typos more obvious, but it would be better to refactor
* so that a natural value like null worked.
* - sender seems to be totally customized to the editor case, and the functions
* that we assume that it has make no sense for the commandLine case. We
* should either document and implement the same function set for both cases
* or admit that the cases are different enough to have separate
* implementations.
* - remove remaining sproutcore-isms
* - fold buildFlags into processKeyEvent or something better, preferably the
* latter. We don't want the environment to become a singleton
*/
/**
* Every time we call processKeyEvent, we pass in some flags that require the
* same processing to set them up. This function can be called to do that
* setup.
* @param env Probably environment.env
* @param flags Probably {} (but check other places where this is called)
*/
exports.buildFlags = function(flags) {
flags.context = env.contexts[0];
return flags;
};
/**
* The canon, or the repository of commands, contains functions to process
* events and dispatch command messages to targets.
* @class
*/
var KeyboardManager = function() { };
KeyboardManager.prototype = {
_customKeymappingCache: { states: {} },
/**
* Searches through the command canon for an event matching the given flags
* with a key equivalent matching the given SproutCore event, and, if the
* command is found, sends a message to the appropriate target.
*
* This will get a couple of upgrades in the not-too-distant future:
* 1. caching in the Canon for fast lookup based on key
* 2. there will be an extra layer in between to allow remapping via
* user preferences and keyboard mapping plugins
*
* @return True if a matching command was found, false otherwise.
*/
processKeyEvent: function(evt, sender, flags) {
// Use our modified commandCodes function to detect the meta key in
// more circumstances than SproutCore alone does.
var symbolicName = keyutil.commandCodes(evt, true)[0];
if (util.none(symbolicName)) {
return false;
}
// TODO: Maybe it should be the job of our caller to do this?
exports.buildFlags(flags);
flags.isCommandKey = true;
return this._matchCommand(symbolicName, sender, flags);
},
_matchCommand: function(symbolicName, sender, flags) {
var match = this._findCommandExtension(symbolicName, sender, flags);
if (match && match.commandExt !== 'no command') {
if (flags.isTextView) {
sender.resetKeyBuffers();
}
var commandExt = match.commandExt;
commandExt.load(function(command) {
var request = new Request({
command: command,
commandExt: commandExt
});
history.execute(match.args, request);
});
return true;
}
// 'no command' is returned if a keyevent is handled but there is no
// command executed (for example when switchting the keyboard state).
if (match && match.commandExt === 'no command') {
return true;
} else {
return false;
}
},
_buildBindingsRegex: function(bindings) {
// Escape a given Regex string.
bindings.forEach(function(binding) {
if (!util.none(binding.key)) {
binding.key = new RegExp('^' + binding.key + '$');
} else if (Array.isArray(binding.regex)) {
binding.key = new RegExp('^' + binding.regex[1] + '$');
binding.regex = new RegExp(binding.regex.join('') + '$');
} else {
binding.regex = new RegExp(binding.regex + '$');
}
});
},
/**
* Build the RegExp from the keymapping as RegExp can't stored directly
* in the metadata JSON and as the RegExp used to match the keys/buffer
* need to be adapted.
*/
_buildKeymappingRegex: function(keymapping) {
for (state in keymapping.states) {
this._buildBindingsRegex(keymapping.states[state]);
}
keymapping._convertedRegExp = true;
},
/**
* Loop through the commands in the canon, looking for something that
* matches according to #_commandMatches, and return that.
*/
_findCommandExtension: function(symbolicName, sender, flags) {
// If the flags indicate that we handle the textView's input then take
// a look at keymappings as well.
if (flags.isTextView) {
var currentState = sender._keyState;
// Don't add the symbolic name to the key buffer if the alt_ key is
// part of the symbolic name. If it starts with alt_, this means
// that the user hit an alt keycombo and there will be a single,
// new character detected after this event, which then will be
// added to the buffer (e.g. alt_j will result in ∆).
if (!flags.isCommandKey || symbolicName.indexOf('alt_') === -1) {
sender._keyBuffer +=
symbolicName.replace(/ctrl_meta|meta/,'ctrl');
sender._keyMetaBuffer += symbolicName;
}
// List of all the keymappings to look at.
var ak = [ this._customKeymappingCache ];
// Get keymapping extension points.
ak = ak.concat(catalog.getExtensions('keymapping'));
for (var i = 0; i < ak.length; i++) {
// Check if the keymapping has the current state.
if (util.none(ak[i].states[currentState])) {
continue;
}
if (util.none(ak[i]._convertedRegExp)) {
this._buildKeymappingRegex(ak[i]);
}
// Try to match the current mapping.
var result = this._bindingsMatch(
symbolicName,
flags,
sender,
ak[i]);
if (!util.none(result)) {
return result;
}
}
}
var commandExts = catalog.getExtensions('command');
var reply = null;
var args = {};
symbolicName = symbolicName.replace(/ctrl_meta|meta/,'ctrl');
commandExts.some(function(commandExt) {
if (this._commandMatches(commandExt, symbolicName, flags)) {
reply = commandExt;
return true;
}
return false;
}.bind(this));
return util.none(reply) ? null : { commandExt: reply, args: args };
},
/**
* Checks if the given parameters fit to one binding in the given bindings.
* Returns the command and arguments if a command was matched.
*/
_bindingsMatch: function(symbolicName, flags, sender, keymapping) {
var match;
var commandExt = null;
var args = {};
var bufferToUse;
if (!util.none(keymapping.hasMetaKey)) {
bufferToUse = sender._keyBuffer;
} else {
bufferToUse = sender._keyMetaBuffer;
}
// Add the alt_key to the buffer as we don't want it to be in the buffer
// that is saved but for matching, it needs to be there.
if (symbolicName.indexOf('alt_') === 0 && flags.isCommandKey) {
bufferToUse += symbolicName;
}
// Loop over all the bindings of the keymapp until a match is found.
keymapping.states[sender._keyState].some(function(binding) {
// Check if the key matches.
if (binding.key && !binding.key.test(symbolicName)) {
return false;
}
// Check if the regex matches.
if (binding.regex && !(match = binding.regex.exec(bufferToUse))) {
return false;
}
// Check for disallowed matches.
if (binding.disallowMatches) {
for (var i = 0; i < binding.disallowMatches.length; i++) {
if (!!match[binding.disallowMatches[i]]) {
return true;
}
}
}
// Check predicates.
if (!exports.flagsMatch(binding.predicates, flags)) {
return false;
}
// If there is a command to execute, then figure out the
// comand and the arguments.
if (binding.exec) {
// Get the command.
commandExt = catalog.getExtensionByKey('command', binding.exec);
if (util.none(commandExt)) {
throw new Error('Can\'t find command ' + binding.exec +
' in state=' + sender._keyState +
', symbolicName=' + symbolicName);
}
// Bulid the arguments.
if (binding.params) {
var value;
binding.params.forEach(function(param) {
if (!util.none(param.match) && !util.none(match)) {
value = match[param.match] || param.defaultValue;
} else {
value = param.defaultValue;
}
if (param.type === 'number') {
value = parseInt(value, 10);
}
args[param.name] = value;
});
}
sender.resetKeyBuffers();
}
// Handle the 'then' property.
if (binding.then) {
sender._keyState = binding.then;
sender.resetKeyBuffers();
}
// If there is no command matched now, then return a 'false'
// command to stop matching.
if (util.none(commandExt)) {
commandExt = 'no command';
}
return true;
});
if (util.none(commandExt)) {
return null;
}
return { commandExt: commandExt, args: args };
},
/**
* Check that the given command fits the given key name and flags.
*/
_commandMatches: function(commandExt, symbolicName, flags) {
var mappedKeys = commandExt.key;
if (!mappedKeys) {
return false;
}
// Check predicates
if (!exports.flagsMatch(commandExt.predicates, flags)) {
return false;
}
if (typeof(mappedKeys) === 'string') {
if (mappedKeys != symbolicName) {
return false;
}
return true;
}
if (!Array.isArray(mappedKeys)) {
mappedKeys = [mappedKeys];
commandExt.key = mappedKeys;
}
for (var i = 0; i < mappedKeys.length; i++) {
var keymap = mappedKeys[i];
if (typeof(keymap) === 'string') {
if (keymap == symbolicName) {
return true;
}
continue;
}
if (keymap.key != symbolicName) {
continue;
}
return exports.flagsMatch(keymap.predicates, flags);
}
return false;
},
/**
* Build a cache of custom keymappings whenever the associated setting
* changes.
*/
_customKeymappingChanged: function(settingName, value) {
var ckc = this._customKeymappingCache =
JSON.parse(value);
ckc.states = ckc.states || {};
for (state in ckc.states) {
this._buildBindingsRegex(ckc.states[state]);
}
ckc._convertedRegExp = true;
}
};
/**
*
*/
exports.flagsMatch = function(predicates, flags) {
if (util.none(predicates)) {
return true;
}
if (!flags) {
return false;
}
for (var flagName in predicates) {
if (flags[flagName] !== predicates[flagName]) {
return false;
}
}
return true;
};
/**
* The global exported KeyboardManager
*/
exports.keyboardManager = new KeyboardManager();
});

View file

@ -0,0 +1,273 @@
/*! @license
==========================================================================
SproutCore -- JavaScript Application Framework
copyright 2006-2009, Sprout Systems Inc., Apple Inc. and contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
SproutCore and the SproutCore logo are trademarks of Sprout Systems, Inc.
For more information about SproutCore, visit http://www.sproutcore.com
==========================================================================
@license */
// Most of the following code is taken from SproutCore with a few changes.
define(function(require, exports, module) {
var util = require('pilot/util');
/**
* Helper functions and hashes for key handling.
*/
exports.KeyHelper = function() {
var ret = {
MODIFIER_KEYS: {
16: 'shift', 17: 'ctrl', 18: 'alt', 224: 'meta'
},
FUNCTION_KEYS : {
8: 'backspace', 9: 'tab', 13: 'return', 19: 'pause',
27: 'escape', 33: 'pageup', 34: 'pagedown', 35: 'end',
36: 'home', 37: 'left', 38: 'up', 39: 'right',
40: 'down', 44: 'printscreen', 45: 'insert', 46: 'delete',
112: 'f1', 113: 'f2', 114: 'f3', 115: 'f4',
116: 'f5', 117: 'f7', 119: 'f8', 120: 'f9',
121: 'f10', 122: 'f11', 123: 'f12', 144: 'numlock',
145: 'scrolllock'
},
PRINTABLE_KEYS: {
32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5',
54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a',
66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h',
73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o',
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
221: ']', 222: '\"'
},
/**
* Create the lookup table for Firefox to convert charCodes to keyCodes
* in the keyPress event.
*/
PRINTABLE_KEYS_CHARCODE: {},
/**
* Allow us to lookup keyCodes by symbolic name rather than number
*/
KEY: {}
};
// Create the PRINTABLE_KEYS_CHARCODE hash.
for (var i in ret.PRINTABLE_KEYS) {
var k = ret.PRINTABLE_KEYS[i];
ret.PRINTABLE_KEYS_CHARCODE[k.charCodeAt(0)] = i;
if (k.toUpperCase() != k) {
ret.PRINTABLE_KEYS_CHARCODE[k.toUpperCase().charCodeAt(0)] = i;
}
}
// A reverse map of FUNCTION_KEYS
for (i in ret.FUNCTION_KEYS) {
var name = ret.FUNCTION_KEYS[i].toUpperCase();
ret.KEY[name] = parseInt(i, 10);
}
return ret;
}();
/**
* Determines if the keyDown event is a non-printable or function key.
* These kinds of events are processed as keyboard shortcuts.
* If no shortcut handles the event, then it will be sent as a regular
* keyDown event.
* @private
*/
var isFunctionOrNonPrintableKey = function(evt) {
return !!(evt.altKey || evt.ctrlKey || evt.metaKey ||
((evt.charCode !== evt.which) &&
exports.KeyHelper.FUNCTION_KEYS[evt.which]));
};
/**
* Returns character codes for the event.
* The first value is the normalized code string, with any Shift or Ctrl
* characters added to the beginning.
* The second value is the char string by itself.
* @return {Array}
*/
exports.commandCodes = function(evt, dontIgnoreMeta) {
var code = evt._keyCode || evt.keyCode;
var charCode = (evt._charCode === undefined ? evt.charCode : evt._charCode);
var ret = null;
var key = null;
var modifiers = '';
var lowercase;
var allowShift = true;
// Absent a value for 'keyCode' or 'which', we can't compute the
// command codes. Bail out.
if (code === 0 && evt.which === 0) {
return false;
}
// If the charCode is not zero, then we do not handle a command key
// here. Bail out.
if (charCode !== 0) {
return false;
}
// Check for modifier keys.
if (exports.KeyHelper.MODIFIER_KEYS[charCode]) {
return [exports.KeyHelper.MODIFIER_KEYS[charCode], null];
}
// handle function keys.
if (code) {
ret = exports.KeyHelper.FUNCTION_KEYS[code];
if (!ret && (evt.altKey || evt.ctrlKey || evt.metaKey)) {
ret = exports.KeyHelper.PRINTABLE_KEYS[code];
// Don't handle the shift key if the combo is
// (meta_|ctrl_)<number>
// 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);
};
});

View file

@ -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');
};
});

View file

@ -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;
});

View file

@ -57,5 +57,5 @@ define(function(require, exports, module) {
oop.mixin(proto, mixin);
};
return oop;
});
exports.oop = oop;
});

View file

@ -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();
});

View file

@ -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 <tt>this</tt> 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;
});

View file

@ -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);
}
};
});

View file

@ -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));
};
});

View file

@ -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 <code>key</code> 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.
* <p>Usage:
* <pre>
* // 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');
* </pre>
* @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.
* <p>Example usage:
* <pre>
* 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
* });
* </pre>
* @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;
});

View file

@ -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);
};
});

View file

@ -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 <loic@dachary.org> (2008)
// Johan Euphrosine <proppy@aminche.com> (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.
* <strike>Feature</strike> 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.<anonymous>\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++;
}
}
};
});

Some files were not shown because too many files have changed in this diff Show more