Skip to content
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

Merged
merged 2 commits into from
Nov 5, 2018

Conversation

samiheikki
Copy link
Contributor

@samiheikki samiheikki commented Aug 28, 2018

Fixes #46


This change is Reviewable

Copy link
Contributor

@platosha platosha left a 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:

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 the colspan 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.

@samiheikki samiheikki force-pushed the fix/colspan-runtime branch 2 times, most recently from 0da7117 to a26f48e Compare October 18, 2018 17:04
@samiheikki
Copy link
Contributor Author

Thanks for the great review. I updated the PR based on your feedback.

Copy link
Member

@web-padawan web-padawan left a 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-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 the colspan 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

@web-padawan web-padawan force-pushed the fix/colspan-runtime branch 2 times, most recently from a18106f to 10f6535 Compare November 2, 2018 10:58
Copy link
Contributor

@platosha platosha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 2 of 4 files at r2, 3 of 3 files at r3.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @samiheikki)

Copy link
Member

@web-padawan web-padawan left a 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)

Copy link
Member

@web-padawan web-padawan left a 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:

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.)

Done.

Copy link
Contributor

@platosha platosha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

Copy link
Contributor Author

@samiheikki samiheikki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

Copy link
Member

@web-padawan web-padawan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

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.

None yet

4 participants