From b6181e1cb17280eee09fc5dc1e707b3be4416d8d Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Thu, 13 Apr 2023 08:42:18 +0100 Subject: [PATCH] Refactor data widget implementation To avoid code duplication --- core/modules/widgets/data.js | 36 ++++++++++++ core/modules/widgets/testcase.js | 69 ++-------------------- core/modules/widgets/widget.js | 15 +++++ plugins/tiddlywiki/innerwiki/innerwiki.js | 70 ++--------------------- 4 files changed, 60 insertions(+), 130 deletions(-) diff --git a/core/modules/widgets/data.js b/core/modules/widgets/data.js index 3ed8ae9ed..c5c2b9e37 100644 --- a/core/modules/widgets/data.js +++ b/core/modules/widgets/data.js @@ -42,6 +42,42 @@ DataWidget.prototype.execute = function() { this.makeChildWidgets(); }; +/* +Read the tiddler value(s) from a data widget – must be called after the .render() method +*/ +DataWidget.prototype.readDataTiddlerValues = function() { + var self = this; + // Start with a blank object + var item = Object.create(null); + // Read any attributes not prefixed with $ + $tw.utils.each(this.attributes,function(value,name) { + if(name.charAt(0) !== "$") { + item[name] = value; + } + }); + // Deal with $tiddler or $filter attributes + var titles; + if(this.hasAttribute("$tiddler")) { + titles = [this.getAttribute("$tiddler")]; + } else if(this.hasAttribute("$filter")) { + titles = this.wiki.filterTiddlers(this.getAttribute("$filter")); + } + if(titles) { + var results = []; + $tw.utils.each(titles,function(title,index) { + var tiddler = self.wiki.getTiddler(title), + fields; + if(tiddler) { + fields = tiddler.getFieldStrings(); + } + results.push($tw.utils.extend({},fields,item)); + }) + return results; + } else { + return [item]; + } +}; + /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ diff --git a/core/modules/widgets/testcase.js b/core/modules/widgets/testcase.js index 17275d092..be18a39ae 100644 --- a/core/modules/widgets/testcase.js +++ b/core/modules/widgets/testcase.js @@ -48,7 +48,10 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) { // Create a wiki this.testcaseWiki = new $tw.Wiki(); // Load tiddlers from child data widgets - var tiddlers = this.readTiddlerDataWidgets(this.contentRoot.children); + var tiddlers = []; + this.findChildrenDataWidgets(this.contentRoot.children,"data",function(widget) { + Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues()); + }); this.testcaseWiki.addTiddlers(tiddlers); // Load tiddlers from the optional testcaseTiddler if(this.testcaseTiddler) { @@ -119,70 +122,6 @@ TestCaseWidget.prototype.testcaseRawTiddler = function(parent,nextSibling,title, parent.insertBefore(this.document.createTextNode(text),nextSibling); }; -/* -Find child data widgets -*/ -TestCaseWidget.prototype.findDataWidgets = function(children,tag,callback) { - var self = this; - $tw.utils.each(children,function(child) { - if(child.dataWidgetTag === tag) { - callback(child); - } - if(child.children) { - self.findDataWidgets(child.children,tag,callback); - } - }); -}; - -/* -Find the child data widgets -*/ -TestCaseWidget.prototype.readTiddlerDataWidgets = function(children) { - var self = this, - results = []; - this.findDataWidgets(children,"data",function(widget) { - Array.prototype.push.apply(results,self.readTiddlerDataWidget(widget)); - }); - return results; -}; - -/* -Read the value(s) from a data widget -*/ -TestCaseWidget.prototype.readTiddlerDataWidget = function(dataWidget) { - var self = this; - // Start with a blank object - var item = Object.create(null); - // Read any attributes not prefixed with $ - $tw.utils.each(dataWidget.attributes,function(value,name) { - if(name.charAt(0) !== "$") { - item[name] = value; - } - }); - // Deal with $tiddler or $filter attributes - var titles; - if(dataWidget.hasAttribute("$tiddler")) { - titles = [dataWidget.getAttribute("$tiddler")]; - } else if(dataWidget.hasAttribute("$filter")) { - titles = this.wiki.filterTiddlers(dataWidget.getAttribute("$filter")); - } - if(titles) { - var self = this; - var results = []; - $tw.utils.each(titles,function(title,index) { - var tiddler = self.wiki.getTiddler(title), - fields; - if(tiddler) { - fields = tiddler.getFieldStrings(); - } - results.push($tw.utils.extend({},fields,item)); - }) - return results; - } else { - return [item]; - } -}; - /* Compute the internal state of the widget */ diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 741914fdc..1fe9db629 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -829,6 +829,21 @@ Widget.prototype.allowActionPropagation = function() { return true; }; +/* +Find child <$data> widgets recursively. The tag name allows aliased versions of the widget to be found too +*/ +Widget.prototype.findChildrenDataWidgets = function(children,tag,callback) { + var self = this; + $tw.utils.each(children,function(child) { + if(child.dataWidgetTag === tag) { + callback(child); + } + if(child.children) { + self.findChildrenDataWidgets(child.children,tag,callback); + } + }); +}; + exports.widget = Widget; })(); diff --git a/plugins/tiddlywiki/innerwiki/innerwiki.js b/plugins/tiddlywiki/innerwiki/innerwiki.js index f2ea99567..9bd58eba8 100644 --- a/plugins/tiddlywiki/innerwiki/innerwiki.js +++ b/plugins/tiddlywiki/innerwiki/innerwiki.js @@ -143,7 +143,7 @@ Create the anchors */ InnerWikiWidget.prototype.createAnchors = function() { var self = this; - this.findDataWidgets(this.children,"anchor",function(widget) { + this.findChildrenDataWidgets(this.children,"anchor",function(widget) { var anchorWidth = 40, anchorHeight = 40, getAnchorCoordinate = function(name) { @@ -233,76 +233,16 @@ InnerWikiWidget.prototype.createInnerHTML = function() { IMPLANT_PREFIX = "<" + "script>\n$tw.preloadTiddlerArray(", IMPLANT_SUFFIX = ");\n\n", parts = html.split(SPLIT_MARKER), - tiddlers = this.readTiddlerDataWidgets(this.children); + tiddlers = []; + this.findChildrenDataWidgets(this.children,"data",function(widget) { + Array.prototype.push.apply(tiddlers,widget.readDataTiddlerValues()); + }); if(parts.length === 2) { html = parts[0] + IMPLANT_PREFIX + JSON.stringify(tiddlers) + IMPLANT_SUFFIX + SPLIT_MARKER + parts[1]; } return html; }; -/* -Find child data widgets -*/ -InnerWikiWidget.prototype.findDataWidgets = function(children,tag,callback) { - var self = this; - $tw.utils.each(children,function(child) { - if(child.dataWidgetTag === tag) { - callback(child); - } - if(child.children) { - self.findDataWidgets(child.children,tag,callback); - } - }); -}; - -/* -Find the child data widgets -*/ -InnerWikiWidget.prototype.readTiddlerDataWidgets = function(children) { - var self = this, - results = []; - this.findDataWidgets(children,"data",function(widget) { - Array.prototype.push.apply(results,self.readTiddlerDataWidget(widget)); - }); - return results; -}; - -/* -Read the value(s) from a data widget -*/ -InnerWikiWidget.prototype.readTiddlerDataWidget = function(dataWidget) { - // Start with a blank object - var item = Object.create(null); - // Read any attributes not prefixed with $ - $tw.utils.each(dataWidget.attributes,function(value,name) { - if(name.charAt(0) !== "$") { - item[name] = value; - } - }); - // Deal with $tiddler or $filter attributes - var titles; - if(dataWidget.hasAttribute("$tiddler")) { - titles = [dataWidget.getAttribute("$tiddler")]; - } else if(dataWidget.hasAttribute("$filter")) { - titles = this.wiki.filterTiddlers(dataWidget.getAttribute("$filter")); - } - if(titles) { - var self = this; - var results = []; - $tw.utils.each(titles,function(title,index) { - var tiddler = self.wiki.getTiddler(title), - fields; - if(tiddler) { - fields = tiddler.getFieldStrings(); - } - results.push($tw.utils.extend({},fields,item)); - }) - return results; - } else { - return [item]; - } -}; - /* Compute the internal state of the widget */