From 11ac88c012ffe63281d3df62a871d3f7131667d1 Mon Sep 17 00:00:00 2001 From: Joe Walker Date: Thu, 23 Dec 2010 15:30:55 +0000 Subject: [PATCH 001/621] move cockpit/pilot to a submodules --- .gitmodules | 3 + demo/boot.js | 61 +- editor.html | 45 +- plugins/cockpit/cli.js | 1083 ------------------ plugins/cockpit/index.js | 59 - plugins/cockpit/test/assert.js | 317 ----- plugins/cockpit/test/testCli.js | 359 ------ plugins/cockpit/test/testNothing.js | 40 - plugins/cockpit/ui/cliView.css | 164 --- plugins/cockpit/ui/cliView.js | 369 ------ plugins/cockpit/ui/images/closer.png | Bin 669 -> 0 bytes plugins/cockpit/ui/images/dot_clear.gif | Bin 42 -> 0 bytes plugins/cockpit/ui/images/minus.png | Bin 604 -> 0 bytes plugins/cockpit/ui/images/pinaction.png | Bin 1502 -> 0 bytes plugins/cockpit/ui/images/pinin.png | Bin 1199 -> 0 bytes plugins/cockpit/ui/images/pinout.png | Bin 1553 -> 0 bytes plugins/cockpit/ui/images/pins.png | Bin 1712 -> 0 bytes plugins/cockpit/ui/images/plus.png | Bin 635 -> 0 bytes plugins/cockpit/ui/images/throbber.gif | Bin 10819 -> 0 bytes plugins/cockpit/ui/requestView.css | 39 - plugins/cockpit/ui/requestView.html | 28 - plugins/cockpit/ui/requestView.js | 149 --- plugins/cockpit/ui/settings.js | 85 -- plugins/pilot/canon.js | 342 ------ plugins/pilot/catalog.js | 65 -- plugins/pilot/commands/basic.js | 263 ----- plugins/pilot/commands/history.js | 117 -- plugins/pilot/commands/settings.js | 135 --- plugins/pilot/console.js | 76 -- plugins/pilot/dom.js | 154 --- plugins/pilot/domtemplate.js | 404 ------- plugins/pilot/event.js | 242 ---- plugins/pilot/event_emitter.js | 84 -- plugins/pilot/fixoldbrowsers.js | 164 --- plugins/pilot/index.js | 73 -- plugins/pilot/keyboard/index.js | 459 -------- plugins/pilot/keyboard/keyutil.js | 273 ----- plugins/pilot/keyboard/tests/testKeyboard.js | 99 -- plugins/pilot/lang.js | 107 -- plugins/pilot/oop.js | 58 - plugins/pilot/plugin_manager.js | 158 --- plugins/pilot/promise.js | 264 ----- plugins/pilot/proxy.js | 83 -- plugins/pilot/rangeutils.js | 185 --- plugins/pilot/settings.js | 303 ----- plugins/pilot/settings/canon.js | 57 - plugins/pilot/stacktrace.js | 332 ------ plugins/pilot/tests/testRangeutils.js | 163 --- plugins/pilot/typecheck.js | 80 -- plugins/pilot/types.js | 262 ----- plugins/pilot/types/basic.js | 291 ----- plugins/pilot/types/command.js | 75 -- plugins/pilot/types/settings.js | 109 -- plugins/pilot/useragent.js | 92 -- support/cockpit | 1 + 55 files changed, 79 insertions(+), 8292 deletions(-) delete mode 100644 plugins/cockpit/cli.js delete mode 100644 plugins/cockpit/index.js delete mode 100644 plugins/cockpit/test/assert.js delete mode 100644 plugins/cockpit/test/testCli.js delete mode 100644 plugins/cockpit/test/testNothing.js delete mode 100644 plugins/cockpit/ui/cliView.css delete mode 100644 plugins/cockpit/ui/cliView.js delete mode 100644 plugins/cockpit/ui/images/closer.png delete mode 100644 plugins/cockpit/ui/images/dot_clear.gif delete mode 100644 plugins/cockpit/ui/images/minus.png delete mode 100644 plugins/cockpit/ui/images/pinaction.png delete mode 100644 plugins/cockpit/ui/images/pinin.png delete mode 100644 plugins/cockpit/ui/images/pinout.png delete mode 100644 plugins/cockpit/ui/images/pins.png delete mode 100644 plugins/cockpit/ui/images/plus.png delete mode 100644 plugins/cockpit/ui/images/throbber.gif delete mode 100644 plugins/cockpit/ui/requestView.css delete mode 100644 plugins/cockpit/ui/requestView.html delete mode 100644 plugins/cockpit/ui/requestView.js delete mode 100644 plugins/cockpit/ui/settings.js delete mode 100644 plugins/pilot/canon.js delete mode 100644 plugins/pilot/catalog.js delete mode 100644 plugins/pilot/commands/basic.js delete mode 100644 plugins/pilot/commands/history.js delete mode 100644 plugins/pilot/commands/settings.js delete mode 100644 plugins/pilot/console.js delete mode 100644 plugins/pilot/dom.js delete mode 100644 plugins/pilot/domtemplate.js delete mode 100644 plugins/pilot/event.js delete mode 100644 plugins/pilot/event_emitter.js delete mode 100644 plugins/pilot/fixoldbrowsers.js delete mode 100644 plugins/pilot/index.js delete mode 100644 plugins/pilot/keyboard/index.js delete mode 100644 plugins/pilot/keyboard/keyutil.js delete mode 100644 plugins/pilot/keyboard/tests/testKeyboard.js delete mode 100644 plugins/pilot/lang.js delete mode 100644 plugins/pilot/oop.js delete mode 100644 plugins/pilot/plugin_manager.js delete mode 100644 plugins/pilot/promise.js delete mode 100644 plugins/pilot/proxy.js delete mode 100644 plugins/pilot/rangeutils.js delete mode 100644 plugins/pilot/settings.js delete mode 100644 plugins/pilot/settings/canon.js delete mode 100644 plugins/pilot/stacktrace.js delete mode 100644 plugins/pilot/tests/testRangeutils.js delete mode 100644 plugins/pilot/typecheck.js delete mode 100644 plugins/pilot/types.js delete mode 100644 plugins/pilot/types/basic.js delete mode 100644 plugins/pilot/types/command.js delete mode 100644 plugins/pilot/types/settings.js delete mode 100644 plugins/pilot/useragent.js create mode 160000 support/cockpit diff --git a/.gitmodules b/.gitmodules index 346eb6aa..0927bff1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "support/node-htmlparser"] path = support/node-htmlparser url = git://github.com/tautologistics/node-htmlparser.git +[submodule "support/cockpit"] + path = support/cockpit + url = git://github.com/joewalker/cockpit.git diff --git a/demo/boot.js b/demo/boot.js index 2997b5ed..bbf08f18 100644 --- a/demo/boot.js +++ b/demo/boot.js @@ -35,17 +35,36 @@ * * ***** END LICENSE BLOCK ***** */ +/* +setupPlugins(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); + }); +}); + // TODO: Yuck! A global function -var setupPlugins = function(config, callback) { - config = config || {}; +var setupPlugins = function(callback) { + var config = { + pluginDirs: { + "../demo": { + singleFiles: ["demo_startup"] + } + } + }; + if (!config.pluginDirs) { config.pluginDirs = {}; } // config.pluginDirs["../lib"] = { // packages: ["ace"] // }; - config.pluginDirs["../plugins"] = { - packages: ["pilot", "cockpit"] + config.pluginDirs["../support/cockpit/support/pilot/lib"] = { + packages: [ "pilot" ] + }; + config.pluginDirs["../support/cockpit/lib"] = { + packages: [ "cockpit" ] }; var knownPlugins = []; @@ -99,7 +118,7 @@ var setupPlugins = function(config, callback) { main: "index", lib: "." }); - knownPlugins.push(packages[i]); + knownPlugins.push(packages[i] + "/index"); } } if (dirInfo.singleFiles) { @@ -125,3 +144,35 @@ var setupPlugins = function(config, callback) { }); }); }; +*/ + +var config = { + packagePaths: { + "../lib": [ + { name:"ace", lib: "." } + ], + "../support/cockpit/lib": [ + { name: "cockpit", main: "index", lib: "." } + ], + "../support/cockpit/support/pilot/lib": [ + { name: "pilot", main: "index", lib: "." } + ] + }, + paths: { demo_startup: "../demo/demo_startup" } +}; + +var deps = [ "pilot/fixoldbrowsers", "pilot/plugin_manager", "pilot/settings", + "pilot/environment", "demo_startup" ]; + +require(config, deps, function() { + var catalog = require("pilot/plugin_manager").catalog; + var REASON_START = require("pilot/plugin_manager").REASONS.APP_STARTUP; + var settings = require("pilot/settings").settings; + + catalog.registerPlugins([ "pilot/index", "cockpit/index" ]).then(function() { + var env = require("pilot/environment").create(); + catalog.startupPlugins({ env:env }, REASON_START).then(function() { + require("demo_startup").launch(env); + }); + }); +}); diff --git a/editor.html b/editor.html index 2e66ea17..a6b28321 100644 --- a/editor.html +++ b/editor.html @@ -46,10 +46,24 @@ display: none; } - #cockpit { + #cockpitInput { position: absolute; width: 100%; bottom: 0; + + border: none; outline: none; + font-family: consolas, courier, monospace; + font-size: 120%; + } + + #cockpitOutput { + padding: 10px; + margin: 0 15px; + border: 1px solid #AAA; + -moz-border-radius-topleft: 10px; + -moz-border-radius-topright: 10px; + border-top-left-radius: 4px; border-top-right-radius: 4px; + background: #DDD; color: #000; } @@ -177,31 +191,10 @@ echo $output; ?> - + - - - - - + + - \ No newline at end of file + diff --git a/plugins/cockpit/cli.js b/plugins/cockpit/cli.js deleted file mode 100644 index df183782..00000000 --- a/plugins/cockpit/cli.js +++ /dev/null @@ -1,1083 +0,0 @@ -/* ***** 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 lang = require('pilot/lang'); -var oop = require('pilot/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'); - -/** - * Normally type upgrade is done when the owning command is registered, but - * out commandParam isn't part of a command, so it misses out. - */ -exports.startup = function(data, reason) { - canon.upgradeType(commandParam); -}; - -/** - * The information required to tell the user there is a problem with their - * input. - * TODO: There a several places where {start,end} crop up. Perhaps we should - * have a Cursor object. - */ -function Hint(status, message, start, end, predictions) { - this.status = status; - this.message = message; - - if (typeof start === 'number') { - this.start = start; - this.end = end; - this.predictions = predictions; - } - else { - var arg = start; - this.start = arg.start; - this.end = arg.end; - this.predictions = arg.predictions; - } -} -Hint.prototype = { -}; -/** - * Loop over the array of hints finding the one we should display. - * @param hints array of hints - */ -Hint.sort = function(hints, cursor) { - // Calculate 'distance from cursor' - if (cursor !== undefined) { - hints.forEach(function(hint) { - if (hint.start === Argument.AT_CURSOR) { - hint.distance = 0; - } - else if (cursor < hint.start) { - hint.distance = hint.start - cursor; - } - else if (cursor > hint.end) { - hint.distance = cursor - hint.end; - } - else { - hint.distance = 0; - } - }, this); - } - // Sort - hints.sort(function(hint1, hint2) { - // Compare first based on distance from cursor - if (cursor !== undefined) { - var diff = hint1.distance - hint2.distance; - if (diff != 0) { - return diff; - } - } - // otherwise go with hint severity - return hint2.status - hint1.status; - }); - // tidy-up - if (cursor !== undefined) { - hints.forEach(function(hint) { - delete hint.distance; - }, this); - } - return hints; -}; -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. - * We publish a 'change' event when-ever the text changes - * @param emitter Arguments use something else to pass on change events. - * Currently this will be the creating Requisition. This prevents dependency - * loops and prevents us from needing to merge listener lists. - * @param text The string (trimmed) that contains the argument - * @param start The position of the text in the original input string - * @param end See start - * @param priorSpace Knowledge of the whitespace used prior to this argument in - * the input string allows us to re-generate the original input from the - * arguments. - * @constructor - */ -function Argument(emitter, text, start, end, priorSpace) { - this.emitter = emitter; - this.setText(text); - this.start = start; - this.end = end; - this.priorSpace = priorSpace; -} -Argument.prototype = { - /** - * Return the result of merging these arguments - */ - merge: function(following) { - if (following.emitter != this.emitter) { - throw new Error('Can\'t merge Arguments from different EventEmitters'); - } - return new Argument( - this.emitter, - this.text + following.priorSpace + following.text, - this.start, following.end, - this.priorSpace); - }, - - /** - * See notes on events in Assignment. We might need to hook changes here - * into a CliRequisition so they appear of the command line. - */ - setText: function(text) { - if (text == null) { - throw new Error('Illegal text for Argument: ' + text); - } - var ev = { argument: this, oldText: this.text, text: text }; - this.text = text; - this.emitter._dispatchEvent('argumentChange', ev); - }, - - /** - * Helper when we're putting arguments back together - */ - toString: function() { - return this.priorSpace + this.text; - } -}; -/** - * Merge an array of arguments into a single argument. - * All Arguments in the array are expected to have the same emitter - */ -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; -}; -/** - * We sometimes need a way to say 'this error occurs where ever the cursor is' - */ -Argument.AT_CURSOR = -1; - - -/** - * A link between a parameter and the data for that parameter. - * The data for the parameter is available as in the preferred type and as - * an Argument for the CLI. - *

