]> git.donarmstrong.com Git - dactyl.git/blob - common/modules/config.jsm
Import 1.0b7.1 supporting Firefox up to 8.*
[dactyl.git] / common / modules / config.jsm
1 // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
2 // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
3 // Copyright (c) 2008-2011 by Kris Maglione <maglione.k@gmail.com>
4 //
5 // This work is licensed for reuse under an MIT license. Details are
6 // given in the LICENSE.txt file included with this file.
7 "use strict";
8
9 try {
10
11 let global = this;
12 Components.utils.import("resource://dactyl/bootstrap.jsm");
13 defineModule("config", {
14     exports: ["ConfigBase", "Config", "config"],
15     require: ["services", "storage", "util", "template"],
16     use: ["io", "messages", "prefs", "styles"]
17 }, this);
18
19 var ConfigBase = Class("ConfigBase", {
20     /**
21      * Called on dactyl startup to allow for any arbitrary application-specific
22      * initialization code. Must call superclass's init function.
23      */
24     init: function init() {
25         this.features.push = deprecated("Set.add", function push(feature) Set.add(this, feature));
26         if (util.haveGecko("2b"))
27             Set.add(this.features, "Gecko2");
28
29         this.timeout(function () {
30             services["dactyl:"].pages.dtd = function () [null, util.makeDTD(config.dtd)];
31         });
32     },
33
34     loadStyles: function loadStyles(force) {
35         const { highlight } = require("highlight");
36         const { _ } = require("messages");
37
38         highlight.styleableChrome = this.styleableChrome;
39
40         highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
41         highlight.loadCSS(this.helpCSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
42
43         if (!util.haveGecko("2b"))
44             highlight.loadCSS(<![CDATA[
45                 !TabNumber               font-weight: bold; margin: 0px; padding-right: .8ex;
46                 !TabIconNumber {
47                     font-weight: bold;
48                     color: white;
49                     text-align: center;
50                     text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
51                 }
52             ]]>);
53
54         let hl = highlight.set("Find", "");
55         hl.onChange = function () {
56             function hex(val) ("#" + util.regexp.iterate(/\d+/g, val)
57                                          .map(function (num) ("0" + Number(num).toString(16)).slice(-2))
58                                          .join("")
59                               ).slice(0, 7);
60
61             let elem = services.appShell.hiddenDOMWindow.document.createElement("div");
62             elem.style.cssText = this.cssText;
63             let style = util.computedStyle(elem);
64
65             let keys = iter(Styles.propertyIter(this.cssText)).map(function (p) p.name).toArray();
66             let bg = keys.some(function (k) /^background/.test(k));
67             let fg = keys.indexOf("color") >= 0;
68
69             prefs[bg ? "safeSet" : "safeReset"]("ui.textHighlightBackground", hex(style.backgroundColor));
70             prefs[fg ? "safeSet" : "safeReset"]("ui.textHighlightForeground", hex(style.color));
71         };
72     },
73
74     get addonID() this.name + "@dactyl.googlecode.com",
75     addon: Class.memoize(function () {
76         let addon;
77         do {
78             addon = (JSMLoader.bootstrap || {}).addon;
79             if (addon && !addon.getResourceURI) {
80                 util.reportError(Error(_("addon.unavailable")));
81                 yield 10;
82             }
83         }
84         while (addon && !addon.getResourceURI);
85
86         if (!addon)
87             addon = require("addons").AddonManager.getAddonByID(this.addonID);
88         yield addon;
89     }, true),
90
91     /**
92      * The current application locale.
93      */
94     appLocale: Class.memoize(function () services.chromeRegistry.getSelectedLocale("global")),
95
96     /**
97      * The current dactyl locale.
98      */
99     locale: Class.memoize(function () this.bestLocale(this.locales)),
100
101     /**
102      * The current application locale.
103      */
104     locales: Class.memoize(function () {
105         // TODO: Merge with completion.file code.
106         function getDir(str) str.match(/^(?:.*[\/\\])?/)[0];
107
108         let uri = "resource://dactyl-locale/";
109         let jar = io.isJarURL(uri);
110         if (jar) {
111             let prefix = getDir(jar.JAREntry);
112             var res = iter(s.slice(prefix.length).replace(/\/.*/, "") for (s in io.listJar(jar.JARFile, prefix)))
113                         .toArray();
114         }
115         else {
116             res = array(f.leafName
117                         // Fails on FF3: for (f in util.getFile(uri).iterDirectory())
118                         for (f in values(util.getFile(uri).readDirectory()))
119                         if (f.isDirectory())).array;
120         }
121
122         function exists(pkg) {
123             try {
124                 services["resource:"].getSubstitution(pkg);
125                 return true;
126             }
127             catch (e) {
128                 return false;
129             }
130         }
131
132         return array.uniq([this.appLocale, this.appLocale.replace(/-.*/, "")]
133                             .filter(function (locale) exists("dactyl-locale-" + locale))
134                             .concat(res));
135     }),
136
137     /**
138      * Returns the best locale match to the current locale from a list
139      * of available locales.
140      *
141      * @param {[string]} list A list of available locales
142      * @returns {string}
143      */
144     bestLocale: function (list) {
145         let langs = Set(list);
146         return values([this.appLocale, this.appLocale.replace(/-.*/, ""),
147                        "en", "en-US", iter(langs).next()])
148             .nth(function (l) Set.has(langs, l), 0);
149     },
150
151     /**
152      * @property {string} The pathname of the VCS repository clone's root
153      *     directory if the application is running from one via an extension
154      *     proxy file.
155      */
156     VCSPath: Class.memoize(function () {
157         if (/pre$/.test(this.addon.version)) {
158             let uri = util.newURI(this.addon.getResourceURI("").spec + "../.hg");
159             if (uri instanceof Ci.nsIFileURL &&
160                     uri.file.exists() &&
161                     io.pathSearch("hg"))
162                 return uri.file.parent.path;
163         }
164         return null;
165     }),
166
167     /**
168      * @property {string} The name of the VCS branch that the application is
169      *     running from if using an extension proxy file or was built from if
170      *     installed as an XPI.
171      */
172     branch: Class.memoize(function () {
173         if (this.VCSPath)
174             return io.system(["hg", "-R", this.VCSPath, "branch"]).output;
175         return (/pre-hg\d+-(\S*)/.exec(this.version) || [])[1];
176     }),
177
178     /** @property {string} The Dactyl version string. */
179     version: Class.memoize(function () {
180         if (this.VCSPath)
181             return io.system(["hg", "-R", this.VCSPath, "log", "-r.",
182                               "--template=hg{rev}-" + this.branch + " ({date|isodate})"]).output;
183         let version = this.addon.version;
184         if ("@DATE@" !== "@" + "DATE@")
185             version += " " + _("dactyl.created", "@DATE@");
186         return version;
187     }),
188
189     get fileExt() this.name.slice(0, -6),
190
191     dtd: Class.memoize(function ()
192         iter(this.dtdExtra,
193              (["dactyl." + k, v] for ([k, v] in iter(config.dtdDactyl))),
194              (["dactyl." + s, config[s]] for each (s in config.dtdStrings)))
195             .toObject()),
196
197     dtdDactyl: memoize({
198         get name() config.name,
199         get home() "http://dactyl.sourceforge.net/",
200         get apphome() this.home + this.name,
201         code: "http://code.google.com/p/dactyl/",
202         get issues() this.home + "bug/" + this.name,
203         get plugins() "http://dactyl.sf.net/" + this.name + "/plugins",
204         get faq() this.home + this.name + "/faq",
205
206         "list.mailto": Class.memoize(function () config.name + "@googlegroups.com"),
207         "list.href": Class.memoize(function () "http://groups.google.com/group/" + config.name),
208
209         "hg.latest": Class.memoize(function () this.code + "source/browse/"), // XXX
210         "irc": "irc://irc.oftc.net/#pentadactyl",
211     }),
212
213     dtdExtra: {
214         "xmlns.dactyl": "http://vimperator.org/namespaces/liberator",
215         "xmlns.html":   "http://www.w3.org/1999/xhtml",
216         "xmlns.xul":    "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
217
218         "tag.command-line": <link topic="command-line">command line</link>,
219         "tag.status-line":  <link topic="status-line">status line</link>,
220         "mode.command-line": <link topic="command-line-mode">Command Line</link>,
221     },
222
223     dtdStrings: [
224         "appName",
225         "fileExt",
226         "host",
227         "hostbin",
228         "idName",
229         "name",
230         "version"
231     ],
232
233     helpStyles: /^(Help|StatusLine|REPL)|^(Boolean|Dense|Indicator|MoreMsg|Number|Object|Logo|Key(word)?|String)$/,
234     styleHelp: function styleHelp() {
235         if (!this.helpStyled) {
236             const { highlight } = require("highlight");
237             for (let k in keys(highlight.loaded))
238                 if (this.helpStyles.test(k))
239                     highlight.loaded[k] = true;
240         }
241         this.helpCSS = true;
242     },
243
244     Local: function Local(dactyl, modules, window) ({
245         init: function init() {
246
247             let append = <e4x xmlns={XUL} xmlns:dactyl={NS}>
248                     <menupopup id="viewSidebarMenu"/>
249                     <broadcasterset id="mainBroadcasterSet"/>
250             </e4x>;
251             for each (let [id, [name, key, uri]] in Iterator(this.sidebars)) {
252                 append.XUL::menupopup[0].* +=
253                         <menuitem observes={"pentadactyl-" + id + "Sidebar"} label={name} accesskey={key} xmlns={XUL}/>;
254                 append.XUL::broadcasterset[0].* +=
255                         <broadcaster id={"pentadactyl-" + id + "Sidebar"}
256                             autoCheck="false" type="checkbox" group="sidebar"
257                             sidebartitle={name} sidebarurl={uri}
258                             oncommand="toggleSidebar(this.id || this.observes);" xmlns={XUL}/>;
259             }
260
261             util.overlayWindow(window, { append: append.elements() });
262         },
263
264         browser: Class.memoize(function () window.gBrowser),
265         tabbrowser: Class.memoize(function () window.gBrowser),
266
267         get browserModes() [modules.modes.NORMAL],
268
269         /**
270          * @property {string} The ID of the application's main XUL window.
271          */
272         mainWindowId: window.document.documentElement.id,
273
274         /**
275          * @property {number} The height (px) that is available to the output
276          *     window.
277          */
278         get outputHeight() this.browser.mPanelContainer.boxObject.height,
279
280         tabStrip: Class.memoize(function () window.document.getElementById("TabsToolbar") || this.tabbrowser.mTabContainer),
281     }),
282
283     /**
284      * @property {Object} A mapping of names and descriptions
285      *     of the autocommands available in this application. Primarily used
286      *     for completion results.
287      */
288     autocommands: {},
289
290     /**
291      * @property {Object} A map of :command-complete option values to completer
292      *     function names.
293      */
294     completers: {
295        abbreviation: "abbreviation",
296        altstyle: "alternateStyleSheet",
297        bookmark: "bookmark",
298        buffer: "buffer",
299        charset: "charset",
300        color: "colorScheme",
301        command: "command",
302        dialog: "dialog",
303        dir: "directory",
304        environment: "environment",
305        event: "autocmdEvent",
306        extension: "extension",
307        file: "file",
308        help: "help",
309        highlight: "highlightGroup",
310        history: "history",
311        javascript: "javascript",
312        macro: "macro",
313        mapping: "userMapping",
314        mark: "mark",
315        menu: "menuItem",
316        option: "option",
317        preference: "preference",
318        qmark: "quickmark",
319        runtime: "runtime",
320        search: "search",
321        shellcmd: "shellCommand",
322        toolbar: "toolbar",
323        url: "url",
324        usercommand: "userCommand"
325     },
326
327     /**
328      * @property {Object} Application specific defaults for option values. The
329      *     property names must be the options' canonical names, and the values
330      *     must be strings as entered via :set.
331      */
332     defaults: { guioptions: "rb" },
333     cleanups: {},
334
335     /**
336      * @property {Object} A map of dialogs available via the
337      *      :dialog command. Property names map dialog names to an array
338      *      with the following elements:
339      *  [0] description - A description of the dialog, used in
340      *                    command completion results for :dialog.
341      *  [1] action - The function executed by :dialog.
342      *  [2] test - Function which returns true if the dialog is available in
343      *      the current window. @optional
344      */
345     dialogs: {},
346
347     /**
348      * @property {set} A list of features available in this
349      *    application. Used extensively in feature test macros. Use
350      *    dactyl.has(feature) to check for a feature's presence
351      *    in this array.
352      */
353     features: {},
354
355     /**
356      * @property {string} The file extension used for command script files.
357      *     This is the name string sans "dactyl".
358      */
359     get fileExtension() this.name.slice(0, -6),
360
361     guioptions: {},
362
363     hasTabbrowser: false,
364
365     /**
366      * @property {string} The name of the application that hosts the
367      *     extension. E.g., "Firefox" or "XULRunner".
368      */
369     host: null,
370
371     /**
372      * @property {[[]]} An array of application specific mode specifications.
373      *     The values of each mode are passed to modes.addMode during
374      *     dactyl startup.
375      */
376     modes: [],
377
378     /**
379      * @property {string} The name of the extension.
380      *    Required.
381      */
382     name: null,
383
384     /**
385      * @property {[string]} A list of extra scripts in the dactyl or
386      *    application namespaces which should be loaded before dactyl
387      *    initialization.
388      */
389     scripts: [],
390
391     sidebars: {},
392
393     /**
394      * @property {string} The leaf name of any temp files created by
395      *     {@link io.createTempFile}.
396      */
397     get tempFile() this.name + ".tmp",
398
399     /**
400      * @constant
401      * @property {string} The default highlighting rules.
402      * See {@link Highlights#loadCSS} for details.
403      */
404     CSS: UTF8(String.replace(<><![CDATA[
405         // <css>
406         Boolean      /* JavaScript booleans */       color: red;
407         Function     /* JavaScript functions */      color: navy;
408         Null         /* JavaScript null values */    color: blue;
409         Number       /* JavaScript numbers */        color: blue;
410         Object       /* JavaScript objects */        color: maroon;
411         String       /* String values */             color: green; white-space: pre;
412         Comment      /* JavaScriptor CSS comments */ color: gray;
413
414         Key          /* Keywords */                  font-weight: bold;
415
416         Enabled      /* Enabled item indicator text */  color: blue;
417         Disabled     /* Disabled item indicator text */ color: red;
418
419         FontFixed           /* The font used for fixed-width text */ \
420                                              font-family: monospace !important;
421         FontCode            /* The font used for code listings */ \
422                             font-size: 9pt;  font-family: monospace !important;
423         FontProportional    /* The font used for proportionally spaced text */ \
424                             font-size: 10pt; font-family: "Droid Sans", "Helvetica LT Std", Helvetica, "DejaVu Sans", Verdana, sans-serif !important;
425
426         // Hack to give these groups slightly higher precedence
427         // than their unadorned variants.
428         CmdCmdLine;[dactyl|highlight]>*  &#x0d; StatusCmdLine;[dactyl|highlight]>*
429         CmdNormal;[dactyl|highlight]     &#x0d; StatusNormal;[dactyl|highlight]
430         CmdErrorMsg;[dactyl|highlight]   &#x0d; StatusErrorMsg;[dactyl|highlight]
431         CmdInfoMsg;[dactyl|highlight]    &#x0d; StatusInfoMsg;[dactyl|highlight]
432         CmdModeMsg;[dactyl|highlight]    &#x0d; StatusModeMsg;[dactyl|highlight]
433         CmdMoreMsg;[dactyl|highlight]    &#x0d; StatusMoreMsg;[dactyl|highlight]
434         CmdQuestion;[dactyl|highlight]   &#x0d; StatusQuestion;[dactyl|highlight]
435         CmdWarningMsg;[dactyl|highlight] &#x0d; StatusWarningMsg;[dactyl|highlight]
436
437         Normal            /* Normal text */ \
438                           color: black   !important; background: white       !important; font-weight: normal !important;
439         StatusNormal      /* Normal text in the status line */ \
440                           color: inherit !important; background: transparent !important;
441         ErrorMsg          /* Error messages */ \
442                           color: white   !important; background: red         !important; font-weight: bold !important;
443         InfoMsg           /* Information messages */ \
444                           color: black   !important; background: white       !important;
445         StatusInfoMsg     /* Information messages in the status line */ \
446                           color: inherit !important; background: transparent !important;
447         LineNr            /* The line number of an error */ \
448                           color: orange  !important; background: white       !important;
449         ModeMsg           /* The mode indicator */ \
450                           color: black   !important; background: white       !important;
451         StatusModeMsg     /* The mode indicator in the status line */ \
452                           color: inherit !important; background: transparent !important; padding-right: 1em;
453         MoreMsg           /* The indicator that there is more text to view */ \
454                           color: green   !important; background: white       !important;
455         StatusMoreMsg                                background: transparent !important;
456         Message           /* A message as displayed in <ex>:messages</ex> */ \
457                           white-space: pre-wrap !important; min-width: 100%; width: 100%; padding-left: 4em; text-indent: -4em; display: block;
458         Message String    /* A message as displayed in <ex>:messages</ex> */ \
459                           white-space: pre-wrap;
460         NonText           /* The <em>~</em> indicators which mark blank lines in the completion list */ \
461                           color: blue; background: transparent !important;
462         *Preview          /* The completion preview displayed in the &tag.command-line; */ \
463                           color: gray;
464         Question          /* A prompt for a decision */ \
465                           color: green   !important; background: white       !important; font-weight: bold !important;
466         StatusQuestion    /* A prompt for a decision in the status line */ \
467                           color: green   !important; background: transparent !important;
468         WarningMsg        /* A warning message */ \
469                           color: red     !important; background: white       !important;
470         StatusWarningMsg  /* A warning message in the status line */ \
471                           color: red     !important; background: transparent !important;
472         Disabled          /* Disabled items */ \
473                           color: gray    !important;
474
475         CmdLine;>*;;FontFixed   /* The command line */ \
476                                 padding: 1px !important;
477         CmdPrompt;.dactyl-commandline-prompt  /* The default styling form the command prompt */
478         CmdInput;.dactyl-commandline-command
479         CmdOutput         /* The output of commands executed by <ex>:run</ex> */ \
480                           white-space: pre;
481
482         CompGroup                      /* Item group in completion output */
483         CompGroup:not(:first-of-type)  margin-top: .5em;
484         CompGroup:last-of-type         padding-bottom: 1.5ex;
485
486         CompTitle            /* Completion row titles */ \
487                              color: magenta; background: white; font-weight: bold;
488         CompTitle>*          padding: 0 .5ex;
489         CompTitleSep         /* The element which separates the completion title from its results */ \
490                              height: 1px; background: magenta; background: -moz-linear-gradient(60deg, magenta, white);
491
492         CompMsg              /* The message which may appear at the top of a group of completion results */ \
493                              font-style: italic; margin-left: 16px;
494
495         CompItem             /* A single row of output in the completion list */
496         CompItem:nth-child(2n+1)    background: rgba(0, 0, 0, .04);
497         CompItem[selected]   /* A selected row of completion list */ \
498                              background: yellow;
499         CompItem>*           padding: 0 .5ex;
500
501         CompIcon             /* The favicon of a completion row */ \
502                              width: 16px; min-width: 16px; display: inline-block; margin-right: .5ex;
503         CompIcon>img         max-width: 16px; max-height: 16px; vertical-align: middle;
504
505         CompResult           /* The result column of the completion list */ \
506                              width: 36%; padding-right: 1%; overflow: hidden;
507         CompDesc             /* The description column of the completion list */ \
508                              color: gray; width: 62%; padding-left: 1em;
509
510         CompLess             /* The indicator shown when completions may be scrolled up */ \
511                              text-align: center; height: 0;    line-height: .5ex; padding-top: 1ex;
512         CompLess::after      /* The character of indicator shown when completions may be scrolled up */ \
513                              content: "⌃";
514
515         CompMore             /* The indicator shown when completions may be scrolled down */ \
516                              text-align: center; height: .5ex; line-height: .5ex; margin-bottom: -.5ex;
517         CompMore::after      /* The character of indicator shown when completions may be scrolled down */ \
518                              content: "⌄";
519
520         Dense              /* Arbitrary elements which should be packed densely together */\
521                            margin-top: 0; margin-bottom: 0;
522
523         EditorEditing;;*   /* Text fields for which an external editor is open */ \
524                            background-color: #bbb !important; -moz-user-input: none !important; -moz-user-modify: read-only !important;
525         EditorError;;*     /* Text fields briefly after an error has occurred running the external editor */ \
526                            background: red !important;
527         EditorBlink1;;*    /* Text fields briefly after successfully running the external editor, alternated with EditorBlink2 */ \
528                            background: yellow !important;
529         EditorBlink2;;*    /* Text fields briefly after successfully running the external editor, alternated with EditorBlink1 */
530
531         REPL                /* Read-Eval-Print-Loop output */ \
532                             overflow: auto; max-height: 40em;
533         REPL-R;;;Question   /* Prompts in REPL mode */
534         REPL-E              /* Evaled input in REPL mode */ \
535                             white-space: pre-wrap;
536         REPL-P              /* Evaled output in REPL mode */ \
537                             white-space: pre-wrap; margin-bottom: 1em;
538
539         Usage               /* Output from the :*usage commands */ \
540                             width: 100%;
541         UsageHead           /* Headings in output from the :*usage commands */
542         UsageBody           /* The body of listings in output from the :*usage commands */
543         UsageItem           /* Individual items in output from the :*usage commands */
544         UsageItem:nth-of-type(2n)    background: rgba(0, 0, 0, .04);
545
546         Indicator   /* The <em>#</em> and  <em>%</em> in the <ex>:buffers</ex> list */ \
547                     color: blue; width: 1.5em; text-align: center;
548         Filter      /* The matching text in a completion list */ \
549                     font-weight: bold;
550
551         Keyword     /* A bookmark keyword for a URL */ \
552                     color: red;
553         Tag         /* A bookmark tag for a URL */ \
554                     color: blue;
555
556         Link                        /* A link with additional information shown on hover */ \
557                                     position: relative; padding-right: 2em;
558         Link:not(:hover)>LinkInfo   opacity: 0; left: 0; width: 1px; height: 1px; overflow: hidden;
559         LinkInfo                    {
560             /* Information shown when hovering over a link */
561             color: black;
562             position: absolute;
563             left: 100%;
564             padding: 1ex;
565             margin: -1ex -1em;
566             background: rgba(255, 255, 255, .8);
567             border-radius: 1ex;
568         }
569
570         StatusLine;;;FontFixed  {
571             /* The status bar */
572             -moz-appearance: none !important;
573             font-weight: bold;
574             background: transparent !important;
575             border: 0px !important;
576             padding-right: 0px !important;
577             min-height: 18px !important;
578             text-shadow: none !important;
579         }
580         StatusLineNormal;[dactyl|highlight]    /* The status bar for an ordinary web page */ \
581                                                color: white !important; background: black   !important;
582         StatusLineBroken;[dactyl|highlight]    /* The status bar for a broken web page */ \
583                                                color: black !important; background: #FFa0a0 !important; /* light-red */
584         StatusLineSecure;[dactyl|highlight]    /* The status bar for a secure web page */ \
585                                                color: black !important; background: #a0a0FF !important; /* light-blue */
586         StatusLineExtended;[dactyl|highlight]  /* The status bar for a secure web page with an Extended Validation (EV) certificate */ \
587                                                color: black !important; background: #a0FFa0 !important; /* light-green */
588
589         !TabClose;.tab-close-button            /* The close button of a browser tab */ \
590                                                /* The close button of a browser tab */
591         !TabIcon;.tab-icon,.tab-icon-image     /* The icon of a browser tab */ \
592                                                /* The icon of a browser tab */
593         !TabText;.tab-text                     /* The text of a browser tab */
594         TabNumber                              /* The number of a browser tab, next to its icon */ \
595                                                font-weight: bold; margin: 0px; padding-right: .8ex; cursor: default;
596         TabIconNumber  {
597             /* The number of a browser tab, over its icon */
598             cursor: default;
599             width: 16px;
600             margin: 0 2px 0 -18px !important;
601             font-weight: bold;
602             color: white;
603             text-align: center;
604             text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
605         }
606
607         Title       /* The title of a listing, including <ex>:pageinfo</ex>, <ex>:jumps</ex> */ \
608                     color: magenta; font-weight: bold;
609         URL         /* A URL */ \
610                     text-decoration: none; color: green; background: inherit;
611         URL:hover   text-decoration: underline; cursor: pointer;
612         URLExtra    /* Extra information about a URL */ \
613                     color: gray;
614
615         FrameIndicator;;* {
616             /* The styling applied to briefly indicate the active frame */
617             background-color: red;
618             opacity: 0.5;
619             z-index: 999999;
620             position: fixed;
621             top:      0;
622             bottom:   0;
623             left:     0;
624             right:    0;
625         }
626
627         Bell          /* &dactyl.appName;’s visual bell */ \
628                       background-color: black !important;
629
630         Hint;;* {
631             /* A hint indicator. See <ex>:help hints</ex> */
632             font:        bold 10px "Droid Sans Mono", monospace !important;
633             margin:      -.2ex;
634             padding:     0 0 0 1px;
635             outline:     1px solid rgba(0, 0, 0, .5);
636             background:  rgba(255, 248, 231, .8);
637             color:       black;
638         }
639         Hint[active];;*  background: rgba(255, 253, 208, .8);
640         Hint::after;;*   content: attr(text) !important;
641         HintElem;;*      /* The hintable element */ \
642                          background-color: yellow  !important; color: black !important;
643         HintActive;;*    /* The hint element of link which will be followed by <k name="CR"/> */ \
644                          background-color: #88FF00 !important; color: black !important;
645         HintImage;;*     /* The indicator which floats above hinted images */ \
646                          opacity: .5 !important;
647
648         Button                  /* A button widget */ \
649                                 display: inline-block; font-weight: bold; cursor: pointer; color: black; text-decoration: none;
650         Button:hover            text-decoration: underline;
651         Button[collapsed]       visibility: collapse; width: 0;
652         Button::before          content: "["; color: gray; text-decoration: none !important;
653         Button::after           content: "]"; color: gray; text-decoration: none !important;
654         Button:not([collapsed]) ~ Button:not([collapsed])::before  content: "/[";
655
656         Buttons                 /* A group of buttons */
657
658         DownloadCell                    /* A table cell in the :downloads manager */ \
659                                         display: table-cell; padding: 0 1ex;
660
661         Downloads                       /* The :downloads manager */ \
662                                         display: table; margin: 0; padding: 0;
663         DownloadHead;;;CompTitle        /* A heading in the :downloads manager */ \
664                                         display: table-row;
665         DownloadHead>*;;;DownloadCell
666
667         Download                        /* A download in the :downloads manager */ \
668                                         display: table-row;
669         Download:not([active])          color: gray;
670         Download:nth-child(2n+1)        background: rgba(0, 0, 0, .04);
671
672         Download>*;;;DownloadCell
673         DownloadButtons                 /* A button group in the :downloads manager */
674         DownloadPercent                 /* The percentage column for a download */
675         DownloadProgress                /* The progress column for a download */
676         DownloadProgressHave            /* The completed portion of the progress column */
677         DownloadProgressTotal           /* The remaining portion of the progress column */
678         DownloadSource                  /* The download source column for a download */
679         DownloadState                   /* The download state column for a download */
680         DownloadTime                    /* The time remaining column for a download */
681         DownloadTitle                   /* The title column for a download */
682         DownloadTitle>Link>a         max-width: 48ex; overflow: hidden; display: inline-block;
683
684         AddonCell                    /* A cell in tell :addons manager */ \
685                                      display: table-cell; padding: 0 1ex;
686
687         Addons                       /* The :addons manager */ \
688                                      display: table; margin: 0; padding: 0;
689         AddonHead;;;CompTitle        /* A heading in the :addons manager */ \
690                                      display: table-row;
691         AddonHead>*;;;AddonCell
692
693         Addon                        /* An add-on in the :addons manager */ \
694                                      display: table-row;
695         Addon:nth-child(2n+1)        background: rgba(0, 0, 0, .04);
696
697         Addon>*;;;AddonCell
698         AddonButtons
699         AddonDescription
700         AddonName                    max-width: 48ex; overflow: hidden;
701         AddonStatus
702         AddonVersion
703
704         // </css>
705     ]]></>, /&#x0d;/g, "\n")),
706
707     helpCSS: UTF8(<><![CDATA[
708         // <css>
709         InlineHelpLink                              /* A help link shown in the command line or multi-line output area */ \
710                                                     font-size: inherit !important; font-family: inherit !important;
711
712         Help;;;FontProportional                     /* A help page */ \
713                                                     line-height: 1.4em;
714
715         HelpInclude                                 /* A help page included in the consolidated help listing */ \
716                                                     margin: 2em 0;
717
718         HelpArg;;;FontCode                          /* A required command argument indicator */ \
719                                                     color: #6A97D4;
720         HelpOptionalArg;;;FontCode                  /* An optional command argument indicator */ \
721                                                     color: #6A97D4;
722
723         HelpBody                                    /* The body of a help page */ \
724                                                     display: block; margin: 1em auto; max-width: 100ex; padding-bottom: 1em; margin-bottom: 4em; border-bottom-width: 1px;
725         HelpBorder;*;dactyl://help/*                /* The styling of bordered elements */ \
726                                                     border-color: silver; border-width: 0px; border-style: solid;
727         HelpCode;;;FontCode                         /* Code listings */ \
728                                                     display: block; white-space: pre; margin-left: 2em;
729         HelpTT;html|tt;dactyl://help/*;FontCode     /* Teletype text */
730
731         HelpDefault;;;FontCode                      /* The default value of a help item */ \
732                                                     display: inline-block; margin: -1px 1ex 0 0; white-space: pre; vertical-align: text-top;
733
734         HelpDescription                             /* The description of a help item */ \
735                                                     display: block; clear: right;
736         HelpDescription[short]                      clear: none;
737         HelpEm;html|em;dactyl://help/*              /* Emphasized text */ \
738                                                     font-weight: bold; font-style: normal;
739
740         HelpEx;;;FontCode                           /* An Ex command */ \
741                                                     display: inline-block; color: #527BBD;
742
743         HelpExample                                 /* An example */ \
744                                                     display: block; margin: 1em 0;
745         HelpExample::before                         content: "__MSG_help.Example__: "; font-weight: bold;
746
747         HelpInfo                                    /* Arbitrary information about a help item */ \
748                                                     display: block; width: 20em; margin-left: auto;
749         HelpInfoLabel                               /* The label for a HelpInfo item */ \
750                                                     display: inline-block; width: 6em;  color: magenta; font-weight: bold; vertical-align: text-top;
751         HelpInfoValue                               /* The details for a HelpInfo item */ \
752                                                     display: inline-block; width: 14em; text-decoration: none;             vertical-align: text-top;
753
754         HelpItem                                    /* A help item */ \
755                                                     display: block; margin: 1em 1em 1em 10em; clear: both;
756
757         HelpKey;;;FontCode                          /* A keyboard key specification */ \
758                                                     color: #102663;
759         HelpKeyword                                 /* A keyword */ \
760                                                     font-weight: bold; color: navy;
761
762         HelpLink;html|a;dactyl://help/*             /* A hyperlink */ \
763                                                     text-decoration: none !important;
764         HelpLink[href]:hover                        text-decoration: underline !important;
765         HelpLink[href^="mailto:"]::after            content: "✉"; padding-left: .2em;
766         HelpLink[rel=external] {
767             /* A hyperlink to an external resource */
768             /* Thanks, Wikipedia */
769             background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAFVBMVEVmmcwzmcyZzP8AZswAZv////////9E6giVAAAAB3RSTlP///////8AGksDRgAAADhJREFUGFcly0ESAEAEA0Ei6/9P3sEcVB8kmrwFyni0bOeyyDpy9JTLEaOhQq7Ongf5FeMhHS/4AVnsAZubxDVmAAAAAElFTkSuQmCC) no-repeat scroll right center;
770             padding-right: 13px;
771         }
772
773         ErrorMsg HelpEx       color: inherit; background: inherit; text-decoration: underline;
774         ErrorMsg HelpKey      color: inherit; background: inherit; text-decoration: underline;
775         ErrorMsg HelpOption   color: inherit; background: inherit; text-decoration: underline;
776         ErrorMsg HelpTopic    color: inherit; background: inherit; text-decoration: underline;
777
778         HelpTOC               /* The Table of Contents for a help page */
779         HelpTOC>ol ol         margin-left: -1em;
780
781         HelpOrderedList;ol;dactyl://help/*                          /* Any ordered list */ \
782                                                                     margin: 1em 0;
783         HelpOrderedList1;ol[level="1"],ol;dactyl://help/*           /* A first-level ordered list */ \
784                                                                     list-style: outside decimal; display: block;
785         HelpOrderedList2;ol[level="2"],ol ol;dactyl://help/*        /* A second-level ordered list */ \
786                                                                     list-style: outside upper-alpha;
787         HelpOrderedList3;ol[level="3"],ol ol ol;dactyl://help/*     /* A third-level ordered list */ \
788                                                                     list-style: outside lower-roman;
789         HelpOrderedList4;ol[level="4"],ol ol ol ol;dactyl://help/*  /* A fourth-level ordered list */ \
790                                                                     list-style: outside decimal;
791
792         HelpList;html|ul;dactyl://help/*      /* An unordered list */ \
793                                               display: block; list-style-position: outside; margin: 1em 0;
794         HelpListItem;html|li;dactyl://help/*  /* A list item, ordered or unordered */ \
795                                               display: list-item;
796
797         HelpNote                                    /* The indicator for a note */ \
798                                                     color: red; font-weight: bold;
799
800         HelpOpt;;;FontCode                          /* An option name */ \
801                                                     color: #106326;
802         HelpOptInfo;;;FontCode                      /* Information about the type and default values for an option entry */ \
803                                                     display: block; margin-bottom: 1ex; padding-left: 4em;
804
805         HelpParagraph;html|p;dactyl://help/*        /* An ordinary paragraph */ \
806                                                     display: block; margin: 1em 0em;
807         HelpParagraph:first-child                   margin-top: 0;
808         HelpParagraph:last-child                    margin-bottom: 0;
809         HelpSpec;;;FontCode                         /* The specification for a help entry */ \
810                                                     display: block; margin-left: -10em; float: left; clear: left; color: #527BBD; margin-right: 1em;
811
812         HelpString;;;FontCode                       /* A quoted string */ \
813                                                     color: green; font-weight: normal;
814         HelpString::before                          content: '"';
815         HelpString::after                           content: '"';
816         HelpString[delim]::before                   content: attr(delim);
817         HelpString[delim]::after                    content: attr(delim);
818
819         HelpNews        /* A news item */           position: relative;
820         HelpNewsOld     /* An old news item */      opacity: .7;
821         HelpNewsNew     /* A new news item */       font-style: italic;
822         HelpNewsTag     /* The version tag for a news item */ \
823                         font-style: normal; position: absolute; left: 100%; padding-left: 1em; color: #527BBD; opacity: .6; white-space: pre;
824
825         HelpHead;html|h1,html|h2,html|h3,html|h4;dactyl://help/* {
826             /* Any help heading */
827             font-weight: bold;
828             color: #527BBD;
829             clear: both;
830         }
831         HelpHead1;html|h1;dactyl://help/* {
832             /* A first-level help heading */
833             margin: 2em 0 1em;
834             padding-bottom: .2ex;
835             border-bottom-width: 1px;
836             font-size: 2em;
837         }
838         HelpHead2;html|h2;dactyl://help/* {
839             /* A second-level help heading */
840             margin: 2em 0 1em;
841             padding-bottom: .2ex;
842             border-bottom-width: 1px;
843             font-size: 1.2em;
844         }
845         HelpHead3;html|h3;dactyl://help/* {
846             /* A third-level help heading */
847             margin: 1em 0;
848             padding-bottom: .2ex;
849             font-size: 1.1em;
850         }
851         HelpHead4;html|h4;dactyl://help/* {
852             /* A fourth-level help heading */
853         }
854
855         HelpTab;html|dl;dactyl://help/* {
856             /* A description table */
857             display: table;
858             width: 100%;
859             margin: 1em 0;
860             border-bottom-width: 1px;
861             border-top-width: 1px;
862             padding: .5ex 0;
863             table-layout: fixed;
864         }
865         HelpTabColumn;html|column;dactyl://help/*   display: table-column;
866         HelpTabColumn:first-child                   width: 25%;
867         HelpTabTitle;html|dt;dactyl://help/*;FontCode  /* The title column of description tables */ \
868                                                     display: table-cell; padding: .1ex 1ex; font-weight: bold;
869         HelpTabDescription;html|dd;dactyl://help/*  /* The description column of description tables */ \
870                                                     display: table-cell; padding: .3ex 1em; text-indent: -1em; border-width: 0px;
871         HelpTabDescription>*;;dactyl://help/*       text-indent: 0;
872         HelpTabRow;html|dl>html|tr;dactyl://help/*  /* Entire rows in description tables */ \
873                                                     display: table-row;
874
875         HelpTag;;;FontCode                          /* A help tag */ \
876                                                     display: inline-block; color: #527BBD; margin-left: 1ex; font-weight: normal;
877         HelpTags                                    /* A group of help tags */ \
878                                                     display: block; float: right; clear: right;
879         HelpTopic;;;FontCode                        /* A link to a help topic */ \
880                                                     color: #102663;
881         HelpType;;;FontCode                         /* An option type */ \
882                                                     color: #102663 !important; margin-right: 2ex;
883
884         HelpWarning                                 /* The indicator for a warning */ \
885                                                     color: red; font-weight: bold;
886
887         HelpXML;;;FontCode                          /* Highlighted XML */ \
888                                                     color: #C5F779; background-color: #444444; font-family: Terminus, Fixed, monospace;
889         HelpXMLBlock {                              white-space: pre; color: #C5F779; background-color: #444444;
890             border: 1px dashed #aaaaaa;
891             display: block;
892             margin-left: 2em;
893             font-family: Terminus, Fixed, monospace;
894         }
895         HelpXMLAttribute                            color: #C5F779;
896         HelpXMLAttribute::after                     color: #E5E5E5; content: "=";
897         HelpXMLComment                              color: #444444;
898         HelpXMLComment::before                      content: "<!--";
899         HelpXMLComment::after                       content: "-->";
900         HelpXMLProcessing                           color: #C5F779;
901         HelpXMLProcessing::before                   color: #444444; content: "<?";
902         HelpXMLProcessing::after                    color: #444444; content: "?>";
903         HelpXMLString                               color: #C5F779; white-space: pre;
904         HelpXMLString::before                       content: '"';
905         HelpXMLString::after                        content: '"';
906         HelpXMLNamespace                            color: #FFF796;
907         HelpXMLNamespace::after                     color: #777777; content: ":";
908         HelpXMLTagStart                             color: #FFF796; white-space: normal; display: inline-block; text-indent: -1.5em; padding-left: 1.5em;
909         HelpXMLTagEnd                               color: #71BEBE;
910         HelpXMLText                                 color: #E5E5E5;
911         // </css>
912     ]]></>)
913 }, {
914 });
915
916 JSMLoader.loadSubScript("resource://dactyl-local-content/config.js", this);
917
918 config.INIT = update(Object.create(config.INIT), config.INIT, {
919     init: function init(dactyl, modules, window) {
920         init.superapply(this, arguments);
921
922         let img = window.Image();
923         img.src = this.logo || "resource://dactyl-local-content/logo.png";
924         img.onload = util.wrapCallback(function () {
925             const { highlight } = require("highlight");
926             highlight.loadCSS(<>{"!Logo  {"}
927                      display:    inline-block;
928                      background: url({img.src});
929                      width:      {img.width}px;
930                      height:     {img.height}px;
931                  {"}"}</>);
932             img = null;
933         });
934     },
935
936     load: function load(dactyl, modules, window) {
937         load.superapply(this, arguments);
938
939         this.timeout(function () {
940             if (this.branch && this.branch !== "default" &&
941                     modules.yes_i_know_i_should_not_report_errors_in_these_branches_thanks.indexOf(this.branch) === -1)
942                 dactyl.warn(_("warn.notDefaultBranch", config.appName, this.branch));
943         }, 1000);
944     }
945 });
946
947 endModule();
948
949 } catch(e){ if (typeof e === "string") e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
950
951 // vim: set fdm=marker sw=4 sts=4 et ft=javascript: