From 5ce2601c10790c102d4390baa363985f06c2b075 Mon Sep 17 00:00:00 2001
From: Saq Imtiaz
Date: Wed, 22 Nov 2023 20:57:08 +0100
Subject: [PATCH] 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
---
core/modules/utils/fakedom.js | 6 ++-
core/modules/widgets/widget.js | 46 ++++++++++++-------
.../ButtonWidget-DataAttributes.tid | 2 +-
.../CheckboxWidget-DataAttributes.tid | 2 +-
.../DraggableWidget-DataAttributes.tid | 2 +-
.../DroppableWidget-DataAttributes.tid | 2 +-
.../LinkWidget-DataAttributes.tid | 2 +-
.../DataAttributes/OrderedStyleAttributes.tid | 15 ++++++
.../SelectWidget-DataAttributes.tid | 2 +-
.../widgets/ElementWidgetEventAttributes.tid | 15 ++++++
.../widgets/ElementWidgetStyleAttributes.tid | 15 ++++++
11 files changed, 86 insertions(+), 23 deletions(-)
create mode 100644 editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.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/widget.js b/core/modules/widgets/widget.js
index bdbedc2ba..af4892b9e 100755
--- a/core/modules/widgets/widget.js
+++ b/core/modules/widgets/widget.js
@@ -415,19 +415,30 @@ Widget.prototype.getAttribute = function(name,defaultText) {
/*
Assign the common attributes of the widget to a domNode
options include:
-sourcePrefix: prefix of attributes that are to be directly assigned (defaults to the emtpy string meaning all attributes)
+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) {
- var self = this;
options = options || {};
- var changedAttributes = options.changedAttributes || this.attributes;
- var sourcePrefix = options.sourcePrefix || "";
- var destPrefix = options.destPrefix || "";
- var EVENT_ATTRIBUTE_PREFIX = "on";
+ 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).toLowerCase() === EVENT_ATTRIBUTE_PREFIX) {
value = undefined;
@@ -445,17 +456,20 @@ Widget.prototype.assignAttributes = function(domNode,options) {
} catch(e) {
}
}
+ };
+ // 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) {
+ if(attribute.name in changedAttributes) {
+ assignAttribute(attribute.name,self.getAttribute(attribute.name));
+ }
+ });
+ // Otherwise update each changed attribute irrespective of order
+ } else {
+ $tw.utils.each(changedAttributes,function(value,name) {
+ assignAttribute(name,self.getAttribute(name));
+ });
}
- $tw.utils.each(changedAttributes,function(value,name) {
- value = self.getAttribute(name);
- // Check for a prefixed attribute
- if(name.substr(0,sourcePrefix.length) === sourcePrefix) {
- domNode.setAttribute(destPrefix + name.substr(sourcePrefix.length),value);
- // Check for a style attribute
- } else if(name.substr(0,6) === "style." && name.length > 6) {
- domNode.style[$tw.utils.unHyphenateCss(name.substr(6))] = value;
- }
- });
};
/*
diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid
index 014e16b58..da3d7080a 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
-<$button tag="div" class="myclass" data-title="mytiddler" style.color="red">
+<$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]] }}}>
diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid
index 6d86daac7..521fa3a13 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
-<$checkbox tag="done" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> Is it done?$checkbox>
+<$checkbox tag="done" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}} onclick="clicked"> Is it done?$checkbox>
+
title: Actions
diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid
index 0fa7c892b..feeb89ded 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
-<$draggable tag="div" class="myclass" data-title="mytiddler" style.color="red">
+<$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]] }}}>
diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid
index cd1b9fe7a..3c7284eb1 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
-<$droppable tag="div" class="myclass" data-title="mytiddler" style.color="red">
+<$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]] }}}>
diff --git a/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid b/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid
index 17d330642..e99e265bb 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output
\whitespace trim
-<$link data-id="mytiddler" style.color="red" to="Temp">
+<$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">
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
index 967e568c2..de2c9995e 100644
--- a/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid
+++ b/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid
@@ -6,7 +6,7 @@ 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]] }}}>
+<$select tiddler='New Tiddler' field='text' default='Choose a new text' data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}} onclick="clicked">
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
+