Skip to content

Add closest, classList, and dataset to the DOM polyfill - #619

Draft
developit wants to merge 6 commits into
mainfrom
cx-dom-convenience
Draft

Add closest, classList, and dataset to the DOM polyfill#619
developit wants to merge 6 commits into
mainfrom
cx-dom-convenience

Conversation

@developit

@developit developit commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What changed

Remote code can now use three familiar DOM conveniences:

  • closest() starts with the element itself and walks parentElement, using the selector matcher already shared by querySelector().
  • classList provides live token operations and read-only indexed access over className.
  • dataset maps camel-cased properties to data-* attribute reads, writes, and deletes.

dataset lives on the shared Element abstraction. Remote DOM deliberately keeps its element model flat, so this makes the API available to ordinary and custom elements without changing document.createElement(), constructor identity, or the existing prototype hierarchy. Each element lazily creates and caches one dataset proxy, preserving normal dataset object identity while keeping it live against attribute changes.

classList is also cached per element. DOMTokenList.prototype inherits from a shared proxy that supplies live numeric properties such as classList[1]; numeric assignments are silently ignored. Internal state uses the polyfill's existing owner and value symbols. This avoids allocating a proxy per element and does not pretend the token list is an array or expose mutable array methods.

These APIs do not add or widen any hooks. Class and data changes continue through the existing attribute methods, so remote synchronization sees exactly the same mutations it did before.

Tests

Added focused coverage for closest-ancestor traversal, live and indexed class updates, token operations, stable class-list and dataset identity, dataset name conversion, string coercion, deletion, and attribute hook calls.

Validated with:

  • pnpm exec vitest run (184 tests)
  • pnpm type-check
  • pnpm lint
  • pnpm --filter @remote-dom/polyfill build on Node 20.20.0

Implement closest, classList, and dataset by composing the existing selector, class-name, and attribute primitives. Keep remote synchronization on the unchanged hooks and cover traversal and mutation behavior.
Preserve remote-dom's flat element model instead of changing createElement and the HTML prototype hierarchy. Dataset remains a direct wrapper around data attribute operations.
Store dataset in a symbol-backed field so repeated access returns the same live object. Use a compact lazy initializer while preserving camel-case attribute normalization.
Cache a proxied DOMTokenList and route numeric properties to live tokens while rejecting indexed writes. Keep non-index properties and methods on the token-list object.
Place one proxy behind DOMTokenList.prototype so numeric lookups read live tokens and numeric assignments are ignored without allocating a proxy per element.
Store the owner and live tokens through the existing OWNER_ELEMENT and VALUE symbols. This follows the polyfill's private-state convention and avoids string-named implementation properties.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant