diff --git a/core/modules/utils/fakedom.js b/core/modules/utils/fakedom.js index fb28465fe..66f2314e2 100755 --- a/core/modules/utils/fakedom.js +++ b/core/modules/utils/fakedom.js @@ -56,36 +56,64 @@ Object.defineProperty(TW_TextNode.prototype, "formattedTextContent", { } }); -var TW_Element = function(tag,namespace) { +var TW_Style = function(el) { + // Define the internal style object + var styleObject = { + // Method to get the entire style object + get: function() { + return el._style; + }, + // Method to set styles using a string (e.g. "color:red; background-color:blue;") + set: function(str) { + var self = this; + str = str || ""; + $tw.utils.each(str.split(";"),function(declaration) { + var parts = declaration.split(":"), + name = $tw.utils.trim(parts[0]), + value = $tw.utils.trim(parts[1]); + if(name && value) { + el._style[$tw.utils.convertStyleNameToPropertyName(name)] = value; + } + }); + }, + // Method to set a specific property without transforming the property name, such as a custom property + setProperty: function(name, value) { + el._style[name] = value; + } + }; + + // Return a Proxy to handle direct access to individual style properties + return new Proxy(styleObject, { + get: function(target, property) { + // If the property exists on styleObject, return it (get, set, setProperty methods) + if (property in target) { + return target[property]; + } + // Otherwise, return the corresponding property from _style + return el._style[$tw.utils.convertStyleNameToPropertyName(property)] || ""; + }, + set: function(target, property, value) { + // Set the property in _style + el._style[$tw.utils.convertStyleNameToPropertyName(property)] = value; + return true; + } + }); +}; + +var TW_Element = function(tag, namespace) { bumpSequenceNumber(this); this.isTiddlyWikiFakeDom = true; this.tag = tag; this.attributes = {}; this.isRaw = false; this.children = []; - this._style = {}; + this._style = {}; // Internal style object + this.style = new TW_Style(this); // Proxy for style management this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml"; }; -Object.setPrototypeOf(TW_Element.prototype,TW_Node.prototype); -Object.defineProperty(TW_Element.prototype, "style", { - get: function() { - return this._style; - }, - set: function(str) { - var self = this; - str = str || ""; - $tw.utils.each(str.split(";"),function(declaration) { - var parts = declaration.split(":"), - name = $tw.utils.trim(parts[0]), - value = $tw.utils.trim(parts[1]); - if(name && value) { - self._style[$tw.utils.convertStyleNameToPropertyName(name)] = value; - } - }); - } -}); +Object.setPrototypeOf(TW_Element.prototype,TW_Node.prototype); Object.defineProperty(TW_Element.prototype, "nodeType", { get: function() { @@ -105,7 +133,7 @@ TW_Element.prototype.setAttribute = function(name,value) { throw "Cannot setAttribute on a raw TW_Element"; } if(name === "style") { - this.style = value; + this.style.set(value); } else { this.attributes[name] = value + ""; } diff --git a/core/modules/widgets/widget.js b/core/modules/widgets/widget.js index b73294654..14e90ba2d 100755 --- a/core/modules/widgets/widget.js +++ b/core/modules/widgets/widget.js @@ -428,6 +428,11 @@ Widget.prototype.assignAttributes = function(domNode,options) { destPrefix = options.destPrefix || "", EVENT_ATTRIBUTE_PREFIX = "on"; var assignAttribute = function(name,value) { + // Process any CSS custom properties + if(name.substr(0,2) === "--" && name.length > 2) { + domNode.style.setProperty(name,value); + return; + } // 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; diff --git a/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes2.tid b/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes2.tid new file mode 100644 index 000000000..6b6a2f953 --- /dev/null +++ b/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes2.tid @@ -0,0 +1,15 @@ +title: Widgets/ElementWidgetCSSCustomProps +description: Element widget should support CSS custom properties +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/wikitext/HTML in WikiText.tid b/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid index b28b471b8..5f1618791 100644 --- a/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid +++ b/editions/tw5.com/tiddlers/wikitext/HTML in WikiText.tid @@ -1,6 +1,6 @@ caption: HTML created: 20131205160816081 -modified: 20230615060119987 +modified: 20241025073517909 tags: WikiText title: HTML in WikiText type: text/vnd.tiddlywiki @@ -68,13 +68,13 @@ In an extension of conventional HTML syntax, attributes of elements and widgets !! Style Attributes -<<.from-version "5.2.2">> TiddlyWiki supports the usual HTML ''style'' attribute for assigning CSS styles to elements: +TiddlyWiki supports the usual HTML ''style'' attribute for assigning CSS styles to elements: ```
Hello
``` -In an extension to HTML, TiddlyWiki also supports accessing individual CSS styles as independent attributes. For example: +<<.from-version "5.2.2">> In an extension to HTML, TiddlyWiki also supports accessing individual CSS styles as independent attributes. For example: ```
Hello
@@ -86,10 +86,8 @@ The advantage of this syntax is that it simplifies assigning computed values to
Hello
``` +<<.from-version "5.3.6">> TiddlyWiki also supports setting [[CSS custom properties|https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties]] as independent attributes. For example: - - - - - - +``` +
Hello
+```