From 62bb8affa48aec958fc73104b060f6a90efc8e1b Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 22 Nov 2023 20:05:40 +0000 Subject: [PATCH 01/32] Add data attribute support to button and other widgets (#7769) * Add data attribute support to button widget * Fix typo * Refactor ready for making mechanism more generic * Apply more generic implementation to multiplate widgets * Refactor to use existing widget.assignAttributes() method * Fix typo * Clarify docs * Update docs * Update select widget to support style.* attributes * Remove obsolete comment * Fixes refresh issues for checkbox and links widgets for data attributes (#7846) * fix: refresh issues with checkbox and links widgets * fix: indenting * Feat: add support for data attributes to Draggable and Droppable widgets (#7845) * Docs clarification * docs: add style and data attributes to Draggable and Droppable widget docs (#7850) * Refactors Select widget to directly create DOM node (#7848) * fix: refactored SelectWidget to directly create DOM nodes * fix: refactored SelectWidget to directly create DOM nodes * fix: improve refresh handling for select widget * Fixes issues in the PR "Button widget data attributes" (#7852) * fix: fixed ordered attributes handling and improved tests to catch event attributes * fix: clean up code from testing * fix: more tests and refactoring * fix: use lowercase when checking for event attribute prefix * fix: use lowercase when checking for event attribute prefix * fix: changed comment wording * fix: minor refactoring * refactor: for brevity --------- Co-authored-by: Saq Imtiaz --- core/modules/utils/fakedom.js | 6 +- core/modules/widgets/browse.js | 10 ++++ core/modules/widgets/button.js | 18 +++++- core/modules/widgets/checkbox.js | 11 ++++ core/modules/widgets/draggable.js | 21 +++++-- core/modules/widgets/droppable.js | 16 ++++- core/modules/widgets/link.js | 14 ++++- core/modules/widgets/radio.js | 4 ++ core/modules/widgets/range.js | 4 ++ core/modules/widgets/select.js | 60 +++++++++++-------- core/modules/widgets/widget.js | 54 +++++++++++------ core/wiki/macros/tabs.tid | 10 +++- .../ButtonWidget-DataAttributes.tid | 27 +++++++++ .../CheckboxWidget-DataAttributes.tid | 22 +++++++ .../DraggableWidget-DataAttributes.tid | 27 +++++++++ .../DroppableWidget-DataAttributes.tid | 27 +++++++++ .../LinkWidget-DataAttributes.tid | 27 +++++++++ .../DataAttributes/OrderedStyleAttributes.tid | 15 +++++ .../SelectWidget-DataAttributes.tid | 27 +++++++++ .../widgets/ElementWidgetEventAttributes.tid | 15 +++++ .../widgets/ElementWidgetStyleAttributes.tid | 15 +++++ .../tw5.com/tiddlers/widgets/BrowseWidget.tid | 4 +- .../tw5.com/tiddlers/widgets/ButtonWidget.tid | 4 +- .../tiddlers/widgets/CheckboxWidget.tid | 4 +- .../tiddlers/widgets/DraggableWidget.tid | 5 +- .../tiddlers/widgets/DroppableWidget.tid | 4 +- .../tw5.com/tiddlers/widgets/LinkWidget.tid | 4 +- .../tw5.com/tiddlers/widgets/RadioWidget.tid | 4 +- .../tw5.com/tiddlers/widgets/RangeWidget.tid | 4 +- .../tw5.com/tiddlers/widgets/SelectWidget.tid | 5 +- 30 files changed, 399 insertions(+), 69 deletions(-) create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/ElementWidgetEventAttributes.tid create mode 100644 editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes.tid diff --git a/core/modules/utils/fakedom.js b/core/modules/utils/fakedom.js index d28161ac6..0c1f5fa54 100755 --- a/core/modules/utils/fakedom.js +++ b/core/modules/utils/fakedom.js @@ -104,7 +104,11 @@ TW_Element.prototype.setAttribute = function(name,value) { if(this.isRaw) { throw "Cannot setAttribute on a raw TW_Element"; } - this.attributes[name] = value + ""; + if(name === "style") { + this.style = value; + } else { + this.attributes[name] = value + ""; + } }; TW_Element.prototype.setAttributeNS = function(namespace,name,value) { diff --git a/core/modules/widgets/browse.js b/core/modules/widgets/browse.js index de3c91fb8..8130825b0 100644 --- a/core/modules/widgets/browse.js +++ b/core/modules/widgets/browse.js @@ -70,6 +70,11 @@ BrowseWidget.prototype.render = function(parent,nextSibling) { } return false; },false); + // Assign data- attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Insert element parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); @@ -95,6 +100,11 @@ BrowseWidget.prototype.execute = function() { Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ BrowseWidget.prototype.refresh = function(changedTiddlers) { + var changedAttributes = this.computeAttributes(); + if($tw.utils.count(changedAttributes) > 0) { + this.refreshSelf(); + return true; + } return false; }; diff --git a/core/modules/widgets/button.js b/core/modules/widgets/button.js index a724d8448..958b6f6da 100644 --- a/core/modules/widgets/button.js +++ b/core/modules/widgets/button.js @@ -59,6 +59,11 @@ ButtonWidget.prototype.render = function(parent,nextSibling) { $tw.utils.pushTop(classes,"tc-popup-handle"); } domNode.className = classes.join(" "); + // Assign data- attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Assign other attributes if(this.style) { domNode.setAttribute("style",this.style); @@ -250,7 +255,7 @@ ButtonWidget.prototype.updateDomNodeClasses = function() { //Add new classes from updated class attribute. $tw.utils.pushTop(domNodeClasses,newClasses); this.domNode.className = domNodeClasses.join(" "); -} +}; /* Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering @@ -260,8 +265,15 @@ ButtonWidget.prototype.refresh = function(changedTiddlers) { if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) { this.refreshSelf(); return true; - } else if(changedAttributes["class"]) { - this.updateDomNodeClasses(); + } else { + if(changedAttributes["class"]) { + this.updateDomNodeClasses(); + } + this.assignAttributes(this.domNodes[0],{ + changedAttributes: changedAttributes, + sourcePrefix: "data-", + destPrefix: "data-" + }); } return this.refreshChildren(changedTiddlers); }; diff --git a/core/modules/widgets/checkbox.js b/core/modules/widgets/checkbox.js index fc987d815..e07513b0a 100644 --- a/core/modules/widgets/checkbox.js +++ b/core/modules/widgets/checkbox.js @@ -53,6 +53,11 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) { this.labelDomNode.appendChild(this.inputDomNode); this.spanDomNode = this.document.createElement("span"); this.labelDomNode.appendChild(this.spanDomNode); + // Assign data- attributes + this.assignAttributes(this.inputDomNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Add a click event handler $tw.utils.addEventListeners(this.inputDomNode,[ {name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"} @@ -325,6 +330,11 @@ CheckboxWidget.prototype.refresh = function(changedTiddlers) { $tw.utils.removeClass(this.labelDomNode,"tc-checkbox-checked"); } } + this.assignAttributes(this.inputDomNode,{ + changedAttributes: changedAttributes, + sourcePrefix: "data-", + destPrefix: "data-" + }); return this.refreshChildren(changedTiddlers) || refreshed; } }; @@ -332,3 +342,4 @@ CheckboxWidget.prototype.refresh = function(changedTiddlers) { exports.checkbox = CheckboxWidget; })(); + \ No newline at end of file diff --git a/core/modules/widgets/draggable.js b/core/modules/widgets/draggable.js index f759ab121..22fdc37e9 100644 --- a/core/modules/widgets/draggable.js +++ b/core/modules/widgets/draggable.js @@ -52,6 +52,11 @@ DraggableWidget.prototype.render = function(parent,nextSibling) { classes.push("tc-draggable"); } domNode.setAttribute("class",classes.join(" ")); + // Assign data- attributes and style. attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Insert the node into the DOM and render any children parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); @@ -108,13 +113,19 @@ DraggableWidget.prototype.updateDomNodeClasses = function() { Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering */ DraggableWidget.prototype.refresh = function(changedTiddlers) { - var changedAttributes = this.computeAttributes(), - changedAttributesCount = $tw.utils.count(changedAttributes); - if(changedAttributesCount === 1 && changedAttributes["class"]) { - this.updateDomNodeClasses(); - } else if(changedAttributesCount > 0) { + var changedAttributes = this.computeAttributes(); + if(changedAttributes.tag || changedAttributes.selector || changedAttributes.dragimagetype || changedAttributes.enable || changedAttributes.startactions || changedAttributes.endactions) { this.refreshSelf(); return true; + } else { + if(changedAttributes["class"]) { + this.assignDomNodeClasses(); + } + this.assignAttributes(this.domNodes[0],{ + changedAttributes: changedAttributes, + sourcePrefix: "data-", + destPrefix: "data-" + }); } return this.refreshChildren(changedTiddlers); }; diff --git a/core/modules/widgets/droppable.js b/core/modules/widgets/droppable.js index 104503b25..0dcba1688 100644 --- a/core/modules/widgets/droppable.js +++ b/core/modules/widgets/droppable.js @@ -42,6 +42,11 @@ DroppableWidget.prototype.render = function(parent,nextSibling) { domNode = this.document.createElement(tag); this.domNode = domNode; this.assignDomNodeClasses(); + // Assign data- attributes and style. attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Add event handlers if(this.droppableEnable) { $tw.utils.addEventListeners(domNode,[ @@ -166,8 +171,15 @@ DroppableWidget.prototype.refresh = function(changedTiddlers) { if(changedAttributes.tag || changedAttributes.enable || changedAttributes.disabledClass || changedAttributes.actions || changedAttributes.effect) { this.refreshSelf(); return true; - } else if(changedAttributes["class"]) { - this.assignDomNodeClasses(); + } else { + if(changedAttributes["class"]) { + this.assignDomNodeClasses(); + } + this.assignAttributes(this.domNodes[0],{ + changedAttributes: changedAttributes, + sourcePrefix: "data-", + destPrefix: "data-" + }); } return this.refreshChildren(changedTiddlers); }; diff --git a/core/modules/widgets/link.js b/core/modules/widgets/link.js index 6f199d395..0d89ee22d 100755 --- a/core/modules/widgets/link.js +++ b/core/modules/widgets/link.js @@ -43,6 +43,11 @@ LinkWidget.prototype.render = function(parent,nextSibling) { } else { // Just insert the link text var domNode = this.document.createElement("span"); + // Assign data- attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); this.domNodes.push(domNode); @@ -138,6 +143,11 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) { widget: this }); } + // Assign data- attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Insert the link into the DOM and render any children parent.insertBefore(domNode,nextSibling); this.renderChildren(domNode,null); @@ -207,8 +217,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of */ LinkWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); - if(changedAttributes.to || changedTiddlers[this.to] || changedAttributes["aria-label"] || changedAttributes.tooltip || - changedAttributes["class"] || changedAttributes.tabindex || changedAttributes.draggable || changedAttributes.tag) { + if($tw.utils.count(changedAttributes) > 0) { this.refreshSelf(); return true; } @@ -218,3 +227,4 @@ LinkWidget.prototype.refresh = function(changedTiddlers) { exports.link = LinkWidget; })(); + \ No newline at end of file diff --git a/core/modules/widgets/radio.js b/core/modules/widgets/radio.js index 363836227..aa7a32cf1 100644 --- a/core/modules/widgets/radio.js +++ b/core/modules/widgets/radio.js @@ -40,6 +40,10 @@ RadioWidget.prototype.render = function(parent,nextSibling) { ); this.inputDomNode = this.document.createElement("input"); this.inputDomNode.setAttribute("type","radio"); + this.assignAttributes(this.inputDomNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); if(isChecked) { this.inputDomNode.checked = true; } diff --git a/core/modules/widgets/range.js b/core/modules/widgets/range.js index 4dd55dc3c..db2699cc4 100644 --- a/core/modules/widgets/range.js +++ b/core/modules/widgets/range.js @@ -50,6 +50,10 @@ RangeWidget.prototype.render = function(parent,nextSibling) { this.inputDomNode.setAttribute("disabled",true); } this.inputDomNode.value = this.getValue(); + this.assignAttributes(this.inputDomNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); // Add a click event handler $tw.utils.addEventListeners(this.inputDomNode,[ {name:"mousedown", handlerObject:this, handlerMethod:"handleMouseDownEvent"}, diff --git a/core/modules/widgets/select.js b/core/modules/widgets/select.js index ab9bef74e..f1ea3b331 100644 --- a/core/modules/widgets/select.js +++ b/core/modules/widgets/select.js @@ -40,7 +40,31 @@ SelectWidget.prototype.render = function(parent,nextSibling) { this.parentDomNode = parent; this.computeAttributes(); this.execute(); - this.renderChildren(parent,nextSibling); + //Create element + var domNode = this.document.createElement("select"); + if(this.selectClass) { + domNode.classname = this.selectClass; + } + // Assign data- attributes + this.assignAttributes(domNode,{ + sourcePrefix: "data-", + destPrefix: "data-" + }); + if(this.selectMultiple) { + domNode.setAttribute("multiple","multiple"); + } + if(this.selectSize) { + domNode.setAttribute("size",this.selectSize); + } + if(this.selectTabindex) { + domNode.setAttribute("tabindex",this.selectTabindex); + } + if(this.selectTooltip) { + domNode.setAttribute("title",this.selectTooltip); + } + this.renderChildren(domNode,nextSibling); + this.parentDomNode.insertBefore(domNode,nextSibling); + this.domNodes.push(domNode); this.setSelectValue(); if(this.selectFocus == "yes") { this.getSelectDomNode().focus(); @@ -113,7 +137,7 @@ SelectWidget.prototype.setSelectValue = function() { Get the DOM node of the select element */ SelectWidget.prototype.getSelectDomNode = function() { - return this.children[0].domNodes[0]; + return this.domNodes[0]; }; // Return an array of the selected opion values @@ -149,27 +173,7 @@ SelectWidget.prototype.execute = function() { this.selectTooltip = this.getAttribute("tooltip"); this.selectFocus = this.getAttribute("focus"); // Make the child widgets - var selectNode = { - type: "element", - tag: "select", - children: this.parseTreeNode.children - }; - if(this.selectClass) { - $tw.utils.addAttributeToParseTreeNode(selectNode,"class",this.selectClass); - } - if(this.selectMultiple) { - $tw.utils.addAttributeToParseTreeNode(selectNode,"multiple","multiple"); - } - if(this.selectSize) { - $tw.utils.addAttributeToParseTreeNode(selectNode,"size",this.selectSize); - } - if(this.selectTabindex) { - $tw.utils.addAttributeToParseTreeNode(selectNode,"tabindex",this.selectTabindex); - } - if(this.selectTooltip) { - $tw.utils.addAttributeToParseTreeNode(selectNode,"title",this.selectTooltip); - } - this.makeChildWidgets([selectNode]); + this.makeChildWidgets(); }; /* @@ -178,17 +182,21 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of SelectWidget.prototype.refresh = function(changedTiddlers) { var changedAttributes = this.computeAttributes(); // If we're using a different tiddler/field/index then completely refresh ourselves - if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip) { + if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tooltip || changedAttributes.tabindex) { this.refreshSelf(); return true; - // If the target tiddler value has changed, just update setting and refresh the children } else { if(changedAttributes.class) { this.selectClass = this.getAttribute("class"); this.getSelectDomNode().setAttribute("class",this.selectClass); } - + this.assignAttributes(this.getSelectDomNode(),{ + changedAttributes: changedAttributes, + sourcePrefix: "data-", + destPrefix: "data-" + }); var childrenRefreshed = this.refreshChildren(changedTiddlers); + // If the target tiddler value has changed, just update setting and refresh the children if(changedTiddlers[this.selectTitle] || childrenRefreshed) { this.setSelectValue(); } diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index 6c3997179..af4892b9e 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -413,16 +413,34 @@ Widget.prototype.getAttribute = function(name,defaultText) { }; /* -Assign the computed attributes of the widget to a domNode +Assign the common attributes of the widget to a domNode options include: -excludeEventAttributes: ignores attributes whose name begins with "on" +sourcePrefix: prefix of attributes that are to be directly assigned (defaults to the empty string meaning all attributes) +destPrefix: prefix to be applied to attribute names that are to be directly assigned (defaults to the emtpy string which means no prefix is added) +changedAttributes: hashmap by attribute name of attributes to process (if missing, process all attributes) +excludeEventAttributes: ignores attributes whose name would begin with "on" */ Widget.prototype.assignAttributes = function(domNode,options) { options = options || {}; - var self = this; + var self = this, + changedAttributes = options.changedAttributes || this.attributes, + sourcePrefix = options.sourcePrefix || "", + destPrefix = options.destPrefix || "", + EVENT_ATTRIBUTE_PREFIX = "on"; var assignAttribute = function(name,value) { + // Process any style attributes before considering sourcePrefix and destPrefix + if(name.substr(0,6) === "style." && name.length > 6) { + domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value; + return; + } + // Check if the sourcePrefix is a match + if(name.substr(0,sourcePrefix.length) === sourcePrefix) { + name = destPrefix + name.substr(sourcePrefix.length); + } else { + value = undefined; + } // Check for excluded attribute names - if(options.excludeEventAttributes && name.substr(0,2) === "on") { + if(options.excludeEventAttributes && name.substr(0,2).toLowerCase() === EVENT_ATTRIBUTE_PREFIX) { value = undefined; } if(value !== undefined) { @@ -432,26 +450,24 @@ Widget.prototype.assignAttributes = function(domNode,options) { namespace = "http://www.w3.org/1999/xlink"; name = name.substr(6); } - // Handle styles - if(name.substr(0,6) === "style." && name.length > 6) { - domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value; - } else { - // Setting certain attributes can cause a DOM error (eg xmlns on the svg element) - try { - domNode.setAttributeNS(namespace,name,value); - } catch(e) { - } + // Setting certain attributes can cause a DOM error (eg xmlns on the svg element) + try { + domNode.setAttributeNS(namespace,name,value); + } catch(e) { } } - } - // Not all parse tree nodes have the orderedAttributes property + }; + // If the parse tree node has the orderedAttributes property then use that order if(this.parseTreeNode.orderedAttributes) { $tw.utils.each(this.parseTreeNode.orderedAttributes,function(attribute,index) { - assignAttribute(attribute.name,self.attributes[attribute.name]); - }); + if(attribute.name in changedAttributes) { + assignAttribute(attribute.name,self.getAttribute(attribute.name)); + } + }); + // Otherwise update each changed attribute irrespective of order } else { - $tw.utils.each(Object.keys(self.attributes).sort(),function(name) { - assignAttribute(name,self.attributes[name]); + $tw.utils.each(changedAttributes,function(value,name) { + assignAttribute(name,self.getAttribute(name)); }); } }; diff --git a/core/wiki/macros/tabs.tid b/core/wiki/macros/tabs.tid index bc8a0255f..1805bc9be 100644 --- a/core/wiki/macros/tabs.tid +++ b/core/wiki/macros/tabs.tid @@ -4,7 +4,15 @@ code-body: yes \define tabs-button() \whitespace trim -<$button set=<> setTo=<> default=<<__default__>> selectedClass="tc-tab-selected" tooltip={{!!tooltip}} role="switch"> +<$button + set=<> + setTo=<> + default=<<__default__>> + selectedClass="tc-tab-selected" + tooltip={{!!tooltip}} + role="switch" + data-tab-title=<> +> <$tiddler tiddler=<>> <$set name="tv-wikilinks" value="no"> <$transclude tiddler=<<__buttonTemplate__>> mode="inline"> diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid new file mode 100644 index 000000000..da3d7080a --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid @@ -0,0 +1,27 @@ +title: Widgets/DataAttributes/ButtonWidget +description: Data Attributes for ButtonWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$button tag="div" class="myclass" data-title="mytiddler" style.color="red" onclick="clicked"> +my tiddler + +<$button tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> +hello + ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

my tiddler
hello

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid new file mode 100644 index 000000000..521fa3a13 --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid @@ -0,0 +1,22 @@ +title: Widgets/DataAttributes/CheckboxWidget +description: Data Attributes for CheckboxWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$checkbox tag="done" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}} onclick="clicked"> Is it done? ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid new file mode 100644 index 000000000..feeb89ded --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid @@ -0,0 +1,27 @@ +title: Widgets/DataAttributes/DraggableWidget +description: Data Attributes for DraggableWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$draggable tag="div" class="myclass" data-title="mytiddler" style.color="red" onclick="clicked"> +my tiddler + +<$draggable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> +hello + ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

