fix(js): Element.attributes, on* event defaults, per-nid getBoundingClientRect (#45) (#186)

Three DOM-completeness gaps that broke jQuery 1.11.3 init and Playwright
  actionability:

  1. Element.attributes was undefined, so legacy IE feature-detect code
     like div.attributes[eventName].expando threw TypeError. Added a
     NamedNodeMap-like backed by a new attribute_names DOM op (length,
     numeric index, string name lookup, getNamedItem/setNamedItem,
     iterable).

  2. Standard on* event handler properties were missing from window, so
     ('on' + ev) in window returned false and forced jQuery into the
     legacy IE branch. Initialised the 79 HTML-spec on* handlers to null.

  3. getBoundingClientRect returned the same {x:8,y:8,width:100,height:20}
     literal for every element, so Playwright's hit-testing couldn't tell
     elements apart. Replaced with a deterministic synthesis from _nid
     mapped into a 12-column grid sized to a 1280x720 viewport. Still not
     pixel-accurate (no layout engine), but stable across reads and
     distinct per node.
This commit is contained in:
SGavrl authored and GitHub committed 2026-05-25 22:08:49 +02:00
1 parent 8a8c767338
commit d15cac6149
2 files changed
+76 -1

No files matched your search

+12
View File
@@ -174,6 +174,18 @@ fn op_dom(state: &OpState, #[string] cmd: String, #[string] arg1: String, #[stri
let val = dom.get_node(NodeId::new(nid)).and_then(|n| n.get_attribute(&arg2).map(|s| s.to_string()));
serde_json::to_string(&val).unwrap_or("null".into())
}
"attribute_names" => {
let nid = arg1.parse::<u32>().unwrap_or(0);
let names: Vec<String> = dom
.get_node(NodeId::new(nid))
.map(|n| {
n.attrs()
.map(|a| a.iter().map(|x| x.name.local.as_ref().to_string()).collect())
.unwrap_or_default()
})
.unwrap_or_default();
serde_json::to_string(&names).unwrap_or("[]".into())
}
"set_attribute" => {
let nid = arg1.parse::<u32>().unwrap_or(0);
let node_id = NodeId::new(nid);