I’ve implemented action-hook and here it is FWIW:
/*\
title: action-hook.js
type: application/javascript
module-type: widget
$action-hook invokes actions after a hook has been triggered
Can be persistent or one time
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
let autoId = 0;
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var HookWidget= function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
HookWidget.prototype = new Widget();
HookWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
};
HookWidget.prototype.execute = function() {
this.id = this.getAttribute("id", autoId++);
this.clear = this.getAttribute("clear", "");
this.persistent = this.getAttribute("persistent", "");
this.name = this.getAttribute("name", "");
this.actions = this.getAttribute("actions", "");
if (this.getAttribute("autostart")) this.invokeAction();
};
HookWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(Object.keys(changedAttributes).length > 0) {
this.refreshSelf(); return true;
}
return this.refreshChildren(changedTiddlers);
};
HookWidget.prototype.allowActionPropagation = function() {
return false;
};
HookWidget.prototype.functionDefinition = function(event) {
const func = new Function('widget', 'actions', 'event',
`return function hook_${this.id}(){widget.invokeActionString(actions, widget, event)}`
)(this, this.actions, event);
func.id = this.id;
return func;
}
HookWidget.prototype.removeHook = function() {
const self = this
const p = $tw.hooks.names[this.name].findIndex(f => f.id == self.id)
if (p != -1) {
$tw.hooks.names[this.name].splice(p, 1);
}
}
HookWidget.prototype.invokeAction = function(triggeringWidget,event) {
const self = this;
const func = function() {
self.invokeActionString(self.actions, self, event)
if(!self.persistent) {
self.removeHook();
}
}
func.id = this.id
if (this.clear) {
this.removeHook()
} else {
$tw.hooks.addHook(this.name, func)
}
return true; // Action was invoked
};
exports["action-hook"] = HookWidget;
})();