Open oravecz opened 7 years ago
You can use Incremental DOM calls directly from the code calling patch
to skip any style nodes if present. This could look something like:
const {
currentPointer,
skipNode,
patch,
} = IncrementalDOM;
function skipStyleNodes() {
let node;
while((node = currentPointer()) && node.nodeName === 'STYLE') {
skipNode();
}
}
class BaseClass extends HTMLElement {
update() {
patch(this.shadowRoot, () => {
skipStyleNodes();
this.render();
});
}
}
The component extending the base class can call update
and just implement their render function without worrying about styles.
For a full example, you can take a look at this.
Thank you very much for that tip. It works, but I'm not clear on exactly why.
From what I gather, the skipStyleNodes()
function traverses the existing DOM structure an marks those nodes I want to skip in a way that the actual idom methods will ignore. However, if this is the case, is the marking of these nodes temporary to this rendering cycle? Iterating each node prior to every render seems extreme when I have a pretty good handle as to exactly where my node is.
Couldn't I mark this style node as a skip one time when I initially render my content? Is there a way to mark it by setting a special attribute on it when I append it to the DOM?
Thanks for the help.
Thank you very much for that tip. It works, but I'm not clear on exactly why.
From what I gather, the skipStyleNodes() function traverses the existing DOM structure an marks those nodes I want to skip in a way that the actual idom methods will ignore. However, if this is the case, is the marking of these nodes temporary to this rendering cycle?
The way Incremental DOM works in general is that it traverses the DOM and compares the element that it is pointing at to the one you just declared. So the skipStyleNodes
function is just advancing the pointer one by one past the style nodes at the start of the shadow root.
Iterating each node prior to every render seems extreme when I have a pretty good handle as to exactly where my node is.
I don't think you need to worry too much about performance, traversing the DOM isn't too slow (and we already do it anyway).
Couldn't I mark this style node as a skip one time when I initially render my content? Is there a way to mark it by setting a special attribute on it when I append it to the DOM?
Even if you did, Incremental DOM would internally do the same thing, checking if it needs to be skipped and traverse past the part in the DOM.
I think in order to use an attribute this would be the responsiblity of the template compiler. I have done something similar in my handlebars compiler. Adding the skip
attribute will add an IncrementalDOM.skip()
call. https://github.com/ahumphreys87/handlebars-idom/blob/master/lib/compiler.js#L144-L146
I'm using the JSX to idom plugin to create a factory function that uses idom. It works spectacularly well. But (there's always a but).
I am writing web components and my JSK is patched into the shadow root. Shadow root is also where I want to insert my style sheet rules. If I insert rules into shadow dom myself, idom comes along and deletes these nodes that are unknown.
Looking at the skip capability, I could put the responsibility on the template author to add a placeholder for styles in their template, and use the skip attribute.
But this is problematic for a couple reasons.
<div>
due to the way JSX works. Not a fan, and I don't think this will work in all cases.What I would really like to do is specify my JSX like so...
And in my component constructor, I would determine if native shadow dom is supported. If it is, I would append the following dom structure to shadow root:
What I would be counting on is that there would be a way to inform idom to ignore this DOM element when it comes across it due to the presence of a special attribute.
I don't believe this exists currently, but is there any approach that would offer similar behavior?