Issues with ixsl:style()
Following changes for bug #3545, we're getting some unit test failures:
ixsl/style01 "keys() not allowed for JSValue at style01.xsl#26"
ixsl/styleEmpty01 "forEach() not allowed for JSValue at styleEmpty01.xsl#18"
ixsl/SVGstyle01 "keys() not allowed for JSValue at SVGstyle01.xsl#26"
ixsl/SVGstyle03 "keys() not allowed for JSValue at SVGstyle03.xsl#32"
(Note that the fix for bug #3545 is not yet released, so these particular failures are only relevant for Saxon-JS development code.)
The documentation for ixsl:style() says that the function returns an XDM map, but evidently we are currently returning a JSValue wrapped object (which allows map:get() lookup, but not all map functions).
Generally, the fix would be to convert the style object using Expr.convertFromJS(style, false, true) rather than just Expr.convertFromJS(style); so that we get an XDM map. However, actually I think there are problems with this (and so problems with the original implementation) which can lead to differences of behaviour for different browsers - because we have not properly taken into account what the style object is. It is a CSSStyleDeclaration object returned by window.getComputedStyle, which represents a collection of CSS property-value pairs. Instead I think we should explicitly construct the XDM map (internally as a HashTrie) to contain only the CSS property-value pairs.
#1 Updated by Debbie Lockett 5 months ago
- Status changed from New to In Progress
In the implementation of ixsl:style() in ExtraFn.js, we now explicitly construct a HashTrie, representing the CSS property-value pairs from the CSSStyleDeclaration object. The resulting XDM map has type map(xs:string, xs:string?)
For information, here are details of the relevant properties of the CSSStyleDeclaration object:
CSSStyleDeclaration.length property returns the number of property-value pairs;
CSSStyleDeclaration.item() returns the property name by index;
CSSStyleDeclaration.getPropertyValue() returns the property value given a property name.
If a CSSStyleDeclaration property value is null or undefined, then the corresponding value in the XDM map is an empty sequence. Otherwise property values are always strings.
<xsl:template match="div[@id='list']//li" mode="ixsl:onmouseover"> <xsl:if test="ixsl:style(.)?font-size = '12px'"> <ixsl:set-style name="fontSize" select="'20px'"/> </xsl:if> </xsl:template>
We could perhaps do more to convert style property names between kebab-case and camel-case if we decide this is too awkward.
Changes have been committed on 1.0 and 2.0 branches; and some JS unit tests updated (since now we need to be strict about using kebab-case for getting style properties. Previously when using the direct conversion of the CSSStyleDeclaration object, using camel-case to get a style property seemed to work, but actually only on some browsers).
Please register to edit this issue