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>
+<$button tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>
+hello
+$button>
++
+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?$checkbox>
++
+title: Actions
+
+<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/>
++
+title: Temp
+color: black
+
+Title1
++
+title: ExpectedResult
+
+Is it done?
\ 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>
+<$draggable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>
+hello
+$draggable>
++
+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>
+<$droppable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>
+hello
+$droppable>
++
+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>
+<$link tag="button" data-id={{Temp}} style.color={{{ [[Temp]get[color]] }}} to="SomeTiddler">
+some tiddler
+$link>
++
+title: Actions
+
+<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/>
++
+title: Temp
+color: black
+
+Title1
++
+title: ExpectedResult
+
+link to Temp some tiddler
\ 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">
+Choose a new text
+A Tale of Two Cities
+A New Kind of Science
+The Dice Man
+$select>
++
+title: Actions
+
+<$action-setfield $tiddler="Temp" $field="text" $value="Title2" color="red"/>
++
+title: Temp
+color: black
+
+Title1
++
+title: ExpectedResult
+
+Choose a new text A Tale of Two Cities A New Kind of Science The Dice Man
\ 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 `` el
|<<.attr uncheckactions>> |<<.from-version "5.1.16">> A string containing ActionWidgets to be triggered when the checkbox is unchecked |
|<<.attr checkactions>> |<<.from-version "5.1.20">> A string containing ActionWidgets to be triggered when the checkbox is checked |
|<<.attr disabled>> |<<.from-version "5.1.23">> Optionally disables the checkbox if set to <<.value yes>> (defaults to <<.value no>>)|
+|<<.attr 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 |
+|<<.attr 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 |
<<.doc-tabs>>
diff --git a/editions/tw5.com/tiddlers/widgets/DraggableWidget.tid b/editions/tw5.com/tiddlers/widgets/DraggableWidget.tid
index c25b15791..b78f9a66f 100644
--- a/editions/tw5.com/tiddlers/widgets/DraggableWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/DraggableWidget.tid
@@ -1,6 +1,6 @@
caption: draggable
created: 20170406081938627
-modified: 20220715120213777
+modified: 20231121101431149
tags: Widgets TriggeringWidgets
title: DraggableWidget
type: text/vnd.tiddlywiki
@@ -20,10 +20,11 @@ See DragAndDropMechanism for an overview.
|selector|<<.from-version 5.2.2>> Optional CSS Selector to identify a DOM element within the widget that will be used as the drag handle |
|class |Optional CSS classes to assign to the DOM element created by the widget. The class `tc-draggable` is added to the the DOM element created by the widget unless the <<.param selector>> attribute is used. The class `tc-dragging` is applied to the DOM element created by the widget while the element is being dragged |
|enable |<<.from-version 5.2.3>> Optional value "no" to disable the draggable functionality (defaults to "yes") |
-
|startactions |Optional action string that gets invoked when dragging ''starts'' |
|endactions |Optional action string that gets invoked when dragging ''ends'' |
|dragimagetype |<<.from-version "5.2.0">> Optional type of drag image: `dom` (the default) or `blank` to disable the drag image |
+|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 |
Either or both of the ''tiddler'' and ''filter'' attributes must be specified in order for there to be a payload to drag.
diff --git a/editions/tw5.com/tiddlers/widgets/DroppableWidget.tid b/editions/tw5.com/tiddlers/widgets/DroppableWidget.tid
index 545fe53fc..46d46860a 100644
--- a/editions/tw5.com/tiddlers/widgets/DroppableWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/DroppableWidget.tid
@@ -1,6 +1,6 @@
caption: droppable
created: 20170406082820317
-modified: 20211009122023265
+modified: 20231121101447359
tags: Widgets TriggeringWidgets
title: DroppableWidget
type: text/vnd.tiddlywiki
@@ -31,6 +31,8 @@ See DragAndDropMechanism for an overview.
|class |Optional CSS classes to assign to the draggable element. The class `tc-droppable` is added automatically, and the class `tc-dragover` is applied while an item is being dragged over the droppable element |
|tag |Optional tag to override the default of a "div" element when the widget is rendered in block mode, or a "span" element when it is rendered in inline mode |
|enable |<<.from-version "5.1.22">> Optional value "no" to disable the droppable functionality (defaults to "yes") |
+|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 |
Within the action string, there are two Variables generated by the DroppableWidget:
diff --git a/editions/tw5.com/tiddlers/widgets/LinkWidget.tid b/editions/tw5.com/tiddlers/widgets/LinkWidget.tid
index 26e78c422..000b3219f 100644
--- a/editions/tw5.com/tiddlers/widgets/LinkWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/LinkWidget.tid
@@ -1,6 +1,6 @@
caption: link
created: 20131024141900000
-modified: 20190610195105615
+modified: 20231113093304323
tags: Widgets
title: LinkWidget
type: text/vnd.tiddlywiki
@@ -23,6 +23,8 @@ The content of the link widget is rendered within the `` tag representing the
|tag |Optional tag to override the default "a" element |
|class|Optional CSS classes //in addition to// the default classes (see below)|
|overrideClass|<<.from-version "5.1.16">> Optional CSS classes //instead of// the default classes |
+|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 |
The draggable functionality is equivalent to using the DraggableWidget with the ''tiddler'' attribute set to the link target.
diff --git a/editions/tw5.com/tiddlers/widgets/RadioWidget.tid b/editions/tw5.com/tiddlers/widgets/RadioWidget.tid
index 9146ff2d0..2ae03b8b4 100644
--- a/editions/tw5.com/tiddlers/widgets/RadioWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/RadioWidget.tid
@@ -1,6 +1,6 @@
caption: radio
created: 20131212195353929
-modified: 20211009121654734
+modified: 20231113093304323
tags: Widgets TriggeringWidgets
title: RadioWidget
type: text/vnd.tiddlywiki
@@ -22,6 +22,8 @@ The content of the `<$radio>` widget is displayed within an HTML `` eleme
|class |The CSS classes assigned to the label around the radio button <<.from-version "5.1.14">> `tc-radio` is always applied by default, as well as `tc-radio-selected` when selected |
|actions|<<.from-version "5.1.23">> Optional string containing ActionWidgets to be triggered when the value changes. The variable: ''actionValue'' is available for the actions |
|disabled|<<.from-version "5.1.23">> Optional. Set to "yes" to disable the radio input. Defaults to "no" |
+|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 |
!! Field Mode
diff --git a/editions/tw5.com/tiddlers/widgets/RangeWidget.tid b/editions/tw5.com/tiddlers/widgets/RangeWidget.tid
index f2fd38092..c4f787ebd 100644
--- a/editions/tw5.com/tiddlers/widgets/RangeWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/RangeWidget.tid
@@ -1,6 +1,6 @@
caption: range
created: 20171102134825376
-modified: 20211009121606405
+modified: 20231113093304323
tags: Widgets TriggeringWidgets
title: RangeWidget
type: text/vnd.tiddlywiki
@@ -26,6 +26,8 @@ The content of the `<$range>` widget is ignored.
|actionsStart|<<.from-version "5.1.23">> Optional, A string containing ~ActionWidgets to be triggered when the "handle" is ''clicked''. The variable: ''actionValueHasChanged'' is always `no` here|
|actionsStop|<<.from-version "5.1.23">> Optional, A string containing ~ActionWidgets to be triggered when the "handle" is ''released''. The variable: ''actionValueHasChanged'' is `yes`, ''if'' the new-value is different to the start-value |
|disabled|<<.from-version "5.1.23">> Optional, disables the range input if set to "yes". Defaults to "no"|
+|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 |
! Examples
diff --git a/editions/tw5.com/tiddlers/widgets/SelectWidget.tid b/editions/tw5.com/tiddlers/widgets/SelectWidget.tid
index e22fcfec6..210b1d823 100644
--- a/editions/tw5.com/tiddlers/widgets/SelectWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/SelectWidget.tid
@@ -1,6 +1,6 @@
caption: select
created: 20131024141900000
-modified: 20211108165037846
+modified: 20231113093304323
tags: TriggeringWidgets Widgets
title: SelectWidget
type: text/vnd.tiddlywiki
@@ -42,6 +42,9 @@ The content of the `<$select>` widget should be one or more HTML `` or `
|actions |A string containing ActionWidgets to be triggered when the key combination is detected |
|focus |<<.from-version "5.2.4">> Optional. Set to "yes" to automatically focus the HTML select element after creation |
|tabindex |<<.from-version "5.3.1">> Optional. Sets the `tabindex` attribute of the HTML select element to the given value |
+|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 |
+
! Examples
!! Simple Lists