chemerisuk / better-dom

Live extension playground
http://chemerisuk.github.io/better-dom/
MIT License
545 stars 35 forks source link

Shadow DOM support #25

Closed chemerisuk closed 9 years ago

chemerisuk commented 10 years ago

Version 2.1.0 will introduce new method $Element#context. The goal for this method is to create new browser contexts, e.g. independent subtrees in the DOM. Those subtrees provide:

1) scoped CSS rules: you always start with default UA rules 2) internal DOM events do not bubble into the document tree 3) subtree is not accessible via find[All] (neither native querySelector[All]) because it's in another document. 4) elements inside of context can't be crawled, therefore they are not SEO-frieldly 5) potential support for element media queries in future (after implementing https://github.com/chemerisuk/better-dom/issues/23)

However contexts are not equal to the Shadow DOM - they introduce several extra elements in the main document. But the big advantage is that we can use them today (yes, IE8+ is supported!).

chemerisuk commented 9 years ago

There are couple of open questions still related to the $Element#context, so moving it to 2.2.0. Version 2.1.0 will have an experimental implementation.

chemerisuk commented 9 years ago

Alright, I have a progress. The main advantage of contexts is that they provide CSS encapsulation, that can be used TODAY. Performance penalty should not be a big deal, because I use <object> elements instead of <iframe>, and that elements are quite light.

Conceptually the API will look like:

el.context("my-ctx", (root) => {
  // perform context manipulation using root object
});

The callback function is always invoked asynchronously.

The root object is instance of $Document, e.g. it has methods like create[All], importStyles etc. An important feature of contexts is that you have to use root.create for making new elements instead of DOM.create, otherwise IE8 (at least) fails to append such elements to the context document.

Unlike shadow DOM you can have several contexts for a single DOM element. Just use a different context name (the first argument).

Returned value of the method is $Element that represents the context in the main document tree. Therefore it's possible to detach the context using $Element#remove or perform any other DOM manipulation on it:

// this line removes context element from the DOM
el.context("my-ctx").remove();
chemerisuk commented 9 years ago

After some thinking I decided do not implement this method: the approach has difficulties with scripting, styling, a11y and SEO. The main value for it was true CSS rules encapsulation which is almost achievable via custom tags. As number of cons is much longer than pros, I decided to drop the method from better-dom APIs.