├── .coverignore
├── .coverrc
├── .gitignore
├── .jshintrc
├── .travis.yml
├── LICENSE
├── README.md
├── docs
├── design.md
├── developing-gcli.md
├── index.md
├── running-tests.md
├── writing-commands.md
├── writing-tests.md
└── writing-types.md
├── gcli.js
├── index.html
├── lib
└── gcli
│ ├── cli.js
│ ├── commands
│ ├── clear.js
│ ├── commands.js
│ ├── connect.js
│ ├── context.js
│ ├── demo
│ │ ├── alert.js
│ │ ├── demo.js
│ │ ├── echo.js
│ │ └── sleep.js
│ ├── global.js
│ ├── help.js
│ ├── intro.js
│ ├── lang.js
│ ├── mocks.js
│ ├── pref.js
│ ├── preflist.js
│ ├── server
│ │ ├── exec.js
│ │ ├── exit.js
│ │ ├── firefox.js
│ │ ├── orion.js
│ │ ├── server.js
│ │ └── standard.js
│ └── test.js
│ ├── connectors
│ ├── connectors.js
│ ├── front.js
│ ├── index.js
│ ├── protocol.js
│ ├── remoted.js
│ ├── websocket.js
│ ├── websocketserver.js
│ └── xhr.js
│ ├── converters
│ ├── basic.js
│ ├── converters.js
│ ├── html.js
│ └── terminal.js
│ ├── fields
│ ├── delegate.js
│ ├── fields.js
│ └── selection.js
│ ├── index.js
│ ├── items
│ ├── basic.js
│ ├── demo.js
│ ├── remote.js
│ ├── server.js
│ ├── standard.js
│ └── ui.js
│ ├── languages
│ ├── command.html
│ ├── command.js
│ ├── javascript.js
│ └── languages.js
│ ├── nls
│ └── strings.js
│ ├── settings.js
│ ├── system.js
│ ├── test
│ ├── automators
│ │ ├── requisition.js
│ │ └── terminal.js
│ ├── helpers.js
│ ├── index.js
│ ├── mockCommands.js
│ ├── mockDocument.js
│ ├── mockFileCommands.js
│ ├── mockSettings.js
│ ├── suite.js
│ ├── testAsync.js
│ ├── testCanon.js
│ ├── testCli1.js
│ ├── testCli2.js
│ ├── testCompletion1.js
│ ├── testCompletion2.js
│ ├── testContext.js
│ ├── testDate.js
│ ├── testExec.js
│ ├── testFail.js
│ ├── testFile.js
│ ├── testFileparser.js
│ ├── testFilesystem.js
│ ├── testFocus.js
│ ├── testHelp.js
│ ├── testHistory.js
│ ├── testIncomplete.js
│ ├── testInputter.js
│ ├── testIntro.js
│ ├── testJs.js
│ ├── testKeyboard1.js
│ ├── testKeyboard2.js
│ ├── testKeyboard3.js
│ ├── testKeyboard4.js
│ ├── testKeyboard5.js
│ ├── testKeyboard6.js
│ ├── testMenu.js
│ ├── testNode.js
│ ├── testPref1.js
│ ├── testPref2.js
│ ├── testRemoteWs.js
│ ├── testRemoteXhr.js
│ ├── testResource.js
│ ├── testSettings.js
│ ├── testShort.js
│ ├── testSpell.js
│ ├── testSplit.js
│ ├── testString.js
│ ├── testTokenize.js
│ ├── testTooltip.js
│ ├── testTypes.js
│ ├── testUnion.js
│ └── testUrl.js
│ ├── testharness
│ ├── assert.js
│ ├── examiner.js
│ └── status.js
│ ├── types
│ ├── array.js
│ ├── boolean.js
│ ├── command.js
│ ├── date.js
│ ├── delegate.js
│ ├── file.js
│ ├── fileparser.js
│ ├── javascript.js
│ ├── node.js
│ ├── number.js
│ ├── resource.js
│ ├── selection.js
│ ├── setting.js
│ ├── string.js
│ ├── types.js
│ ├── union.js
│ └── url.js
│ ├── ui
│ ├── focus.js
│ ├── history.js
│ ├── intro.js
│ ├── menu.css
│ ├── menu.html
│ ├── menu.js
│ ├── terminal.css
│ ├── terminal.html
│ ├── terminal.js
│ └── view.js
│ └── util
│ ├── domtemplate.js
│ ├── fileparser.js
│ ├── filesystem.js
│ ├── host.js
│ ├── l10n.js
│ ├── legacy.js
│ ├── prism.js
│ ├── spell.js
│ └── util.js
├── package.json
├── phantom-test.js
├── remote.html
├── scripts
├── i18n.js
├── require.js
├── shim.js
└── text.js
├── webpack.config.js
├── wp-index.html
└── wp-index.js
/.coverignore:
--------------------------------------------------------------------------------
1 |
2 | lib/server
3 |
4 | node_modules/connect
5 | node_modules/dryice
6 | node_modules/express
7 | node_modules/formidable
8 | node_modules/gclitest
9 | node_modules/socket.io
10 | node_modules/test
11 |
12 | node_modules/util/promise.js
13 |
14 | node_modules/gcli/index.js
15 |
--------------------------------------------------------------------------------
/.coverrc:
--------------------------------------------------------------------------------
1 | {
2 | "dataDirectory": "built/coverage_data",
3 | "modules": true,
4 | "html": {
5 | "directory": "built/coverage_html",
6 | "generateIndex": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Junk that could exist anywhere:
3 | .DS_Store
4 | *.swp
5 | *.tmp
6 | .*.gz
7 |
8 | # Editor junk
9 | /.project
10 | /.pydevproject
11 | /.settings/
12 | /.settings.xml
13 | /.settings.xml.old
14 | /.idea/
15 | /.externalToolBuilders/
16 | /gcli.iml
17 |
18 | # A handy place to put stuff that git should ignore:
19 | /ignore
20 |
21 | # Build artifacts
22 | /built
23 |
24 | # Manually installed node packages should be ignored
25 | /node_modules/
26 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "undef": true,
3 | "camelcase": false,
4 | "curly": true,
5 | "noarg": true,
6 | "quotmark": "single",
7 | "strict": true,
8 | "eqnull": true,
9 | "evil": true,
10 | "eqnull": true,
11 | "browser": true,
12 | "devel": true,
13 | "node": true,
14 | "phantom": true,
15 | "laxbreak": true,
16 | "iterator": true,
17 | "unused":"vars",
18 | "globals": {
19 | "define": false,
20 | "Components": false,
21 | "Event": false,
22 | "CSSRule": false,
23 | "Proxy": false,
24 | "info": false,
25 | "io": false,
26 | "ok": false
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | language: node_js
3 | sudo: false
4 | node_js:
5 | - "4.1"
6 | script:
7 | - "node gcli.js test"
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | GCLI - Graphic Command Line
3 | ===========================
4 |
5 | GCLI is a graphical command line component. It is being integrated with
6 | Firefox developer tools and with editors like Orion and Ace. It can be embedded
7 | in web pages and JavaScript applications.
8 |
9 |
10 | Why?
11 | ----
12 |
13 | Command lines have advantages over graphical UIs in speed of entry and the
14 | ability to contain an almost unlimited set of commands without becoming
15 | cluttered. On the other hand GUIs typically come with better discoverability.
16 | GCLI is an experiment to see if we can improve the discoverability of command
17 | lines whilst retaining the speed and powerful command set of traditional CLIs.
18 |
19 | There are a number of problems with the design of traditional command lines:
20 |
21 | * They assume a curses-style 80x24 (or similar) character array for output.
22 | Even system consoles are capable of graphics these days. It ought to be
23 | possible to have richer output.
24 | * They assume serial access to the output - one command at a time.
25 | This made sense when multi-tasking was expensive, however with modern
26 | processors single-tasking is starting to look expensive.
27 | * They are so loosely coupled that the integration is typically nothing more
28 | than argv/stdout/stderr/stdin.
29 | That level of integration made sense on memory constrained devices, but with
30 | more resources, we can provide much richer integration.
31 |
32 |
33 | Getting Started
34 | ---------------
35 |
36 | $ git clone git://github.com/joewalker/gcli.git
37 | $ cd gcli
38 | -> Load index.html into your web browser (except Chrome)
39 | For Chrome:
40 | install node (http://nodejs.org/download/)
41 | $ npm install .
42 | $ node ./gcli.js
43 | -> Load http://localhost:9999/
44 |
45 | When you see the ':' prompt, type 'help' to see a list of commands.
46 |
47 |
48 | Related Links
49 | -------------
50 |
51 | * **Bug reports**: http://j.mp/gclibug
52 | * **GCLI in Firefox**: https://developer.mozilla.org/en-US/docs/Tools/GCLI
53 | * **GCLI on the Web**: https://github.com/joewalker/gcli/blob/master/docs/index.md
54 |
55 |
--------------------------------------------------------------------------------
/docs/design.md:
--------------------------------------------------------------------------------
1 |
2 | # The Design of GCLI
3 |
4 | ## Design Goals
5 |
6 | GCLI should be:
7 |
8 | - primarily for technical users.
9 | - as fast as a traditional CLI. It should be possible to put your head down,
10 | and look at the keyboard and use GCLI 'blind' at full speed without making
11 | mistakes.
12 | - principled about the way it encourages people to build commands. There is
13 | benefit from unifying the underlying concepts.
14 | - automatically helpful.
15 |
16 | GCLI should not attempt to:
17 |
18 | - convert existing GUI users to a CLI.
19 | - use natural language input. The closest we should get to natural language is
20 | thinking of commands as ```verb noun --adjective```.
21 | - gain a touch based interface. Whilst it's possible (even probable) that touch
22 | can provide further benefits to command line users, that can wait while we
23 | catch up with 1985.
24 | - slavishly follow the syntax of existing commands, predictability is more
25 | important.
26 | - be a programming language. Shell scripts are mini programming languages but
27 | we have JavaScript sat just next door. It's better to integrate than compete.
28 |
29 |
30 | ## Design Challenges
31 |
32 | What has changed since 1970 that might cause us to make changes to the design
33 | of the command line?
34 |
35 |
36 | ### Connection limitations
37 |
38 | Unix pre-dates the Internet and treats almost everything as a file. Since the
39 | Internet it could be more useful to use URIs as ways to identify sources of data.
40 |
41 |
42 | ### Memory limitations
43 |
44 | Modern computers have something like 6 orders of magnitude more memory than the
45 | PDP-7 on which Unix was developed. Innovations like stdin/stdout and pipes are
46 | ways to connect systems without long-term storage of the results. The ability
47 | to store results for some time (potentially in more than one format)
48 | significantly reduces the need for these concepts. We should make the results
49 | of past commands addressable for re-use at a later time.
50 |
51 | There are a number of possible policies for eviction of items from the history.
52 | We should investigate options other than a simple stack.
53 |
54 |
55 | ### Multi-tasking limitations
56 |
57 | Multi-tasking was a problem in 1970; the problem was getting a computer to do
58 | many jobs on 1 core. Today the problem is getting a computer to do one job on
59 | many cores. However we're stuck with this legacy in 2 ways. Firstly that the
60 | default is to force everything to wait until the previous job is finished, but
61 | more importantly that output from parallel jobs frequently collides
62 |
63 | $ find / -ctime 5d -print &
64 | $ find / -uid 0 -print &
65 | // good luck working out what came from where
66 |
67 | $ tail -f logfile.txt &
68 | $ vi main.c
69 | // have a nice time editing that file
70 |
71 | GCLI should allow commands to be asynchronous and will provide UI elements to
72 | inform the user of job completion. It will also keep asynchronous command
73 | output contained within it's own display area.
74 |
75 |
76 | ### Output limitations
77 |
78 | The PDP-7 had a teletype. There is something like 4 orders of magnitude more
79 | information that can be displayed on a modern display than a 80x24 character
80 | based console. We can use this flexibility to provide better help to the user
81 | in entering their command.
82 |
83 | The additional display richness can also allow interaction with result output.
84 | Command output can include links to follow-up commands, and even ask for
85 | additional input. (e.g. "your search returned zero results do you want to try
86 | again with a different search string")
87 |
88 | There is no reason why output must be static. For example, it could be
89 | informative to see the results of an "ls" command alter given changes made by
90 | subsequent commands. (It should be noted that there are times when historical
91 | information is important too)
92 |
93 |
94 | ### Integration limitations
95 |
96 | In 1970, command execution meant retrieving a program from storage, and running
97 | it. This required minimal interaction between the command line processor and
98 | the program being run, and was good for resource constrained systems.
99 | This lack of interaction resulted in the processing of command line arguments
100 | being done everywhere, when the task was better suited to command line.
101 | We should provide metadata about the commands being run, to allow the command
102 | line to process, interpret and provide help on the input.
103 |
--------------------------------------------------------------------------------
/docs/running-tests.md:
--------------------------------------------------------------------------------
1 |
2 | # Running Tests
3 |
4 | GCLI has a test suite that can be run in a number of different environments.
5 | Some of the tests don't work in all environments. These should be automatically
6 | skipped when not applicable.
7 |
8 |
9 | ## Web
10 |
11 | Running a limited set of test from the web is the easiest. Simply load
12 | 'localtest.html' and the unit tests should be run automatically, with results
13 | displayed on the console. Tests can be re-run using the 'test' command.
14 |
15 | It also creates a function 'testCommands()' to be run at a JS prompt, which
16 | enables the test commands for debugging purposes.
17 |
18 |
19 | ## Firefox
20 |
21 | GCLI's test suite integrates with Mochitest and runs automatically on each test
22 | run. Dryice packages the tests to format them for the Firefox build system.
23 |
24 | For more information about running Mochitest on Firefox (including GCLI) see
25 | [the MDN, Mochitest docs](https://developer.mozilla.org/en/Mochitest)
26 |
27 |
28 | # Node
29 |
30 | Running the test suite under node can be done as follows:
31 |
32 | $ node gcli.js test
33 |
34 | Or, using the `test` command:
35 |
36 | $ node gcli.js
37 | Serving GCLI to http://localhost:9999/
38 | This is also a limited GCLI prompt.
39 | Type 'help' for a list of commands, CTRL+C twice to exit:
40 | : test
41 |
42 | testCli: Pass (funcs=9, checks=208)
43 | testCompletion: Pass (funcs=1, checks=139)
44 | testExec: Pass (funcs=1, checks=133)
45 | testHistory: Pass (funcs=3, checks=13)
46 | ....
47 |
48 | Summary: Pass (951 checks)
49 |
50 |
51 | # Travis CI
52 |
53 | GCLI check-ins are automatically tested by [Travis CI](https://travis-ci.org/joewalker/gcli).
54 |
55 |
56 | # Test Case Generation
57 |
58 | GCLI can generate test cases automagically. Load ```localtest.html```, type a
59 | command to be tested into GCLI, and the press F2. GCLI will output to the
60 | console a template test case for the entered command.
61 |
--------------------------------------------------------------------------------
/docs/writing-tests.md:
--------------------------------------------------------------------------------
1 |
2 | # Writing Tests
3 |
4 | There are several sources of GCLI tests and several environments in which they
5 | are run.
6 |
7 | The majority of GCLI tests are stored in
8 | [this repository](https://github.com/joewalker/gcli/) in files named like
9 | ```./lib/gclitest/test*.js```. These tests run in Firefox, Chrome, Opera,
10 | and NodeJS/JsDom
11 |
12 | See [Running Tests](running-tests.md) for further details.
13 |
14 | GCLI comes with a generic unit test harness (in ```./lib/test/```) and a
15 | set of helpers for creating GCLI tests (in ```./lib/gclitest/helpers.js```).
16 |
17 | # GCLI tests in Firefox
18 |
19 | The build process converts the GCLI tests to run under Mochitest inside the
20 | Firefox unit tests. It also adds some
21 |
--------------------------------------------------------------------------------
/docs/writing-types.md:
--------------------------------------------------------------------------------
1 |
2 | # Writing Types
3 |
4 | Commands are a fundamental building block because they are what the users
5 | directly interacts with, however they are built on ``Type``s. There are a
6 | number of built in types:
7 |
8 | * string. This is a JavaScript string
9 | * number. A JavaScript number
10 | * boolean. A JavaScript boolean
11 | * selection. This is an selection from a number of alternatives
12 | * delegate. This type could change depending on other factors, but is well
13 | defined when one of the conversion routines is called.
14 |
15 | There are a number of additional types defined by Pilot and GCLI as
16 | extensions to the ``selection`` and ``delegate`` types
17 |
18 | * setting. One of the defined settings
19 | * settingValue. A value that can be applied to an associated setting.
20 | * command. One of the defined commands
21 |
22 | Most of our types are 'static' e.g. there is only one type of 'string', however
23 | some types like 'selection' and 'delegate' are customizable.
24 |
25 | All types must inherit from Type and have the following methods:
26 |
27 | /**
28 | * Convert the given value to a string representation.
29 | * Where possible, there should be round-tripping between values and their
30 | * string representations.
31 | */
32 | stringify: function(value) { return 'string version of value'; },
33 |
34 | /**
35 | * Convert the given str to an instance of this type.
36 | * Where possible, there should be round-tripping between values and their
37 | * string representations.
38 | * @return Conversion
39 | */
40 | parse: function(str) { return new Conversion(...); },
41 |
42 | /**
43 | * The plug-in system, and other things need to know what this type is
44 | * called. The name alone is not enough to fully specify a type. Types like
45 | * 'selection' and 'delegate' need extra data, however this function returns
46 | * only the name, not the extra data.
47 | *
In old bespin, equality was based on the name. This may turn out to be
48 | * important in Ace too.
49 | */
50 | name: 'example',
51 |
52 | In addition, defining the following function can be helpful, although Type
53 | contains default implementations:
54 |
55 | * nudge(value, by)
56 |
57 | Type, Conversion and Status are all declared by commands.js.
58 |
59 | The values produced by the parse function can be of any type, but if you are
60 | producing your own, you are strongly encouraged to include properties called
61 | ``name`` and ``description`` where it makes sense. There are a number of
62 | places in GCLI where the UI will be able to provide better help to users if
63 | your values include these properties.
64 |
65 |
66 | # Writing Fields
67 |
68 | Fields are visual representations of types. For simple types like string it is
69 | enough to use ````, however more complex types we may wish to
70 | provide a custom widget to allow the user to enter values of the given type.
71 |
72 | This is an example of a very simple new password field type:
73 |
74 | function PasswordField(doc) {
75 | this.doc = doc;
76 | }
77 |
78 | PasswordField.prototype = Object.create(Field.prototype);
79 |
80 | PasswordField.prototype.createElement = function(assignment) {
81 | this.assignment = assignment;
82 | this.input = dom.createElement(this.doc, 'input');
83 | this.input.type = 'password';
84 | this.input.value = assignment.arg ? assignment.arg.text : '';
85 |
86 | this.onKeyup = function() {
87 | this.assignment.setValue(this.input.value);
88 | }.bind(this);
89 | this.input.addEventListener('keyup', this.onKeyup, false);
90 |
91 | this.onChange = function() {
92 | this.input.value = this.assignment.arg.text;
93 | };
94 | this.assignment.onAssignmentChange.add(this.onChange, this);
95 |
96 | return this.input;
97 | };
98 |
99 | PasswordField.prototype.destroy = function() {
100 | this.input.removeEventListener('keyup', this.onKeyup, false);
101 | this.assignment.onAssignmentChange.remove(this.onChange, this);
102 | };
103 |
104 | PasswordField.claim = function(type) {
105 | return type.name === 'password' ? Field.claim.MATCH : Field.claim.NO_MATCH;
106 | };
107 |
--------------------------------------------------------------------------------
/gcli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | /*
3 | * Copyright 2012, Mozilla Foundation and contributors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | 'use strict';
19 |
20 | var system = require('./lib/gcli/system').createSystem();
21 |
22 | var items = [
23 | require('./lib/gcli/items/basic').items,
24 | require('./lib/gcli/items/ui').items,
25 | require('./lib/gcli/items/remote').items,
26 | require('./lib/gcli/items/standard').items,
27 | require('./lib/gcli/items/demo').items,
28 | require('./lib/gcli/items/server').items,
29 |
30 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
31 |
32 | system.addItems(items);
33 |
34 | var util = require('./lib/gcli/util/util');
35 | var Requisition = require('./lib/gcli/cli').Requisition;
36 |
37 | var requisition = new Requisition(system);
38 | var command, extraActions;
39 |
40 | if (process.argv.length < 3) {
41 | // No command passed in. Serve GCLI over http and start a local REPL
42 | command = 'server start';
43 | extraActions = function(output) {
44 | if (!output.error) {
45 | startRepl();
46 | }
47 | };
48 | }
49 | else {
50 | // Command passed in. No server/REPL and a process.exit(1) on failure to
51 | // propagate test errors
52 | command = process.argv.slice(2).join(' ');
53 | extraActions = function(output) {
54 | if (output.error) {
55 | process.exit(1);
56 | }
57 | };
58 | }
59 |
60 | /**
61 | * Convert an Output object to a string, and then log that to stdout/stderr
62 | * depending on the error status
63 | */
64 | function logResults(output) {
65 | var context = requisition.conversionContext;
66 | return output.convert('string', context).then(function(message) {
67 | if (output.error) {
68 | console.error(message);
69 | }
70 | else {
71 | console.log(message);
72 | }
73 | return output;
74 | });
75 | }
76 |
77 | requisition.updateExec(command)
78 | .then(logResults)
79 | .then(extraActions)
80 | .catch(util.errorHandler);
81 |
82 | /**
83 | * Start a NodeJS REPL to execute commands
84 | */
85 | function startRepl() {
86 | var repl = require('repl');
87 |
88 | var gcliEval = function(command, scope, file, callback) {
89 | // Why does node wrap the command in '(...)\n'?
90 | command = command.replace(/^\((.*)\n\)$/, function(all, part) {
91 | return part;
92 | });
93 |
94 | if (command.length !== 0) {
95 | requisition.updateExec(command)
96 | .then(logResults)
97 | .then(function() { callback(); })
98 | .catch(function(ex) { util.errorHandler(ex); callback(); });
99 | }
100 | };
101 |
102 | console.log('This is also a limited GCLI REPL. ' +
103 | 'Type \'help\' for a list of commands, CTRL+C 3 times to exit:');
104 | repl.start(': ', process, gcliEval, false, true);
105 | }
106 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GCLI: Graphical Command Line
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lib/gcli/commands/clear.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 |
21 | exports.items = [
22 | {
23 | // A command to clear the output area
24 | item: 'command',
25 | name: 'clear',
26 | description: l10n.lookup('clearDesc'),
27 | returnType: 'clearoutput',
28 | exec: function(args, context) { }
29 | },
30 | {
31 | item: 'converter',
32 | from: 'clearoutput',
33 | to: 'view',
34 | exec: function(ignore, conversionContext) {
35 | return {
36 | html: '',
37 | data: {
38 | onload: function(ev) {
39 | // element starts off being the span above, and we walk up the
40 | // tree looking for the terminal
41 | var element = ev.target;
42 | while (element != null && element.terminal == null) {
43 | element = element.parentElement;
44 | }
45 |
46 | if (element == null) {
47 | // This is only an event handler on a completed command
48 | // So we're relying on this showing up in the console
49 | throw new Error('Failed to find clear');
50 | }
51 |
52 | element.terminal.clear();
53 | }
54 | }
55 | };
56 | }
57 | }
58 | ];
59 |
--------------------------------------------------------------------------------
/lib/gcli/commands/context.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 | var cli = require('../cli');
21 |
22 | /**
23 | * 'context' command
24 | */
25 | var context = {
26 | item: 'command',
27 | name: 'context',
28 | description: l10n.lookup('contextDesc'),
29 | manual: l10n.lookup('contextManual'),
30 | params: [
31 | {
32 | name: 'prefix',
33 | type: 'command',
34 | description: l10n.lookup('contextPrefixDesc'),
35 | defaultValue: null
36 | }
37 | ],
38 | returnType: 'string',
39 | // The context command is client only because it's essentially sugar for
40 | // typing commands. When there is a command prefix in action, it is the job
41 | // of the remoter to add the prefix to the typed strings that are sent for
42 | // remote execution
43 | noRemote: true,
44 | exec: function echo(args, context) {
45 | var requisition = cli.getMapping(context).requisition;
46 |
47 | if (args.prefix == null) {
48 | requisition.prefix = null;
49 | return l10n.lookup('contextEmptyReply');
50 | }
51 |
52 | if (args.prefix.exec != null) {
53 | throw new Error(l10n.lookupFormat('contextNotParentError',
54 | [ args.prefix.name ]));
55 | }
56 |
57 | requisition.prefix = args.prefix.name;
58 | return l10n.lookupFormat('contextReply', [ args.prefix.name ]);
59 | }
60 | };
61 |
62 | exports.items = [ context ];
63 |
--------------------------------------------------------------------------------
/lib/gcli/commands/demo/alert.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.items = [
20 | {
21 | // Arm window.alert with metadata
22 | item: 'command',
23 | name: 'alert',
24 | description: 'Show an alert dialog',
25 | params: [
26 | {
27 | name: 'message',
28 | type: 'string',
29 | description: 'Message to display'
30 | }
31 | ],
32 | exec: function(args, context) {
33 | window.alert(args.message);
34 | }
35 | }
36 | ];
37 |
--------------------------------------------------------------------------------
/lib/gcli/commands/demo/echo.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.items = [
20 | {
21 | item: 'command',
22 | name: 'echo',
23 | description: {
24 | root: 'Show a message',
25 | fr_fr: 'Afficher un message'
26 | },
27 | params: [
28 | {
29 | name: 'message',
30 | type: 'string',
31 | description: {
32 | root: 'The message to output',
33 | fr_fr: 'Le message à afficher'
34 | }
35 | }
36 | ],
37 | returnType: 'string',
38 | exec: function(args, context) {
39 | return args.message;
40 | }
41 | }
42 | ];
43 |
--------------------------------------------------------------------------------
/lib/gcli/commands/demo/sleep.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.items = [
20 | {
21 | item: 'command',
22 | name: 'sleep',
23 | description: 'Wait for a while',
24 | params: [
25 | {
26 | name: 'length',
27 | type: { name: 'number', min: 1 },
28 | description: 'How long to wait (s)'
29 | }
30 | ],
31 | returnType: 'string',
32 | exec: function(args, context) {
33 | return new Promise(function(resolve, reject) {
34 | setTimeout(function() {
35 | resolve('Done');
36 | }, args.length * 1000);
37 | });
38 | }
39 | }
40 | ];
41 |
--------------------------------------------------------------------------------
/lib/gcli/commands/global.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 |
21 | exports.items = [
22 | {
23 | // A type for selecting a known setting
24 | item: 'type',
25 | name: 'global',
26 | parent: 'selection',
27 | remote: true,
28 | lookup: function(context) {
29 | var knownWindows = context.environment.window == null ?
30 | [ ] : [ context.environment.window ];
31 |
32 | this.last = findWindows(knownWindows).map(function(window) {
33 | return { name: windowToString(window), value: window };
34 | });
35 |
36 | return this.last;
37 | }
38 | },
39 | {
40 | // A command to switch JS globals
41 | item: 'command',
42 | name: 'global',
43 | description: l10n.lookup('globalDesc'),
44 | params: [
45 | {
46 | name: 'window',
47 | type: 'global',
48 | description: l10n.lookup('globalWindowDesc'),
49 | }
50 | ],
51 | returnType: 'string',
52 | exec: function(args, context) {
53 | context.shell.global = args.window;
54 | return l10n.lookupFormat('globalOutput', [ windowToString(args.window) ]);
55 | }
56 | }
57 | ];
58 |
59 | function windowToString(win) {
60 | return win.location ? win.location.href : 'NodeJS-Global';
61 | }
62 |
63 | function findWindows(knownWindows) {
64 | knownWindows.forEach(function(window) {
65 | addChildWindows(window, knownWindows);
66 | });
67 | return knownWindows;
68 | }
69 |
70 | function addChildWindows(win, knownWindows) {
71 | var iframes = win.document.querySelectorAll('iframe');
72 | [].forEach.call(iframes, function(iframe) {
73 | var iframeWin = iframe.contentWindow;
74 | if (knownWindows.indexOf(iframeWin) === -1) {
75 | knownWindows.push(iframeWin);
76 | addChildWindows(iframeWin, knownWindows);
77 | }
78 | });
79 | }
80 |
--------------------------------------------------------------------------------
/lib/gcli/commands/intro.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 | var intro = require('../ui/intro');
21 |
22 | exports.items = [
23 | {
24 | item: 'converter',
25 | from: 'intro',
26 | to: 'view',
27 | exec: intro.createView
28 | },
29 | {
30 | item: 'command',
31 | name: 'intro',
32 | description: l10n.lookup('introDesc'),
33 | manual: l10n.lookup('introManual'),
34 | returnType: 'intro',
35 | exec: function(args, context) {
36 | // The intro command is pure formatting - no data
37 | }
38 | }
39 | ];
40 |
--------------------------------------------------------------------------------
/lib/gcli/commands/lang.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 | var cli = require('../cli');
21 |
22 | exports.items = [
23 | {
24 | // A type that lists available languages
25 | item: 'type',
26 | name: 'language',
27 | parent: 'selection',
28 | lookup: function(context) {
29 | return context.system.languages.getAll().map(function(language) {
30 | return { name: language.name, value: language };
31 | });
32 | }
33 | },
34 | {
35 | // A command to switch languages
36 | item: 'command',
37 | name: 'lang',
38 | description: l10n.lookup('langDesc'),
39 | params: [
40 | {
41 | name: 'language',
42 | type: 'language'
43 | }
44 | ],
45 | returnType: 'view',
46 | exec: function(args, context) {
47 | var terminal = cli.getMapping(context).terminal;
48 |
49 | context.environment.window.setTimeout(function() {
50 | terminal.switchLanguage(args.language);
51 | }, 10);
52 |
53 | return {
54 | html:
55 | '
' +
56 | ' ${langOutput}' +
57 | '
',
58 | data: {
59 | langOutput: l10n.lookupFormat('langOutput', [ args.language.name ]),
60 | style: args.language.proportionalFonts ? '' : 'gcli-row-script'
61 | }
62 | };
63 | }
64 | }
65 | ];
66 |
--------------------------------------------------------------------------------
/lib/gcli/commands/mocks.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var cli = require('../cli');
20 | var mockCommands = require('../test/mockCommands');
21 | var mockFileCommands = require('../test/mockFileCommands');
22 | var mockSettings = require('../test/mockSettings');
23 | var mockDocument = require('../test/mockDocument');
24 |
25 | var isNode = (typeof(process) !== 'undefined' &&
26 | process.title.indexOf('node') != -1);
27 |
28 | exports.items = [
29 | {
30 | item: 'command',
31 | name: 'mocks',
32 | description: 'Add/remove mock commands',
33 | params: [
34 | {
35 | name: 'included',
36 | type: {
37 | name: 'selection',
38 | data: [ 'on', 'off' ]
39 | },
40 | description: 'Turn mock commands on or off',
41 | }
42 | ],
43 | returnType: 'string',
44 |
45 | exec: function(args, context) {
46 | var requisition = cli.getMapping(context).requisition;
47 | this[args.included](requisition);
48 | return 'Mock commands are now ' + args.included;
49 | },
50 |
51 | on: function(requisition) {
52 | mockCommands.setup(requisition);
53 | mockSettings.setup(requisition.system);
54 | mockDocument.setup(requisition);
55 |
56 | if (isNode) {
57 | mockFileCommands.setup(requisition);
58 | }
59 | },
60 |
61 | off: function(requisition) {
62 | mockCommands.shutdown(requisition);
63 | mockSettings.shutdown(requisition.system);
64 | mockDocument.shutdown(requisition);
65 |
66 | if (isNode) {
67 | mockFileCommands.shutdown(requisition);
68 | }
69 | }
70 | }
71 | ];
72 |
--------------------------------------------------------------------------------
/lib/gcli/commands/pref.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 |
21 | exports.items = [
22 | {
23 | // 'pref' command
24 | item: 'command',
25 | name: 'pref',
26 | description: l10n.lookup('prefDesc'),
27 | manual: l10n.lookup('prefManual')
28 | },
29 | {
30 | // 'pref show' command
31 | item: 'command',
32 | name: 'pref show',
33 | description: l10n.lookup('prefShowDesc'),
34 | manual: l10n.lookup('prefShowManual'),
35 | params: [
36 | {
37 | name: 'setting',
38 | type: 'setting',
39 | description: l10n.lookup('prefShowSettingDesc'),
40 | manual: l10n.lookup('prefShowSettingManual')
41 | }
42 | ],
43 | exec: function(args, context) {
44 | return l10n.lookupFormat('prefShowSettingValue',
45 | [ args.setting.name, args.setting.value ]);
46 | }
47 | },
48 | {
49 | // 'pref set' command
50 | item: 'command',
51 | name: 'pref set',
52 | description: l10n.lookup('prefSetDesc'),
53 | manual: l10n.lookup('prefSetManual'),
54 | params: [
55 | {
56 | name: 'setting',
57 | type: 'setting',
58 | description: l10n.lookup('prefSetSettingDesc'),
59 | manual: l10n.lookup('prefSetSettingManual')
60 | },
61 | {
62 | name: 'value',
63 | type: 'settingValue',
64 | description: l10n.lookup('prefSetValueDesc'),
65 | manual: l10n.lookup('prefSetValueManual')
66 | }
67 | ],
68 | exec: function(args, context) {
69 | args.setting.value = args.value;
70 | }
71 | },
72 | {
73 | // 'pref reset' command
74 | item: 'command',
75 | name: 'pref reset',
76 | description: l10n.lookup('prefResetDesc'),
77 | manual: l10n.lookup('prefResetManual'),
78 | params: [
79 | {
80 | name: 'setting',
81 | type: 'setting',
82 | description: l10n.lookup('prefResetSettingDesc'),
83 | manual: l10n.lookup('prefResetSettingManual')
84 | }
85 | ],
86 | exec: function(args, context) {
87 | args.setting.setDefault();
88 | }
89 | }
90 | ];
91 |
--------------------------------------------------------------------------------
/lib/gcli/commands/server/exec.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var host = require('../../util/host');
20 | var l10n = require('../../util/l10n');
21 | var cli = require('../../cli');
22 |
23 | exports.items = [
24 | {
25 | // 'cd' command
26 | item: 'command',
27 | name: 'cd',
28 | description: l10n.lookup('cdDesc'),
29 | manual: l10n.lookup('cdManual'),
30 | params: [
31 | {
32 | name: 'directory',
33 | type: {
34 | name: 'file',
35 | filetype: 'directory',
36 | existing: 'yes'
37 | },
38 | description: l10n.lookup('cdDirectoryDesc')
39 | }
40 | ],
41 | returnType: 'string',
42 | exec: function(args, context) {
43 | context.shell.cwd = args.directory;
44 | return l10n.lookupFormat('cdOutput', [ context.shell.cwd ]);
45 | }
46 | },
47 | {
48 | // 'exec' command
49 | item: 'command',
50 | name: 'exec',
51 | description: l10n.lookup('execDesc'),
52 | manual: l10n.lookup('execManual'),
53 | params: [
54 | {
55 | name: 'command',
56 | type: 'string',
57 | description: l10n.lookup('execCommandDesc')
58 | }
59 | ],
60 | returnType: 'output',
61 | exec: function(args, context) {
62 | var cmdArgs = cli.tokenize(args.command).map(function(arg) {
63 | return arg.text;
64 | });
65 | var cmd = cmdArgs.shift();
66 |
67 | var spawnSpec = {
68 | cmd: cmd,
69 | args: cmdArgs,
70 | env: context.shell.env,
71 | cwd: context.shell.cwd
72 | };
73 |
74 | return host.spawn(context, spawnSpec).then(function(output) {
75 | if (output.code === 0) {
76 | return output;
77 | }
78 |
79 | throw output.data;
80 | }, function(output) {
81 | throw output.data;
82 | });
83 | }
84 | },
85 | {
86 | // How we display the output of a generic exec command: we have to assume
87 | // that it is a string to be displayed in a monospaced font
88 | item: 'converter',
89 | from: 'output',
90 | to: 'view',
91 | exec: function(output, context) {
92 | return {
93 | html: '
${output.data}
',
94 | data: { output: output }
95 | };
96 | }
97 | },
98 | {
99 | item: 'converter',
100 | from: 'output',
101 | to: 'string',
102 | exec: function(output, context) {
103 | return output.data;
104 | }
105 | }
106 | ];
107 |
--------------------------------------------------------------------------------
/lib/gcli/commands/server/exit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.items = [
20 | {
21 | item: 'command',
22 | name: 'exit',
23 | description: 'Quit from GCLI',
24 | exec: function(args, context) {
25 | process.exit(0);
26 | }
27 | }
28 | ];
29 |
--------------------------------------------------------------------------------
/lib/gcli/commands/server/orion.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var copy = require('dryice').copy;
20 | var fs = require('fs');
21 | var path = require('path');
22 |
23 | /**
24 | * 'orion' build command
25 | */
26 | exports.items = [
27 | {
28 | item: 'command',
29 | name: 'orion',
30 | description: 'Build the Orion-GCLI target',
31 | params: [
32 | {
33 | name: 'location',
34 | type: {
35 | name: 'file',
36 | filetype: 'directory',
37 | existing: 'yes'
38 | },
39 | defaultValue: process.env.ORION_HOME || undefined,
40 | description: 'The location of the org.eclipse.orion.client checkout'
41 | }
42 | ],
43 | returnType: 'string',
44 | exec: function(args, context) {
45 | var gcliHome = path.dirname(require.main.filename);
46 | var root = path.normalize(args.location);
47 | var dest = path.join(root, 'bundles/org.eclipse.orion.client.ui/web/gcli');
48 | var count = 0;
49 |
50 | if (!fs.existsSync(dest)) {
51 | throw new Error('\'' + dest + '\' does not exist.');
52 | }
53 |
54 | var stats = fs.statSync(dest);
55 | if (!stats.isDirectory()) {
56 | throw new Error('\'' + dest + '\' is not a directory.');
57 | }
58 |
59 | var output = 'Building GCLI files for Orion';
60 | output += '\n Source = ' + gcliHome;
61 | output += '\n Dest = ' + dest;
62 |
63 | var logCopy = function(filename) {
64 | output += '\n ' + filename.substr(dest.length + 1);
65 | count++;
66 | return filename;
67 | };
68 |
69 | output += '\nCopying:';
70 | copy({
71 | source: gcliHome + '/LICENSE',
72 | dest: dest + '/LICENSE'
73 | });
74 | logCopy(dest + '/LICENSE');
75 |
76 | output += '\nCopying (and adding AMD headers):';
77 | copy({
78 | source: { root: gcliHome + '/lib/gcli' },
79 | filenameFilter: logCopy,
80 | filter: defineFilter,
81 | dest: dest + '/gcli'
82 | });
83 |
84 | output += '\nCopying (and adding AMD headers):';
85 | copy({
86 | source: { root: gcliHome + '/web/gcli' },
87 | filenameFilter: logCopy,
88 | filter: defineFilter,
89 | dest: dest + '/gcli'
90 | });
91 |
92 | output += '\nCopied ' + count + ' files';
93 |
94 | return output;
95 | }
96 | }
97 | ];
98 |
99 | /**
100 | * A filter to munge CommonJS headers
101 | */
102 | var defineFilter = function(input, source) {
103 | var output = input.toString();
104 |
105 | if (source.path.match(/\.js$/)) {
106 | output = output.replace(/(["'](do not )?use strict[\"\'];)/,
107 | 'define(function(require, exports, module) {\n\n$1');
108 | output += '\n\n});\n';
109 | }
110 |
111 | return output;
112 | };
113 | defineFilter.onRead = true;
114 |
--------------------------------------------------------------------------------
/lib/gcli/commands/server/standard.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var copy = require('dryice').copy;
20 | var path = require('path');
21 |
22 | exports.items = [
23 | {
24 | // 'standard' build command
25 | // There are 2 important ways to build GCLI.
26 | // The first is for use within a normal web page.
27 | // It has compressed and uncompressed versions of the output script file.
28 | item: 'command',
29 | name: 'standard',
30 | description: 'Build the basic GCLI web target',
31 | returnType: 'terminal',
32 | exec: function(args, context) {
33 | var log = 'Building standard outputs to built/gcli[-uncompressed].js\n';
34 |
35 | copy.mkdirSync(path.dirname(require.main.filename) + '/built', 493 /*0755*/);
36 | var project = copy.createCommonJsProject({
37 | roots: [ path.dirname(require.main.filename) + '/lib' ]
38 | });
39 | var sources = copy.createDataObject();
40 |
41 | copy({
42 | source: {
43 | project: project,
44 | // This list of dependencies should reflect index.html
45 | require: [ 'gcli/index', 'gcli/demo' ]
46 | },
47 | filter: copy.filter.moduleDefines,
48 | dest: sources
49 | });
50 | copy({
51 | source: { root: project, include: /.*\.png$|.*\.gif$/ },
52 | filter: copy.filter.base64,
53 | dest: sources
54 | });
55 | log += project.report() + '\n';
56 |
57 | // Create a GraphML dependency report. Directions:
58 | // - Install yEd (http://www.yworks.com/en/products_yed_about.htm)
59 | // - Load gcli/built/gcli.graphml
60 | // - Resize the nodes (Tools->Fit Node to Label)
61 | // - Apply a layout (Layout->Hierarchical)
62 | log += 'Outputting dependency graph to built/gcli.graphml\n';
63 | if (project.getDependencyGraphML) {
64 | copy({
65 | source: { value:project.getDependencyGraphML() },
66 | dest: 'built/gcli.graphml'
67 | });
68 | }
69 |
70 | // Create the output scripts, compressed and uncompressed
71 | copy({ source: 'index.html', filter: tweakIndex, dest: 'built/index.html' });
72 | copy({
73 | source: [ copy.getMiniRequire(), sources ],
74 | dest: 'built/gcli-uncompressed.js'
75 | });
76 | try {
77 | copy({
78 | source: [ copy.getMiniRequire(), sources ],
79 | filter: copy.filter.uglifyjs,
80 | dest: 'built/gcli.js'
81 | });
82 | }
83 | catch (ex) {
84 | log += 'ERROR: Uglify compression fails on windows/linux. ' +
85 | 'Skipping creation of built/gcli.js\n';
86 | }
87 | return log;
88 | }
89 | }
90 | ];
91 |
92 | /**
93 | * Filter index.html to:
94 | * - Make links relative, we flatten out the scripts directory
95 | * - Replace require.js with the built GCLI script file
96 | * - Remove the RequireJS configuration
97 | */
98 | function tweakIndex(data) {
99 | return data
100 | .replace(/scripts\/require.js/, 'gcli-uncompressed.js')
101 | .replace(/\s*requirejs.config\([^;]*;\n/, '');
102 | }
103 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/connectors.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is how to implement a connector
21 | * var baseConnector = {
22 | * item: 'connector',
23 | * name: 'foo',
24 | *
25 | * connect: function(url) {
26 | * return Promise.resolve(new FooConnection(url));
27 | * }
28 | * };
29 | */
30 |
31 | /**
32 | * A prototype base for Connectors
33 | */
34 | function Connection() {
35 | }
36 |
37 | /**
38 | * Add an event listener
39 | */
40 | Connection.prototype.on = function(event, action) {
41 | if (!this._listeners) {
42 | this._listeners = {};
43 | }
44 | if (!this._listeners[event]) {
45 | this._listeners[event] = [];
46 | }
47 | this._listeners[event].push(action);
48 | };
49 |
50 | /**
51 | * Remove an event listener
52 | */
53 | Connection.prototype.off = function(event, action) {
54 | if (!this._listeners) {
55 | return;
56 | }
57 | var actions = this._listeners[event];
58 | if (actions) {
59 | this._listeners[event] = actions.filter(function(li) {
60 | return li !== action;
61 | }.bind(this));
62 | }
63 | };
64 |
65 | /**
66 | * Emit an event. For internal use only
67 | */
68 | Connection.prototype._emit = function(event, data) {
69 | if (this._listeners == null || this._listeners[event] == null) {
70 | return;
71 | }
72 |
73 | var listeners = this._listeners[event];
74 | listeners.forEach(function(listener) {
75 | // Fail fast if we mutate the list of listeners while emitting
76 | if (listeners !== this._listeners[event]) {
77 | throw new Error('Listener list changed while emitting');
78 | }
79 |
80 | try {
81 | listener.call(null, data);
82 | }
83 | catch (ex) {
84 | console.log('Error calling listeners to ' + event);
85 | console.error(ex);
86 | }
87 | }.bind(this));
88 | };
89 |
90 | /**
91 | * Send a message to the other side of the connection
92 | */
93 | Connection.prototype.call = function(feature, data) {
94 | throw new Error('Not implemented');
95 | };
96 |
97 | /**
98 | * Disconnecting a Connection destroys the resources it holds. There is no
99 | * common route back to being connected once this has been called
100 | */
101 | Connection.prototype.disconnect = function() {
102 | return Promise.resolve();
103 | };
104 |
105 | exports.Connection = Connection;
106 |
107 | /**
108 | * A manager for the registered Connectors
109 | */
110 | function Connectors() {
111 | // This is where we cache the connectors that we know about
112 | this._registered = {};
113 | }
114 |
115 | /**
116 | * Add a new connector to the cache
117 | */
118 | Connectors.prototype.add = function(connector) {
119 | this._registered[connector.name] = connector;
120 | };
121 |
122 | /**
123 | * Remove an existing connector from the cache
124 | */
125 | Connectors.prototype.remove = function(connector) {
126 | var name = typeof connector === 'string' ? connector : connector.name;
127 | delete this._registered[name];
128 | };
129 |
130 | /**
131 | * Get access to the list of known connectors
132 | */
133 | Connectors.prototype.getAll = function() {
134 | return Object.keys(this._registered).map(function(name) {
135 | return this._registered[name];
136 | }.bind(this));
137 | };
138 |
139 | var defaultConnectorName;
140 |
141 | /**
142 | * Get access to a connector by name. If name is undefined then first try to
143 | * use the same connector that we used last time, and if there was no last
144 | * time, then just use the first registered connector as a default.
145 | */
146 | Connectors.prototype.get = function(name) {
147 | if (name == null) {
148 | name = (defaultConnectorName == null) ?
149 | Object.keys(this._registered)[0] :
150 | defaultConnectorName;
151 | }
152 |
153 | defaultConnectorName = name;
154 | return this._registered[name];
155 | };
156 |
157 | exports.Connectors = Connectors;
158 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/front.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * Asynchronous construction. Use GcliFront();
21 | * @private
22 | */
23 | function GcliFront() {
24 | throw new Error('Use GcliFront.create().then(front => ...)');
25 | }
26 |
27 | /**
28 | *
29 | */
30 | GcliFront.create = function(connector, url) {
31 | return connector.connect(url).then(function(connection) {
32 | var front = Object.create(GcliFront.prototype);
33 | return front._init(connection);
34 | });
35 | };
36 |
37 | /**
38 | * Asynchronous construction. Use GcliFront();
39 | * @private
40 | */
41 | GcliFront.prototype._init = function(connection) {
42 | this.connection = connection;
43 | return this;
44 | };
45 |
46 | GcliFront.prototype.on = function(eventName, action) {
47 | this.connection.on(eventName, action);
48 | };
49 |
50 | GcliFront.prototype.off = function(eventName, action) {
51 | this.connection.off(eventName, action);
52 | };
53 |
54 |
55 | GcliFront.prototype.specs = function() {
56 | var data = {
57 | };
58 | return this.connection.call('specs', data);
59 | };
60 |
61 | GcliFront.prototype.execute = function(typed) {
62 | var data = {
63 | typed: typed
64 | };
65 | return this.connection.call('execute', data);
66 | };
67 |
68 | GcliFront.prototype.parseFile = function(typed, filetype, existing, matches) {
69 | var data = {
70 | typed: typed,
71 | filetype: filetype,
72 | existing: existing,
73 | matches: matches
74 | };
75 | return this.connection.call('parseFile', data);
76 | };
77 |
78 | GcliFront.prototype.parseType = function(typed, paramName) {
79 | var data = {
80 | typed: typed,
81 | paramName: paramName
82 | };
83 | return this.connection.call('parseType', data);
84 | };
85 |
86 | GcliFront.prototype.nudgeType = function(typed, by, paramName) {
87 | var data = {
88 | typed: typed,
89 | by: by,
90 | paramName: paramName
91 | };
92 | return this.connection.call('nudgeType', by, data);
93 | };
94 |
95 | GcliFront.prototype.getSelectionLookup = function(commandName, paramName) {
96 | var data = {
97 | commandName: commandName,
98 | paramName: paramName
99 | };
100 | return this.connection.call('getSelectionLookup', data);
101 | };
102 |
103 | GcliFront.prototype.system = function(cmd, args, cwd, env) {
104 | var data = {
105 | cmd: cmd,
106 | args: args,
107 | cwd: cwd,
108 | env: env
109 | };
110 | return this.connection.call('system', data);
111 | };
112 |
113 | exports.GcliFront = GcliFront;
114 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var createSystem = require('../system').createSystem;
20 | var connectFront = require('../system').connectFront;
21 | var GcliFront = require('./front').GcliFront;
22 |
23 | // Patch-up IE9
24 | require('../util/legacy');
25 |
26 | /**
27 | * Connect to a remote system and setup the commands/types/converters etc needed
28 | * to make it all work
29 | */
30 | exports.createSystem = function(options) {
31 | options = options || {};
32 |
33 | var system = createSystem();
34 |
35 | // The items that are always needed on the client
36 | var items = [
37 | require('../items/basic').items,
38 | require('../items/ui').items,
39 | require('../items/remote').items,
40 | // The context command makes no sense on the server
41 | require('../commands/context').items,
42 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
43 | system.addItems(items);
44 |
45 | // These are the commands stored on the remote side that have converters which
46 | // we'll need to present the data. Ideally front.specs() would transfer these,
47 | // that doesn't happen yet so we add them manually
48 | var requiredConverters = [
49 | require('../cli').items,
50 | require('../commands/clear').items,
51 | require('../commands/connect').items,
52 | require('../commands/global').items,
53 | require('../commands/help').items,
54 | require('../commands/intro').items,
55 | require('../commands/lang').items,
56 | require('../commands/preflist').items,
57 | require('../commands/pref').items,
58 | require('../commands/test').items,
59 | ].reduce(function(prev, curr) { return prev.concat(curr); }, [])
60 | .filter(function(item) { return item.item === 'converter'; });
61 | system.addItems(requiredConverters);
62 |
63 | var connector = system.connectors.get(options.method);
64 | return GcliFront.create(connector, options.url).then(function(front) {
65 | return connectFront(system, front).then(function() {
66 | return system;
67 | });
68 | });
69 | };
70 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/protocol.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a quick and dirty stub that allows us to write code in remoted.js
21 | * that looks like gcli.js
22 | */
23 | exports.method = function(func, spec) {
24 | // An array of strings, being the names of the parameters
25 | var argSpecs = [];
26 | if (spec.request != null) {
27 | Object.keys(spec.request).forEach(function(name) {
28 | var arg = spec.request[name];
29 | argSpecs[arg.index] = name;
30 | });
31 | }
32 |
33 | return function(data) {
34 | var args = (data == null) ?
35 | [] :
36 | argSpecs.map(function(name) { return data[name]; });
37 | return func.apply(this, args);
38 | };
39 | };
40 |
41 | var Arg = exports.Arg = function(index, type) {
42 | if (this == null) {
43 | return new Arg(index, type);
44 | }
45 |
46 | this.index = index;
47 | this.type = type;
48 | };
49 |
50 | var RetVal = exports.RetVal = function(type) {
51 | if (this == null) {
52 | return new RetVal(type);
53 | }
54 |
55 | this.type = type;
56 | };
57 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/websocket.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var Connection = require('./connectors').Connection;
20 |
21 | exports.items = [
22 | {
23 | // Communicate with a remote server over XMLHttpRequest
24 | item: 'connector',
25 | name: 'websocket',
26 |
27 | connect: function(url) {
28 | url = url || exports.document.location.origin;
29 |
30 | if (connections[url] == null) {
31 | connections[url] = new Promise(function(resolve, reject) {
32 | var io = require('socket.io-client');
33 | var socket = io.connect(url);
34 | var wsc = new WebsocketConnection(socket, url);
35 |
36 | // What to do when a reply is received
37 | socket.on('reply', wsc.onReply);
38 |
39 | socket.on('event', wsc.onEvent);
40 |
41 | socket.on('connected', function() {
42 | resolve(wsc);
43 | });
44 |
45 | socket.on('connect_error', function() {
46 | reject(wsc);
47 | });
48 | }.bind(this));
49 | }
50 | return connections[url];
51 | }
52 | }
53 | ];
54 |
55 | /**
56 | * We only connect once to each URL
57 | */
58 | var connections = {};
59 |
60 | /**
61 | * The ability to add functionality by adding a new script tag is specific to
62 | * a browser, so this code is not going to work in NodeJS/Firefox etc.
63 | * We export the document that we are using so multi-frame environments can
64 | * update the default document
65 | */
66 | exports.document = typeof document !== 'undefined' ? document : undefined;
67 |
68 | /**
69 | * Handle a 'session' in which we make a number of calls
70 | */
71 | function WebsocketConnection(socket, url) {
72 | this.socket = socket;
73 | this.url = url;
74 |
75 | this.deferreds = {};
76 | this.nextRequestId = 0;
77 |
78 | this.onReply = this.onReply.bind(this);
79 | this.onEvent = this.onEvent.bind(this);
80 | }
81 |
82 | WebsocketConnection.prototype = Object.create(Connection.prototype);
83 |
84 | /**
85 | * Connect a websocket reply to the request that caused it
86 | */
87 | WebsocketConnection.prototype.onReply = function(res) {
88 | var deferred = this.deferreds[res.id];
89 | if (deferred == null) {
90 | throw new Error('Unknown id \'' + res.id + '\'');
91 | }
92 |
93 | if (res.reply) {
94 | deferred.resolve(res.reply);
95 | }
96 | else {
97 | deferred.reject(res.exception);
98 | }
99 |
100 | delete this.deferreds[res.id];
101 | };
102 |
103 | /**
104 | * Connect a websocket reply to the request that caused it
105 | */
106 | WebsocketConnection.prototype.onEvent = function(res) {
107 | this._emit(res.name, res.data);
108 | };
109 |
110 | /**
111 | * Kill this connection
112 | */
113 | WebsocketConnection.prototype.disconnect = function() {
114 | Object.keys(this.deferreds).forEach(function(id) {
115 | this.deferreds[id].reject('Disconnected');
116 | }.bind(this));
117 |
118 | return Promise.resolve(undefined);
119 | };
120 |
121 | /**
122 | * Initiate a websocket call using socket.io
123 | * @param command The name of the exposed feature. See server.js:remoted for
124 | * the remoted function
125 | * @param data The block of data to pass to the exposed feature. See the docs
126 | * for the exposed feature for what properties are required
127 | * @return A promise of the data returned by the remote feature
128 | */
129 | WebsocketConnection.prototype.call = function(command, data) {
130 | return new Promise(function(resolve, reject) {
131 | var id = this.nextRequestId++;
132 | this.deferreds[id] = { resolve: resolve, reject: reject };
133 |
134 | this.socket.emit(command, { id: id, data: data });
135 | }.bind(this));
136 | };
137 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/websocketserver.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var socketio = require('socket.io');
4 |
5 | var util = require('../util/util');
6 | var cli = require('../cli');
7 | var Remoter = require('./remoted').Remoter;
8 |
9 | /**
10 | * Start a web-socket server from an existing express server
11 | */
12 | exports.init = function(server, context) {
13 | // To debug socket.io:
14 | // DEBUG=* node yourfile.js
15 | // or in the browser:
16 | // localStorage.debug='*';
17 | // And then filter by the scopes you’re interested in.
18 | // You can use , to separate them.
19 | var io = socketio.listen(server);
20 | exports.useSocket(io, context);
21 | };
22 |
23 | /**
24 | * Link to an existing web-socket server
25 | */
26 | exports.useSocket = function(io, context) {
27 | io.sockets.on('connection', function(socket) {
28 | // Tell the browser that we're up and running
29 | socket.emit('connected');
30 |
31 | var requisition = cli.getMapping(context).requisition;
32 | var remoter = new Remoter(requisition);
33 |
34 | remoter.addListener(function(name, data) {
35 | // console.log('EMIT ' + name + ' ' + debugStr(data, 30));
36 | socket.emit('event', { name: name, data: data });
37 | });
38 |
39 | Object.keys(remoter.exposed).forEach(function(command) {
40 | socket.on(command, function(request) {
41 | // Handle errors from exceptions an promise rejections
42 | var onError = function(err) {
43 | console.log('SOCKET ' + command +
44 | '(' + debugStr(request.data, 30) + ') Exception');
45 | util.errorHandler(err);
46 |
47 | socket.emit('reply', {
48 | id: request.id,
49 | exception: '' + err
50 | });
51 | };
52 |
53 | try {
54 | var func = remoter.exposed[command];
55 | var reply = func.call(remoter, request.data);
56 | Promise.resolve(reply).then(function(data) {
57 | console.log('SOCKET ' + command +
58 | '(' + debugStr(request.data, 30) + ') → ' +
59 | debugStr(data, 20) + ')');
60 |
61 | socket.emit('reply', {
62 | id: request.id,
63 | reply: data
64 | });
65 | }, onError);
66 | }
67 | catch (ex) {
68 | onError(ex);
69 | }
70 | });
71 | });
72 | });
73 | };
74 |
75 | /**
76 | * Get a quick one line debug summary of an object
77 | */
78 | function debugStr(obj) {
79 | var summary = JSON.stringify(obj) || '';
80 | return summary.length > 40 ? summary.substr(0, 39) + '…' : summary;
81 | }
82 |
--------------------------------------------------------------------------------
/lib/gcli/connectors/xhr.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var Connection = require('./connectors').Connection;
20 |
21 | exports.items = [
22 | {
23 | // Communicate with a remote server over XMLHttpRequest
24 | item: 'connector',
25 | name: 'xhr',
26 |
27 | connect: function(url) {
28 | // TODO: store the url and use it
29 | // Ignore host and port for now. Assume local connection
30 | return Promise.resolve(new XhrConnection());
31 | }
32 | }
33 | ];
34 |
35 | /**
36 | * Make remote calls using XMLHttpRequest.
37 | * Note this connection method does not support server initiated events. Use
38 | * WebsocketConnection if you need that.
39 | */
40 | function XhrConnection() {
41 | }
42 |
43 | XhrConnection.prototype = Object.create(Connection.prototype);
44 |
45 | /**
46 | * Initiate an XHR call
47 | * See server.js:remoted for details on the remoted functions
48 | * @param command The name of the exposed feature.
49 | * @param data The block of data to pass to the exposed feature
50 | * @return Promise of the data returned by the remote feature
51 | */
52 | XhrConnection.prototype.call = function(command, data) {
53 | return new Promise(function(resolve, reject) {
54 | var xhr = new XMLHttpRequest();
55 | xhr.open('POST', '/' + command, true);
56 | xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
57 |
58 | xhr.onreadystatechange = function(event) {
59 | if (xhr.readyState === 4) {
60 | if (xhr.status >= 300 || xhr.status < 200) {
61 | reject({
62 | data: xhr.responseText,
63 | code: xhr.status
64 | });
65 | }
66 | else {
67 | var output = JSON.parse(xhr.responseText);
68 | resolve(output);
69 | }
70 | }
71 | }.bind(this);
72 |
73 | xhr.send(JSON.stringify(data));
74 | }.bind(this));
75 | };
76 |
--------------------------------------------------------------------------------
/lib/gcli/converters/basic.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 |
21 | /**
22 | * Several converters are just data.toString inside a 'p' element
23 | */
24 | function nodeFromDataToString(data, conversionContext) {
25 | var node = util.createElement(conversionContext.document, 'p');
26 | node.textContent = data.toString();
27 | return node;
28 | }
29 |
30 | exports.items = [
31 | {
32 | item: 'converter',
33 | from: 'string',
34 | to: 'dom',
35 | exec: nodeFromDataToString
36 | },
37 | {
38 | item: 'converter',
39 | from: 'number',
40 | to: 'dom',
41 | exec: nodeFromDataToString
42 | },
43 | {
44 | item: 'converter',
45 | from: 'boolean',
46 | to: 'dom',
47 | exec: nodeFromDataToString
48 | },
49 | {
50 | item: 'converter',
51 | from: 'undefined',
52 | to: 'dom',
53 | exec: function(data, conversionContext) {
54 | return util.createElement(conversionContext.document, 'span');
55 | }
56 | },
57 | {
58 | item: 'converter',
59 | from: 'json',
60 | to: 'view',
61 | exec: function(json, context) {
62 | var html = JSON.stringify(json, null, ' ').replace(/\n/g, ' ');
63 | return {
64 | html: '
' + html + '
'
65 | };
66 | }
67 | },
68 | {
69 | item: 'converter',
70 | from: 'number',
71 | to: 'string',
72 | exec: function(data) { return '' + data; }
73 | },
74 | {
75 | item: 'converter',
76 | from: 'boolean',
77 | to: 'string',
78 | exec: function(data) { return '' + data; }
79 | },
80 | {
81 | item: 'converter',
82 | from: 'undefined',
83 | to: 'string',
84 | exec: function(data) { return ''; }
85 | },
86 | {
87 | item: 'converter',
88 | from: 'json',
89 | to: 'string',
90 | exec: function(json, conversionContext) {
91 | return JSON.stringify(json, null, ' ');
92 | }
93 | }
94 | ];
95 |
--------------------------------------------------------------------------------
/lib/gcli/converters/html.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 |
21 | /**
22 | * 'html' means a string containing HTML markup. We use innerHTML to inject
23 | * this into a DOM which has security implications, so this module will not
24 | * be used in all implementations.
25 | */
26 | exports.items = [
27 | {
28 | item: 'converter',
29 | from: 'html',
30 | to: 'dom',
31 | exec: function(html, conversionContext) {
32 | var div = util.createElement(conversionContext.document, 'div');
33 | div.innerHTML = html;
34 | return div;
35 | }
36 | },
37 | {
38 | item: 'converter',
39 | from: 'html',
40 | to: 'string',
41 | exec: function(html, conversionContext) {
42 | var div = util.createElement(conversionContext.document, 'div');
43 | div.innerHTML = html;
44 | return div.textContent;
45 | }
46 | }
47 | ];
48 |
--------------------------------------------------------------------------------
/lib/gcli/converters/terminal.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 |
21 | /**
22 | * A 'terminal' object is a string or an array of strings, which are typically
23 | * the output from a shell command
24 | */
25 | exports.items = [
26 | {
27 | item: 'converter',
28 | from: 'terminal',
29 | to: 'dom',
30 | createTextArea: function(text, conversionContext) {
31 | var node = util.createElement(conversionContext.document, 'textarea');
32 | node.classList.add('gcli-row-subterminal');
33 | node.readOnly = true;
34 | node.textContent = text;
35 | return node;
36 | },
37 | exec: function(data, conversionContext) {
38 | if (Array.isArray(data)) {
39 | var node = util.createElement(conversionContext.document, 'div');
40 | data.forEach(function(member) {
41 | node.appendChild(this.createTextArea(member, conversionContext));
42 | });
43 | return node;
44 | }
45 | return this.createTextArea(data);
46 | }
47 | },
48 | {
49 | item: 'converter',
50 | from: 'terminal',
51 | to: 'string',
52 | exec: function(data, conversionContext) {
53 | return Array.isArray(data) ? data.join('') : '' + data;
54 | }
55 | }
56 | ];
57 |
--------------------------------------------------------------------------------
/lib/gcli/fields/delegate.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 | var Field = require('./fields').Field;
21 |
22 | /**
23 | * A field that works with delegate types by delaying resolution until that
24 | * last possible time
25 | */
26 | function DelegateField(type, options) {
27 | Field.call(this, type, options);
28 | this.options = options;
29 |
30 | this.element = util.createElement(this.document, 'div');
31 | this.update();
32 |
33 | this.onFieldChange = util.createEvent('DelegateField.onFieldChange');
34 | }
35 |
36 | DelegateField.prototype = Object.create(Field.prototype);
37 |
38 | DelegateField.prototype.update = function() {
39 | var subtype = this.type.getType(this.options.requisition.executionContext);
40 | if (typeof subtype.parse !== 'function') {
41 | subtype = this.options.requisition.system.types.createType(subtype);
42 | }
43 |
44 | // It's not clear that we can compare subtypes in this way.
45 | // Perhaps we need a type.equals(...) function
46 | if (subtype === this.subtype) {
47 | return;
48 | }
49 |
50 | if (this.field) {
51 | this.field.destroy();
52 | }
53 |
54 | this.subtype = subtype;
55 | var fields = this.options.requisition.system.fields;
56 | this.field = fields.get(subtype, this.options);
57 |
58 | util.clearElement(this.element);
59 | this.element.appendChild(this.field.element);
60 | };
61 |
62 | DelegateField.claim = function(type, context) {
63 | return type.isDelegate ? Field.MATCH : Field.NO_MATCH;
64 | };
65 |
66 | DelegateField.prototype.destroy = function() {
67 | this.element = undefined;
68 | this.options = undefined;
69 | if (this.field) {
70 | this.field.destroy();
71 | }
72 | this.subtype = undefined;
73 | Field.prototype.destroy.call(this);
74 | };
75 |
76 | DelegateField.prototype.setConversion = function(conversion) {
77 | this.field.setConversion(conversion);
78 | };
79 |
80 | DelegateField.prototype.getConversion = function() {
81 | return this.field.getConversion();
82 | };
83 |
84 | Object.defineProperty(DelegateField.prototype, 'isImportant', {
85 | get: function() {
86 | return this.field.isImportant;
87 | },
88 | enumerable: true
89 | });
90 |
91 | /**
92 | * Exported items
93 | */
94 | exports.items = [
95 | DelegateField
96 | ];
97 |
--------------------------------------------------------------------------------
/lib/gcli/fields/selection.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 | var Menu = require('../ui/menu').Menu;
21 |
22 | var Argument = require('../types/types').Argument;
23 | var Conversion = require('../types/types').Conversion;
24 | var Field = require('./fields').Field;
25 |
26 | /**
27 | * A field that allows selection of one of a number of options
28 | */
29 | function SelectionField(type, options) {
30 | Field.call(this, type, options);
31 |
32 | this.arg = new Argument();
33 |
34 | this.menu = new Menu({
35 | document: this.document,
36 | maxPredictions: Conversion.maxPredictions
37 | });
38 | this.element = this.menu.element;
39 |
40 | this.onFieldChange = util.createEvent('SelectionField.onFieldChange');
41 |
42 | // i.e. Register this.onItemClick as the default action for a menu click
43 | this.menu.onItemClick.add(this.itemClicked, this);
44 | }
45 |
46 | SelectionField.prototype = Object.create(Field.prototype);
47 |
48 | SelectionField.claim = function(type, context) {
49 | if (context == null) {
50 | return Field.NO_MATCH;
51 | }
52 | return type.getType(context).hasPredictions ? Field.DEFAULT : Field.NO_MATCH;
53 | };
54 |
55 | SelectionField.prototype.destroy = function() {
56 | this.menu.onItemClick.remove(this.itemClicked, this);
57 | this.menu.destroy();
58 | this.menu = undefined;
59 | this.element = undefined;
60 | Field.prototype.destroy.call(this);
61 | };
62 |
63 | SelectionField.prototype.setConversion = function(conversion) {
64 | this.arg = conversion.arg;
65 | this.setMessage(conversion.message);
66 |
67 | var context = this.requisition.executionContext;
68 | conversion.getPredictions(context).then(function(predictions) {
69 | var items = predictions.map(function(prediction) {
70 | // If the prediction value is an 'item' (that is an object with a name and
71 | // description) then use that, otherwise use the prediction itself, because
72 | // at least that has a name.
73 | return prediction.value && prediction.value.description ?
74 | prediction.value :
75 | prediction;
76 | }, this);
77 | if (this.menu != null) {
78 | this.menu.show(items, conversion.arg.text);
79 | }
80 | }.bind(this)).catch(util.errorHandler);
81 | };
82 |
83 | SelectionField.prototype.itemClicked = function(ev) {
84 | var arg = new Argument(ev.name, '', ' ');
85 | var context = this.requisition.executionContext;
86 |
87 | this.type.parse(arg, context).then(function(conversion) {
88 | this.onFieldChange({ conversion: conversion });
89 | this.setMessage(conversion.message);
90 | }.bind(this)).catch(util.errorHandler);
91 | };
92 |
93 | SelectionField.prototype.getConversion = function() {
94 | // This tweaks the prefix/suffix of the argument to fit
95 | this.arg = this.arg.beget({ text: this.input.value });
96 | return this.type.parse(this.arg, this.requisition.executionContext);
97 | };
98 |
99 | /**
100 | * Allow the terminal to use RETURN to chose the current menu item when
101 | * it can't execute the command line
102 | * @return true if an item was 'clicked', false otherwise
103 | */
104 | SelectionField.prototype.selectChoice = function() {
105 | var selected = this.menu.selected;
106 | if (selected == null) {
107 | return false;
108 | }
109 |
110 | this.itemClicked({ name: selected });
111 | return true;
112 | };
113 |
114 | Object.defineProperty(SelectionField.prototype, 'isImportant', {
115 | get: function() {
116 | return this.type.name !== 'command';
117 | },
118 | enumerable: true
119 | });
120 |
121 | /**
122 | * Allow registration and de-registration.
123 | */
124 | exports.items = [ SelectionField ];
125 |
--------------------------------------------------------------------------------
/lib/gcli/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /*
20 | * The intent of this module is to pull together all the parts needed to start
21 | * a command line to make it easier to get started.
22 | *
23 | * Basic usage is like this:
24 | *
25 | * var gcli = require('gcli/index');
26 | *
27 | * // A system is a set of commands/types/etc that the command line uses
28 | * var system = gcli.createSystem();
29 | * system.addItems(gcli.items);
30 | * system.addItems(gcli.commandItems);
31 | * system.addItems([
32 | * // Your own commands go here
33 | * ]);
34 | *
35 | * // Create the UI
36 | * gcli.createTerminal(system).then(function(terminal) {
37 | * // Take any actions when the command line starts for example
38 | * terminal.language.showIntro();
39 | * });
40 | */
41 |
42 | // Patch-up old browsers
43 | require('./util/legacy');
44 |
45 | exports.createSystem = require('./system').createSystem;
46 |
47 | var Terminal = require('./ui/terminal').Terminal;
48 | exports.createTerminal = Terminal.create.bind(Terminal);
49 |
50 | /**
51 | * This is all the items we need for a basic GCLI (except for the commands)
52 | */
53 | exports.items = [
54 | require('./items/basic').items,
55 | require('./items/ui').items,
56 | require('./items/remote').items,
57 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
58 |
59 | exports.commandItems = require('./items/standard').items;
60 |
--------------------------------------------------------------------------------
/lib/gcli/items/basic.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of the types and converters that will be needed in almost all
21 | * command lines. The types are listed in 2 sets because delegate and selection
22 | * are depended on by others, (e.g boolean depends on selection) and array is
23 | * built into cli.js parsing somewhat.
24 | *
25 | * Keeping this module small helps reduce bringing in unwanted dependencies.
26 | */
27 | exports.items = [
28 | require('../types/delegate').items,
29 | require('../types/selection').items,
30 | require('../types/array').items,
31 |
32 | require('../types/boolean').items,
33 | require('../types/command').items,
34 | require('../types/date').items,
35 | require('../types/javascript').items,
36 | require('../types/node').items,
37 | require('../types/number').items,
38 | require('../types/resource').items,
39 | require('../types/setting').items,
40 | require('../types/string').items,
41 | require('../types/union').items,
42 | require('../types/url').items,
43 |
44 | require('../converters/converters').items,
45 | require('../converters/basic').items,
46 | require('../converters/html').items,
47 | require('../converters/terminal').items,
48 |
49 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
50 |
--------------------------------------------------------------------------------
/lib/gcli/items/demo.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of demo commands.
21 | *
22 | * Keeping this module small helps reduce bringing in unwanted dependencies.
23 | */
24 | exports.items = [
25 | require('../commands/demo/alert').items,
26 | require('../commands/demo/demo').items,
27 | require('../commands/demo/echo').items,
28 | require('../commands/demo/sleep').items,
29 |
30 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
31 |
--------------------------------------------------------------------------------
/lib/gcli/items/remote.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of the available connectors when linking to GCLIs together
21 | *
22 | * Keeping this module small helps reduce bringing in unwanted dependencies.
23 | */
24 | exports.items = [
25 | require('../connectors/websocket').items,
26 | require('../connectors/xhr').items,
27 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
28 |
--------------------------------------------------------------------------------
/lib/gcli/items/server.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of the commands designed to run in nodejs / io.js.
21 | *
22 | * Keeping this module small helps reduce bringing in unwanted dependencies.
23 | */
24 | exports.items = [
25 | require('../types/file').items,
26 |
27 | require('../commands/server/exec').items,
28 | require('../commands/server/exit').items,
29 | require('../commands/server/firefox').items,
30 | require('../commands/server/orion').items,
31 | require('../commands/server/server').items,
32 | require('../commands/server/standard').items
33 |
34 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
35 |
--------------------------------------------------------------------------------
/lib/gcli/items/standard.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of the standard commands that are likely to be in most
21 | * command lines.
22 | *
23 | * Keeping this module small helps reduce bringing in unwanted dependencies.
24 | */
25 | exports.items = [
26 | require('../cli').items,
27 | require('../commands/clear').items,
28 | require('../commands/connect').items,
29 | require('../commands/context').items,
30 | require('../commands/global').items,
31 | require('../commands/help').items,
32 | require('../commands/intro').items,
33 | require('../commands/lang').items,
34 | require('../commands/mocks').items,
35 | require('../commands/pref').items,
36 | require('../commands/preflist').items,
37 | require('../commands/test').items,
38 |
39 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
40 |
--------------------------------------------------------------------------------
/lib/gcli/items/ui.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This is a list of the fields, settings and languages that we need to build
21 | * a user interface.
22 | *
23 | * Keeping this module small helps reduce bringing in unwanted dependencies.
24 | */
25 | exports.items = [
26 | require('../fields/fields').items,
27 | require('../fields/delegate').items,
28 | require('../fields/selection').items,
29 |
30 | require('../ui/focus').items,
31 | require('../ui/intro').items,
32 |
33 | require('../languages/command').items,
34 | require('../languages/javascript').items,
35 |
36 | ].reduce(function(prev, curr) { return prev.concat(curr); }, []);
37 |
--------------------------------------------------------------------------------
/lib/gcli/languages/command.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 | :${output.typed}
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/gcli/languages/javascript.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var host = require('../util/host');
20 | var prism = require('../util/prism').Prism;
21 |
22 | function isMultiline(text) {
23 | return typeof text === 'string' && text.indexOf('\n') > -1;
24 | }
25 |
26 | exports.items = [
27 | {
28 | // Language implementation for Javascript
29 | item: 'language',
30 | name: 'javascript',
31 | prompt: '>',
32 |
33 | constructor: function(terminal) {
34 | this.document = terminal.document;
35 | this.focusManager = terminal.focusManager;
36 |
37 | this.updateHints();
38 | },
39 |
40 | destroy: function() {
41 | this.document = undefined;
42 | },
43 |
44 | exec: function(input) {
45 | return this.evaluate(input).then(function(response) {
46 | var output = (response.exception != null) ?
47 | response.exception.class :
48 | response.output;
49 |
50 | var isSameString = typeof output === 'string' &&
51 | input.substr(1, input.length - 2) === output;
52 | var isSameOther = typeof output !== 'string' &&
53 | input === '' + output;
54 |
55 | // Place strings in quotes
56 | if (typeof output === 'string' && response.exception == null) {
57 | if (output.indexOf('\'') === -1) {
58 | output = '\'' + output + '\'';
59 | }
60 | else {
61 | output = output.replace(/\\/, '\\').replace(/"/, '"').replace(/'/, '\'');
62 | output = '"' + output + '"';
63 | }
64 | }
65 |
66 | var line;
67 | if (isSameString || isSameOther || output === undefined) {
68 | line = input;
69 | }
70 | else if (isMultiline(output)) {
71 | line = input + '\n/*\n' + output + '\n*/';
72 | }
73 | else {
74 | line = input + ' // ' + output;
75 | }
76 |
77 | var grammar = prism.languages[this.name];
78 | return prism.highlight(line, grammar, this.name);
79 | }.bind(this));
80 | },
81 |
82 | evaluate: function(input) {
83 | return host.script.evaluate(input);
84 | }
85 | }
86 | ];
87 |
--------------------------------------------------------------------------------
/lib/gcli/test/automators/requisition.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var KeyEvent = require('../../util/util').KeyEvent;
20 |
21 | /**
22 | * See notes in helpers.checkOptions()
23 | */
24 | exports.createRequisitionAutomator = function(requisition) {
25 | var cursor = { start: 0, end: 0 };
26 | var typed = '';
27 | var index = 0;
28 |
29 | var updateCursor = function() {
30 | cursor.start = typed.length;
31 | cursor.end = typed.length;
32 | };
33 |
34 | var automator = {
35 | setInput: function(t) {
36 | typed = t;
37 | updateCursor();
38 | return requisition.update(t);
39 | },
40 |
41 | setCursor: function(c) {
42 | cursor.start = c.start;
43 | cursor.end = c.end;
44 | },
45 |
46 | focus: function() {
47 | },
48 |
49 | getInputState: function() {
50 | return {
51 | typed: typed,
52 | cursor: { start: cursor.start, end: cursor.end }
53 | };
54 | },
55 |
56 | getErrorMessage: function() {
57 | return requisition.getStatusMessage();
58 | },
59 |
60 | getCompleterTemplateData: function() {
61 | // See also language/command:getCompleterTemplateData
62 | return requisition.getStateData(cursor.start, index);
63 | },
64 |
65 | fakeKey: function(keyCode) {
66 | if (keyCode === KeyEvent.DOM_VK_BACK_SPACE) {
67 | typed = typed.slice(0, -1);
68 | }
69 | if (keyCode === KeyEvent.DOM_VK_TAB) {
70 | return requisition.complete(cursor, index).then(function(updated) {
71 | // Abort UI changes if this UI update has been overtaken
72 | if (updated) {
73 | index = 0;
74 | }
75 | });
76 | }
77 | if (keyCode === KeyEvent.DOM_VK_UP) {
78 | index++;
79 | }
80 | if (keyCode === KeyEvent.DOM_VK_DOWN) {
81 | index--;
82 | }
83 | if (keyCode === KeyEvent.DOM_VK_RETURN) {
84 | throw new Error('Fake DOM_VK_RETURN not supported');
85 | }
86 | typed = requisition.toString();
87 | updateCursor();
88 | },
89 |
90 | destroy: function() {
91 | }
92 | };
93 |
94 | Object.defineProperty(automator, 'focusManager', {
95 | get: function() { return null; },
96 | enumerable: true
97 | });
98 |
99 | Object.defineProperty(automator, 'field', {
100 | get: function() { return null; },
101 | enumerable: true
102 | });
103 |
104 | return automator;
105 | };
106 |
--------------------------------------------------------------------------------
/lib/gcli/test/automators/terminal.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * See notes in helpers.checkOptions()
21 | */
22 | exports.createTerminalAutomator = function(terminal) {
23 | var automator = {
24 | setInput: function(typed) {
25 | return terminal.setInput(typed);
26 | },
27 |
28 | setCursor: function(cursor) {
29 | return terminal.language.setCursor(cursor);
30 | },
31 |
32 | focus: function() {
33 | return terminal.focus();
34 | },
35 |
36 | getInputState: function() {
37 | return terminal.getInputState();
38 | },
39 |
40 | getErrorMessage: function() {
41 | return terminal.errorEle.textContent;
42 | },
43 |
44 | getCompleterTemplateData: function() {
45 | return terminal.language.getCompleterTemplateData();
46 | },
47 |
48 | fakeKey: function(keyCode) {
49 | var fakeEvent = {
50 | keyCode: keyCode,
51 | preventDefault: function() { },
52 | timeStamp: new Date().getTime()
53 | };
54 |
55 | terminal.onKeyDown(fakeEvent);
56 |
57 | if (keyCode === 8 /*KeyEvent.DOM_VK_BACK_SPACE*/) {
58 | terminal.inputElement.value = terminal.inputElement.value.slice(0, -1);
59 | }
60 |
61 | return terminal.handleKeyUp(fakeEvent);
62 | }
63 | };
64 |
65 | Object.defineProperty(automator, 'focusManager', {
66 | get: function() { return terminal.focusManager; },
67 | enumerable: true
68 | });
69 |
70 | Object.defineProperty(automator, 'field', {
71 | get: function() { return terminal.field; },
72 | enumerable: true
73 | });
74 |
75 | return automator;
76 | };
77 |
--------------------------------------------------------------------------------
/lib/gcli/test/mockDocument.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var usingMockDocument = false;
20 |
21 | /**
22 | * Registration and de-registration.
23 | */
24 | exports.setup = function(requisition) {
25 | if (requisition.environment.window == null) {
26 | var jsdom = require('jsdom').jsdom;
27 | var document = jsdom('' +
28 | '' +
29 | '' +
30 | ' ' +
31 | ' ' +
32 | '' +
33 | '' +
34 | '' +
35 | '' +
36 | '');
37 | requisition.environment.window = document.defaultView;
38 |
39 | usingMockDocument = true;
40 | }
41 | };
42 |
43 | exports.shutdown = function(requisition) {
44 | if (usingMockDocument) {
45 | requisition.environment.window = undefined;
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/lib/gcli/test/mockSettings.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.tempTBoolSpec = {
20 | name: 'tempTBool',
21 | type: 'boolean',
22 | description: 'temporary default true boolean',
23 | defaultValue: true
24 | };
25 | exports.tempTBool = undefined;
26 |
27 | var tempFBoolSpec = {
28 | name: 'tempFBool',
29 | type: 'boolean',
30 | description: 'temporary default false boolean',
31 | defaultValue: false
32 | };
33 | exports.tempFBool = undefined;
34 |
35 | var tempUStringSpec = {
36 | name: 'tempUString',
37 | type: 'string',
38 | description: 'temporary default undefined string'
39 | };
40 | exports.tempUString = undefined;
41 |
42 | var tempNStringSpec = {
43 | name: 'tempNString',
44 | type: 'string',
45 | description: 'temporary default undefined string',
46 | defaultValue: null
47 | };
48 | exports.tempNString = undefined;
49 |
50 | var tempQStringSpec = {
51 | name: 'tempQString',
52 | type: 'string',
53 | description: 'temporary default "q" string',
54 | defaultValue: 'q'
55 | };
56 | exports.tempQString = undefined;
57 |
58 | var tempNumberSpec = {
59 | name: 'tempNumber',
60 | type: 'number',
61 | description: 'temporary number',
62 | defaultValue: 42
63 | };
64 | exports.tempNumber = undefined;
65 |
66 | var tempSelectionSpec = {
67 | name: 'tempSelection',
68 | type: { name: 'selection', data: [ 'a', 'b', 'c' ] },
69 | description: 'temporary selection',
70 | defaultValue: 'a'
71 | };
72 | exports.tempSelection = undefined;
73 |
74 | /**
75 | * Registration and de-registration.
76 | */
77 | exports.setup = function(system) {
78 | exports.tempTBool = system.settings.add(exports.tempTBoolSpec);
79 | exports.tempFBool = system.settings.add(tempFBoolSpec);
80 | exports.tempUString = system.settings.add(tempUStringSpec);
81 | exports.tempNString = system.settings.add(tempNStringSpec);
82 | exports.tempQString = system.settings.add(tempQStringSpec);
83 | exports.tempNumber = system.settings.add(tempNumberSpec);
84 | exports.tempSelection = system.settings.add(tempSelectionSpec);
85 | };
86 |
87 | exports.shutdown = function(system) {
88 | system.settings.remove(exports.tempTBoolSpec);
89 | system.settings.remove(tempFBoolSpec);
90 | system.settings.remove(tempUStringSpec);
91 | system.settings.remove(tempNStringSpec);
92 | system.settings.remove(tempQStringSpec);
93 | system.settings.remove(tempNumberSpec);
94 | system.settings.remove(tempSelectionSpec);
95 |
96 | exports.tempTBool = undefined;
97 | exports.tempFBool = undefined;
98 | exports.tempUString = undefined;
99 | exports.tempNString = undefined;
100 | exports.tempQString = undefined;
101 | exports.tempNumber = undefined;
102 | exports.tempSelection = undefined;
103 | };
104 |
--------------------------------------------------------------------------------
/lib/gcli/test/suite.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | // We need to make sure GCLI is initialized before we begin testing it
20 | require('../index');
21 | var examiner = require('../testharness/examiner');
22 |
23 | exports.init = function(isNode) {
24 | // It's tempting to want to unify these strings and make addSuite() do the
25 | // call to require(), however that breaks the build system which looks for
26 | // the strings passed to require
27 | examiner.addSuite('testAsync', require('./testAsync'));
28 | examiner.addSuite('testCanon', require('./testCanon'));
29 | examiner.addSuite('testCli1', require('./testCli1'));
30 | examiner.addSuite('testCli2', require('./testCli2'));
31 | examiner.addSuite('testCompletion1', require('./testCompletion1'));
32 | examiner.addSuite('testCompletion2', require('./testCompletion2'));
33 | examiner.addSuite('testContext', require('./testContext'));
34 | examiner.addSuite('testDate', require('./testDate'));
35 | examiner.addSuite('testExec', require('./testExec'));
36 | examiner.addSuite('testFail', require('./testFail'));
37 |
38 | if (isNode) {
39 | examiner.addSuite('testFile', require('./testFile'));
40 | examiner.addSuite('testFileparser', require('./testFileparser'));
41 | examiner.addSuite('testFilesystem', require('./testFilesystem'));
42 | }
43 |
44 | examiner.addSuite('testFocus', require('./testFocus'));
45 | examiner.addSuite('testHelp', require('./testHelp'));
46 | examiner.addSuite('testHistory', require('./testHistory'));
47 | examiner.addSuite('testInputter', require('./testInputter'));
48 | examiner.addSuite('testIncomplete', require('./testIncomplete'));
49 | examiner.addSuite('testIntro', require('./testIntro'));
50 | examiner.addSuite('testJs', require('./testJs'));
51 | examiner.addSuite('testKeyboard1', require('./testKeyboard1'));
52 | examiner.addSuite('testKeyboard2', require('./testKeyboard2'));
53 | examiner.addSuite('testKeyboard3', require('./testKeyboard3'));
54 | examiner.addSuite('testKeyboard4', require('./testKeyboard4'));
55 | examiner.addSuite('testKeyboard5', require('./testKeyboard5'));
56 | examiner.addSuite('testMenu', require('./testMenu'));
57 | examiner.addSuite('testNode', require('./testNode'));
58 | examiner.addSuite('testPref1', require('./testPref1'));
59 | examiner.addSuite('testPref2', require('./testPref2'));
60 | examiner.addSuite('testRemoteXhr', require('./testRemoteXhr'));
61 | // Loading 2 different remoting systems at a time breaks
62 | //examiner.addSuite('testRemoteWs', require('./testRemoteWs'));
63 | examiner.addSuite('testResource', require('./testResource'));
64 | examiner.addSuite('testSettings', require('./testSettings'));
65 | examiner.addSuite('testShort', require('./testShort'));
66 | examiner.addSuite('testSpell', require('./testSpell'));
67 | examiner.addSuite('testSplit', require('./testSplit'));
68 | examiner.addSuite('testString', require('./testString'));
69 | examiner.addSuite('testTokenize', require('./testTokenize'));
70 | examiner.addSuite('testTooltip', require('./testTooltip'));
71 | examiner.addSuite('testTypes', require('./testTypes'));
72 | examiner.addSuite('testUnion', require('./testUnion'));
73 | examiner.addSuite('testUrl', require('./testUrl'));
74 | };
75 |
--------------------------------------------------------------------------------
/lib/gcli/test/testAsync.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testBasic = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | setup: 'tsslo',
25 | check: {
26 | input: 'tsslo',
27 | hints: 'w',
28 | markup: 'IIIII',
29 | cursor: 5,
30 | current: '__command',
31 | status: 'ERROR',
32 | predictions: ['tsslow'],
33 | unassigned: [ ]
34 | }
35 | },
36 | {
37 | setup: 'tsslo',
38 | check: {
39 | input: 'tsslow ',
40 | hints: 'Shalom',
41 | markup: 'VVVVVVV',
42 | cursor: 7,
43 | current: 'hello',
44 | status: 'ERROR',
45 | predictions: [
46 | 'Shalom', 'Namasté', 'Hallo', 'Dydd-da', 'Chào', 'Hej',
47 | 'Saluton', 'Sawubona'
48 | ],
49 | unassigned: [ ],
50 | args: {
51 | command: { name: 'tsslow' },
52 | hello: {
53 | arg: '',
54 | status: 'INCOMPLETE'
55 | },
56 | }
57 | }
58 | },
59 | {
60 | setup: 'tsslow S',
61 | check: {
62 | input: 'tsslow S',
63 | hints: 'halom',
64 | markup: 'VVVVVVVI',
65 | cursor: 8,
66 | current: 'hello',
67 | status: 'ERROR',
68 | predictions: [ 'Shalom', 'Saluton', 'Sawubona', 'Namasté' ],
69 | unassigned: [ ],
70 | args: {
71 | command: { name: 'tsslow' },
72 | hello: {
73 | arg: ' S',
74 | status: 'INCOMPLETE'
75 | },
76 | }
77 | }
78 | },
79 | {
80 | setup: 'tsslow S',
81 | check: {
82 | input: 'tsslow Shalom ',
83 | hints: '',
84 | markup: 'VVVVVVVVVVVVVV',
85 | cursor: 14,
86 | current: 'hello',
87 | status: 'VALID',
88 | predictions: [ 'Shalom' ],
89 | unassigned: [ ],
90 | args: {
91 | command: { name: 'tsslow' },
92 | hello: {
93 | arg: ' Shalom ',
94 | status: 'VALID',
95 | message: ''
96 | },
97 | }
98 | }
99 | }
100 | ]);
101 | };
102 |
--------------------------------------------------------------------------------
/lib/gcli/test/testFail.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testBasic = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | setup: 'tsfail reject',
25 | exec: {
26 | output: 'rejected promise',
27 | type: 'error',
28 | error: true
29 | }
30 | },
31 | {
32 | setup: 'tsfail rejecttyped',
33 | exec: {
34 | output: '54',
35 | type: 'number',
36 | error: true
37 | }
38 | },
39 | {
40 | setup: 'tsfail throwerror',
41 | exec: {
42 | output: /thrown error$/,
43 | type: 'error',
44 | error: true
45 | }
46 | },
47 | {
48 | setup: 'tsfail throwstring',
49 | exec: {
50 | output: 'thrown string',
51 | type: 'error',
52 | error: true
53 | }
54 | },
55 | {
56 | setup: 'tsfail noerror',
57 | exec: {
58 | output: 'no error',
59 | type: 'string',
60 | error: false
61 | }
62 | }
63 | ]);
64 | };
65 |
--------------------------------------------------------------------------------
/lib/gcli/test/testFileparser.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var fileparser = require('../util/fileparser');
21 |
22 | var local = false;
23 |
24 | exports.testGetPredictor = function(options) {
25 | if (!options.isNode || !local) {
26 | assert.log('Skipping tests due to install differences.');
27 | return;
28 | }
29 |
30 | var opts = { filetype: 'file', existing: 'yes' };
31 | var predictor = fileparser.getPredictor('/usr/locl/bin/nmp', opts);
32 | return predictor().then(function(replies) {
33 | assert.is(replies[0].name,
34 | '/usr/local/bin/npm',
35 | 'predict npm');
36 | });
37 | };
38 |
--------------------------------------------------------------------------------
/lib/gcli/test/testFilesystem.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var helpers = require('./helpers');
21 | var filesystem = require('../util/filesystem');
22 |
23 | exports.testSplit = function(options) {
24 | if (!options.isNode) {
25 | return;
26 | }
27 |
28 | helpers.arrayIs(filesystem.split('', '/'),
29 | [ '.' ],
30 | 'split ');
31 |
32 | helpers.arrayIs(filesystem.split('a', '/'),
33 | [ 'a' ],
34 | 'split a');
35 |
36 | helpers.arrayIs(filesystem.split('a/b/c', '/'),
37 | [ 'a', 'b', 'c' ],
38 | 'split a/b/c');
39 |
40 | helpers.arrayIs(filesystem.split('/a/b/c/', '/'),
41 | [ 'a', 'b', 'c' ],
42 | 'split a/b/c');
43 |
44 | helpers.arrayIs(filesystem.split('/a/b///c/', '/'),
45 | [ 'a', 'b', 'c' ],
46 | 'split a/b/c');
47 | };
48 |
49 | exports.testJoin = function(options) {
50 | if (!options.isNode) {
51 | return;
52 | }
53 |
54 | assert.is(filesystem.join('usr', 'local', 'bin'),
55 | 'usr/local/bin',
56 | 'join to usr/local/bin');
57 | };
58 |
--------------------------------------------------------------------------------
/lib/gcli/test/testFocus.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testBasic = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | name: 'exec setup',
25 | setup: function() {
26 | // Just check that we've got focus, and everything is clear
27 | helpers.focusInput(options);
28 | return helpers.setInput(options, 'echo hi');
29 | },
30 | check: { },
31 | exec: { }
32 | },
33 | {
34 | setup: 'tsn deep',
35 | check: {
36 | input: 'tsn deep',
37 | hints: ' down nested cmd',
38 | markup: 'IIIVIIII',
39 | cursor: 8,
40 | status: 'ERROR',
41 | outputState: 'false:default',
42 | tooltipState: 'false:default'
43 | }
44 | },
45 | {
46 | setup: 'tsn deep',
47 | check: {
48 | input: 'tsn deep down nested cmd ',
49 | hints: '',
50 | markup: 'VVVVVVVVVVVVVVVVVVVVVVVVV',
51 | cursor: 25,
52 | status: 'VALID',
53 | outputState: 'false:default',
54 | tooltipState: 'false:default'
55 | }
56 | }
57 | ]);
58 | };
59 |
--------------------------------------------------------------------------------
/lib/gcli/test/testHistory.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var History = require('../ui/history').History;
21 |
22 | exports.testSimpleHistory = function (options) {
23 | var history = new History({});
24 | history.add('foo');
25 | history.add('bar');
26 | assert.is(history.backward(), 'bar');
27 | assert.is(history.backward(), 'foo');
28 |
29 | // Adding to the history again moves us back to the start of the history.
30 | history.add('quux');
31 | assert.is(history.backward(), 'quux');
32 | assert.is(history.backward(), 'bar');
33 | assert.is(history.backward(), 'foo');
34 | };
35 |
36 | exports.testBackwardsPastIndex = function (options) {
37 | var history = new History({});
38 | history.add('foo');
39 | history.add('bar');
40 | assert.is(history.backward(), 'bar');
41 | assert.is(history.backward(), 'foo');
42 |
43 | // Moving backwards past recorded history just keeps giving you the last
44 | // item.
45 | assert.is(history.backward(), 'foo');
46 | };
47 |
48 | exports.testForwardsPastIndex = function (options) {
49 | var history = new History({});
50 | history.add('foo');
51 | history.add('bar');
52 | assert.is(history.backward(), 'bar');
53 | assert.is(history.backward(), 'foo');
54 |
55 | // Going forward through the history again.
56 | assert.is(history.forward(), 'bar');
57 |
58 | // 'Present' time.
59 | assert.is(history.forward(), '');
60 |
61 | // Going to the 'future' just keeps giving us the empty string.
62 | assert.is(history.forward(), '');
63 | };
64 |
--------------------------------------------------------------------------------
/lib/gcli/test/testInputter.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var KeyEvent = require('../util/util').KeyEvent;
21 |
22 | var latestEvent;
23 | var latestData;
24 |
25 | var outputted = function(ev) {
26 | latestEvent = ev;
27 |
28 | ev.output.promise.then(function() {
29 | latestData = ev.output.data;
30 | });
31 | };
32 |
33 |
34 | exports.setup = function(options) {
35 | options.requisition.commandOutputManager.onOutput.add(outputted);
36 | };
37 |
38 | exports.shutdown = function(options) {
39 | options.requisition.commandOutputManager.onOutput.remove(outputted);
40 | };
41 |
42 | exports.testOutput = function(options) {
43 | latestEvent = undefined;
44 | latestData = undefined;
45 |
46 | var terminal = options.terminal;
47 | if (!terminal) {
48 | assert.log('Skipping testInputter.testOutput due to lack of terminal.');
49 | return;
50 | }
51 |
52 | var focusManager = terminal.focusManager;
53 |
54 | terminal.setInput('tss');
55 |
56 | var ev0 = { keyCode: KeyEvent.DOM_VK_RETURN };
57 | terminal.onKeyDown(ev0);
58 |
59 | assert.is(terminal.getInputState().typed,
60 | 'tss',
61 | 'terminal should do nothing on RETURN keyDown');
62 | assert.is(latestEvent, undefined, 'no events this test');
63 | assert.is(latestData, undefined, 'no data this test');
64 |
65 | var ev1 = { keyCode: KeyEvent.DOM_VK_RETURN };
66 | return terminal.handleKeyUp(ev1).then(function() {
67 | assert.ok(latestEvent != null, 'events this test');
68 | assert.is(latestData.name, 'tss', 'last command is tss');
69 |
70 | assert.is(terminal.getInputState().typed,
71 | '',
72 | 'terminal should exec on RETURN keyUp');
73 |
74 | assert.ok(focusManager._recentOutput, 'recent output happened');
75 |
76 | var ev2 = { keyCode: KeyEvent.DOM_VK_F1 };
77 | return terminal.handleKeyUp(ev2).then(function() {
78 | assert.ok(!focusManager._recentOutput, 'no recent output happened post F1');
79 | assert.ok(focusManager._helpRequested, 'F1 = help');
80 |
81 | var ev3 = { keyCode: KeyEvent.DOM_VK_ESCAPE };
82 | return terminal.handleKeyUp(ev3).then(function() {
83 | assert.ok(!focusManager._helpRequested, 'ESCAPE = anti help');
84 | });
85 | });
86 |
87 | });
88 | };
89 |
--------------------------------------------------------------------------------
/lib/gcli/test/testIntro.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testIntroStatus = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | skipRemainingIf: function commandIntroMissing() {
25 | return options.requisition.system.commands.get('intro') == null;
26 | },
27 | setup: 'intro',
28 | check: {
29 | typed: 'intro',
30 | markup: 'VVVVV',
31 | status: 'VALID',
32 | hints: ''
33 | }
34 | },
35 | {
36 | setup: 'intro foo',
37 | check: {
38 | typed: 'intro foo',
39 | markup: 'VVVVVVEEE',
40 | status: 'ERROR',
41 | hints: ''
42 | }
43 | },
44 | {
45 | setup: 'intro',
46 | check: {
47 | typed: 'intro',
48 | markup: 'VVVVV',
49 | status: 'VALID',
50 | hints: ''
51 | },
52 | exec: {
53 | output: [
54 | /command\s*line/,
55 | /help/,
56 | /F1/,
57 | /Escape/
58 | ]
59 | }
60 | }
61 | ]);
62 | };
63 |
--------------------------------------------------------------------------------
/lib/gcli/test/testKeyboard1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var javascript = require('../types/javascript');
20 | var helpers = require('./helpers');
21 |
22 | exports.testSimple = function(options) {
23 | return helpers.audit(options, [
24 | {
25 | setup: 'tsela',
26 | check: { input: 'tselarr ', cursor: 8 }
27 | },
28 | {
29 | setup: 'tsn di',
30 | check: { input: 'tsn dif ', cursor: 8 }
31 | },
32 | {
33 | setup: 'tsg a',
34 | check: { input: 'tsg aaa ', cursor: 8 }
35 | }
36 | ]);
37 | };
38 |
39 | exports.testScript = function(options) {
40 | return helpers.audit(options, [
41 | {
42 | skipRemainingIf: options.isRemote ||
43 | options.requisition.system.commands.get('{') == null,
44 | setup: '{ wind',
45 | check: { input: '{ window' }
46 | },
47 | {
48 | setup: '{ window.docum',
49 | check: { input: '{ window.document' }
50 | }
51 | ]);
52 | };
53 |
54 | exports.testJsdom = function(options) {
55 | return helpers.audit(options, [
56 | {
57 | skipIf: options.isRemote ||
58 | options.requisition.system.commands.get('{') == null,
59 | setup: '{ window.document.titl',
60 | check: { input: '{ window.document.title ' }
61 | }
62 | ]);
63 | };
64 |
--------------------------------------------------------------------------------
/lib/gcli/test/testKeyboard2.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testIncr = function(options) {
22 | return helpers.audit(options, [
23 | /*
24 | // We currently refuse to increment/decrement things with a non-valid
25 | // status which makes sense for many cases, and is a decent default.
26 | // However in theory we could do better, these tests are there for then
27 | {
28 | setup: 'tsu -70',
29 | check: { input: 'tsu -5' }
30 | },
31 | {
32 | setup: 'tsu -7',
33 | check: { input: 'tsu -5' }
34 | },
35 | {
36 | setup: 'tsu -6',
37 | check: { input: 'tsu -5' }
38 | },
39 | */
40 | {
41 | setup: 'tsu -5',
42 | check: { input: 'tsu -3' }
43 | },
44 | {
45 | setup: 'tsu -4',
46 | check: { input: 'tsu -3' }
47 | },
48 | {
49 | setup: 'tsu -3',
50 | check: { input: 'tsu 0' }
51 | },
52 | {
53 | setup: 'tsu -2',
54 | check: { input: 'tsu 0' }
55 | },
56 | {
57 | setup: 'tsu -1',
58 | check: { input: 'tsu 0' }
59 | },
60 | {
61 | setup: 'tsu 0',
62 | check: { input: 'tsu 3' }
63 | },
64 | {
65 | setup: 'tsu 1',
66 | check: { input: 'tsu 3' }
67 | },
68 | {
69 | setup: 'tsu 2',
70 | check: { input: 'tsu 3' }
71 | },
72 | {
73 | setup: 'tsu 3',
74 | check: { input: 'tsu 6' }
75 | },
76 | {
77 | setup: 'tsu 4',
78 | check: { input: 'tsu 6' }
79 | },
80 | {
81 | setup: 'tsu 5',
82 | check: { input: 'tsu 6' }
83 | },
84 | {
85 | setup: 'tsu 6',
86 | check: { input: 'tsu 9' }
87 | },
88 | {
89 | setup: 'tsu 7',
90 | check: { input: 'tsu 9' }
91 | },
92 | {
93 | setup: 'tsu 8',
94 | check: { input: 'tsu 9' }
95 | },
96 | {
97 | setup: 'tsu 9',
98 | check: { input: 'tsu 10' }
99 | },
100 | {
101 | setup: 'tsu 10',
102 | check: { input: 'tsu 10' }
103 | }
104 | /*
105 | // See notes above
106 | {
107 | setup: 'tsu 100',
108 | check: { input: 'tsu 10' }
109 | }
110 | */
111 | ]);
112 | };
113 |
--------------------------------------------------------------------------------
/lib/gcli/test/testKeyboard3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testDecr = function(options) {
22 | return helpers.audit(options, [
23 | /*
24 | // See notes at top of testIncr in testKeyboard2.js
25 | {
26 | setup: 'tsu -70',
27 | check: { input: 'tsu -5' }
28 | },
29 | {
30 | setup: 'tsu -7',
31 | check: { input: 'tsu -5' }
32 | },
33 | {
34 | setup: 'tsu -6',
35 | check: { input: 'tsu -5' }
36 | },
37 | */
38 | {
39 | setup: 'tsu -5',
40 | check: { input: 'tsu -5' }
41 | },
42 | {
43 | setup: 'tsu -4',
44 | check: { input: 'tsu -5' }
45 | },
46 | {
47 | setup: 'tsu -3',
48 | check: { input: 'tsu -5' }
49 | },
50 | {
51 | setup: 'tsu -2',
52 | check: { input: 'tsu -3' }
53 | },
54 | {
55 | setup: 'tsu -1',
56 | check: { input: 'tsu -3' }
57 | },
58 | {
59 | setup: 'tsu 0',
60 | check: { input: 'tsu -3' }
61 | },
62 | {
63 | setup: 'tsu 1',
64 | check: { input: 'tsu 0' }
65 | },
66 | {
67 | setup: 'tsu 2',
68 | check: { input: 'tsu 0' }
69 | },
70 | {
71 | setup: 'tsu 3',
72 | check: { input: 'tsu 0' }
73 | },
74 | {
75 | setup: 'tsu 4',
76 | check: { input: 'tsu 3' }
77 | },
78 | {
79 | setup: 'tsu 5',
80 | check: { input: 'tsu 3' }
81 | },
82 | {
83 | setup: 'tsu 6',
84 | check: { input: 'tsu 3' }
85 | },
86 | {
87 | setup: 'tsu 7',
88 | check: { input: 'tsu 6' }
89 | },
90 | {
91 | setup: 'tsu 8',
92 | check: { input: 'tsu 6' }
93 | },
94 | {
95 | setup: 'tsu 9',
96 | check: { input: 'tsu 6' }
97 | },
98 | {
99 | setup: 'tsu 10',
100 | check: { input: 'tsu 9' }
101 | }
102 | /*
103 | // See notes at top of testIncr
104 | {
105 | setup: 'tsu 100',
106 | check: { input: 'tsu 9' }
107 | }
108 | */
109 | ]);
110 | };
111 |
--------------------------------------------------------------------------------
/lib/gcli/test/testKeyboard5.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testCompleteDown = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | setup: 'tsn e',
25 | check: { input: 'tsn exte ' }
26 | },
27 | {
28 | setup: 'tsn e',
29 | check: { input: 'tsn ext ' }
30 | },
31 | {
32 | setup: 'tsn e',
33 | check: { input: 'tsn extend ' }
34 | },
35 | {
36 | setup: 'tsn e',
37 | check: { input: 'tsn exten ' }
38 | },
39 | {
40 | setup: 'tsn e',
41 | check: { input: 'tsn exte ' }
42 | },
43 | {
44 | setup: 'tsn e',
45 | check: { input: 'tsn ext ' }
46 | }
47 | ]);
48 | };
49 |
--------------------------------------------------------------------------------
/lib/gcli/test/testKeyboard6.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testCompleteUp = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | setup: 'tsn e',
25 | check: { input: 'tsn extend ' }
26 | },
27 | {
28 | setup: 'tsn e',
29 | check: { input: 'tsn exten ' }
30 | },
31 | {
32 | setup: 'tsn e',
33 | check: { input: 'tsn exte ' }
34 | },
35 | {
36 | setup: 'tsn e',
37 | check: { input: 'tsn ext ' }
38 | },
39 | {
40 | setup: 'tsn e',
41 | check: { input: 'tsn extend ' }
42 | },
43 | {
44 | setup: 'tsn e',
45 | check: { input: 'tsn exten ' }
46 | },
47 | {
48 | setup: 'tsn e',
49 | check: { input: 'tsn exte ' }
50 | },
51 | {
52 | setup: 'tsn e',
53 | check: { input: 'tsn ext ' }
54 | }
55 | ]);
56 | };
57 |
--------------------------------------------------------------------------------
/lib/gcli/test/testMenu.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testOptions = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | setup: 'tslong',
25 | check: {
26 | input: 'tslong',
27 | markup: 'VVVVVV',
28 | status: 'ERROR',
29 | hints: ' [options]',
30 | args: {
31 | msg: { value: undefined, status: 'INCOMPLETE' },
32 | num: { value: undefined, status: 'VALID' },
33 | sel: { value: undefined, status: 'VALID' },
34 | bool: { value: false, status: 'VALID' },
35 | bool2: { value: false, status: 'VALID' },
36 | sel2: { value: undefined, status: 'VALID' },
37 | num2: { value: undefined, status: 'VALID' }
38 | }
39 | }
40 | }
41 | ]);
42 | };
43 |
--------------------------------------------------------------------------------
/lib/gcli/test/testPref1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var helpers = require('./helpers');
20 |
21 | exports.testPrefShowStatus = function(options) {
22 | return helpers.audit(options, [
23 | {
24 | skipRemainingIf: options.requisition.system.commands.get('pref') == null,
25 | setup: 'pref s',
26 | check: {
27 | typed: 'pref s',
28 | hints: 'et',
29 | markup: 'IIIIVI',
30 | status: 'ERROR'
31 | }
32 | },
33 | {
34 | setup: 'pref show',
35 | check: {
36 | typed: 'pref show',
37 | hints: ' ',
38 | markup: 'VVVVVVVVV',
39 | status: 'ERROR'
40 | }
41 | },
42 | {
43 | setup: 'pref show ',
44 | check: {
45 | typed: 'pref show ',
46 | hints: 'eagerHelper',
47 | markup: 'VVVVVVVVVV',
48 | status: 'ERROR'
49 | }
50 | },
51 | {
52 | setup: 'pref show tempTBo',
53 | check: {
54 | typed: 'pref show tempTBo',
55 | hints: 'ol',
56 | markup: 'VVVVVVVVVVIIIIIII',
57 | status: 'ERROR'
58 | }
59 | },
60 | {
61 | setup: 'pref show tempTBool',
62 | check: {
63 | typed: 'pref show tempTBool',
64 | markup: 'VVVVVVVVVVVVVVVVVVV',
65 | status: 'VALID',
66 | hints: ''
67 | }
68 | },
69 | {
70 | setup: 'pref show tempTBool 4',
71 | check: {
72 | typed: 'pref show tempTBool 4',
73 | markup: 'VVVVVVVVVVVVVVVVVVVVE',
74 | status: 'ERROR',
75 | hints: ''
76 | }
77 | },
78 | {
79 | setup: 'pref show tempNumber 4',
80 | check: {
81 | typed: 'pref show tempNumber 4',
82 | markup: 'VVVVVVVVVVVVVVVVVVVVVE',
83 | status: 'ERROR',
84 | hints: ''
85 | }
86 | }
87 | ]);
88 | };
89 |
90 | exports.testPrefSetStatus = function(options) {
91 | return helpers.audit(options, [
92 | {
93 | skipRemainingIf: options.requisition.system.commands.get('pref') == null,
94 | setup: 'pref s',
95 | check: {
96 | typed: 'pref s',
97 | hints: 'et',
98 | markup: 'IIIIVI',
99 | status: 'ERROR'
100 | }
101 | },
102 | {
103 | setup: 'pref set',
104 | check: {
105 | typed: 'pref set',
106 | hints: ' ',
107 | markup: 'VVVVVVVV',
108 | status: 'ERROR'
109 | }
110 | },
111 | {
112 | setup: 'pref xxx',
113 | check: {
114 | typed: 'pref xxx',
115 | markup: 'IIIIVIII',
116 | status: 'ERROR'
117 | }
118 | },
119 | {
120 | setup: 'pref set ',
121 | check: {
122 | typed: 'pref set ',
123 | hints: 'eagerHelper ',
124 | markup: 'VVVVVVVVV',
125 | status: 'ERROR'
126 | }
127 | },
128 | {
129 | setup: 'pref set tempTBo',
130 | check: {
131 | typed: 'pref set tempTBo',
132 | hints: 'ol ',
133 | markup: 'VVVVVVVVVIIIIIII',
134 | status: 'ERROR'
135 | }
136 | },
137 | {
138 | skipIf: options.isRemote,
139 | setup: 'pref set tempTBool 4',
140 | check: {
141 | typed: 'pref set tempTBool 4',
142 | markup: 'VVVVVVVVVVVVVVVVVVVE',
143 | status: 'ERROR',
144 | hints: ''
145 | }
146 | },
147 | {
148 | setup: 'pref set tempNumber 4',
149 | check: {
150 | typed: 'pref set tempNumber 4',
151 | markup: 'VVVVVVVVVVVVVVVVVVVVV',
152 | status: 'VALID',
153 | hints: ''
154 | }
155 | }
156 | ]);
157 | };
158 |
--------------------------------------------------------------------------------
/lib/gcli/test/testPref2.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var helpers = require('./helpers');
21 | var mockSettings = require('./mockSettings');
22 |
23 | exports.testPrefExec = function(options) {
24 | if (options.requisition.system.commands.get('pref') == null) {
25 | assert.log('Skipping test; missing pref command.');
26 | return;
27 | }
28 |
29 | if (options.isRemote) {
30 | assert.log('Skipping test which assumes local settings.');
31 | return;
32 | }
33 |
34 | assert.is(mockSettings.tempNumber.value, 42, 'set to 42');
35 |
36 | return helpers.audit(options, [
37 | {
38 | // Delegated remote types can't transfer value types so we only test for
39 | // the value of 'value' when we're local
40 | skipIf: options.isRemote,
41 | setup: 'pref set tempNumber 4',
42 | check: {
43 | setting: { value: mockSettings.tempNumber },
44 | args: { value: { value: 4 } }
45 | }
46 | },
47 | {
48 | setup: 'pref set tempNumber 4',
49 | check: {
50 | input: 'pref set tempNumber 4',
51 | hints: '',
52 | markup: 'VVVVVVVVVVVVVVVVVVVVV',
53 | cursor: 21,
54 | current: 'value',
55 | status: 'VALID',
56 | predictions: [ ],
57 | unassigned: [ ],
58 | args: {
59 | command: { name: 'pref set' },
60 | setting: {
61 | arg: ' tempNumber',
62 | status: 'VALID',
63 | message: ''
64 | },
65 | value: {
66 | arg: ' 4',
67 | status: 'VALID',
68 | message: ''
69 | }
70 | }
71 | },
72 | exec: {
73 | output: ''
74 | },
75 | post: function() {
76 | assert.is(mockSettings.tempNumber.value, 4, 'set to 4');
77 | }
78 | },
79 | {
80 | setup: 'pref reset tempNumber',
81 | check: {
82 | args: {
83 | command: { name: 'pref reset' },
84 | setting: { value: mockSettings.tempNumber }
85 | }
86 | },
87 | exec: {
88 | output: ''
89 | },
90 | post: function() {
91 | assert.is(mockSettings.tempNumber.value, 42, 'reset to 42');
92 | }
93 | },
94 | {
95 | skipRemainingIf: function commandPrefListMissing() {
96 | return options.requisition.system.commands.get('pref list') == null;
97 | },
98 | setup: 'pref list tempNum',
99 | check: {
100 | args: {
101 | command: { name: 'pref list' },
102 | search: { value: 'tempNum' }
103 | }
104 | },
105 | exec: {
106 | output: /tempNum/
107 | }
108 | },
109 | ]);
110 | };
111 |
--------------------------------------------------------------------------------
/lib/gcli/test/testSpell.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009 Panagiotis Astithas
3 | * Permission to use, copy, modify, and distribute this software for any
4 | * purpose with or without fee is hereby granted, provided that the above
5 | * copyright notice and this permission notice appear in all copies.
6 | *
7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 | */
15 |
16 | 'use strict';
17 |
18 | var assert = require('../testharness/assert');
19 | var spell = require('../util/spell');
20 |
21 | exports.testSpellerSimple = function(options) {
22 | var alternatives = [
23 | 'window', 'document', 'InstallTrigger', 'requirejs', 'require','define',
24 | 'console', 'location', 'constructor', 'getInterface', 'external', 'sidebar'
25 | ];
26 |
27 | assert.is(spell.correct('document', alternatives), 'document');
28 | assert.is(spell.correct('documen', alternatives), 'document');
29 | assert.is(spell.correct('ocument', alternatives), 'document');
30 | assert.is(spell.correct('odcument', alternatives), 'document');
31 |
32 | assert.is(spell.correct('=========', alternatives), undefined);
33 | };
34 |
35 | exports.testRank = function(options) {
36 | var distances = spell.rank('fred', [ 'banana', 'fred', 'ed', 'red', 'FRED' ]);
37 |
38 | assert.is(distances.length, 5, 'rank length');
39 |
40 | assert.is(distances[0].name, 'fred', 'fred name #0');
41 | assert.is(distances[1].name, 'FRED', 'FRED name #1');
42 | assert.is(distances[2].name, 'red', 'red name #2');
43 | assert.is(distances[3].name, 'ed', 'ed name #3');
44 | assert.is(distances[4].name, 'banana', 'banana name #4');
45 |
46 | assert.is(distances[0].dist, 0, 'fred dist 0');
47 | assert.is(distances[1].dist, 4, 'FRED dist 4');
48 | assert.is(distances[2].dist, 10, 'red dist 10');
49 | assert.is(distances[3].dist, 20, 'ed dist 20');
50 | assert.is(distances[4].dist, 100, 'banana dist 100');
51 | };
52 |
53 | exports.testRank2 = function(options) {
54 | var distances = spell.rank('caps', [ 'CAPS', 'false' ]);
55 | assert.is(JSON.stringify(distances),
56 | '[{"name":"CAPS","dist":4},{"name":"false","dist":50}]',
57 | 'spell.rank("caps", [ "CAPS", "false" ]');
58 | };
59 |
60 | exports.testDistancePrefix = function(options) {
61 | assert.is(spell.distancePrefix('fred', 'freddy'), 0, 'distancePrefix fred');
62 | assert.is(spell.distancePrefix('FRED', 'freddy'), 4, 'distancePrefix FRED');
63 | };
64 |
--------------------------------------------------------------------------------
/lib/gcli/test/testSplit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 |
21 | var cli = require('../cli');
22 |
23 | exports.testSplitSimple = function(options) {
24 | var args = cli.tokenize('s');
25 | options.requisition._split(args);
26 | assert.is(args.length, 0);
27 | assert.is(options.requisition.commandAssignment.arg.text, 's');
28 | };
29 |
30 | exports.testFlatCommand = function(options) {
31 | var args = cli.tokenize('tsv');
32 | options.requisition._split(args);
33 | assert.is(args.length, 0);
34 | assert.is(options.requisition.commandAssignment.value.name, 'tsv');
35 |
36 | args = cli.tokenize('tsv a b');
37 | options.requisition._split(args);
38 | assert.is(options.requisition.commandAssignment.value.name, 'tsv');
39 | assert.is(args.length, 2);
40 | assert.is(args[0].text, 'a');
41 | assert.is(args[1].text, 'b');
42 | };
43 |
44 | exports.testJavascript = function(options) {
45 | if (!options.requisition.system.commands.get('{')) {
46 | assert.log('Skipping testJavascript because { is not registered');
47 | return;
48 | }
49 |
50 | var args = cli.tokenize('{');
51 | options.requisition._split(args);
52 | assert.is(args.length, 1);
53 | assert.is(args[0].text, '');
54 | assert.is(options.requisition.commandAssignment.arg.text, '');
55 | assert.is(options.requisition.commandAssignment.value.name, '{');
56 | };
57 |
58 | // BUG 663081 - add tests for sub commands
59 |
--------------------------------------------------------------------------------
/lib/gcli/test/testTooltip.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var helpers = require('./helpers');
21 |
22 | exports.testActivate = function(options) {
23 | return helpers.audit(options, [
24 | {
25 | setup: ' ',
26 | check: {
27 | input: ' ',
28 | hints: '',
29 | markup: 'V',
30 | cursor: 1,
31 | current: '__command',
32 | status: 'ERROR',
33 | message: '',
34 | unassigned: [ ],
35 | outputState: 'false:default',
36 | tooltipState: 'false:default'
37 | }
38 | },
39 | {
40 | setup: 'tsb ',
41 | check: {
42 | input: 'tsb ',
43 | hints: 'false',
44 | markup: 'VVVV',
45 | cursor: 4,
46 | current: 'toggle',
47 | status: 'VALID',
48 | options: [ 'false', 'true' ],
49 | message: '',
50 | predictions: [ 'false', 'true' ],
51 | unassigned: [ ],
52 | outputState: 'false:default',
53 | tooltipState: 'true:importantFieldFlag'
54 | }
55 | },
56 | {
57 | setup: 'tsb t',
58 | check: {
59 | input: 'tsb t',
60 | hints: 'rue',
61 | markup: 'VVVVI',
62 | cursor: 5,
63 | current: 'toggle',
64 | status: 'ERROR',
65 | options: [ 'true' ],
66 | message: '',
67 | predictions: [ 'true' ],
68 | unassigned: [ ],
69 | outputState: 'false:default',
70 | tooltipState: 'true:importantFieldFlag'
71 | }
72 | },
73 | {
74 | setup: 'tsb tt',
75 | check: {
76 | input: 'tsb tt',
77 | hints: ' -> true',
78 | markup: 'VVVVII',
79 | cursor: 6,
80 | current: 'toggle',
81 | status: 'ERROR',
82 | options: [ 'true' ],
83 | message: '',
84 | predictions: [ 'true' ],
85 | unassigned: [ ],
86 | outputState: 'false:default',
87 | tooltipState: 'true:importantFieldFlag'
88 | }
89 | },
90 | {
91 | setup: 'wxqy',
92 | check: {
93 | input: 'wxqy',
94 | hints: '',
95 | markup: 'EEEE',
96 | cursor: 4,
97 | current: '__command',
98 | status: 'ERROR',
99 | options: [ ],
100 | message: 'Can\'t use \'wxqy\'.',
101 | predictions: [ ],
102 | unassigned: [ ],
103 | outputState: 'false:default',
104 | tooltipState: 'true:isError'
105 | }
106 | },
107 | {
108 | setup: '',
109 | check: {
110 | input: '',
111 | hints: '',
112 | markup: '',
113 | cursor: 0,
114 | current: '__command',
115 | status: 'ERROR',
116 | message: '',
117 | unassigned: [ ],
118 | outputState: 'false:default',
119 | tooltipState: 'false:default'
120 | }
121 | }
122 | ]);
123 | };
124 |
--------------------------------------------------------------------------------
/lib/gcli/test/testTypes.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var util = require('../util/util');
21 |
22 | function forEachType(options, templateTypeSpec, callback) {
23 | var types = options.requisition.system.types;
24 | return util.promiseEach(types.getTypeNames(), function(name) {
25 | var typeSpec = {};
26 | util.copyProperties(templateTypeSpec, typeSpec);
27 | typeSpec.name = name;
28 | typeSpec.requisition = options.requisition;
29 |
30 | // Provide some basic defaults to help selection/delegate/array work
31 | if (name === 'selection') {
32 | typeSpec.data = [ 'a', 'b' ];
33 | }
34 | else if (name === 'delegate') {
35 | typeSpec.delegateType = function() {
36 | return 'string';
37 | };
38 | }
39 | else if (name === 'array') {
40 | typeSpec.subtype = 'string';
41 | }
42 | else if (name === 'remote') {
43 | return;
44 | }
45 | else if (name === 'union') {
46 | typeSpec.alternatives = [{ name: 'string' }];
47 | }
48 | else if (options.isRemote) {
49 | if (name === 'node' || name === 'nodelist') {
50 | return;
51 | }
52 | }
53 |
54 | var type = types.createType(typeSpec);
55 | var reply = callback(type);
56 | return Promise.resolve(reply);
57 | });
58 | }
59 |
60 | exports.testDefault = function(options) {
61 | return forEachType(options, {}, function(type) {
62 | var context = options.requisition.executionContext;
63 | var blank = type.getBlank(context).value;
64 |
65 | // boolean and array types are exempt from needing undefined blank values
66 | if (type.name === 'boolean') {
67 | assert.is(blank, false, 'blank boolean is false');
68 | }
69 | else if (type.name === 'array') {
70 | assert.ok(Array.isArray(blank), 'blank array is array');
71 | assert.is(blank.length, 0, 'blank array is empty');
72 | }
73 | else if (type.name === 'nodelist') {
74 | assert.ok(typeof blank.item, 'function', 'blank.item is function');
75 | assert.is(blank.length, 0, 'blank nodelist is empty');
76 | }
77 | else {
78 | assert.is(blank, undefined, 'default defined for ' + type.name);
79 | }
80 | });
81 | };
82 |
83 | exports.testNullDefault = function(options) {
84 | var context = null; // Is this test still valid with a null context?
85 |
86 | return forEachType(options, { defaultValue: null }, function(type) {
87 | var reply = type.stringify(null, context);
88 | return Promise.resolve(reply).then(function(str) {
89 | assert.is(str, '', 'stringify(null) for ' + type.name);
90 | });
91 | });
92 | };
93 |
94 | exports.testGetSpec = function(options) {
95 | return forEachType(options, {}, function(type) {
96 | if (type.name === 'param') {
97 | return;
98 | }
99 |
100 | var spec = type.getSpec('cmd', 'param');
101 | assert.ok(spec != null, 'non null spec for ' + type.name);
102 |
103 | var str = JSON.stringify(spec);
104 | assert.ok(str != null, 'serializable spec for ' + type.name);
105 |
106 | var example = options.requisition.system.types.createType(spec);
107 | assert.ok(example != null, 'creatable spec for ' + type.name);
108 | });
109 | };
110 |
--------------------------------------------------------------------------------
/lib/gcli/test/testUrl.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var assert = require('../testharness/assert');
20 | var helpers = require('./helpers');
21 |
22 | exports.testDefault = function(options) {
23 | return helpers.audit(options, [
24 | {
25 | skipRemainingIf: options.isPhantomjs, // PhantomJS URL type is broken
26 | setup: 'urlc',
27 | check: {
28 | input: 'urlc',
29 | markup: 'VVVV',
30 | hints: ' ',
31 | status: 'ERROR',
32 | args: {
33 | url: {
34 | value: undefined,
35 | arg: '',
36 | status: 'INCOMPLETE'
37 | }
38 | }
39 | }
40 | },
41 | {
42 | setup: 'urlc example',
43 | check: {
44 | input: 'urlc example',
45 | markup: 'VVVVVIIIIIII',
46 | hints: ' -> http://example/',
47 | predictions: [
48 | 'http://example/',
49 | 'https://example/',
50 | 'http://localhost:9999/example'
51 | ],
52 | status: 'ERROR',
53 | args: {
54 | url: {
55 | value: undefined,
56 | arg: ' example',
57 | status: 'INCOMPLETE'
58 | }
59 | }
60 | },
61 | },
62 | {
63 | setup: 'urlc example.com/',
64 | check: {
65 | input: 'urlc example.com/',
66 | markup: 'VVVVVIIIIIIIIIIII',
67 | hints: ' -> http://example.com/',
68 | status: 'ERROR',
69 | args: {
70 | url: {
71 | value: undefined,
72 | arg: ' example.com/',
73 | status: 'INCOMPLETE'
74 | }
75 | }
76 | },
77 | },
78 | {
79 | setup: 'urlc http://example.com/index?q=a#hash',
80 | check: {
81 | input: 'urlc http://example.com/index?q=a#hash',
82 | markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
83 | hints: '',
84 | status: 'VALID',
85 | args: {
86 | url: {
87 | value: function(data) {
88 | assert.is(data.hash, '#hash', 'url hash');
89 | },
90 | arg: ' http://example.com/index?q=a#hash',
91 | status: 'VALID'
92 | }
93 | }
94 | },
95 | exec: { output: /"url": ?/ }
96 | }
97 | ]);
98 | };
99 |
--------------------------------------------------------------------------------
/lib/gcli/testharness/assert.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * Module dependency loop resolution
21 | * examiner/assert both want to depend on each other, and we'd rather not
22 | * depend on util.createEvent (which could make matters worse) so we just
23 | * have examiner record the current test here.
24 | */
25 | exports.currentTest = null;
26 |
27 | /**
28 | * To we log what's going on with the tests. Useful for when something is going
29 | * bizarrely wrong, and we want to know what.
30 | */
31 | exports.testLogging = false;
32 |
33 | /**
34 | * Record a test failure if |value| is not truthy
35 | * Failure is marked by a record being added to the failure list with a message
36 | * property containing the passed message.
37 | */
38 | exports.ok = function(value, message) {
39 | if (!exports.currentTest) {
40 | console.error('No currentTest for ' + message);
41 | return;
42 | }
43 |
44 | if (!value) {
45 | console.error('Failure: ' + message);
46 |
47 | exports.currentTest.failures.push({ message: message });
48 | }
49 | else {
50 | exports.currentTest.checks++;
51 | }
52 | };
53 |
54 | /**
55 | * Record a test failure if |p1 !== p2|
56 | * Failure is marked by a record being added to the failure list with the
57 | * following properties:
58 | * - message: The string passed in to the |is| function
59 | * - params: (true) To distinguish from an |ok| failure
60 | * - p1: The first parameter to compare
61 | * - p2: The second parameter to compare against
62 | */
63 | exports.is = function(p1, p2, message) {
64 | if (!exports.currentTest) {
65 | console.error('No currentTest for ' + message);
66 | return;
67 | }
68 |
69 | if (p1 !== p2) {
70 | console.error('Failure: ' + message + ' (in ' + exports.currentTest + ')');
71 | console.error('- (Actual) P1: ', typeof p1 === 'string' ? '"' + p1 + '"' : p1);
72 | console.error('- (Expected) P2: ', typeof p2 === 'string' ? '"' + p2 + '"' : p2);
73 |
74 | exports.currentTest.failures.push({ message: message, params: true, p1: p1, p2: p2 });
75 | }
76 | else {
77 | exports.currentTest.checks++;
78 | }
79 | };
80 |
81 | /**
82 | * Add some extra information to the test logs
83 | */
84 | exports.log = function(message) {
85 | if (!exports.currentTest) {
86 | console.error('No currentTest for ' + message);
87 | return;
88 | }
89 |
90 | exports.currentTest.skipped.push({ message: message });
91 | };
92 |
--------------------------------------------------------------------------------
/lib/gcli/testharness/status.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * This should really be inside assert.js, however that is over-ridden by
21 | * a custom assert.js for mozilla, so we keep it separate to avoid
22 | * duplicating it in 2 places.
23 | */
24 | exports.stati = {
25 | notrun: { index: 0, name: 'Skipped' },
26 | executing: { index: 1, name: 'Executing' },
27 | pass: { index: 2, name: 'Pass' },
28 | fail: { index: 3, name: 'Fail' },
29 | };
30 |
--------------------------------------------------------------------------------
/lib/gcli/types/array.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var ArrayConversion = require('./types').ArrayConversion;
20 | var ArrayArgument = require('./types').ArrayArgument;
21 |
22 | exports.items = [
23 | {
24 | // A set of objects of the same type
25 | item: 'type',
26 | name: 'array',
27 | subtype: undefined,
28 |
29 | constructor: function() {
30 | if (!this.subtype) {
31 | console.error('Array.typeSpec is missing subtype. Assuming string.' +
32 | this.name);
33 | this.subtype = 'string';
34 | }
35 | this.subtype = this.types.createType(this.subtype);
36 | },
37 |
38 | getSpec: function(commandName, paramName) {
39 | return {
40 | name: 'array',
41 | subtype: this.subtype.getSpec(commandName, paramName),
42 | };
43 | },
44 |
45 | stringify: function(values, context) {
46 | if (values == null) {
47 | return '';
48 | }
49 | // BUG 664204: Check for strings with spaces and add quotes
50 | return values.join(' ');
51 | },
52 |
53 | parse: function(arg, context) {
54 | if (arg.type !== 'ArrayArgument') {
55 | console.error('non ArrayArgument to ArrayType.parse', arg);
56 | throw new Error('non ArrayArgument to ArrayType.parse');
57 | }
58 |
59 | // Parse an argument to a conversion
60 | // Hack alert. ArrayConversion needs to be able to answer questions about
61 | // the status of individual conversions in addition to the overall state.
62 | // |subArg.conversion| allows us to do that easily.
63 | var subArgParse = function(subArg) {
64 | return this.subtype.parse(subArg, context).then(function(conversion) {
65 | subArg.conversion = conversion;
66 | return conversion;
67 | }.bind(this));
68 | }.bind(this);
69 |
70 | var conversionPromises = arg.getArguments().map(subArgParse);
71 | return Promise.all(conversionPromises).then(function(conversions) {
72 | return new ArrayConversion(conversions, arg);
73 | });
74 | },
75 |
76 | getBlank: function(context) {
77 | return new ArrayConversion([], new ArrayArgument());
78 | }
79 | },
80 | ];
81 |
--------------------------------------------------------------------------------
/lib/gcli/types/boolean.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var Status = require('./types').Status;
20 | var Conversion = require('./types').Conversion;
21 | var BlankArgument = require('./types').BlankArgument;
22 | var SelectionType = require('./selection').SelectionType;
23 |
24 | exports.items = [
25 | {
26 | // 'boolean' type
27 | item: 'type',
28 | name: 'boolean',
29 | parent: 'selection',
30 |
31 | getSpec: function() {
32 | return 'boolean';
33 | },
34 |
35 | lookup: [
36 | { name: 'false', value: false },
37 | { name: 'true', value: true }
38 | ],
39 |
40 | parse: function(arg, context) {
41 | if (arg.type === 'TrueNamedArgument') {
42 | return Promise.resolve(new Conversion(true, arg));
43 | }
44 | if (arg.type === 'FalseNamedArgument') {
45 | return Promise.resolve(new Conversion(false, arg));
46 | }
47 | return SelectionType.prototype.parse.call(this, arg, context);
48 | },
49 |
50 | stringify: function(value, context) {
51 | if (value == null) {
52 | return '';
53 | }
54 | return '' + value;
55 | },
56 |
57 | getBlank: function(context) {
58 | return new Conversion(false, new BlankArgument(), Status.VALID, '',
59 | Promise.resolve(this.lookup));
60 | }
61 | }
62 | ];
63 |
--------------------------------------------------------------------------------
/lib/gcli/types/file.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /*
20 | * The file type is a bit of a spiders-web, but there isn't a nice solution
21 | * yet. The core of the problem is that the modules used by Firefox and NodeJS
22 | * intersect with the modules used by the web, but not each other. Except here.
23 | * So we have to do something fancy to get the sharing but not mess up the web.
24 | *
25 | * This file requires 'gcli/types/fileparser', and there are 4 implementations
26 | * of this:
27 | * - '/lib/gcli/types/fileparser.js', the default web version that uses XHR to
28 | * talk to the node server
29 | * - '/lib/server/gcli/types/fileparser.js', an NodeJS stub, and ...
30 | * - '/mozilla/gcli/types/fileparser.js', the Firefox implementation both of
31 | * these are shims which import
32 | * - 'gcli/util/fileparser', does the real work, except the actual file access
33 | *
34 | * The file access comes from the 'gcli/util/filesystem' module, and there are
35 | * 2 implementations of this:
36 | * - '/lib/server/gcli/util/filesystem.js', which uses NodeJS APIs
37 | * - '/mozilla/gcli/util/filesystem.js', which uses OS.File APIs
38 | */
39 |
40 | var fileparser = require('./fileparser');
41 | var Conversion = require('./types').Conversion;
42 |
43 | exports.items = [
44 | {
45 | item: 'type',
46 | name: 'file',
47 |
48 | filetype: 'any', // One of 'file', 'directory', 'any'
49 | existing: 'maybe', // Should be one of 'yes', 'no', 'maybe'
50 | matches: undefined, // RegExp to match the file part of the path
51 |
52 | hasPredictions: true,
53 |
54 | constructor: function() {
55 | if (this.filetype !== 'any' && this.filetype !== 'file' &&
56 | this.filetype !== 'directory') {
57 | throw new Error('filetype must be one of [any|file|directory]');
58 | }
59 |
60 | if (this.existing !== 'yes' && this.existing !== 'no' &&
61 | this.existing !== 'maybe') {
62 | throw new Error('existing must be one of [yes|no|maybe]');
63 | }
64 | },
65 |
66 | getSpec: function(commandName, paramName) {
67 | return {
68 | name: 'remote',
69 | commandName: commandName,
70 | paramName: paramName
71 | };
72 | },
73 |
74 | stringify: function(file) {
75 | if (file == null) {
76 | return '';
77 | }
78 |
79 | return file.toString();
80 | },
81 |
82 | parse: function(arg, context) {
83 | var options = {
84 | filetype: this.filetype,
85 | existing: this.existing,
86 | matches: this.matches
87 | };
88 | var promise = fileparser.parse(context, arg.text, options);
89 |
90 | return promise.then(function(reply) {
91 | return new Conversion(reply.value, arg, reply.status,
92 | reply.message, reply.predictor);
93 | });
94 | }
95 | }
96 | ];
97 |
--------------------------------------------------------------------------------
/lib/gcli/types/fileparser.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.parse = require('../util/fileparser').parse;
20 |
--------------------------------------------------------------------------------
/lib/gcli/types/setting.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | exports.items = [
20 | {
21 | // A type for selecting a known setting
22 | item: 'type',
23 | name: 'setting',
24 | parent: 'selection',
25 | cacheable: true,
26 | lookup: function(context) {
27 | var settings = context.system.settings;
28 |
29 | // Lazily add a settings.onChange listener to clear the cache
30 | if (!this._registeredListener) {
31 | settings.onChange.add(function(ev) {
32 | this.clearCache();
33 | }, this);
34 | this._registeredListener = true;
35 | }
36 |
37 | return settings.getAll().map(function(setting) {
38 | return { name: setting.name, value: setting };
39 | });
40 | }
41 | },
42 | {
43 | // A type for entering the value of a known setting
44 | // Customizations:
45 | // - settingParamName The name of the setting parameter so we can customize
46 | // the type that we are expecting to read
47 | item: 'type',
48 | name: 'settingValue',
49 | parent: 'delegate',
50 | settingParamName: 'setting',
51 | delegateType: function(context) {
52 | if (context != null) {
53 | var setting = context.getArgsObject()[this.settingParamName];
54 | if (setting != null) {
55 | return setting.type;
56 | }
57 | }
58 |
59 | return 'blank';
60 | }
61 | }
62 | ];
63 |
--------------------------------------------------------------------------------
/lib/gcli/types/string.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var Status = require('./types').Status;
20 | var Conversion = require('./types').Conversion;
21 |
22 | exports.items = [
23 | {
24 | // 'string' the most basic string type where all we need to do is to take
25 | // care of converting escaped characters like \t, \n, etc.
26 | // For the full list see
27 | // https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals
28 | // The exception is that we ignore \b because replacing '\b' characters in
29 | // stringify() with their escaped version injects '\\b' all over the place
30 | // and the need to support \b seems low)
31 | // Customizations:
32 | // allowBlank: Allow a blank string to be counted as valid
33 | item: 'type',
34 | name: 'string',
35 | allowBlank: false,
36 |
37 | getSpec: function() {
38 | return this.allowBlank ?
39 | { name: 'string', allowBlank: true } :
40 | 'string';
41 | },
42 |
43 | stringify: function(value, context) {
44 | if (value == null) {
45 | return '';
46 | }
47 |
48 | return value
49 | .replace(/\\/g, '\\\\')
50 | .replace(/\f/g, '\\f')
51 | .replace(/\n/g, '\\n')
52 | .replace(/\r/g, '\\r')
53 | .replace(/\t/g, '\\t')
54 | .replace(/\v/g, '\\v')
55 | .replace(/\n/g, '\\n')
56 | .replace(/\r/g, '\\r')
57 | .replace(/ /g, '\\ ')
58 | .replace(/'/g, '\\\'')
59 | .replace(/"/g, '\\"')
60 | .replace(/{/g, '\\{')
61 | .replace(/}/g, '\\}');
62 | },
63 |
64 | parse: function(arg, context) {
65 | if (!this.allowBlank && (arg.text == null || arg.text === '')) {
66 | return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE, ''));
67 | }
68 |
69 | // The string '\\' (i.e. an escaped \ (represented here as '\\\\' because it
70 | // is double escaped)) is first converted to a private unicode character and
71 | // then at the end from \uF000 to a single '\' to avoid the string \\n being
72 | // converted first to \n and then to a
73 | var value = arg.text
74 | .replace(/\\\\/g, '\uF000')
75 | .replace(/\\f/g, '\f')
76 | .replace(/\\n/g, '\n')
77 | .replace(/\\r/g, '\r')
78 | .replace(/\\t/g, '\t')
79 | .replace(/\\v/g, '\v')
80 | .replace(/\\n/g, '\n')
81 | .replace(/\\r/g, '\r')
82 | .replace(/\\ /g, ' ')
83 | .replace(/\\'/g, '\'')
84 | .replace(/\\"/g, '"')
85 | .replace(/\\{/g, '{')
86 | .replace(/\\}/g, '}')
87 | .replace(/\uF000/g, '\\');
88 |
89 | return Promise.resolve(new Conversion(value, arg));
90 | }
91 | }
92 | ];
93 |
--------------------------------------------------------------------------------
/lib/gcli/types/union.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 | var Conversion = require('./types').Conversion;
21 | var Status = require('./types').Status;
22 |
23 | exports.items = [
24 | {
25 | // The union type allows for a combination of different parameter types.
26 | item: 'type',
27 | name: 'union',
28 | hasPredictions: true,
29 |
30 | constructor: function() {
31 | // Get the properties of the type. Later types in the list should always
32 | // be more general, so 'catch all' types like string must be last
33 | this.alternatives = this.alternatives.map(function(typeData) {
34 | return this.types.createType(typeData);
35 | }.bind(this));
36 | },
37 |
38 | getSpec: function(command, param) {
39 | var spec = { name: 'union', alternatives: [] };
40 | this.alternatives.forEach(function(type) {
41 | spec.alternatives.push(type.getSpec(command, param));
42 | }.bind(this));
43 | return spec;
44 | },
45 |
46 | stringify: function(value, context) {
47 | if (value == null) {
48 | return '';
49 | }
50 |
51 | var type = this.alternatives.find(function(typeData) {
52 | return typeData.name === value.type;
53 | });
54 |
55 | return type.stringify(value[value.type], context);
56 | },
57 |
58 | parse: function(arg, context) {
59 | var conversionPromises = this.alternatives.map(function(type) {
60 | return type.parse(arg, context);
61 | }.bind(this));
62 |
63 | return Promise.all(conversionPromises).then(function(conversions) {
64 | // Find a list of the predictions made by any conversion
65 | var predictionPromises = conversions.map(function(conversion) {
66 | return conversion.getPredictions(context);
67 | }.bind(this));
68 |
69 | return Promise.all(predictionPromises).then(function(allPredictions) {
70 | // Take one prediction from each set of predictions, ignoring
71 | // duplicates, until we've got up to Conversion.maxPredictions
72 | var maxIndex = allPredictions.reduce(function(prev, prediction) {
73 | return Math.max(prev, prediction.length);
74 | }.bind(this), 0);
75 | var predictions = [];
76 |
77 | indexLoop:
78 | for (var index = 0; index < maxIndex; index++) {
79 | for (var p = 0; p <= allPredictions.length; p++) {
80 | if (predictions.length >= Conversion.maxPredictions) {
81 | break indexLoop;
82 | }
83 |
84 | if (allPredictions[p] != null) {
85 | var prediction = allPredictions[p][index];
86 | if (prediction != null && predictions.indexOf(prediction) === -1) {
87 | predictions.push(prediction);
88 | }
89 | }
90 | }
91 | }
92 |
93 | var bestStatus = Status.ERROR;
94 | var value;
95 | for (var i = 0; i < conversions.length; i++) {
96 | var conversion = conversions[i];
97 | var thisStatus = conversion.getStatus(arg);
98 | if (thisStatus < bestStatus) {
99 | bestStatus = thisStatus;
100 | }
101 | if (bestStatus === Status.VALID) {
102 | var type = this.alternatives[i].name;
103 | value = { type: type };
104 | value[type] = conversion.value;
105 | break;
106 | }
107 | }
108 |
109 | var msg = (bestStatus === Status.VALID) ?
110 | '' :
111 | l10n.lookupFormat('typesSelectionNomatch', [ arg.text ]);
112 | return new Conversion(value, arg, bestStatus, msg, predictions);
113 | }.bind(this));
114 | }.bind(this));
115 | },
116 | }
117 | ];
118 |
--------------------------------------------------------------------------------
/lib/gcli/types/url.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var host = require('../util/host');
20 | var Status = require('./types').Status;
21 | var Conversion = require('./types').Conversion;
22 |
23 | exports.items = [
24 | {
25 | item: 'type',
26 | name: 'url',
27 |
28 | getSpec: function() {
29 | return 'url';
30 | },
31 |
32 | stringify: function(value, context) {
33 | if (value == null) {
34 | return '';
35 | }
36 | return value.href;
37 | },
38 |
39 | parse: function(arg, context) {
40 | var conversion;
41 |
42 | try {
43 | var url = host.createUrl(arg.text);
44 | conversion = new Conversion(url, arg);
45 | }
46 | catch (ex) {
47 | var predictions = [];
48 | var status = Status.ERROR;
49 |
50 | // Maybe the URL was missing a scheme?
51 | if (arg.text.indexOf('://') === -1) {
52 | [ 'http', 'https' ].forEach(function(scheme) {
53 | try {
54 | var http = host.createUrl(scheme + '://' + arg.text);
55 | predictions.push({ name: http.href, value: http });
56 | }
57 | catch (ex) {
58 | // Ignore
59 | }
60 | }.bind(this));
61 |
62 | // Try to create a URL with the current page as a base ref
63 | if ('window' in context.environment) {
64 | try {
65 | var base = context.environment.window.location.href;
66 | var localized = host.createUrl(arg.text, base);
67 | predictions.push({ name: localized.href, value: localized });
68 | }
69 | catch (ex) {
70 | // Ignore
71 | }
72 | }
73 | }
74 |
75 | if (predictions.length > 0) {
76 | status = Status.INCOMPLETE;
77 | }
78 |
79 | conversion = new Conversion(undefined, arg, status,
80 | ex.message, predictions);
81 | }
82 |
83 | return Promise.resolve(conversion);
84 | }
85 | }
86 | ];
87 |
--------------------------------------------------------------------------------
/lib/gcli/ui/history.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | /**
20 | * A History object remembers commands that have been entered in the past and
21 | * provides an API for accessing them again.
22 | * See Bug 681340: Search through history (like C-r in bash)?
23 | */
24 | function History() {
25 | // This is the actual buffer where previous commands are kept.
26 | // 'this._buffer[0]' should always be equal the empty string. This is so
27 | // that when you try to go in to the "future", you will just get an empty
28 | // command.
29 | this._buffer = [''];
30 |
31 | // This is an index in to the history buffer which points to where we
32 | // currently are in the history.
33 | this._current = 0;
34 | }
35 |
36 | /**
37 | * Avoid memory leaks
38 | */
39 | History.prototype.destroy = function() {
40 | this._buffer = undefined;
41 | };
42 |
43 | /**
44 | * Record and save a new command in the history.
45 | */
46 | History.prototype.add = function(command) {
47 | this._buffer.splice(1, 0, command);
48 | this._current = 0;
49 | };
50 |
51 | /**
52 | * Get the next (newer) command from history.
53 | */
54 | History.prototype.forward = function() {
55 | if (this._current > 0 ) {
56 | this._current--;
57 | }
58 | return this._buffer[this._current];
59 | };
60 |
61 | /**
62 | * Get the previous (older) item from history.
63 | */
64 | History.prototype.backward = function() {
65 | if (this._current < this._buffer.length - 1) {
66 | this._current++;
67 | }
68 | return this._buffer[this._current];
69 | };
70 |
71 | exports.History = History;
72 |
--------------------------------------------------------------------------------
/lib/gcli/ui/intro.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var l10n = require('../util/l10n');
20 | var Output = require('../cli').Output;
21 | var view = require('./view');
22 |
23 | /**
24 | * Record if the user has clicked on 'Got It!'
25 | */
26 | exports.items = [
27 | {
28 | item: 'setting',
29 | name: 'hideIntro',
30 | type: 'boolean',
31 | description: l10n.lookup('hideIntroDesc'),
32 | defaultValue: false
33 | }
34 | ];
35 |
36 | /**
37 | * Called when the UI is ready to add a welcome message to the output
38 | */
39 | exports.maybeShowIntro = function(commandOutputManager, conversionContext) {
40 | var hideIntro = conversionContext.system.settings.get('hideIntro');
41 | if (hideIntro.value) {
42 | return;
43 | }
44 |
45 | var output = new Output(conversionContext);
46 | output.type = 'view';
47 | commandOutputManager.onOutput({ output: output });
48 |
49 | var viewData = this.createView(null, conversionContext, true);
50 |
51 | output.complete({ isTypedData: true, type: 'view', data: viewData });
52 | };
53 |
54 | /**
55 | * Called when the UI is ready to add a welcome message to the output
56 | */
57 | exports.createView = function(ignoreArgs, conversionContext, showHideButton) {
58 | return view.createView({
59 | html:
60 | '
33 |
--------------------------------------------------------------------------------
/lib/gcli/ui/view.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var util = require('../util/util');
20 | var host = require('../util/host');
21 | var domtemplate = require('../util/domtemplate');
22 |
23 |
24 | /**
25 | * We want to avoid commands having to create DOM structures because that's
26 | * messy and because we're going to need to have command output displayed in
27 | * different documents. A View is a way to wrap an HTML template (for
28 | * domtemplate) in with the data and options to render the template, so anyone
29 | * can later run the template in the context of any document.
30 | * View also cuts out a chunk of boiler place code.
31 | * @param options The information needed to create the DOM from HTML. Includes:
32 | * - html (required): The HTML source, probably from a call to require
33 | * - options (default={}): The domtemplate options. See domtemplate for details
34 | * - data (default={}): The data to domtemplate. See domtemplate for details.
35 | * - css (default=none): Some CSS to be added to the final document. If 'css'
36 | * is used, use of cssId is strongly recommended.
37 | * - cssId (default=none): An ID to prevent multiple CSS additions. See
38 | * util.importCss for more details.
39 | * @return An object containing a single function 'appendTo()' which runs the
40 | * template adding the result to the specified element. Takes 2 parameters:
41 | * - element (required): the element to add to
42 | * - clear (default=false): if clear===true then remove all pre-existing
43 | * children of 'element' before appending the results of this template.
44 | */
45 | exports.createView = function(options) {
46 | if (options.html == null) {
47 | throw new Error('options.html is missing');
48 | }
49 |
50 | return {
51 | /**
52 | * RTTI. Yeah.
53 | */
54 | isView: true,
55 |
56 | /**
57 | * Run the template against the document to which element belongs.
58 | * @param element The element to append the result to
59 | * @param clear Set clear===true to remove all children of element
60 | */
61 | appendTo: function(element, clear) {
62 | // Strict check on the off-chance that we later think of other options
63 | // and want to replace 'clear' with an 'options' parameter, but want to
64 | // support backwards compat.
65 | if (clear === true) {
66 | util.clearElement(element);
67 | }
68 |
69 | element.appendChild(this.toDom(element.ownerDocument));
70 | },
71 |
72 | /**
73 | * Actually convert the view data into a DOM suitable to be appended to
74 | * an element
75 | * @param document to use in realizing the template
76 | */
77 | toDom: function(document) {
78 | if (options.css) {
79 | util.importCss(options.css, document, options.cssId);
80 | }
81 |
82 | var child = host.toDom(document, options.html);
83 | domtemplate.template(child, options.data || {}, options.options || {});
84 | return child;
85 | }
86 | };
87 | };
88 |
--------------------------------------------------------------------------------
/lib/gcli/util/filesystem.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var fs = require('fs');
20 | var path = require('path');
21 |
22 | var util = require('./util');
23 |
24 | /**
25 | * A set of functions defining a filesystem API for fileparser.js
26 | */
27 |
28 | exports.join = function() {
29 | return path.join.apply(path, arguments);
30 | };
31 |
32 | exports.dirname = function() {
33 | return path.dirname.apply(path, arguments);
34 | };
35 |
36 | exports.sep = path.sep;
37 |
38 | exports.home = typeof process !== 'undefined' ? process.env.HOME : '';
39 |
40 | /**
41 | * The NodeJS docs suggest using ``pathname.split(path.sep)`` to cut a path
42 | * into a number of components. But this doesn't take into account things like
43 | * path normalization and removing the initial (or trailing) blanks from
44 | * absolute (or / terminated) paths.
45 | * http://www.nodejs.org/api/path.html#path_path_sep
46 | * @param pathname (string) The part to cut up
47 | * @return An array of path components
48 | */
49 | exports.split = function(pathname) {
50 | pathname = path.normalize(pathname);
51 | var parts = pathname.split(exports.sep);
52 | return parts.filter(function(part) {
53 | return part !== '';
54 | });
55 | };
56 |
57 | /**
58 | * @param pathname string, path of an existing directory
59 | * @param matches optional regular expression - filter output to include only
60 | * the files that match the regular expression. The regexp is applied to the
61 | * filename only not to the full path
62 | * @return A promise of an array of stat objects for each member of the
63 | * directory pointed to by ``pathname``, each containing 2 extra properties:
64 | * - pathname: The full pathname of the file
65 | * - filename: The final filename part of the pathname
66 | */
67 | exports.ls = function(pathname, matches) {
68 | return new Promise(function(resolve, reject) {
69 | fs.readdir(pathname, function(err, files) {
70 | if (err) {
71 | reject(err);
72 | }
73 | else {
74 | if (matches) {
75 | files = files.filter(function(file) {
76 | return matches.test(file);
77 | });
78 | }
79 |
80 | var statsPromise = util.promiseEach(files, function(filename) {
81 | var filepath = path.join(pathname, filename);
82 | return exports.stat(filepath).then(function(stats) {
83 | stats.filename = filename;
84 | stats.pathname = filepath;
85 | return stats;
86 | });
87 | });
88 |
89 | statsPromise.then(resolve, reject);
90 | }
91 | });
92 | }.bind(this));
93 | };
94 |
95 | /**
96 | * stat() is annoying because it considers stat('/doesnt/exist') to be an
97 | * error, when the point of stat() is to *find* *out*. So this wrapper just
98 | * converts 'ENOENT' i.e. doesn't exist to { exists:false } and adds
99 | * exists:true to stat blocks from existing paths
100 | */
101 | exports.stat = function(pathname) {
102 | return new Promise(function(resolve, reject) {
103 | fs.stat(pathname, function(err, stats) {
104 | if (err) {
105 | if (err.code === 'ENOENT') {
106 | resolve({
107 | exists: false,
108 | isDir: false,
109 | isFile: false
110 | });
111 | }
112 | else {
113 | reject(err);
114 | }
115 | }
116 | else {
117 | resolve({
118 | exists: true,
119 | isDir: stats.isDirectory(),
120 | isFile: stats.isFile()
121 | });
122 | }
123 | });
124 | }.bind(this));
125 | };
126 |
127 | /**
128 | * We may read the first line of a file to describe it?
129 | * Right now, however, we do nothing.
130 | */
131 | exports.describe = function(pathname) {
132 | return Promise.resolve('');
133 | };
134 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gcli",
3 | "description": "JavaScript Command Line",
4 | "version": "0.6.4",
5 | "homepage": "http://github.com/joewalker/gcli",
6 | "engines": {
7 | "node": ">= 4.1.0"
8 | },
9 | "dependencies": {
10 | "body-parser": "1.14.0",
11 | "dom-urls": "1.0.0",
12 | "dryice": "0.4.11",
13 | "es6-promise": "3.0.2",
14 | "express": "4.13.3",
15 | "jsdom": "6.5.1",
16 | "json-loader": "0.5.3",
17 | "morgan": "1.6.1",
18 | "node-libs-browser": "0.5.3",
19 | "raw-loader": "0.5.1",
20 | "socket.io": "1.3.7",
21 | "socket.io-client": "1.3.7",
22 | "webpack": "1.12.2"
23 | },
24 | "author": "Joe Walker ",
25 | "main": "lib/gcli",
26 | "repository": {
27 | "type": "git",
28 | "url": "http://github.com/joewalker/gcli.git"
29 | },
30 | "scripts": {
31 | "test": "node gcli.js test"
32 | },
33 | "licenses": [
34 | {
35 | "type": "Apache-2.0",
36 | "url": "http://www.apache.org/licenses/LICENSE-2.0"
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/phantom-test.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var page = require('webpage').create();
20 | var system = require('system');
21 |
22 | var exitOnComplete = function() {
23 | var complete = page.evaluate(function() {
24 | return document.complete;
25 | });
26 | var status = page.evaluate(function() {
27 | return document.testStatus;
28 | });
29 |
30 | if (complete === true) {
31 | var exitValue = (status == 'Pass' ? 0 : -1);
32 | phantom.exit(exitValue);
33 | }
34 | };
35 |
36 | var pageLoaded = function(status) {
37 | setInterval(exitOnComplete, 50);
38 | };
39 |
40 | page.onConsoleMessage = function() {
41 | console.log.apply(console, arguments);
42 | };
43 |
44 | if (system.args.length === 1) {
45 | page.open('http://localhost:9999/index.html', pageLoaded);
46 | } else {
47 | if (system.args[1] === '--shutdown') {
48 | page.open('http://localhost:9999/index.html?shutdown=true', pageLoaded);
49 | }
50 | else {
51 | console.error('Options: --shutdown');
52 | phantom.exit(-1);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/remote.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GCLI: Graphical Command Line
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/scripts/shim.js:
--------------------------------------------------------------------------------
1 |
2 | // Only needed for PhantomJS
3 | if (!Function.prototype.bind) {
4 | Function.prototype.bind = function (oThis) {
5 | if (typeof this !== "function") {
6 | // closest thing possible to the ECMAScript 5 internal IsCallable function
7 | throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
8 | }
9 |
10 | var aArgs = Array.prototype.slice.call(arguments, 1),
11 | fToBind = this,
12 | fNOP = function () {},
13 | fBound = function () {
14 | return fToBind.apply(this instanceof fNOP && oThis
15 | ? this
16 | : oThis,
17 | aArgs.concat(Array.prototype.slice.call(arguments)));
18 | };
19 |
20 | fNOP.prototype = this.prototype;
21 | fBound.prototype = new fNOP();
22 |
23 | return fBound;
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 | /* eslint no-var: 0 */
19 |
20 | var path = require('path');
21 | var webpack = require('webpack');
22 |
23 | module.exports = {
24 | entry: {
25 | 'wp-index': [ './wp-index.js' ],
26 | },
27 | output: {
28 | path: path.join(__dirname, 'built'),
29 | filename: '[name].js',
30 | sourceMapFilename: '[file].map',
31 | publicPath: 'http://localhost:3000/',
32 | },
33 | module: {
34 | loaders: [
35 | { test: /\.css$/, loader: 'raw' },
36 | { test: /\.html$/, loader: 'raw' },
37 | { test: /\.json$/, loader: 'json' },
38 | ],
39 | },
40 | plugins: [
41 | new webpack.IgnorePlugin(/child_process$/),
42 | new webpack.IgnorePlugin(/dom-urls$/),
43 | new webpack.IgnorePlugin(/fs$/),
44 | new webpack.IgnorePlugin(/jsdom$/),
45 | new webpack.IgnorePlugin(/path$/),
46 | ],
47 | };
48 |
--------------------------------------------------------------------------------
/wp-index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GCLI: Graphical Command Line
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/wp-index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012, Mozilla Foundation and contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | 'use strict';
18 |
19 | var gcli = require('./lib/gcli/index');
20 | var demo = require('./lib/gcli/items/demo');
21 | var test = require('./lib/gcli/test/index');
22 |
23 | // Add the commands/types/converters as required
24 | var system = gcli.createSystem();
25 | system.addItems(gcli.items); // Common infrastructure: types, etc
26 | system.addItems(gcli.commandItems); // Common set of useful commands
27 | system.addItems(demo.items); // Extra demo commands
28 |
29 | gcli.createTerminal(system).then(function(terminal) {
30 | terminal.language.showIntro(); // Intro text
31 | test.run(terminal, false); // Run the unit test at each startup
32 | }).catch(console.error.bind(console));
33 |
--------------------------------------------------------------------------------