my tiddler
hello

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid new file mode 100644 index 000000000..3c7284eb1 --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid @@ -0,0 +1,27 @@ +title: Widgets/DataAttributes/DroppableWidget +description: Data Attributes for DroppableWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$droppable tag="div" class="myclass" data-title="mytiddler" style.color="red" onclick="clicked"> +my tiddler + +<$droppable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> +hello + ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

my tiddler
hello

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid new file mode 100644 index 000000000..e99e265bb --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid @@ -0,0 +1,27 @@ +title: Widgets/DataAttributes/LinkWidget +description: Data Attributes for LinkWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$link data-id="mytiddler" style.color="red" to="Temp" onclick="clicked"> +link to Temp + +<$link tag="button" data-id={{Temp}} style.color={{{ [[Temp]get[color]] }}} to="SomeTiddler"> +some tiddler + ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

link to Temp

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.tid new file mode 100644 index 000000000..2f6d2cb1a --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.tid @@ -0,0 +1,15 @@ +title: Widgets/DataAttributes/OrderedStyleAttributes +description: Ordered style attributes +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +
+hello +
++ +title: ExpectedResult + +

hello

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid new file mode 100644 index 000000000..de2c9995e --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid @@ -0,0 +1,27 @@ +title: Widgets/DataAttributes/SelectWidget +description: Data Attributes for SelectWidget +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +<$select tiddler='New Tiddler' field='text' default='Choose a new text' data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}} onclick="clicked"> + + + + + ++ +title: Actions + +<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/> ++ +title: Temp +color: black + +Title1 ++ +title: ExpectedResult + +

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/ElementWidgetEventAttributes.tid b/editions/test/tiddlers/tests/data/widgets/ElementWidgetEventAttributes.tid new file mode 100644 index 000000000..4c2f6eb04 --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/ElementWidgetEventAttributes.tid @@ -0,0 +1,15 @@ +title: Widgets/ElementWidgetEventAttributes +description: Element widget should not support event attributes starting with "on" +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +
+TiddlyWiki +
++ +title: ExpectedResult + +

