moving files from pilot to ace where they more properly belong

This commit is contained in:
Joe Walker 2011-03-29 17:59:53 +01:00
commit 1e24a23ca5
17 changed files with 1176 additions and 44 deletions

View file

@ -75,8 +75,8 @@ copy({
require: [
"pilot/fixoldbrowsers",
"pilot/index",
"pilot/plugin_manager",
"pilot/environment",
"ace/plugin_manager",
"ace/environment",
"ace/editor",
"ace/edit_session",
"ace/undomanager",

View file

@ -75,8 +75,8 @@ copy({
require: [
"pilot/fixoldbrowsers",
"pilot/index",
"pilot/plugin_manager",
"pilot/environment",
"ace/plugin_manager",
"ace/environment",
"ace/editor",
"ace/edit_session",
"ace/undomanager",

View file

@ -38,8 +38,8 @@
var deps = [
"pilot/fixoldbrowsers",
"pilot/index",
"pilot/plugin_manager",
"pilot/environment",
"ace/plugin_manager",
"ace/environment",
"ace/editor",
"ace/edit_session",
"ace/virtual_renderer",
@ -72,7 +72,7 @@ require(deps, function() {
var editor = new Editor(new Renderer(el, "ace/theme/textmate"));
editor.setSession(doc);
var env = require("pilot/environment").create();
var env = require("ace/environment").create();
catalog.startupPlugins({ env: env }).then(function() {
env.document = doc;
env.editor = editor;

View file

@ -42,8 +42,8 @@ var require = window.__ace_shadowed__.require;
var deps = [
"pilot/fixoldbrowsers",
"pilot/index",
"pilot/plugin_manager",
"pilot/environment",
"ace/plugin_manager",
"ace/environment",
"ace/editor",
"ace/edit_session",
"ace/virtual_renderer",
@ -77,7 +77,7 @@ window.__ace_shadowed__.edit = function(el) {
var editor = new Editor(new Renderer(el, "ace/theme/textmate"));
editor.setSession(doc);
var env = require("pilot/environment").create();
var env = require("ace/environment").create();
catalog.startupPlugins({ env: env }).then(function() {
env.document = doc;
env.editor = env;

View file

@ -35,6 +35,7 @@
*
* ***** END LICENSE BLOCK ***** */
/*
require({
paths: {
demo: "../demo",
@ -44,16 +45,42 @@ require({
}
});
var deps = [ "pilot/fixoldbrowsers", "pilot/plugin_manager", "pilot/settings",
"pilot/environment", "demo/demo" ];
var deps = [ "pilot/fixoldbrowsers", "ace/plugin_manager",
"ace/environment", "demo/demo" ];
var plugins = [ "pilot/index", "cockpit/index", "ace/defaults" ];
var plugins = [ "pilot/index", "cockpit/index", "ace/index" ];
require(deps, function() {
var catalog = require("pilot/plugin_manager").catalog;
var catalog = require("ace/plugin_manager").catalog;
catalog.registerPlugins(plugins).then(function() {
var env = require("pilot/environment").create();
var env = require("ace/environment").create();
catalog.startupPlugins({ env: env }).then(function() {
require("demo/demo").launch(env);
});
});
});
});
*/
require({
paths: {
demo: "../demo",
ace: "../lib/ace",
cockpit: "../support/cockpit/lib/cockpit",
pilot: "../support/cockpit/support/pilot/lib/pilot"
}
});
var deps = [
"ace/environment", "pilot/index", "cockpit/index", "ace/index",
"pilot/fixoldbrowsers"
];
require(deps, function(environment, pilot, cockpit) {
var data = { env: environment.create() };
pilot.startup(data);
cockpit.startup(data);
new cockpit.CliView(data.env);
require([ "demo/demo" ], function(demo) {
demo.launch(data.env);
});
}.bind(this));

View file

@ -77,7 +77,7 @@ exports.launch = function(env) {
custom: new HashHandler({
"gotoright": "Tab"
})
}
};
var docs = {};
@ -88,7 +88,7 @@ exports.launch = function(env) {
}
docs.plain = new EditSession(loreIpsum);
docs.plain.setUseWrapMode(true);
docs.plain.setWrapLimitRange(80, 80)
docs.plain.setWrapLimitRange(80, 80);
docs.plain.setMode(new TextMode());
docs.plain.setUndoManager(new UndoManager());
@ -139,7 +139,7 @@ exports.launch = function(env) {
docs.svg = new EditSession(document.getElementById("svgtext").innerHTML.replace("&lt;", "<"));
docs.svg.setMode(new SvgMode());
docs.svg.setUndoManager(new UndoManager());
docs.textile = new EditSession(document.getElementById("textiletext").innerHTML);
docs.textile.setMode(new TextileMode());
docs.textile.setUndoManager(new UndoManager());
@ -383,11 +383,11 @@ exports.launch = function(env) {
});
window.env = env;
/**
* This demonstrates how you can define commands and bind shortcuts to them.
*/
// Command to focus the command line from the editor.
canon.addCommand({
name: "focuscli",
@ -400,7 +400,7 @@ exports.launch = function(env) {
env.cli.cliView.element.focus();
}
});
// Command to focus the editor line from the command line.
canon.addCommand({
name: "focuseditor",
@ -413,7 +413,7 @@ exports.launch = function(env) {
env.editor.focus();
}
});
// Fake-Save, works from the editor and the command line.
canon.addCommand({
name: "save",
@ -426,7 +426,7 @@ exports.launch = function(env) {
alert("Fake Save File");
}
});
// Fake-Print with custom lookup-sender-match function.
canon.addCommand({
name: "save",
@ -435,9 +435,9 @@ exports.launch = function(env) {
mac: "Command-P",
sender: function(env, sender, hashId, keyString) {
if (sender == "editor") {
return true;
return true;
} else {
alert("Sorry, can only print from the editor");
alert("Sorry, can only print from the editor");
}
}
},

View file

@ -0,0 +1,139 @@
/* ***** 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 canon = require('pilot/canon');
var pref = {
metadata: {
description: 'Commands for managing preferences'
},
showMetadata: {
description: 'Show preferences',
params: [
{
name: 'filter',
type: 'string',
description: 'Regex filter to show only some settings',
defaultValue: null
}
]
},
show: function(filter) {
var names = canon.getEnvironment().settings.getSettingNames();
// first sort the settingsList based on the name
names.sort(function(name1, name2) {
return name1.localeCompare(name2);
});
if (filter) {
filter = new RegExp(filter);
}
var html = '';
names.forEach(function(name) {
if (filter && !filter.test(name)) {
return;
}
var setting = canon.getEnvironment().settings.getSetting(name);
var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' +
setting.name;
html += '<a class="setting" href="' + url +
'" title="View external documentation on setting: ' +
setting.name +
'" target="_blank">' +
setting.name +
'</a> = ' +
setting.value +
'<br/>';
});
canon.getRequest().done(html);
},
setMetadata: {
description: 'Alter current settings',
params: [
{
name: 'setting',
type: 'setting',
description: 'The name of the setting to display or alter'
},
{
name: 'value',
type: 'settingValue',
description: 'The new value for the chosen setting'
}
]
},
set: function(setting, value) {
setting.set(value);
canon.getRequest().done('Setting: <strong>' + setting.name +
'</strong> = ' + setting.get());
},
resetMetadata: {
description: 'Reset a preference to it\'s default values',
params: [
{
name: 'setting',
type: 'setting',
description: 'The name of the setting to return to defaults'
}
]
},
reset: function(setting) {
setting.reset();
request.done('Reset ' + setting.name + ' to default: ' + setting.value);
}
};
exports.startup = function() {
canon.addCommands(pref, 'pref');
};
exports.shutdown = function() {
canon.removeCommands(pref, 'pref');
};
});

51
lib/ace/environment.js Normal file
View file

@ -0,0 +1,51 @@
/* ***** 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 DomTemplate.
*
* 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) (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
/**
* Create an environment object
*/
function create() {
return {
};
};
exports.create = create;
});

View file

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Joe Walker (jwalker@mozilla.com)
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)
*
* Alternatively, the contents of this file may be used under the terms of
@ -38,14 +39,18 @@
define(function(require, exports, module) {
var settings = require("ace/settings/default-settings")
exports.startup = function startup(data, reason) {
settings.startup(data, reason)
}
exports.startup = function startup(data) {
require("ace/settings").startup(data);
require("ace/commands/settings").startup(data);
require("ace/settings/default-settings").startup(data);
};
exports.shutdown = function shutdown(data, reason) {
settings.shutdown(data, reason)
}
exports.shutdown = function shutdown(data) {
require("ace/settings/default-settings").shutdown(data);
require("ace/commands/settings").shutdown(data);
require("ace/settings").shutdown(data);
};
})
});

View file

@ -38,7 +38,7 @@
define(function(require, exports, module) {
var keyUtil = require("pilot/keys");
var keyUtil = require("ace/keys");
function HashHandler(config) {
this.setConfig(config);
@ -100,17 +100,17 @@ function HashHandler(config) {
if (hashId != 0 || keyCode != 0) {
return {
command: (this.$config.reverse[hashId] || {})[textOrKey]
}
};
} else {
return {
command: "inserttext",
args: {
text: textOrKey
}
}
};
}
}
}).call(HashHandler.prototype)
};
}).call(HashHandler.prototype);
exports.HashHandler = HashHandler;
});

View file

@ -39,10 +39,11 @@
define(function(require, exports, module) {
var useragent = require("pilot/useragent");
var keyUtil = require("pilot/keys");
var event = require("pilot/event");
var settings = require("pilot/settings").settings;
var canon = require("pilot/canon");
var keyUtil = require("ace/keys");
var settings = require("ace/settings").settings;
require("ace/commands/default_commands");
var KeyBinding = function(editor) {

118
lib/ace/keys.js Normal file
View file

@ -0,0 +1,118 @@
/*! @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 oop = require("pilot/oop");
/**
* Helper functions and hashes for key handling.
*/
var Keys = (function() {
var ret = {
MODIFIER_KEYS: {
16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
},
KEY_MODS: {
"ctrl": 1, "alt": 2, "option" : 2,
"shift": 4, "meta": 8, "command": 8
},
FUNCTION_KEYS : {
8 : "Backspace",
9 : "Tab",
13 : "Return",
19 : "Pause",
27 : "Esc",
32 : "Space",
33 : "PageUp",
34 : "PageDown",
35 : "End",
36 : "Home",
37 : "Left",
38 : "Up",
39 : "Right",
40 : "Down",
44 : "Print",
45 : "Insert",
46 : "Delete",
112: "F1",
113: "F2",
114: "F3",
115: "F4",
116: "F5",
117: "F6",
118: "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: '\"'
}
};
// A reverse map of FUNCTION_KEYS
for (i in ret.FUNCTION_KEYS) {
var name = ret.FUNCTION_KEYS[i].toUpperCase();
ret[name] = parseInt(i, 10);
}
// Add the MODIFIER_KEYS, FUNCTION_KEYS and PRINTABLE_KEYS to the KEY
// variables as well.
oop.mixin(ret, ret.MODIFIER_KEYS);
oop.mixin(ret, ret.PRINTABLE_KEYS);
oop.mixin(ret, ret.FUNCTION_KEYS);
return ret;
})();
oop.mixin(exports, Keys);
exports.keyCodeToString = function(keyCode) {
return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
};
});

159
lib/ace/plugin_manager.js Normal file
View file

@ -0,0 +1,159 @@
/* ***** 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,
REGISTERED: 2,
STARTED: 3,
UNREGISTERED: 4,
SHUTDOWN: 5,
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;
},
register: function(data, reason) {
var pr = new Promise();
if (this.status != this.INSTALLED) {
pr.resolve(this);
return pr;
}
require([this.name], function(pluginModule) {
if (pluginModule.register) {
pluginModule.register(data, reason);
}
this.status = this.REGISTERED;
pr.resolve(this);
}.bind(this));
return pr;
},
startup: function(data, reason) {
reason = reason || exports.REASONS.APP_STARTUP;
var pr = new Promise();
if (this.status != this.REGISTERED) {
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, data, reason) {
var registrationPromises = [];
pluginList.forEach(function(pluginName) {
var plugin = this.plugins[pluginName];
if (plugin === undefined) {
plugin = new exports.Plugin(pluginName);
this.plugins[pluginName] = plugin;
registrationPromises.push(plugin.register(data, reason));
}
}.bind(this));
return Promise.group(registrationPromises);
},
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();
});

247
lib/ace/promise.js Normal file
View file

@ -0,0 +1,247 @@
/* ***** 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");
/**
* 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;
/**
* 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++;
_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();
console.groupEnd();
return this;
}
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;
});

385
lib/ace/settings.js Normal file
View file

@ -0,0 +1,385 @@
/* vim:ts=4:sts=4:sw=4:
* ***** 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)
* Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.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 oop = require('pilot/oop');
var types = require('pilot/types');
var EventEmitter = require('pilot/event_emitter').EventEmitter;
var SelectionType = require('pilot/types/basic').SelectionType;
var DeferredType = require('pilot/types/basic').DeferredType;
var Argument = require('pilot/argument').Argument;
/**
* 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);
}
if (this.onChange) {
this.on('change', this.onChange.bind(this));
}
this.set(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:
* // 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 = {};
// Storage for the active settings
this._settings = {};
// We often want sorted setting names. Cache
this._settingNames = [];
if (persister) {
this.setPersister(persister);
}
};
Settings.prototype = {
/**
* Function to add to the list of available settings.
* <p>Example usage:
* <pre>
* 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;
this._settingNames.push(setting.name);
this._settingNames.sort();
},
addSettings: function addSettings(settings) {
Object.keys(settings).forEach(function (name) {
var setting = settings[name];
if (!('name' in setting)) setting.name = name;
this.addSetting(setting);
}, this);
},
removeSetting: function(setting) {
var name = (typeof setting === 'string' ? setting : setting.name);
setting = this._settings[name];
delete this._settings[name];
util.arrayRemove(this._settingNames, name);
settings.removeAllListeners('change');
},
removeSettings: function removeSettings(settings) {
Object.keys(settings).forEach(function(name) {
var setting = settings[name];
if (!('name' in setting)) setting.name = name;
this.removeSettings(setting);
}, this);
},
getSettings: function() {
return Object.keys(this._settings).map(function(name) {
return this._settings[name];
}, this);
},
getSettingNames: function() {
return this._settingNames;
},
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);
}, 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.getSetting(setting).get()
});
}, 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.parseString(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;
/**
* EVIL: This relies on us using settingValue in the same event as setting
* The alternative is to have some central place where we store the current
* command line, but this might be a lesser evil for now.
*/
var lastSetting;
/**
* Select from the available settings
*/
var setting = new SelectionType({
name: 'setting',
data: function() {
return env.settings.getSettings();
},
noMatch: function() {
lastSetting = null;
}
});
(function() {
var originalStringify = setting.stringify;
setting.stringify = function(setting) {
lastSetting = setting;
return originalStringify.call(this, setting);
};
var originalParse = setting.parse;
setting.parse = function(arg) {
var conversion = originalParse.call(this, arg);
lastSetting = conversion.value;
return conversion;
};
})();
/**
* Something of a hack to allow the set command to give a clearer definition
* of the type to the command line.
*/
var settingValue = new DeferredType({
name: 'settingValue',
defer: function() {
if (lastSetting) {
return lastSetting.type;
}
else {
// console.error('Missing lastSetting. Defaulting to blank');
return types.getType('blank');
}
}
});
var env;
/**
* Registration and de-registration.
*/
exports.startup = function(data) {
env = data.env;
types.registerType(setting);
types.registerType(settingValue);
};
exports.shutdown = function(data) {
types.unregisterType(setting);
types.unregisterType(settingValue);
};
});

View file

@ -84,13 +84,13 @@ var settings = {
}
};
exports.startup = function startup(data, reason) {
exports.startup = function startup(data) {
env = data.env;
types.registerTypes(settingTypes);
data.env.settings.addSettings(settings);
};
exports.shutdown = function shutdown(data, reason) {
exports.shutdown = function shutdown(data) {
data.env.settings.removeSettings(settings);
};

@ -1 +1 @@
Subproject commit aa56894ef1cfa30ab038d77fbc79f72416eb43e6
Subproject commit e20180cc3311b0d366e2624ddd1b150767bb41e4