fix(js,dom): add Storage global, CharacterData ChildNode methods, fix remove/isConnected (#176)

fix(dom): add missing DOM/JS shims for modern frameworks

Closes #163.

Adds missing DOM and JS shims required by modern frameworks (Svelte 5, 
Vue, Lit) and consent-management SDKs to execute without errors:

- Define the `Storage` global constructor to resolve `ReferenceError`s 
  and fix `Storage.prototype` access.
- Apply standard ChildNode methods (`before`, `after`, `replaceWith`, 
  `remove`) to `CharacterData.prototype`. This prevents `TypeError`s when 
  frameworks call these on Text or Comment nodes during hydration.
- Update `Element.prototype.isConnected` to perform a genuine parent-walk 
  rather than returning a hardcoded `true`.
- Fix `Element.prototype.remove` to properly clean up the internal ID 
  index so removed elements are no longer queryable.
- Remove outdated no-op stubs on the `Element` class that were shadowing 
  the proper polyfill implementations.
This commit is contained in:
Ben Younes authored and GitHub committed 2026-05-24 17:36:19 +00:00
1 parent 10810e250c
commit 183c444a56
3 files changed
+67 -4

No files matched your search

+34
View File
@@ -322,6 +322,40 @@ impl DomTree {
}
}
/// Detach a node from its parent AND remove it (and all descendants)
/// from the id-index so that `getElementById` no longer returns them.
/// Unlike `remove()`, this does NOT free the nodes — the JS side may
/// still hold references to the wrappers.
pub fn remove_child(&self, node_id: NodeId) {
// Collect all id attribute values in the subtree. We snapshot them
// before detaching so `get_attribute` can still see the tree.
let ids_to_remove: Vec<String> = {
let descendants = self.descendants(node_id);
let inner = self.inner.borrow();
let mut ids: Vec<String> = Vec::new();
if let Some(Some(node)) = inner.nodes.get(node_id.index()) {
if let Some(id_val) = node.get_attribute("id") {
ids.push(id_val.to_string());
}
}
for desc_id in &descendants {
if let Some(Some(node)) = inner.nodes.get(desc_id.index()) {
if let Some(id_val) = node.get_attribute("id") {
ids.push(id_val.to_string());
}
}
}
ids
};
self.detach(node_id);
let mut inner = self.inner.borrow_mut();
for id_str in &ids_to_remove {
inner.id_index.remove(id_str);
}
}
pub fn remove(&self, node_id: NodeId) {
self.detach(node_id);
let descendants = self.descendants(node_id);