TiddlyWiki

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes.tid b/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes.tid new file mode 100644 index 000000000..a36a51323 --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes.tid @@ -0,0 +1,15 @@ +title: Widgets/ElementWidgetStyleAttributes +description: Element widget should support style.* attributes +type: text/vnd.tiddlywiki-multiple +tags: [[$:/tags/wiki-test-spec]] + +title: Output + +\whitespace trim +
+TiddlyWiki +
++ +title: ExpectedResult + +

TiddlyWiki

\ No newline at end of file diff --git a/editions/tw5.com/tiddlers/widgets/BrowseWidget.tid b/editions/tw5.com/tiddlers/widgets/BrowseWidget.tid index 28012bd68..b0364a71a 100644 --- a/editions/tw5.com/tiddlers/widgets/BrowseWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/BrowseWidget.tid @@ -1,6 +1,6 @@ caption: browse created: 20131024141900000 -modified: 20200421221304177 +modified: 20231113093304323 tags: Widgets title: BrowseWidget type: text/vnd.tiddlywiki @@ -20,6 +20,8 @@ The content of the <<.wid BrowseWidget>> widget is ignored. |accept |<<.from-version "5.1.23">> Optional comma delimited [[list of file accepted extensions|https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers]] and/or MIME types | |message |Optional override of widget message to be generated. The files will be passed in the JavaScript object `event.target.files` | |param |Optional parameter to be passed with the custom message | +|data-* |<<.from-version "5.3.2">> Optional [[data attributes|https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes]] to be assigned to the HTML element | +|style.* |<<.from-version "5.3.2">> Optional [[CSS properties|https://developer.mozilla.org/en-US/docs/Web/CSS/Reference]] to be assigned to the HTML element | On iPhone/iPad choosing the multiple option will remove the ability to take photographs/videos directly into TiddlyWiki. diff --git a/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid b/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid index da61838af..d74c09575 100644 --- a/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid @@ -1,6 +1,6 @@ caption: button created: 20131024141900000 -modified: 20220810192251345 +modified: 20231113093304323 tags: Widgets TriggeringWidgets title: ButtonWidget type: text/vnd.tiddlywiki @@ -41,6 +41,8 @@ The content of the `<$button>` widget is displayed within the button. |aria-label |Optional [[Accessibility]] label | |tooltip |Optional tooltip | |class |An optional CSS class name to be assigned to the HTML element| +|data-* |<<.from-version "5.3.2">> Optional [[data attributes|https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes]] to be assigned to the HTML element | +|style.* |<<.from-version "5.3.2">> Optional [[CSS properties|https://developer.mozilla.org/en-US/docs/Web/CSS/Reference]] to be assigned to the HTML element | |style |An optional CSS style attribute to be assigned to the HTML element | |tag |An optional html tag to use instead of the default "button" | |dragTiddler |An optional tiddler title making the button draggable and identifying the payload tiddler. See DraggableWidget for details | diff --git a/editions/tw5.com/tiddlers/widgets/CheckboxWidget.tid b/editions/tw5.com/tiddlers/widgets/CheckboxWidget.tid index 47e83e875..00ecbb6f8 100644 --- a/editions/tw5.com/tiddlers/widgets/CheckboxWidget.tid +++ b/editions/tw5.com/tiddlers/widgets/CheckboxWidget.tid @@ -3,7 +3,7 @@ colors: red orange yellow blue created: 20131024141900000 fruits: bananas oranges grapes list: [[CheckboxWidget (tag Mode)]] [[CheckboxWidget (field Mode)]] [[CheckboxWidget (listField Mode)]] [[CheckboxWidget (index Mode)]] [[CheckboxWidget (listIndex Mode)]] [[CheckboxWidget (filter Mode)]] [[CheckboxWidget (indeterminate)]] -modified: 20230316192632667 +modified: 20231113093304323 tags: Widgets TriggeringWidgets title: CheckboxWidget type: text/vnd.tiddlywiki @@ -38,5 +38,7 @@ The content of the `<$checkbox>` widget is displayed within an HTML `