Open smaug---- opened 7 years ago
Using selectors is #77. How would localNameFilter be used for text nodes?
@dtapuska @rniwa thoughts?
Filtering based on element names sense to me but why not just elementFilter
?
Also, should this follow the usual case-insensitive in HTML but case-sensitive in XML semantics?
How would localNameFilter be used for text nodes?
Er, silly me, that would need to be nodeName, not localName. And since attributeFilter uses localName, elementFilter should too.
I don't care too much about the name. elementFilter would be ok to me. But it should be case sensitive, similar to attributeFilter.
Case-sensitive elementFilter
matching on local name sounds fairly straightforward. I could work on specifying that and writing tests, but also happy to hand it to someone else if there's interest since this seems like a nice starter bug.
I am ready to check for this chance.Please authorize me.
@hemant1612 what you want to do is fork this repository and then create a pull request from the fork. The other thing that will need to be done is writing new web-platform-tests.
Filtering based on element names sense to me but why not just elementFilter?
My main issue with elementFilter
is that it solves a subclass of the problem and motivates future additions like attributeFilter
or combinations for cases where elements and attributes of particular type are expected.
querySelector handle all of that and can be internally optimized by engines for common cases (like elementFilter, attributeFilter etc.) while keeping the "slow case" still faster than doing that in the JS code
We definitely don't want to execute CSS selectors on every DOM mutation. That's simply non-starter.
That's simply non-starter.
1) Why?
For use cases where someone will put it, it basically means that if they can't get it on the MutationObserver config to be performed (and heavily optimized) by the engine, they'll put it in the callback anyway, because their observer clearly needs it.
If the concern is performance, I fail to understand how is it a win.
2) But, assuming that I'm missing something
Is a combination of localNameFilter
and attributeFilter
realistic?
That's simply non-starter.
- Why?
It would be way too slow.
For use cases where someone will put it, it basically means that if they can't get it on the MutationObserver config to be performed (and heavily optimized) by the engine, they'll put it in the callback anyway, because their observer clearly needs it.
That's okay. Evaluating selectors after the fact is a lot more efficient especially because you'd be executing a lot of them all at once. What's extremely slow is for each DOM mutation to synchronously execute a selector to determine whether a given element should be queued to an observer or not. That's not the kind of work you don't want to be doing for every node being added or removed.
- But, assuming that I'm missing something Is a combination of localNameFilter and attributeFilter realistic?
That's a lot more realistic filtering assuming attribute filter is about filtering based on the presence of an attribute and not its value.
But it does change the meaning of attributeFilter, if that starts to affect to MutationRecords created because of childList: true.
@smaug---- Oh yeah, I think we're talking about something different here. It's filtering of records based on attributes, not attributeFilter
as it exists today.
So hasAttributeFilter
, effectively? And localNameFilter
?
Maybe elementLocalNameFilter
and elementAttributesFilter
to match the existing naming convention?
elementFilter
(counterpart to attributeFilter
) and elementAttributeFilter
(singular for attribute to match existing style)? I kinda like elementHasAttributeFilter
for the latter as well to make it clearer how it's different.
It seems there's implementer interest, so what's needed to complete this is people willing to update the DOM Standard and write corresponding tests (ideally different people, but okay if they're the same).
Closes #850
In which I proposed adding an elementLocalNameFilter
as there is no current functionality to support mutation to the DOM involving changes to specific element tags.
With late page hydration seen in modern web frameworks, monitoring changes to elements on the page can be quite useful.
New property: elementLocalNameFilter
(optional)
Description: Set to a list of element tag/qualified names if not all element changes need to be observed and subTree
is true or omitted.
let observer = new MutationObserver(mutations) => {
mutations.forEach(mutation => {
// immediate handle on all new 'input' elements on the page...
});
});
observer.observe(document.documentElement, {
childList: true,
subTree: true,
elementLocalNameFilter: ['input']
});
Addition to observe
method invocations.
The observe(target, options) method, when invoked, must run these steps:
X. If options elementLocalNameFilter is present and options’s subTree is omitted, then set options’s elementChanges to true.
X. If options’s elementLocalNameFilter is present and options’s subTree is false, then throw a TypeError.
(fixing)
For easy of use and consistency with attributeFilter
which doesn't callout that it's a local name, I'd suggest elementFilter
as the name of the filter.
We can revisit adding a new variant of filtering which takes qualified name (e.g. namespace and/or prefix into account) in the future.
If options elementLocalNameFilter is present and options’s subTree is omitted, then set options’s elementChanges to true.
I don't think there is such a thing as "elementChanges".
If options’s elementLocalNameFilter is present and options’s subTree is false, then throw a TypeError.
I don't think we should do this. It's definitely useful to be able to observe the direct child of an element of specific types.
We'd now have to consider what happens when both attributeFilter and elementFilter are set. One interpretation is that they're independent. We'd be monitoring insertion and removal of elements of specific types, and any changes to a set of attributes. Alternatively, they combine. We'd be only observing changes to attributes on elements of specific types.
For easy of use and consistency with
attributeFilter
which doesn't callout that it's a local name, I'd suggestelementFilter
as the name of the filter.
I am open to either name for this.
We'd now have to consider what happens when both attributeFilter and elementFilter are set. One interpretation is that they're independent. We'd be monitoring insertion and removal of elements of specific types, and any changes to a set of attributes. Alternatively, they combine. We'd be only observing changes to attributes on elements of specific types.
I have drafted a PR that implements an intersection of elementHasAttributeFilter & elementLocalNameFilter when both are present. This applies the filter to the addedNodes and removedNodes field.
Depending on which implementation strategy is chosen for integrating these features with attributeFilter, I believe it would be best to run each filter, one by one, on the nodes observed in the mutation event, asserting that either addedNodes or removedNodes list is not empty between after each filter that is applied.
Regardless of what is favored for mixing filters (union or intersection), I think it should be consistent for all combinations of filters.
Personally, I believe intersection is easier to use.
Another option is to have an additional operand option which allows the implementor to chose how to combined filters themselves.
Depending on which implementation strategy is chosen for integrating these features with attributeFilter, I believe it would be best to run each filter, one by one, on the nodes observed in the mutation event, asserting that either addedNodes or removedNodes list is not empty between after each filter that is applied.
Yeah, we just need to decide what to do here in order to proceed with this proposal.
Regardless of what is favored for mixing filters (union or intersection), I think it should be consistent for all combinations of filters.
Personally, I believe intersection is easier to use.
I tend to agree although it's unclear what happens to CihldNode observation when an attribute filter is specified. I guess we'd ignore it for child changes?
Filed https://bugs.webkit.org/show_bug.cgi?id=222784 for WebKit.
I'd suggest
elementFilter
as the name of the filter.
Why not nodeFilter
? This would also match with addedNodes
and removedNodes
.
Because it would take element local names and there is precedent with attributeFilter
. addedNodes
and removedNodes
can return non-element nodes and as such cannot have a more specific name.
I was looking at a slow (cross) browser addon code, and one thing they need to do is to figure out when new input elements have been added to the tree. This means that all the added (and removed) elements are touched, which forces browsers to have JS wrappers for those and create MutationRecords too.
localNamefilter, similar to attributeFilter would optimize some of that out. Using css for filtering might be also one option, but it is way more heavy weight in general, so if possible, I'd stick with localNames. (and localNameFilter could be used for text node filtering too, unlike css)
And while addons aren't part of the web, I think web pages have similar use cases.