Hook

mooz edited this page Sep 13, 2010 · 4 revisions

Notes on this page.

The eval command will be useful to confirm the code in this page.

M-: (in another way, Alt + : ) , input a code with a prompt and hit
the Enter. The eval command is a good friend of developers.

For a detailed explanation, see this page.

Hooks

KeySnail supports hooks in order to bind functions to hook points in programs.

For example, to register a function to the KeyPress hook, add the following code.

hook.addToHook("KeyPress",
               function (aKey) {
                   display.prettyPrint(aKey + " pressed");
               });

This code makes display.prettyPrint(aKey + " pressed") is executed by
each user’s key input. In this case, the function displays the key name.

In order to register functions to hook points, use addToHook or
setHook. Both of two functions takes same arguments, but addToHook
add a function to the last of the hook point, while setHook deletes
all the functions that are already registered to the hook, and add a function.

Therefore, when you want to register hooks in a plugin, you should always use addToHook.

Arguments that are passed to hook points differ in each hook point.
See the below.

KeyPress

Timing

Functions registered to the hook are called in each user’s key input.

Arguments

Functions registered to the hook are passed the @string representation
of key inputs (with the KeySnail format).

Example.

hook.addToHook("KeyPress",
               function (aKey) {
                   display.prettyPrint(aKey + " pressed");
               });

The string representation of inputted keys are passed to aKey and displays it.

KeyBoardQuit

Timing

Functions registered to the hook are called when key.quitKey (C-g, in default) is inputted.

Arguments

Key event is passed to the functions registered to the hook.

Example

hook.setHook('KeyBoardQuit', function (aEvent) {
    if (key.currentKeySequence.length)
        return;

    command.closeFindBar();

    if (util.isCaretEnabled())
        command.resetMark(aEvent);
    else             
        goDoCommand("cmd_selectNone");

    if (KeySnail.windowType == "navigator:browser")
        key.generateKey(aEvent.originalTarget, KeyEvent.DOM_VK_ESCAPE, true);
});

Many users probably already wrote this code in .keysnail.js. As usual
ways, because you cannot bind a command to key.quitKey, you have to
register a command to the hook point like this code.

PreCommand, PostCommand

Timing

Functions that are registered to the hook is called before the
command is called (PreCommand), or after it (PostCommand).

Arguments

To functions registered to the hook, objects like the below are passed:

var hookArg = {
            func  : aFunc,
            event : aEvent,
            arg   : aArg
        };

In func, command body (function), in event key event , and in arg prefix arguments are contained.

Special Behaviour

You can cancel the command itself by throwing an exception inside a function registered to PreCommand hook.

Example

hook.addToHook("PostCommand",
               function (aHookArg) {
                   var func = aHookArg.func;
                   display.prettyPrint(func.ksDescription + " executed");
               });

In this case, you get the ‘command body’ as aHookArg and its description as func.ksDescription, and displays it.

ClipboardChanged

Timing

Functions that are registered to the hook is called when the
content of the clipboard is changed, i.e., when user copies a text.

Arguments

Content of the text copied by user is passed.

Special Behaviour

When an exception is thrown inside a function registered to PreCommand, the text is not contained to the kill ring.

Example

hook.addToHook("ClipboardChanged",
               function (aText) {
                   util.alert("Clipboard Changed!", aText + " copied");
               });

In this case, it shows a dialog with the text copied at the time.

LocationChange

Timing

When the value of the location bar is changed, i.e., when the page is
loaded or tab is switched.

Arguments

Object that contains URI of the loaded page or the switched tab is passed.

URL as a string is saved in the spec property.

Example

hook.addToHook('LocationChange', function (aNsURI) {
    if (aNsURI || aNsURI.spec) {
        var url = aNsURI.spec;

        display.prettyPrint(url);
    }
});

In this case, displays a URL at the right upper side of the screen
when a tab is switched etc.

It will be useful when you want to set actions for particular web
sites like GreaseMonkey.

PluginLoaded

Timing

Functions that are registered to the hook is called when all the
plugins are loaded.

Arguments

This hook does not pass any argument.

This hook is useful when a plugin changes or overwrites values of other plugins.

KeySnail loads plugins by this order:

  1. Plugins whose name starts with “_” (library)
  2. Init file (.keysnail.js)
  3. Other plugins by alphabetical order

If a plugin in phase 3 tries to use or overwrite values of other
plugins, it will fail because Keysnail does not assur that the other
plugin is not loaded before the plugin. (Indeed you can change the name of the other plugin.)

PluginLoaded hook is the solution. Functions that are registered to
the hook is called after all the plugins are loaded.

  1. Plugins whose name starts with “_” (library)
  2. Init file (.keysnail.js)
  3. Other plugins by alphabetical order
  4. Execute functions that are registered to PluginLoaded

You can safely use or change values of other plugins because when
registered functions are called, all plugins has been already loaded.

For example, The caret hit plugin registers a function to this hook in
order to overwrite the value of extended hint mode action of the HoK plugin.

hook.addToHook('PluginLoaded', function () {
    if (!plugins.hok)
        return;

    var actions = [
        [headMode, M({ja: "キャレットを要素の先頭へ移動", en: "Move caret to the head of the selected element"}),
         function (e) moveCaret(e, true, false)],
        [tailMode, M({ja: "キャレットを要素の末尾へ移動", en: "Move caret to the tail of the selected element"}),
         function (e) moveCaret(e, false, false)],
        [selectHeadMode, M({ja: "要素を選択してキャレットを先頭へ移動", en: "Select element and move caret to the head"}),
         function (e) moveCaret(e, false, true)],
        [selectTailMode, M({ja: "要素を選択してキャレットを末尾へ移動", en: "Select element and move caret to the tail"}),
         function (e) moveCaret(e, false, true)]
    ];
// omitted.

Unload

Timing

Functions that are registered to the hook are called when the main
window of Firefox is closed.

Arguments

This hook does not pass any argument.

Example

Functions that are registered to the hook behaves like destructors. It
will be useful when you want to do actions when a plugin is killed.

Versions

Unload hook is available since KeySnail 1.1.8.

KeySnailInitialized

Timing

Functions set to this hook called when KeySnail’s initialization is done.

Arguments

This hook gives no argument.

Version

KeySnailInitialized hook is available from KeySnail 1.3.2.