From 9eda02868f21e9dd1733ffe26352bd7ac96285b4 Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Tue, 9 Mar 2021 18:07:07 +0000 Subject: [PATCH] Introduce messagecatcher widget --- core/modules/widgets/messagecatcher.js | 100 ++++++++++++++++++ .../tiddlers/widgets/MessageCatcherWidget.tid | 42 ++++++++ 2 files changed, 142 insertions(+) create mode 100644 core/modules/widgets/messagecatcher.js create mode 100644 editions/tw5.com/tiddlers/widgets/MessageCatcherWidget.tid diff --git a/core/modules/widgets/messagecatcher.js b/core/modules/widgets/messagecatcher.js new file mode 100644 index 000000000..ae5435f6a --- /dev/null +++ b/core/modules/widgets/messagecatcher.js @@ -0,0 +1,100 @@ +/*\ +title: $:/core/modules/widgets/messagecatcher.js +type: application/javascript +module-type: widget + +Message catcher widget + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var Widget = require("$:/core/modules/widgets/widget.js").widget; + +var MessageCatcherWidget = function(parseTreeNode,options) { + this.initialise(parseTreeNode,options); +}; + +/* +Inherit from the base widget class +*/ +MessageCatcherWidget.prototype = new Widget(); + +/* +Render this widget into the DOM +*/ +MessageCatcherWidget.prototype.render = function(parent,nextSibling) { + var self = this; + // Remember parent + this.parentDomNode = parent; + // Compute attributes and execute state + this.computeAttributes(); + this.execute(); + // Add our message handler + if(this.messageType) { + this.addEventListeners([ + {type: this.messageType, handler: "handleEvent"} + ]); + } + // Render children + this.renderChildren(parent,null); +}; + +/* +Compute the internal state of the widget +*/ +MessageCatcherWidget.prototype.execute = function() { + var self = this; + // Get attributes that require a refresh on change + this.messageType = this.getAttribute("type"); + this.messageActions = this.getAttribute("actions"); + // Make child widgets + this.makeChildWidgets(); +}; + +/* +Handle an event +*/ +MessageCatcherWidget.prototype.handleEvent = function(event) { + if(this.messageActions) { + // Collect all the event properties into variables + var collectProps = function(obj,prefix) { + prefix = prefix || ""; + var props = {}; + $tw.utils.each(obj,function(value,name) { + if(["string","boolean","number"].indexOf(typeof value) !== -1) { + props[prefix + name] = value.toString(); + } + }); + return props; + }; + var variables = $tw.utils.extend( + {}, + collectProps(event.paramObject,"event-paramObject-"), + collectProps(event,"event-"), + { + modifier: $tw.keyboardManager.getEventModifierKeyDescriptor(event) + }); + this.invokeActionString(this.messageActions,this,event,variables); + } + return false; +}; + +/* +Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering +*/ +MessageCatcherWidget.prototype.refresh = function(changedTiddlers) { + var changedAttributes = this.computeAttributes(); + if(changedAttributes["type"]) { + this.refreshSelf(); + return true; + } + return this.refreshChildren(changedTiddlers); +}; + +exports.messagecatcher = MessageCatcherWidget; + +})(); diff --git a/editions/tw5.com/tiddlers/widgets/MessageCatcherWidget.tid b/editions/tw5.com/tiddlers/widgets/MessageCatcherWidget.tid new file mode 100644 index 000000000..406c4cda5 --- /dev/null +++ b/editions/tw5.com/tiddlers/widgets/MessageCatcherWidget.tid @@ -0,0 +1,42 @@ +created: 20210309133636211 +modified: 20210309133636211 +tags: Widgets +title: MessageCatcherWidget +type: text/vnd.tiddlywiki + +! Introduction + +<<.from-version "5.1.24">> + +The message catcher widget traps [[messages|Messages]] dispatched within its child content, and allows invoking a series of ActionWidgets in response to those messages. + +! Content and Attributes + +The content of the `<$messagecatcher>` widget is displayed normally. + +|!Attribute |!Description | +|type |Name of the message be trapped, for example "tm-scroll" or "tm-navigate" | +|actions |Action string to be invoked when a matching message is trapped | + +! Variables + +The message catcher widget + +|!Variables |!Description | +|`event-*` |All string-based properties of the `event` object, with the names prefixed with `event-` | +|`event-paramObject-*` |All string-based properties of the `event.paramObject` object, with the names prefixed with `event-paramObject-` | +|`modifier` |For messages that originated with browser events, the modifier keys that were pressed when the event was fired. The possible modifiers are ''norma'' (no modifiers), ''ctrl'', ''ctrl-alt'', ''ctrl-shift'', ''alt'', ''alt-shift'', ''shift'' and ''ctrl-alt-shift'' | + +! Example + +<$macrocall $name="wikitext-example-without-html" src=""" +\define actions() +<$action-log/> +\end + +<$messagecatcher type="tm-navigate" actions=<>> + +Click on [[this link]] to fire an action. See the browser JavaScript console for the output + + +"""/> \ No newline at end of file