cssstyle
cssstyle copied to clipboard
Values are not properly converted to DOMString
I'm not sure that the following behavior tested in Chrome and Firefox is described in any specification:
// Case 1: toString() from prototype
class Prop {
toString() {
return 1 // Number
}
}
style.setProperty('opacity', new Prop) // Ok, new value: 1
// Case 2: toString() from instance
const Prop = {
toString() {
return 1
}
}
style.setProperty('opacity', Prop) // Ok, new value: 1
// Case 3: recursive toString()
class RecursiveProp {
toString() {
return new Prop()
}
}
style.setProperty('opacity', new RecursiveProp) // Error
Ie. the value should be converted to String if it has a toString()
method. cssstyle
currently returns ''
for all cases, ie. it results to an invalid value. Chrome and Firefox throw an error for case 3.
From what I understand, a value is converted to a DOMString
when passing from JavaScript to a DOM element style
interface.
Interface CSSStyleDeclaration
void setProperty(in DOMString propertyName, in DOMString value, in DOMString priority) raises(DOMException);
https://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
ECMAScript values are converted to an IDL value when passed to a platform object expecting that type
https://heycam.github.io/webidl/#es-type-mapping
An ECMAScript value V is converted to an IDL
DOMString
value by running the following algorithm:
- If V is
null
and the conversion is to an IDL type associated with theLegacyNullToEmptyString
extended attribute, then return theDOMString
value that represents the empty string.- Let x be ToString(V)
- Return the IDL
DOMString
value [...]
https://heycam.github.io/webidl/#es-DOMString
I renamed the title of this issue to handle the following cases that were also not handled correctly:
target.style.opacity = Symbol('1') // Error
target.style.opacity = { toString: () => [0] } // Error
target.style.opacity = BigInt(1) // '1'
target.style.setProperty('--custom', undefined) // 'undefined'
target.style.setProperty('--custom', true) // 'true'
target.style.setProperty('--custom', { toString: () => null }) // 'null'