We also record validity information where applicable. - *

For values, null and undefined have distinct definitions. null means - * that a value has been provided, undefined means that it has not. - * Thus, null is a valid default value, and common because it identifies an - * parameter that is optional. undefined means there is no value from - * the command line. - * @constructor - */ -function Assignment(param, requisition) { - this.param = param; - this.requisition = requisition; - this.setValue(param.defaultValue); -}; -Assignment.prototype = { - /** - * The parameter that we are assigning to - * @readonly - */ - param: undefined, - - /** - * Report on the status of the last parse() conversion. - * @see types.Conversion - */ - conversion: undefined, - - /** - * The current value in a type as specified by param.type - */ - value: undefined, - - /** - * The string version of the current value - */ - arg: 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.arg = undefined; - } - this.value = value; - - var text = (value == null) ? '' : this.param.type.stringify(value); - if (this.arg) { - this.arg.setText(text); - } - - this.conversion = undefined; - this.requisition._assignmentChanged(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.conversion.arg = arg; // TODO: make this automatic? - this.value = this.conversion.value; - this.requisition._assignmentChanged(this); - }, - - /** - * Create a list of the hints associated with this parameter assignment. - * Generally there will be only one hint generated because we're currently - * only displaying one hint at a time, ordering by distance from cursor - * and severity. Since distance from cursor will be the same for all hints - * from this assignment all but the most severe will ever be used. It might - * make sense with more experience to alter this to function to be getHint() - */ - getHint: function() { - // Allow the parameter to provide documentation - if (this.param.getCustomHint && this.value && this.arg) { - var hint = this.param.getCustomHint(this.value, this.arg); - if (hint) { - return hint; - } - } - - // If there is no argument, use the cursor position - var message = '' + this.param.name + ': '; - if (this.param.description) { - // TODO: This should be a short description - do we need to trim? - message += this.param.description.trim(); - - // Ensure the help text ends with '. ' - if (message.charAt(message.length - 1) !== '.') { - message += '.'; - } - if (message.charAt(message.length - 1) !== ' ') { - message += ' '; - } - } - var status = Status.VALID; - var start = this.arg ? this.arg.start : Argument.AT_CURSOR; - var end = this.arg ? this.arg.end : Argument.AT_CURSOR; - var predictions; - - // Non-valid conversions will have useful information to pass on - if (this.conversion) { - status = this.conversion.status; - if (this.conversion.message) { - message += this.conversion.message; - } - predictions = this.conversion.predictions; - } - - // Hint if the param is required, but not provided - var argProvided = this.arg && this.arg.text !== ''; - var dataProvided = this.value !== undefined || argProvided; - if (this.param.defaultValue === undefined && !dataProvided) { - status = Status.INVALID; - message += 'Required<\strong>'; - } - - return new Hint(status, message, start, end, predictions); - }, - - /** - * Basically setValue(conversion.predictions[0]) done in a safe - * way. - */ - complete: function() { - if (this.conversion && this.conversion.predictions && - this.conversion.predictions.length > 0) { - this.setValue(this.conversion.predictions[0]); - } - }, - - /** - * Replace the current value with the lower value if such a concept - * exists. - */ - decrement: function() { - var replacement = this.param.type.decrement(this.value); - if (replacement != null) { - this.setValue(replacement); - } - }, - - /** - * Replace the current value with the higher value if such a concept - * exists. - */ - increment: function() { - var replacement = this.param.type.increment(this.value); - if (replacement != null) { - this.setValue(replacement); - } - }, - - /** - * Helper when we're rebuilding command lines. - */ - toString: function() { - return this.arg ? this.arg.toString() : ''; - } -}; -exports.Assignment = Assignment; - - -/** - * This is a special parameter to reflect the command itself. - */ -var commandParam = { - name: 'command', - type: 'command', - description: 'The command to execute', - - /** - * Provide some documentation for a command. - */ - getCustomHint: function(command, arg) { - var docs = []; - docs.push(' > '); - docs.push(command.name); - if (command.params && command.params.length > 0) { - command.params.forEach(function(param) { - if (param.defaultValue === undefined) { - docs.push(' [' + param.name + ']'); - } - else { - docs.push(' [' + param.name + ']'); - } - }, this); - } - docs.push('
'); - - docs.push(command.description ? command.description : '(No description)'); - docs.push('
'); - - if (command.params && command.params.length > 0) { - docs.push('

'); - } - - return new Hint(Status.VALID, docs.join(''), arg); - } -}; - -/** - * 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. - *

Events

- * We publish the following events: