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
This commit is contained in:
Saq Imtiaz 2023-11-22 20:57:08 +01:00 committed by GitHub
parent fb57eab2f4
commit 5ce2601c10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 86 additions and 23 deletions

View File

@ -104,7 +104,11 @@ TW_Element.prototype.setAttribute = function(name,value) {
if(this.isRaw) { if(this.isRaw) {
throw "Cannot setAttribute on a raw TW_Element"; 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) { TW_Element.prototype.setAttributeNS = function(namespace,name,value) {

View File

@ -415,19 +415,30 @@ Widget.prototype.getAttribute = function(name,defaultText) {
/* /*
Assign the common attributes of the widget to a domNode Assign the common attributes of the widget to a domNode
options include: 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) 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) changedAttributes: hashmap by attribute name of attributes to process (if missing, process all attributes)
excludeEventAttributes: ignores attributes whose name would begin with "on" excludeEventAttributes: ignores attributes whose name would begin with "on"
*/ */
Widget.prototype.assignAttributes = function(domNode,options) { Widget.prototype.assignAttributes = function(domNode,options) {
var self = this;
options = options || {}; options = options || {};
var changedAttributes = options.changedAttributes || this.attributes; var self = this,
var sourcePrefix = options.sourcePrefix || ""; changedAttributes = options.changedAttributes || this.attributes,
var destPrefix = options.destPrefix || ""; sourcePrefix = options.sourcePrefix || "",
var EVENT_ATTRIBUTE_PREFIX = "on"; destPrefix = options.destPrefix || "",
EVENT_ATTRIBUTE_PREFIX = "on";
var assignAttribute = function(name,value) { 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 // Check for excluded attribute names
if(options.excludeEventAttributes && name.substr(0,2).toLowerCase() === EVENT_ATTRIBUTE_PREFIX) { if(options.excludeEventAttributes && name.substr(0,2).toLowerCase() === EVENT_ATTRIBUTE_PREFIX) {
value = undefined; value = undefined;
@ -445,17 +456,20 @@ Widget.prototype.assignAttributes = function(domNode,options) {
} catch(e) { } 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;
}
});
}; };
/* /*

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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 my tiddler
</$button> </$button>
<$button tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> <$button tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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 title: Actions

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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 my tiddler
</$draggable> </$draggable>
<$draggable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> <$draggable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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 my tiddler
</$droppable> </$droppable>
<$droppable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}> <$droppable tag="div" class="myclass" data-title={{Temp}} style.color={{{ [[Temp]get[color]] }}}>

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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 to Temp
</$link> </$link>
<$link tag="button" data-id={{Temp}} style.color={{{ [[Temp]get[color]] }}} to="SomeTiddler"> <$link tag="button" data-id={{Temp}} style.color={{{ [[Temp]get[color]] }}} to="SomeTiddler">

View File

@ -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
<div style="background:red;color:blue;" style.background="green">
hello
</div>
+
title: ExpectedResult
<p><div style="background:green;color:blue;">hello</div></p>

View File

@ -6,7 +6,7 @@ tags: [[$:/tags/wiki-test-spec]]
title: Output title: Output
\whitespace trim \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">
<option disabled>Choose a new text</option> <option disabled>Choose a new text</option>
<option>A Tale of Two Cities</option> <option>A Tale of Two Cities</option>
<option>A New Kind of Science</option> <option>A New Kind of Science</option>

View File

@ -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
<div class="hello" onclick="clicked">
TiddlyWiki
</div>
+
title: ExpectedResult
<p><div class="hello">TiddlyWiki</div></p>

View File

@ -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
<div class="hello" onclick="clicked" style.color="blue" style.color="red" style.background="yellow">
TiddlyWiki
</div>
+
title: ExpectedResult
<p><div class="hello" style="color:red;background:yellow;">TiddlyWiki</div></p>