diff --git a/common/components/protocols.js b/common/components/protocols.js index ac8f0920..21388b78 100644 --- a/common/components/protocols.js +++ b/common/components/protocols.js @@ -188,6 +188,7 @@ Dactyl.prototype = { return redirect("dactyl://help/" + tag, uri); if (tag in this.HELP_TAGS) return redirect("dactyl://help/" + this.HELP_TAGS[tag] + "#" + tag.replace(/#/g, encodeURIComponent), uri); + break; case "locale": return makeChannel(["resource://dactyl-locale", config.locale, path].join("/"), uri); case "locale-local": @@ -228,7 +229,7 @@ function StringChannel(data, contentType, uri) { } function XMLChannel(uri, contentType) { - let channel = services.io.newChannelFromURI(uri); + var channel = services.io.newChannelFromURI(uri); try { var channelStream = channel.open(); } diff --git a/common/content/help.js b/common/content/help.js index 207c7807..9faf7a2a 100644 --- a/common/content/help.js +++ b/common/content/help.js @@ -6,14 +6,18 @@ function checkFragment() { document.title = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "title")[0].textContent; - var frag = document.location.hash.substr(1); - var elem = document.getElementById(frag); + function action() { content.scrollTo(0, content.scrollY + elem.getBoundingClientRect().top - 10); // 10px context } - if (elem) { - action(); - setTimeout(action, 10); + + var frag = document.location.hash.substr(1); + if (frag) { + var elem = document.getElementById(frag); + if (elem) { + action(); + setTimeout(action, 10); + } } } diff --git a/common/content/help.xsl b/common/content/help.xsl index 0f5ae9b5..87c1597b 100644 --- a/common/content/help.xsl +++ b/common/content/help.xsl @@ -295,7 +295,10 @@ - + + + dactyl://help-tag/ + # @@ -370,6 +373,7 @@ + @@ -468,7 +472,12 @@ :set - + + + '' + + + = @@ -482,7 +491,7 @@ - + diff --git a/common/locale/en-US/cmdline.xml b/common/locale/en-US/cmdline.xml index 80f754ef..0ad33329 100644 --- a/common/locale/en-US/cmdline.xml +++ b/common/locale/en-US/cmdline.xml @@ -181,7 +181,7 @@
  • :abbreviate
  • :autocmd
  • -
  • :cabbrev
  • +
  • :cabbreviate
  • :cmap
  • :cnoremap
  • :command
  • @@ -195,7 +195,7 @@
  • :elseif
  • :execute
  • :highlight
  • -
  • :iabbrev
  • +
  • :iabbreviate
  • :if
  • :imap
  • :inoremap
  • @@ -286,8 +286,8 @@ form and a long form, such as -name and -n. Most options accept arguments, which come after the option separated by either a space or an equal sign. For instance, the following three forms, - -name=foo, -name foo, and - -n foo, are all acceptable and entirely equivalent. + -name=foo, -name foo, and + -n foo, are all acceptable and entirely equivalent.

    diff --git a/common/locale/en-US/hints.xml b/common/locale/en-US/hints.xml index baf0196c..0fb2c512 100644 --- a/common/locale/en-US/hints.xml +++ b/common/locale/en-US/hints.xml @@ -41,7 +41,7 @@ special meanings in QuickHint mode:

    -
    +
    Selects the first highlighted element, or that focused by .
    diff --git a/common/locale/en-US/intro.xml b/common/locale/en-US/intro.xml index 09fc4afa..3c1e2902 100644 --- a/common/locale/en-US/intro.xml +++ b/common/locale/en-US/intro.xml @@ -21,7 +21,7 @@ navigation, and tool bars by default. If you find it uncomfortable to work without them, you can re-enable them by typing

    -mT +mT

    If you have trouble remembering commands or keyboard shortcuts, you can bring up this help page at any time by typing :help or diff --git a/common/locale/en-US/map.xml b/common/locale/en-US/map.xml index 6bc6f7a0..c046d553 100644 --- a/common/locale/en-US/map.xml +++ b/common/locale/en-US/map.xml @@ -27,7 +27,7 @@ Key mappings are the most basic means &dactyl.appName; provides for altering the actions of key presses. Each key mapping is associated with a mode, such as insert, - normal, or + normal, or command-line, and only has effect when that mode is active. Although each mode has a full suite of internal mappings, they may be easily augmented, @@ -277,7 +277,7 @@ expected.

  • - or represent the carriage + or represent the carriage return key.
  • represents the backspace key.
  • diff --git a/common/locale/en-US/options.xml b/common/locale/en-US/options.xml index b67bfabf..488f6ce1 100644 --- a/common/locale/en-US/options.xml +++ b/common/locale/en-US/options.xml @@ -158,11 +158,11 @@

    If the option is a list, the given values are toggled. Given, - foo,bar + foo,bar then, - foo,baz + foo,baz has the same result as - bar,baz + bar,baz

    @@ -690,8 +690,8 @@

    0
    Follow the first hint as soon as typed text uniquely identifies it.
    -
    1
    Follow the selected hint on .
    -
    2
    Follow the selected hint on only if it's been -selected.
    +
    1
    Follow the selected hint on .
    +
    2
    Follow the selected hint on only if it's been -selected.
    @@ -875,7 +875,7 @@ hint. The timeout is measured since the last time a key listed in hintkeys was pressed. It has no effect when narrowing hints by typing part of their text. Set to 0 (the default) to only follow - hints after pressing or when the hint is unique. + hints after pressing or when the hint is unique.

    @@ -1131,7 +1131,7 @@ shift.

    - mail.google.com:jk<Return>,gi + mail.google.com:jk<CR>,gi

    More subtle and complex pass through can be achieved diff --git a/common/locale/en-US/repeat.xml b/common/locale/en-US/repeat.xml index e664369c..3170c1c6 100644 --- a/common/locale/en-US/repeat.xml +++ b/common/locale/en-US/repeat.xml @@ -276,7 +276,7 @@ In addition to its own JavaScript context, each script is executed with its own default group into which its styles, mappings, commands, and autocommands are placed. This - means that commands such as :comclear! can be issued + means that commands such as :delcommand! can be issued without fear of trampling other user-defined mappings. The command :group! default can be issued to clear all such items at once, and should be placed at the head of most scripts to prevent diff --git a/common/locale/en-US/styling.xml b/common/locale/en-US/styling.xml index fe08dc3f..ecd89d18 100644 --- a/common/locale/en-US/styling.xml +++ b/common/locale/en-US/styling.xml @@ -82,7 +82,7 @@

    FrameIndicator
    The indicator shown when a new frame is selected
    Function
    A JavaScript Function object
    Hint
    A hint indicator. See :help hints
    -
    HintActive
    The hint element of link which will be followed by
    +
    HintActive
    The hint element of link which will be followed by
    HintElem
    The hintable element
    HintImage
    The indicator which floats above hinted images
    Indicator
    The # and % in the :buffers list
    diff --git a/common/locale/en-US/tabs.xml b/common/locale/en-US/tabs.xml index ef3a6fd4..d894020c 100644 --- a/common/locale/en-US/tabs.xml +++ b/common/locale/en-US/tabs.xml @@ -43,7 +43,7 @@
    %
    The current buffer
    -
    #
    The alternate buffer for :e # and
    +
    #
    The alternate buffer for :buffer # and
    diff --git a/common/modules/addons.jsm b/common/modules/addons.jsm index 7a6629f2..fec2164d 100644 --- a/common/modules/addons.jsm +++ b/common/modules/addons.jsm @@ -229,9 +229,9 @@ var Addon = Class("Addon", { if (node.update && node.update !== callee) node.update(); - let event = this.document.createEvent("Events"); + let event = this.list.document.createEvent("Events"); event.initEvent("dactyl-commandupdate", true, false); - this.document.dispatchEvent(event); + this.list.document.dispatchEvent(event); } }); @@ -261,9 +261,9 @@ var AddonList = Class("AddonList", { this.ready = false; AddonManager.getAddonsByTypes(types, this.closure(function (addons) { - addons.forEach(this.closure.addAddon); - this.ready = true; - this.update(); + this._addons = addons; + if (this.document) + this._init(); })); AddonManager.addAddonListener(this); }, @@ -271,6 +271,12 @@ var AddonList = Class("AddonList", { AddonManager.removeAddonListener(this); }, + _init: function _init() { + this._addons.forEach(this.closure.addAddon); + this.ready = true; + this.update(); + }, + message: Class.memoize(function () { XML.ignoreWhitespace = true; @@ -284,6 +290,9 @@ var AddonList = Class("AddonList", { , this.document, this.nodes); + if (this._addons) + this._init(); + return this.nodes.list; }), diff --git a/common/modules/contexts.jsm b/common/modules/contexts.jsm index 96d81bf0..f9457e9d 100644 --- a/common/modules/contexts.jsm +++ b/common/modules/contexts.jsm @@ -463,6 +463,11 @@ var Contexts = Module("contexts", { if (args.context) args.context.group = group; + + util.assert(!group.builtin || + !["-description", "-locations", "-nopersist"] + .some(function (arg) set.has(args.explicitOpts, arg)), + "Cannot modify builtin group"); }, { argCount: "?", diff --git a/common/modules/javascript.jsm b/common/modules/javascript.jsm index 95561a2a..c4b8d27a 100644 --- a/common/modules/javascript.jsm +++ b/common/modules/javascript.jsm @@ -73,8 +73,10 @@ var JavaScript = Module("javascript", { let seen = isinstance(obj, ["Sandbox"]) ? set(JavaScript.magicalNames) : {}; let globals = values(toplevel && this.window === obj ? this.globalNames : []); - if (toplevel && "wrappedJSObject" in obj) + + if (toplevel && isObject(obj) && "wrappedJSObject" in obj) yield "wrappedJSObject"; + for (let key in iter(globals, properties(obj, !toplevel, true))) if (!set.add(seen, key)) yield key; diff --git a/common/tests/functional/dactyl.jsm b/common/tests/functional/dactyl.jsm index f7ce56ab..9b2a20e7 100644 --- a/common/tests/functional/dactyl.jsm +++ b/common/tests/functional/dactyl.jsm @@ -1,16 +1,8 @@ -function module(uri) { - if (!/^[a-z-]+:/.exec(uri)) - uri = /([^ ]+\/)[^\/]+$/.exec(Components.stack.filename)[1] + uri + ".jsm"; - - let obj = {}; - Components.utils.import(uri, obj); - return obj; -} +var utils = {}; Components.utils.import(/([^ ]+\/)[^\/]+$/.exec(Components.stack.filename)[1] + "utils.jsm", utils); var EXPORTED_SYMBOLS = ["Controller"]; -var utils = module("utils"); -const { NS } = utils; +const { module, NS } = utils; var elementslib = module("resource://mozmill/modules/elementslib.js"); var frame = module("resource://mozmill/modules/frame.js"); diff --git a/common/tests/functional/testHelpCommands.js b/common/tests/functional/testHelpCommands.js index cf27044d..dd0afe96 100644 --- a/common/tests/functional/testHelpCommands.js +++ b/common/tests/functional/testHelpCommands.js @@ -1,7 +1,11 @@ -const { module } = require("utils"); +const utils = require("utils"); +const { module } = utils; + var jumlib = module("resource://mozmill/modules/jum.js"); var dactyllib = module("dactyl"); +const { Services } = module("resource://gre/modules/Services.jsm"); + var setupModule = function (module) { controller = mozmill.getBrowserController(); dactyl = new dactyllib.Controller(controller); @@ -15,8 +19,15 @@ var setupTest = function (test) { dactyl.runViCommand([["VK_ESCAPE"]]); }; +function urlTarget(url) Services.io.newChannel(url, null, null).name; + +__defineGetter__("doesNotExist", function () { + delete this.doesNotExist; + return this.doesNotExist = urlTarget("dactyl://help-tag/non-existent-help-tag-url-thingy"); +}); + const HELP_FILES = ["all", "tutorial", "intro", "starting", "browsing", - "buffer", "cmdline", "insert", "options", "pattern", "tabs", "hints", + "buffer", "cmdline", "editing", "options", "pattern", "tabs", "hints", "map", "eval", "marks", "repeat", "autocommands", "print", "gui", "styling", "message", "privacy", "developer", "various", "plugins", "faq", "versions", "index"]; @@ -56,6 +67,14 @@ var testExHelpCommand_PageTagArg_OpensHelpPageContainingTag = function () { HELP_COMMAND: function () { dactyl.runExCommand("help " + tag); }, EXPECTED_HELP_TAG: tag }); + + let links = controller.tabs.activeTab.querySelectorAll("a[href^='dactyl:']"); + + let missing = Array.filter(links, function (link) urlTarget(link.href) === doesNotExist) + .map(function (link) link.textContent + " -> " + link.href); + + utils.assertEqual("testHelpCommands.assertNoDeadLinks", 0, missing.length, + "Found dead links in " + tag + ": " + missing.join(", ")); } }; diff --git a/common/tests/functional/utils.jsm b/common/tests/functional/utils.jsm index 75405085..126359c7 100644 --- a/common/tests/functional/utils.jsm +++ b/common/tests/functional/utils.jsm @@ -5,7 +5,7 @@ const Ci = Components.interfaces; function module(uri) { if (!/^[a-z-]+:/.exec(uri)) - uri = /([^ ]+\/)[^\/]+$/.exec(Components.stack.filename)[1] + uri + ".jsm"; + uri = /([^ ]+\/)[^\/]+$/.exec(Components.stack.caller.filename)[1] + uri + ".jsm"; let obj = {}; Components.utils.import(uri, obj); diff --git a/pentadactyl/locale/en-US/tutorial.xml b/pentadactyl/locale/en-US/tutorial.xml index 87118a6f..c5fb5dc5 100644 --- a/pentadactyl/locale/en-US/tutorial.xml +++ b/pentadactyl/locale/en-US/tutorial.xml @@ -26,11 +26,12 @@ regain these by issuing the command

    -mTB +mTB

    - where represents pressing the or key. - If you're a veteran Vim user, this may look familiar. It should. + where represents pressing the + or key. If you're a veteran Vim user, this + may look familiar. It should.

    @@ -143,7 +144,7 @@

    - Your standard buttons (///) will + Your standard buttons (///) will also work as expected.