fix(js): expose CSSStyleDeclaration as a real global interface
CSSStyleDeclaration was added to the _preHideInternals non-enumerable
pre-declaration list (commit c7e7c70) on the assumption that its later
`globalThis.X = X` assignment would fill in the value. But it was the only
one of the 22 WebIDL interfaces with no such assignment, so its value stayed
undefined: `typeof window.CSSStyleDeclaration` was "undefined" while
`'CSSStyleDeclaration' in window` was true, and because it is the type of
element.style / getComputedStyle(), `el.style instanceof CSSStyleDeclaration`
threw "Right-hand side of 'instanceof' is not callable" (Chrome returns true).
Assign globalThis.CSSStyleDeclaration alongside the other interface globals.
The property was already declared writable/configurable, so the assignment
only updates the value and it remains enumerable:false, like a real browser.
Fixes #546
This commit is contained in:
6
crates/obscura-js/js/bootstrap.js
vendored
6
crates/obscura-js/js/bootstrap.js
vendored
@@ -6041,6 +6041,12 @@ globalThis.DocumentType = DocumentType;
|
||||
globalThis.Node = Node;
|
||||
globalThis.Element = Element;
|
||||
globalThis.Document = Document;
|
||||
// CSSStyleDeclaration is the type of element.style and getComputedStyle(); it is
|
||||
// pre-declared non-enumerable in _preHideInternals, but unlike the other WebIDL
|
||||
// interfaces it had no value assignment, leaving `window.CSSStyleDeclaration`
|
||||
// undefined (so `el.style instanceof CSSStyleDeclaration` threw). Assigning here
|
||||
// only fills the value; the property stays enumerable:false, matching Chrome.
|
||||
globalThis.CSSStyleDeclaration = CSSStyleDeclaration;
|
||||
globalThis.XPathResult = globalThis.XPathResult || class XPathResult {};
|
||||
Object.assign(globalThis.XPathResult, {
|
||||
ANY_TYPE: 0,
|
||||
|
||||
@@ -3484,6 +3484,20 @@ mod tests {
|
||||
assert_eq!(kb, serde_json::json!(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cssstyledeclaration_is_a_usable_global_interface() {
|
||||
// CSSStyleDeclaration was pre-declared non-enumerable but never assigned
|
||||
// a value (the only WebIDL interface missing its globalThis.X = X line),
|
||||
// so it was `undefined` while `'CSSStyleDeclaration' in window` was true,
|
||||
// and `el.style instanceof CSSStyleDeclaration` threw. It must be a real
|
||||
// constructor, non-enumerable like a browser, and the type of .style.
|
||||
let mut rt = setup_runtime("<html><body></body></html>");
|
||||
let v = rt
|
||||
.evaluate("(function(){var d=Object.getOwnPropertyDescriptor(window,'CSSStyleDeclaration');return (typeof window.CSSStyleDeclaration)+'|'+(document.body.style instanceof CSSStyleDeclaration)+'|'+(d?d.enumerable:'missing');})()")
|
||||
.unwrap();
|
||||
assert_eq!(v, serde_json::json!("function|true|false"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_event_unknown_type_returns_event() {
|
||||
let mut rt = setup_runtime("<html><body></body></html>");
|
||||
|
||||
Reference in New Issue
Block a user