1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/devtools/gcli/source/docs/developing-gcli.md Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,213 @@ 1.4 + 1.5 +# Developing GCLI 1.6 + 1.7 +## About the code 1.8 + 1.9 +The majority of the GCLI source is stored in the ``lib`` directory. 1.10 + 1.11 +The ``docs`` directory contains documentation. 1.12 +The ``scripts`` directory contains RequireJS that GCLI uses. 1.13 +The ``build`` directory contains files used when creating builds. 1.14 +The ``mozilla`` directory contains the mercurial patch queue of patches to apply 1.15 +to mozilla-central. 1.16 +The ``selenium-tests`` directory contains selenium web-page integration tests. 1.17 + 1.18 +The source in the ``lib`` directory is split into 4 sections: 1.19 + 1.20 +- ``lib/demo`` contains commands used in the demo page. It is not needed except 1.21 + for demo purposes. 1.22 +- ``lib/test`` contains a small test harness for testing GCLI. 1.23 +- ``lib/gclitest`` contains tests that run in the test harness 1.24 +- ``lib/gcli`` contains the actual meat 1.25 + 1.26 +GCLI is split into a UI portion and a Model/Controller portion. 1.27 + 1.28 + 1.29 +## The GCLI Model 1.30 + 1.31 +The heart of GCLI is a ``Requisition``, which is an AST for the input. A 1.32 +``Requisition`` is a command that we'd like to execute, and we're filling out 1.33 +all the inputs required to execute the command. 1.34 + 1.35 +A ``Requisition`` has a ``Command`` that is to be executed. Each Command has a 1.36 +number of ``Parameter``s, each of which has a name and a type as detailed 1.37 +above. 1.38 + 1.39 +As you type, your input is split into ``Argument``s, which are then assigned to 1.40 +``Parameter``s using ``Assignment``s. Each ``Assignment`` has a ``Conversion`` 1.41 +which stores the input argument along with the value that is was converted into 1.42 +according to the type of the parameter. 1.43 + 1.44 +There are special assignments called ``CommandAssignment`` which the 1.45 +``Requisition`` uses to link to the command to execute, and 1.46 +``UnassignedAssignment``used to store arguments that do not have a parameter 1.47 +to be assigned to. 1.48 + 1.49 + 1.50 +## The GCLI UI 1.51 + 1.52 +There are several components of the GCLI UI. Each can have a script portion, 1.53 +some template HTML and a CSS file. The template HTML is processed by 1.54 +``domtemplate`` before use. 1.55 + 1.56 +DomTemplate is fully documented in [it's own repository] 1.57 +(https://github.com/joewalker/domtemplate). 1.58 + 1.59 +The components are: 1.60 + 1.61 +- ``Inputter`` controls the input field, processing special keyboard events and 1.62 + making sure that it stays in sync with the Requisition. 1.63 +- ``Completer`` updates a div that is located behind the input field and used 1.64 + to display completion advice and hint highlights. It is stored in 1.65 + completer.js. 1.66 +- ``Display`` is responsible for containing the popup hints that are displayed 1.67 + above the command line. Typically Display contains a Hinter and a RequestsView 1.68 + although these are not both required. Display itself is optional, and isn't 1.69 + planned for use in the first release of GCLI in Firefox. 1.70 +- ``Hinter`` Is used to display input hints. It shows either a Menu or an 1.71 + ArgFetch component depending on the state of the Requisition 1.72 +- ``Menu`` is used initially to select the command to be executed. It can act 1.73 + somewhat like the Start menu on windows. 1.74 +- ``ArgFetch`` Once the command to be executed has been selected, ArgFetch 1.75 + shows a 'dialog' allowing the user to enter the parameters to the selected 1.76 + command. 1.77 +- ``RequestsView`` Contains a set of ``RequestView`` components, each of which 1.78 + displays a command that has been invoked. RequestsView is a poor name, and 1.79 + should better be called ReportView 1.80 + 1.81 +ArgFetch displays a number of Fields. There are fields for most of the Types 1.82 +discussed earlier. See 'Writing Fields' above for more information. 1.83 + 1.84 + 1.85 +## Testing 1.86 + 1.87 +GCLI contains 2 test suites: 1.88 + 1.89 +- JS level testing is run with the ``test`` command. The tests are located in 1.90 + ``lib/gclitest`` and they use the test runner in ``lib/test``. This is fairly 1.91 + comprehensive, however it does not do UI level testing. 1.92 + If writing a new test it needs to be registered in ``lib/gclitest/index``. 1.93 + For an example of how to write tests, see ``lib/gclitest/testSplit.js``. 1.94 + The test functions are implemented in ``lib/test/assert``. 1.95 +- Browser integration tests are included in ``browser_webconsole_gcli_*.js``, 1.96 + in ``toolkit/components/console/hudservice/tests/browser``. These are 1.97 + run with the rest of the Mozilla test suite. 1.98 + 1.99 + 1.100 +## Coding Conventions 1.101 + 1.102 +The coding conventions for the GCLI project come from the Bespin/Skywriter and 1.103 +Ace projects. They are roughly [Crockford] 1.104 +(http://javascript.crockford.com/code.html) with a few exceptions and 1.105 +additions: 1.106 + 1.107 +* ``var`` does not need to be at the top of each function, we'd like to move 1.108 + to ``let`` when it's generally available, and ``let`` doesn't have the same 1.109 + semantic twists as ``var``. 1.110 + 1.111 +* Strings are generally enclosed in single quotes. 1.112 + 1.113 +* ``eval`` is to be avoided, but we don't declare it evil. 1.114 + 1.115 +The [Google JavaScript conventions] 1.116 +(https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) are 1.117 +more detailed, we tend to deviate in: 1.118 + 1.119 +* Custom exceptions: We generally just use ``throw new Error('message');`` 1.120 + 1.121 +* Multi-level prototype hierarchies: Allowed; we don't have ``goog.inherits()`` 1.122 + 1.123 +* ``else`` begins on a line by itself: 1.124 + 1.125 + if (thing) { 1.126 + doThis(); 1.127 + } 1.128 + else { 1.129 + doThat(); 1.130 + } 1.131 + 1.132 + 1.133 +## Startup 1.134 + 1.135 +Internally GCLI modules have ``startup()``/``shutdown()`` functions which are 1.136 +called on module init from the top level ``index.js`` of that 'package'. 1.137 + 1.138 +In order to initialize a package all that is needed is to require the package 1.139 +index (e.g. ``require('package/index')``). 1.140 + 1.141 +The ``shutdown()`` function was useful when GCLI was used in Bespin as part of 1.142 +dynamic registration/de-registration. It is not known if this feature will be 1.143 +useful in the future. So it has not been entirely removed, it may be at some 1.144 +future date. 1.145 + 1.146 + 1.147 +## Running the Unit Tests 1.148 + 1.149 +Start the GCLI static server: 1.150 + 1.151 + cd path/to/gcli 1.152 + node gcli.js 1.153 + 1.154 +Now point your browser to http://localhost:9999/localtest.html. When the page 1.155 +loads the tests will be automatically run outputting to the console, or you can 1.156 +enter the ``test`` command to run the unit tests. 1.157 + 1.158 + 1.159 +## Contributing Code 1.160 + 1.161 +Please could you do the following to help minimize the amount of rework that we 1.162 +do: 1.163 + 1.164 +1. Check the unit tests run correctly (see **Running the Unit Tests** above) 1.165 +2. Check the code follows the style guide. At a minimum it should look like the 1.166 + code around it. For more detailed notes, see **Coding Conventions** above 1.167 +3. Help me review your work by using good commit comments. Which means 2 things 1.168 + * Well formatted messages, i.e. 50 char summary including bug tag, followed 1.169 + by a blank line followed by a more in-depth message wrapped to 72 chars 1.170 + per line. This is basically the format used by the Linux Kernel. See the 1.171 + [commit log](https://github.com/joewalker/gcli/commits/master) for 1.172 + examples. The be extra helpful, please use the "shortdesc-BUGNUM: " if 1.173 + possible which also helps in reviews. 1.174 + * Commit your changes as a story. Make it easy for me to understand the 1.175 + changes that you've made. 1.176 +4. Sign your work. To improve tracking of who did what, we follow the sign-off 1.177 + procedure used in the Linux Kernel. 1.178 + The sign-off is a simple line at the end of the explanation for the 1.179 + patch, which certifies that you wrote it or otherwise have the right to 1.180 + pass it on as an open-source patch. The rules are pretty simple: if you 1.181 + can certify the below: 1.182 + 1.183 + Developer's Certificate of Origin 1.1 1.184 + 1.185 + By making a contribution to this project, I certify that: 1.186 + 1.187 + (a) The contribution was created in whole or in part by me and I 1.188 + have the right to submit it under the open source license 1.189 + indicated in the file; or 1.190 + 1.191 + (b) The contribution is based upon previous work that, to the best 1.192 + of my knowledge, is covered under an appropriate open source 1.193 + license and I have the right under that license to submit that 1.194 + work with modifications, whether created in whole or in part 1.195 + by me, under the same open source license (unless I am 1.196 + permitted to submit under a different license), as indicated 1.197 + in the file; or 1.198 + 1.199 + (c) The contribution was provided directly to me by some other 1.200 + person who certified (a), (b) or (c) and I have not modified 1.201 + it. 1.202 + 1.203 + (d) I understand and agree that this project and the contribution 1.204 + are public and that a record of the contribution (including all 1.205 + personal information I submit with it, including my sign-off) is 1.206 + maintained indefinitely and may be redistributed consistent with 1.207 + this project or the open source license(s) involved. 1.208 + 1.209 + then you just add a line saying 1.210 + 1.211 + Signed-off-by: Random J Developer <random@developer.example.org> 1.212 + 1.213 + using your real name (sorry, no pseudonyms or anonymous contributions.) 1.214 + 1.215 +Thanks for wanting to contribute code. 1.216 +