Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | |
michael@0 | 2 | # Developing GCLI |
michael@0 | 3 | |
michael@0 | 4 | ## About the code |
michael@0 | 5 | |
michael@0 | 6 | The majority of the GCLI source is stored in the ``lib`` directory. |
michael@0 | 7 | |
michael@0 | 8 | The ``docs`` directory contains documentation. |
michael@0 | 9 | The ``scripts`` directory contains RequireJS that GCLI uses. |
michael@0 | 10 | The ``build`` directory contains files used when creating builds. |
michael@0 | 11 | The ``mozilla`` directory contains the mercurial patch queue of patches to apply |
michael@0 | 12 | to mozilla-central. |
michael@0 | 13 | The ``selenium-tests`` directory contains selenium web-page integration tests. |
michael@0 | 14 | |
michael@0 | 15 | The source in the ``lib`` directory is split into 4 sections: |
michael@0 | 16 | |
michael@0 | 17 | - ``lib/demo`` contains commands used in the demo page. It is not needed except |
michael@0 | 18 | for demo purposes. |
michael@0 | 19 | - ``lib/test`` contains a small test harness for testing GCLI. |
michael@0 | 20 | - ``lib/gclitest`` contains tests that run in the test harness |
michael@0 | 21 | - ``lib/gcli`` contains the actual meat |
michael@0 | 22 | |
michael@0 | 23 | GCLI is split into a UI portion and a Model/Controller portion. |
michael@0 | 24 | |
michael@0 | 25 | |
michael@0 | 26 | ## The GCLI Model |
michael@0 | 27 | |
michael@0 | 28 | The heart of GCLI is a ``Requisition``, which is an AST for the input. A |
michael@0 | 29 | ``Requisition`` is a command that we'd like to execute, and we're filling out |
michael@0 | 30 | all the inputs required to execute the command. |
michael@0 | 31 | |
michael@0 | 32 | A ``Requisition`` has a ``Command`` that is to be executed. Each Command has a |
michael@0 | 33 | number of ``Parameter``s, each of which has a name and a type as detailed |
michael@0 | 34 | above. |
michael@0 | 35 | |
michael@0 | 36 | As you type, your input is split into ``Argument``s, which are then assigned to |
michael@0 | 37 | ``Parameter``s using ``Assignment``s. Each ``Assignment`` has a ``Conversion`` |
michael@0 | 38 | which stores the input argument along with the value that is was converted into |
michael@0 | 39 | according to the type of the parameter. |
michael@0 | 40 | |
michael@0 | 41 | There are special assignments called ``CommandAssignment`` which the |
michael@0 | 42 | ``Requisition`` uses to link to the command to execute, and |
michael@0 | 43 | ``UnassignedAssignment``used to store arguments that do not have a parameter |
michael@0 | 44 | to be assigned to. |
michael@0 | 45 | |
michael@0 | 46 | |
michael@0 | 47 | ## The GCLI UI |
michael@0 | 48 | |
michael@0 | 49 | There are several components of the GCLI UI. Each can have a script portion, |
michael@0 | 50 | some template HTML and a CSS file. The template HTML is processed by |
michael@0 | 51 | ``domtemplate`` before use. |
michael@0 | 52 | |
michael@0 | 53 | DomTemplate is fully documented in [it's own repository] |
michael@0 | 54 | (https://github.com/joewalker/domtemplate). |
michael@0 | 55 | |
michael@0 | 56 | The components are: |
michael@0 | 57 | |
michael@0 | 58 | - ``Inputter`` controls the input field, processing special keyboard events and |
michael@0 | 59 | making sure that it stays in sync with the Requisition. |
michael@0 | 60 | - ``Completer`` updates a div that is located behind the input field and used |
michael@0 | 61 | to display completion advice and hint highlights. It is stored in |
michael@0 | 62 | completer.js. |
michael@0 | 63 | - ``Display`` is responsible for containing the popup hints that are displayed |
michael@0 | 64 | above the command line. Typically Display contains a Hinter and a RequestsView |
michael@0 | 65 | although these are not both required. Display itself is optional, and isn't |
michael@0 | 66 | planned for use in the first release of GCLI in Firefox. |
michael@0 | 67 | - ``Hinter`` Is used to display input hints. It shows either a Menu or an |
michael@0 | 68 | ArgFetch component depending on the state of the Requisition |
michael@0 | 69 | - ``Menu`` is used initially to select the command to be executed. It can act |
michael@0 | 70 | somewhat like the Start menu on windows. |
michael@0 | 71 | - ``ArgFetch`` Once the command to be executed has been selected, ArgFetch |
michael@0 | 72 | shows a 'dialog' allowing the user to enter the parameters to the selected |
michael@0 | 73 | command. |
michael@0 | 74 | - ``RequestsView`` Contains a set of ``RequestView`` components, each of which |
michael@0 | 75 | displays a command that has been invoked. RequestsView is a poor name, and |
michael@0 | 76 | should better be called ReportView |
michael@0 | 77 | |
michael@0 | 78 | ArgFetch displays a number of Fields. There are fields for most of the Types |
michael@0 | 79 | discussed earlier. See 'Writing Fields' above for more information. |
michael@0 | 80 | |
michael@0 | 81 | |
michael@0 | 82 | ## Testing |
michael@0 | 83 | |
michael@0 | 84 | GCLI contains 2 test suites: |
michael@0 | 85 | |
michael@0 | 86 | - JS level testing is run with the ``test`` command. The tests are located in |
michael@0 | 87 | ``lib/gclitest`` and they use the test runner in ``lib/test``. This is fairly |
michael@0 | 88 | comprehensive, however it does not do UI level testing. |
michael@0 | 89 | If writing a new test it needs to be registered in ``lib/gclitest/index``. |
michael@0 | 90 | For an example of how to write tests, see ``lib/gclitest/testSplit.js``. |
michael@0 | 91 | The test functions are implemented in ``lib/test/assert``. |
michael@0 | 92 | - Browser integration tests are included in ``browser_webconsole_gcli_*.js``, |
michael@0 | 93 | in ``toolkit/components/console/hudservice/tests/browser``. These are |
michael@0 | 94 | run with the rest of the Mozilla test suite. |
michael@0 | 95 | |
michael@0 | 96 | |
michael@0 | 97 | ## Coding Conventions |
michael@0 | 98 | |
michael@0 | 99 | The coding conventions for the GCLI project come from the Bespin/Skywriter and |
michael@0 | 100 | Ace projects. They are roughly [Crockford] |
michael@0 | 101 | (http://javascript.crockford.com/code.html) with a few exceptions and |
michael@0 | 102 | additions: |
michael@0 | 103 | |
michael@0 | 104 | * ``var`` does not need to be at the top of each function, we'd like to move |
michael@0 | 105 | to ``let`` when it's generally available, and ``let`` doesn't have the same |
michael@0 | 106 | semantic twists as ``var``. |
michael@0 | 107 | |
michael@0 | 108 | * Strings are generally enclosed in single quotes. |
michael@0 | 109 | |
michael@0 | 110 | * ``eval`` is to be avoided, but we don't declare it evil. |
michael@0 | 111 | |
michael@0 | 112 | The [Google JavaScript conventions] |
michael@0 | 113 | (https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) are |
michael@0 | 114 | more detailed, we tend to deviate in: |
michael@0 | 115 | |
michael@0 | 116 | * Custom exceptions: We generally just use ``throw new Error('message');`` |
michael@0 | 117 | |
michael@0 | 118 | * Multi-level prototype hierarchies: Allowed; we don't have ``goog.inherits()`` |
michael@0 | 119 | |
michael@0 | 120 | * ``else`` begins on a line by itself: |
michael@0 | 121 | |
michael@0 | 122 | if (thing) { |
michael@0 | 123 | doThis(); |
michael@0 | 124 | } |
michael@0 | 125 | else { |
michael@0 | 126 | doThat(); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | |
michael@0 | 130 | ## Startup |
michael@0 | 131 | |
michael@0 | 132 | Internally GCLI modules have ``startup()``/``shutdown()`` functions which are |
michael@0 | 133 | called on module init from the top level ``index.js`` of that 'package'. |
michael@0 | 134 | |
michael@0 | 135 | In order to initialize a package all that is needed is to require the package |
michael@0 | 136 | index (e.g. ``require('package/index')``). |
michael@0 | 137 | |
michael@0 | 138 | The ``shutdown()`` function was useful when GCLI was used in Bespin as part of |
michael@0 | 139 | dynamic registration/de-registration. It is not known if this feature will be |
michael@0 | 140 | useful in the future. So it has not been entirely removed, it may be at some |
michael@0 | 141 | future date. |
michael@0 | 142 | |
michael@0 | 143 | |
michael@0 | 144 | ## Running the Unit Tests |
michael@0 | 145 | |
michael@0 | 146 | Start the GCLI static server: |
michael@0 | 147 | |
michael@0 | 148 | cd path/to/gcli |
michael@0 | 149 | node gcli.js |
michael@0 | 150 | |
michael@0 | 151 | Now point your browser to http://localhost:9999/localtest.html. When the page |
michael@0 | 152 | loads the tests will be automatically run outputting to the console, or you can |
michael@0 | 153 | enter the ``test`` command to run the unit tests. |
michael@0 | 154 | |
michael@0 | 155 | |
michael@0 | 156 | ## Contributing Code |
michael@0 | 157 | |
michael@0 | 158 | Please could you do the following to help minimize the amount of rework that we |
michael@0 | 159 | do: |
michael@0 | 160 | |
michael@0 | 161 | 1. Check the unit tests run correctly (see **Running the Unit Tests** above) |
michael@0 | 162 | 2. Check the code follows the style guide. At a minimum it should look like the |
michael@0 | 163 | code around it. For more detailed notes, see **Coding Conventions** above |
michael@0 | 164 | 3. Help me review your work by using good commit comments. Which means 2 things |
michael@0 | 165 | * Well formatted messages, i.e. 50 char summary including bug tag, followed |
michael@0 | 166 | by a blank line followed by a more in-depth message wrapped to 72 chars |
michael@0 | 167 | per line. This is basically the format used by the Linux Kernel. See the |
michael@0 | 168 | [commit log](https://github.com/joewalker/gcli/commits/master) for |
michael@0 | 169 | examples. The be extra helpful, please use the "shortdesc-BUGNUM: " if |
michael@0 | 170 | possible which also helps in reviews. |
michael@0 | 171 | * Commit your changes as a story. Make it easy for me to understand the |
michael@0 | 172 | changes that you've made. |
michael@0 | 173 | 4. Sign your work. To improve tracking of who did what, we follow the sign-off |
michael@0 | 174 | procedure used in the Linux Kernel. |
michael@0 | 175 | The sign-off is a simple line at the end of the explanation for the |
michael@0 | 176 | patch, which certifies that you wrote it or otherwise have the right to |
michael@0 | 177 | pass it on as an open-source patch. The rules are pretty simple: if you |
michael@0 | 178 | can certify the below: |
michael@0 | 179 | |
michael@0 | 180 | Developer's Certificate of Origin 1.1 |
michael@0 | 181 | |
michael@0 | 182 | By making a contribution to this project, I certify that: |
michael@0 | 183 | |
michael@0 | 184 | (a) The contribution was created in whole or in part by me and I |
michael@0 | 185 | have the right to submit it under the open source license |
michael@0 | 186 | indicated in the file; or |
michael@0 | 187 | |
michael@0 | 188 | (b) The contribution is based upon previous work that, to the best |
michael@0 | 189 | of my knowledge, is covered under an appropriate open source |
michael@0 | 190 | license and I have the right under that license to submit that |
michael@0 | 191 | work with modifications, whether created in whole or in part |
michael@0 | 192 | by me, under the same open source license (unless I am |
michael@0 | 193 | permitted to submit under a different license), as indicated |
michael@0 | 194 | in the file; or |
michael@0 | 195 | |
michael@0 | 196 | (c) The contribution was provided directly to me by some other |
michael@0 | 197 | person who certified (a), (b) or (c) and I have not modified |
michael@0 | 198 | it. |
michael@0 | 199 | |
michael@0 | 200 | (d) I understand and agree that this project and the contribution |
michael@0 | 201 | are public and that a record of the contribution (including all |
michael@0 | 202 | personal information I submit with it, including my sign-off) is |
michael@0 | 203 | maintained indefinitely and may be redistributed consistent with |
michael@0 | 204 | this project or the open source license(s) involved. |
michael@0 | 205 | |
michael@0 | 206 | then you just add a line saying |
michael@0 | 207 | |
michael@0 | 208 | Signed-off-by: Random J Developer <random@developer.example.org> |
michael@0 | 209 | |
michael@0 | 210 | using your real name (sorry, no pseudonyms or anonymous contributions.) |
michael@0 | 211 | |
michael@0 | 212 | Thanks for wanting to contribute code. |
michael@0 | 213 |