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>
5 // This work is licensed for reuse under an MIT license. Details are
6 // given in the LICENSE.txt file included with this file.
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"]
19 var ConfigBase = Class("ConfigBase", {
21 * Called on dactyl startup to allow for any arbitrary application-specific
22 * initialization code. Must call superclass's init function.
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");
29 this.timeout(function () {
30 services["dactyl:"].pages.dtd = function () [null, util.makeDTD(config.dtd)];
34 loadStyles: function loadStyles(force) {
35 const { highlight } = require("highlight");
36 const { _ } = require("messages");
38 highlight.styleableChrome = this.styleableChrome;
40 highlight.loadCSS(this.CSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
41 highlight.loadCSS(this.helpCSS.replace(/__MSG_(.*?)__/g, function (m0, m1) _(m1)));
43 if (!util.haveGecko("2b"))
44 highlight.loadCSS(<![CDATA[
45 !TabNumber font-weight: bold; margin: 0px; padding-right: .8ex;
50 text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
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))
61 let elem = services.appShell.hiddenDOMWindow.document.createElement("div");
62 elem.style.cssText = this.cssText;
63 let style = util.computedStyle(elem);
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;
69 prefs[bg ? "safeSet" : "safeReset"]("ui.textHighlightBackground", hex(style.backgroundColor));
70 prefs[fg ? "safeSet" : "safeReset"]("ui.textHighlightForeground", hex(style.color));
74 get addonID() this.name + "@dactyl.googlecode.com",
75 addon: Class.memoize(function () {
78 addon = (JSMLoader.bootstrap || {}).addon;
79 if (addon && !addon.getResourceURI) {
80 util.reportError(Error(_("addon.unavailable")));
84 while (addon && !addon.getResourceURI);
87 addon = require("addons").AddonManager.getAddonByID(this.addonID);
92 * The current application locale.
94 appLocale: Class.memoize(function () services.chromeRegistry.getSelectedLocale("global")),
97 * The current dactyl locale.
99 locale: Class.memoize(function () this.bestLocale(this.locales)),
102 * The current application locale.
104 locales: Class.memoize(function () {
105 // TODO: Merge with completion.file code.
106 function getDir(str) str.match(/^(?:.*[\/\\])?/)[0];
108 let uri = "resource://dactyl-locale/";
109 let jar = io.isJarURL(uri);
111 let prefix = getDir(jar.JAREntry);
112 var res = iter(s.slice(prefix.length).replace(/\/.*/, "") for (s in io.listJar(jar.JARFile, prefix)))
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;
122 function exists(pkg) {
124 services["resource:"].getSubstitution(pkg);
132 return array.uniq([this.appLocale, this.appLocale.replace(/-.*/, "")]
133 .filter(function (locale) exists("dactyl-locale-" + locale))
138 * Returns the best locale match to the current locale from a list
139 * of available locales.
141 * @param {[string]} list A list of available locales
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);
152 * @property {string} The pathname of the VCS repository clone's root
153 * directory if the application is running from one via an extension
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 &&
162 return uri.file.parent.path;
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.
172 branch: Class.memoize(function () {
174 return io.system(["hg", "-R", this.VCSPath, "branch"]).output;
175 return (/pre-hg\d+-(\S*)/.exec(this.version) || [])[1];
178 /** @property {string} The Dactyl version string. */
179 version: Class.memoize(function () {
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@");
189 get fileExt() this.name.slice(0, -6),
191 dtd: Class.memoize(function ()
193 (["dactyl." + k, v] for ([k, v] in iter(config.dtdDactyl))),
194 (["dactyl." + s, config[s]] for each (s in config.dtdStrings)))
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",
206 "list.mailto": Class.memoize(function () config.name + "@googlegroups.com"),
207 "list.href": Class.memoize(function () "http://groups.google.com/group/" + config.name),
209 "hg.latest": Class.memoize(function () this.code + "source/browse/"), // XXX
210 "irc": "irc://irc.oftc.net/#pentadactyl",
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",
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>,
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;
244 Local: function Local(dactyl, modules, window) ({
245 init: function init() {
247 let append = <e4x xmlns={XUL} xmlns:dactyl={NS}>
248 <menupopup id="viewSidebarMenu"/>
249 <broadcasterset id="mainBroadcasterSet"/>
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}/>;
261 util.overlayWindow(window, { append: append.elements() });
264 browser: Class.memoize(function () window.gBrowser),
265 tabbrowser: Class.memoize(function () window.gBrowser),
267 get browserModes() [modules.modes.NORMAL],
270 * @property {string} The ID of the application's main XUL window.
272 mainWindowId: window.document.documentElement.id,
275 * @property {number} The height (px) that is available to the output
278 get outputHeight() this.browser.mPanelContainer.boxObject.height,
280 tabStrip: Class.memoize(function () window.document.getElementById("TabsToolbar") || this.tabbrowser.mTabContainer),
284 * @property {Object} A mapping of names and descriptions
285 * of the autocommands available in this application. Primarily used
286 * for completion results.
291 * @property {Object} A map of :command-complete option values to completer
295 abbreviation: "abbreviation",
296 altstyle: "alternateStyleSheet",
297 bookmark: "bookmark",
300 color: "colorScheme",
304 environment: "environment",
305 event: "autocmdEvent",
306 extension: "extension",
309 highlight: "highlightGroup",
311 javascript: "javascript",
313 mapping: "userMapping",
317 preference: "preference",
321 shellcmd: "shellCommand",
324 usercommand: "userCommand"
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.
332 defaults: { guioptions: "rb" },
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
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
356 * @property {string} The file extension used for command script files.
357 * This is the name string sans "dactyl".
359 get fileExtension() this.name.slice(0, -6),
363 hasTabbrowser: false,
366 * @property {string} The name of the application that hosts the
367 * extension. E.g., "Firefox" or "XULRunner".
372 * @property {[[]]} An array of application specific mode specifications.
373 * The values of each mode are passed to modes.addMode during
379 * @property {string} The name of the extension.
385 * @property {[string]} A list of extra scripts in the dactyl or
386 * application namespaces which should be loaded before dactyl
394 * @property {string} The leaf name of any temp files created by
395 * {@link io.createTempFile}.
397 get tempFile() this.name + ".tmp",
401 * @property {string} The default highlighting rules.
402 * See {@link Highlights#loadCSS} for details.
404 CSS: UTF8(String.replace(<><![CDATA[
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;
414 Key /* Keywords */ font-weight: bold;
416 Enabled /* Enabled item indicator text */ color: blue;
417 Disabled /* Disabled item indicator text */ color: red;
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;
426 // Hack to give these groups slightly higher precedence
427 // than their unadorned variants.
428 CmdCmdLine;[dactyl|highlight]>* 
 StatusCmdLine;[dactyl|highlight]>*
429 CmdNormal;[dactyl|highlight] 
 StatusNormal;[dactyl|highlight]
430 CmdErrorMsg;[dactyl|highlight] 
 StatusErrorMsg;[dactyl|highlight]
431 CmdInfoMsg;[dactyl|highlight] 
 StatusInfoMsg;[dactyl|highlight]
432 CmdModeMsg;[dactyl|highlight] 
 StatusModeMsg;[dactyl|highlight]
433 CmdMoreMsg;[dactyl|highlight] 
 StatusMoreMsg;[dactyl|highlight]
434 CmdQuestion;[dactyl|highlight] 
 StatusQuestion;[dactyl|highlight]
435 CmdWarningMsg;[dactyl|highlight] 
 StatusWarningMsg;[dactyl|highlight]
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; */ \
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;
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> */ \
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;
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);
492 CompMsg /* The message which may appear at the top of a group of completion results */ \
493 font-style: italic; margin-left: 16px;
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 */ \
499 CompItem>* padding: 0 .5ex;
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;
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;
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 */ \
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 */ \
520 Dense /* Arbitrary elements which should be packed densely together */\
521 margin-top: 0; margin-bottom: 0;
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 */
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;
539 Usage /* Output from the :*usage commands */ \
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);
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 */ \
551 Keyword /* A bookmark keyword for a URL */ \
553 Tag /* A bookmark tag for a URL */ \
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;
560 /* Information shown when hovering over a link */
566 background: rgba(255, 255, 255, .8);
570 StatusLine;;;FontFixed {
572 -moz-appearance: none !important;
574 background: transparent !important;
575 border: 0px !important;
576 padding-right: 0px !important;
577 min-height: 18px !important;
578 text-shadow: none !important;
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 */
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;
597 /* The number of a browser tab, over its icon */
600 margin: 0 2px 0 -18px !important;
604 text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
607 Title /* The title of a listing, including <ex>:pageinfo</ex>, <ex>:jumps</ex> */ \
608 color: magenta; font-weight: bold;
610 text-decoration: none; color: green; background: inherit;
611 URL:hover text-decoration: underline; cursor: pointer;
612 URLExtra /* Extra information about a URL */ \
616 /* The styling applied to briefly indicate the active frame */
617 background-color: red;
627 Bell /* &dactyl.appName;’s visual bell */ \
628 background-color: black !important;
631 /* A hint indicator. See <ex>:help hints</ex> */
632 font: bold 10px "Droid Sans Mono", monospace !important;
635 outline: 1px solid rgba(0, 0, 0, .5);
636 background: rgba(255, 248, 231, .8);
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;
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: "/[";
656 Buttons /* A group of buttons */
658 DownloadCell /* A table cell in the :downloads manager */ \
659 display: table-cell; padding: 0 1ex;
661 Downloads /* The :downloads manager */ \
662 display: table; margin: 0; padding: 0;
663 DownloadHead;;;CompTitle /* A heading in the :downloads manager */ \
665 DownloadHead>*;;;DownloadCell
667 Download /* A download in the :downloads manager */ \
669 Download:not([active]) color: gray;
670 Download:nth-child(2n+1) background: rgba(0, 0, 0, .04);
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;
684 AddonCell /* A cell in tell :addons manager */ \
685 display: table-cell; padding: 0 1ex;
687 Addons /* The :addons manager */ \
688 display: table; margin: 0; padding: 0;
689 AddonHead;;;CompTitle /* A heading in the :addons manager */ \
691 AddonHead>*;;;AddonCell
693 Addon /* An add-on in the :addons manager */ \
695 Addon:nth-child(2n+1) background: rgba(0, 0, 0, .04);
700 AddonName max-width: 48ex; overflow: hidden;
705 ]]></>, /
/g, "\n")),
707 helpCSS: UTF8(<><![CDATA[
709 InlineHelpLink /* A help link shown in the command line or multi-line output area */ \
710 font-size: inherit !important; font-family: inherit !important;
712 Help;;;FontProportional /* A help page */ \
715 HelpInclude /* A help page included in the consolidated help listing */ \
718 HelpArg;;;FontCode /* A required command argument indicator */ \
720 HelpOptionalArg;;;FontCode /* An optional command argument indicator */ \
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 */
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;
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;
740 HelpEx;;;FontCode /* An Ex command */ \
741 display: inline-block; color: #527BBD;
743 HelpExample /* An example */ \
744 display: block; margin: 1em 0;
745 HelpExample::before content: "__MSG_help.Example__: "; font-weight: bold;
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;
754 HelpItem /* A help item */ \
755 display: block; margin: 1em 1em 1em 10em; clear: both;
757 HelpKey;;;FontCode /* A keyboard key specification */ \
759 HelpKeyword /* A keyword */ \
760 font-weight: bold; color: navy;
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;
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;
778 HelpTOC /* The Table of Contents for a help page */
779 HelpTOC>ol ol margin-left: -1em;
781 HelpOrderedList;ol;dactyl://help/* /* Any ordered list */ \
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;
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 */ \
797 HelpNote /* The indicator for a note */ \
798 color: red; font-weight: bold;
800 HelpOpt;;;FontCode /* An option name */ \
802 HelpOptInfo;;;FontCode /* Information about the type and default values for an option entry */ \
803 display: block; margin-bottom: 1ex; padding-left: 4em;
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;
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);
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;
825 HelpHead;html|h1,html|h2,html|h3,html|h4;dactyl://help/* {
826 /* Any help heading */
831 HelpHead1;html|h1;dactyl://help/* {
832 /* A first-level help heading */
834 padding-bottom: .2ex;
835 border-bottom-width: 1px;
838 HelpHead2;html|h2;dactyl://help/* {
839 /* A second-level help heading */
841 padding-bottom: .2ex;
842 border-bottom-width: 1px;
845 HelpHead3;html|h3;dactyl://help/* {
846 /* A third-level help heading */
848 padding-bottom: .2ex;
851 HelpHead4;html|h4;dactyl://help/* {
852 /* A fourth-level help heading */
855 HelpTab;html|dl;dactyl://help/* {
856 /* A description table */
860 border-bottom-width: 1px;
861 border-top-width: 1px;
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 */ \
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 */ \
881 HelpType;;;FontCode /* An option type */ \
882 color: #102663 !important; margin-right: 2ex;
884 HelpWarning /* The indicator for a warning */ \
885 color: red; font-weight: bold;
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;
893 font-family: Terminus, Fixed, monospace;
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;
916 JSMLoader.loadSubScript("resource://dactyl-local-content/config.js", this);
918 config.INIT = update(Object.create(config.INIT), config.INIT, {
919 init: function init(dactyl, modules, window) {
920 init.superapply(this, arguments);
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;
936 load: function load(dactyl, modules, window) {
937 load.superapply(this, arguments);
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));
949 } catch(e){ if (typeof e === "string") e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
951 // vim: set fdm=marker sw=4 sts=4 et ft=javascript: