diff --git a/boot/boot.js b/boot/boot.js index 06d4628c0..1468e00b6 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -2674,6 +2674,18 @@ $tw.hooks.addHook = function(hookName,definition) { } }; +/* +Delete hooks from the hashmap +*/ +$tw.hooks.removeHook = function(hookName,definition) { + if($tw.utils.hop($tw.hooks.names,hookName)) { + var p = $tw.hooks.names[hookName].indexOf(definition); + if(p !== -1) { + $tw.hooks.names[hookName].splice(p, 1); + } + } +}; + /* Invoke the hook by key */ diff --git a/editions/dev/tiddlers/new/HookMechanism.tid b/editions/dev/tiddlers/new/HookMechanism.tid index 0034c9fab..4e4659bca 100644 --- a/editions/dev/tiddlers/new/HookMechanism.tid +++ b/editions/dev/tiddlers/new/HookMechanism.tid @@ -1,9 +1,14 @@ created: 20141122200310516 -modified: 20201213161842776 +modified: 20230923031318421 +tags: Mechanisms title: HookMechanism type: text/vnd.tiddlywiki -The hook mechanism provides a way for plugins to intercept and modify default functionality. Hooks are added as follows: +The hook mechanism provides a way for plugins to intercept and modify default functionality. + +!! Add a hook + +Hooks are added as follows: ```js /* @@ -13,6 +18,8 @@ handler: function to be called when hook is invoked $tw.hooks.addHook(name,handler); ``` +!!! Params and return + The handler function will be called with parameters that depend on the specific hook in question, but they always follow the pattern `handler(value,params...)` * ''value'': an optional value that is to be transformed by the hook function @@ -20,11 +27,29 @@ The handler function will be called with parameters that depend on the specific If required by the hook in question, the handler function must return the modified ''value''. +!!! Multiple handlers + Multiple handlers can be assigned to the same name using repeated calls. When a hook is invoked by name all registered functions will be called sequentially in their order of addition. Note that the ''value'' passed to the subsequent hook function will be the return value of the previous hook function. -Though not essential care should be taken to ensure that hooks are added before they are invoked. For example: [[Hook: th-opening-default-tiddlers-list]] should ideally be added before the story startup module is invoked otherwise any hook specified additions to the default tiddlers will not be seen on the initial loading of the page, though will be visible if the user clicks the home button. +Be careful not to `addHook` in widget's `render` method, which will be call several times. You could `addHook` in methods that only called once, e.g. the constructor of widget class. Otherwise you should `removeHook` then add it again. + +!!! Timing of registration + +Though not essential care should be taken to ensure that hooks are added before they are invoked. + +For example: [[Hook: th-opening-default-tiddlers-list]] should ideally be added before the story startup module is invoked. Otherwise any hook specified additions to the default tiddlers will not be seen on the initial loading of the page, though will be visible if the user clicks the home button. + +!! Remove a hook + +You should clean up the callback when your widget is going to unmount. + +```js +$tw.hooks.removeHook(handler) +``` + +The `handler` should be the same function instance you used in `addHook` (check by `===`). You can save it to `this.xxxHookHandler` on your widget, and call `removeHook` in [[destroy method|Widget `destroy` method examples]]. !! Example