-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mutation observer to update styles on DOM changes #92
Conversation
9bd3319
to
55cf06b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 2 files at r1.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @samiheikki)
src/vaadin-form-layout.html, line 289 at r1 (raw file):
// Observe changes in form item's `colspan` attribute const config = {attributes: true, subtree: true};
subtree
is probably an overkill, the form layout does only work on its direct children.
Would be nice to specify attributeFilter: ['colspan']
, so that it would be only triggered by that attribute. Might require some additional filtering in the mutation callback too.
src/vaadin-form-layout.html, line 290 at r1 (raw file):
// Observe changes in form item's `colspan` attribute const config = {attributes: true, subtree: true}; this.__mutationObserver = new MutationObserver(this.updateStyles.bind(this));
Using updateStyles
as a mutation observer callback is a bad idea:
updateStyles
is a Polymer.Element method that supports an arbitrary styles object as a first argument: https://github.com/Polymer/polymer/blob/7569d74dcb768693ae97639266e924f1d6e1f56c/lib/mixins/element-mixin.html#L613-L639. This is passed further toShadyCSS
to define / update custom CSS properties programmatically.MutationObserver
’s callbacks receivesequence<MutationRecord> mutations
as a first argument: https://dom.spec.whatwg.org/#callbackdef-mutationcallback
I can only guess what updateStyles
does to mutations in this case. But whatever that is, treating mutations as styles is not useful and probably dangerous. Let us use some other method as a mutation observer callback, so that the argument is not silently passed down to ShadyCSS
.
Hint: you might want to use _invokeUpdateStyles
, which invokes updateStyles
without any arguments. (It’s the only reason for this method to exist.)
src/vaadin-form-layout.html, line 290 at r1 (raw file):
// Observe changes in form item's `colspan` attribute const config = {attributes: true, subtree: true}; this.__mutationObserver = new MutationObserver(this.updateStyles.bind(this));
BTW I’m not sure if MutationObserver
is reliable with ShadyDOM. Shady DOM has it’s own observation API. Last time I tried to do a similar task in a Vanilla JS component, I had to use it directly: https://github.com/webcomponents/shadydom/blob/e274f1ee776cfe19d73ba84351fea583846473f6/src/observe-changes.js#L59-L89
Typically, Polymer.FlattenedNodesObserver
saves us from the most of that hassle: https://www.polymer-project.org/2.0/docs/api/classes/Polymer.FlattenedNodesObserver. However, it cannot observe attributes automatically.
I am not sure, the tests should tell better than me. My gut feeling is that this use case requires a two-level observer in this case:
Polymer.FlattenedNodesObserver
to observe for first-level flattened children of the form-layout- Then,
MutationObserver
observing specifically for thecolspan
attribute on every child individually (only the attribute, not subtree, not childList).
src/vaadin-form-layout.html, line 291 at r1 (raw file):
const config = {attributes: true, subtree: true}; this.__mutationObserver = new MutationObserver(this.updateStyles.bind(this)); this.__mutationObserver.observe(Polymer.dom(this).node, config);
Do not use Polymer.dom
, it’s a legacy Polymer v1 API.
0da7117
to
a26f48e
Compare
a26f48e
to
b77b367
Compare
Thanks for the great review. I updated the PR based on your feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 5 files reviewed, 3 unresolved discussions (waiting on @platosha and @samiheikki)
src/vaadin-form-layout.html, line 290 at r1 (raw file):
Previously, platosha (Anton Platonov) wrote…
BTW I’m not sure if
MutationObserver
is reliable with ShadyDOM. Shady DOM has it’s own observation API. Last time I tried to do a similar task in a Vanilla JS component, I had to use it directly: https://github.com/webcomponents/shadydom/blob/e274f1ee776cfe19d73ba84351fea583846473f6/src/observe-changes.js#L59-L89Typically,
Polymer.FlattenedNodesObserver
saves us from the most of that hassle: https://www.polymer-project.org/2.0/docs/api/classes/Polymer.FlattenedNodesObserver. However, it cannot observe attributes automatically.I am not sure, the tests should tell better than me. My gut feeling is that this use case requires a two-level observer in this case:
Polymer.FlattenedNodesObserver
to observe for first-level flattened children of the form-layout- Then,
MutationObserver
observing specifically for thecolspan
attribute on every child individually (only the attribute, not subtree, not childList).
@platosha updated the PR to use your approach with 2 observers, and added the test using dom-repeat to ensure it is indeed required to handle lazily stamped nodes correctly. PTAL
a18106f
to
10f6535
Compare
10f6535
to
80c999f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 4 files at r2, 3 of 3 files at r3.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @samiheikki)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @samiheikki)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 4 files at r2, 3 of 3 files at r3.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @platosha)
src/vaadin-form-layout.html, line 290 at r1 (raw file):
Previously, platosha (Anton Platonov) wrote…
Using
updateStyles
as a mutation observer callback is a bad idea:
updateStyles
is a Polymer.Element method that supports an arbitrary styles object as a first argument: https://github.com/Polymer/polymer/blob/7569d74dcb768693ae97639266e924f1d6e1f56c/lib/mixins/element-mixin.html#L613-L639. This is passed further toShadyCSS
to define / update custom CSS properties programmatically.MutationObserver
’s callbacks receivesequence<MutationRecord> mutations
as a first argument: https://dom.spec.whatwg.org/#callbackdef-mutationcallbackI can only guess what
updateStyles
does to mutations in this case. But whatever that is, treating mutations as styles is not useful and probably dangerous. Let us use some other method as a mutation observer callback, so that the argument is not silently passed down toShadyCSS
.Hint: you might want to use
_invokeUpdateStyles
, which invokesupdateStyles
without any arguments. (It’s the only reason for this method to exist.)
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! all files reviewed, all discussions resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! all files reviewed, all discussions resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! all files reviewed, all discussions resolved
Fixes #46
This change is![Reviewable](https://camo.githubusercontent.com/23b05f5fb48215c989e92cc44cf6512512d083132bd3daf689867c8d9d386888/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)