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

Effective children #2548

Merged
merged 24 commits into from
Oct 14, 2015
Merged

Effective children #2548

merged 24 commits into from
Oct 14, 2015

Conversation

kevinpschaaf
Copy link
Member

No description provided.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

for (var i=0, h, n; (i < elements.length) && (n=elements[i]); i++) {
if (this._isContent(n)) {
n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
if (n.__observeNodesMap.get(this) == null) {
Copy link
Member Author

Choose a reason for hiding this comment

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

n.__observeNodesMap.has(this)

Copy link
Member Author

Choose a reason for hiding this comment

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

Is the check necessary? If everything is working correctly, should only ever observe one content once?

// attribute tracking?
this._observer.observe(this.node, {
childList: true,
attributes: true,
Copy link
Member Author

Choose a reason for hiding this comment

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

Sucks that there's no childList + attributes combo that actually means "any attribute changes on my childList".

So any change (add, remove, attribute change) to any of its light children descendants will incur the cost of an _observeContentElements iteration (once) and a levenshtein (per listener).

Seems potentially expensive enough to keep the attributes option, since it allows you to remove both attributes + subtree.

Is there an option to auto-enable attributes if you encounter a select on a <content> while observing? Or is that too complicated?

this._scheduleNotify.bind(this));
if (this._hasAttrSelect()) {
Polymer.dom(host).observer.enableShadowAttributeTracking();
this._observer._alwaysCallListener = true;
Copy link
Member Author

Choose a reason for hiding this comment

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

_alwaysCallListener needs to get passed up via enableShadowTracking?

…ibutes under native Shadow DOM; +minor factoring
@kevinpschaaf
Copy link
Member Author

LGTM! 👍 🏆 children: [ 👦 👧 👶 ] changed: [ 🚸 ]

kevinpschaaf added a commit that referenced this pull request Oct 14, 2015
@kevinpschaaf kevinpschaaf merged commit c00c772 into master Oct 14, 2015
@kevinpschaaf kevinpschaaf deleted the effective-children branch October 14, 2015 20:08
@samccone
Copy link
Contributor

@sorvell / @kevinpschaaf any design docs around this feature / why it is good / how/when to use it?

@sorvell
Copy link
Contributor

sorvell commented Oct 14, 2015

Will be forthcoming after discussion with @arthurevans ...

@arthurevans
Copy link

What I have learned so far is:

  • use cases for the effective children APIs may be a trifle abstruse. But perhaps not so much as I think.
  • observeNodes is nifty.

For example, consider a tab panel element that we use like this:

<simple-tab-panel>
  <simple-tab></simple-tab>
  <simple-tab></simple-tab>
  <div class="tab-page"></div>
  <div class="tab-page"></div>
</simple-tab-panel>

The contract is simply: clicking the first tab shows the first tab-page, and so on. But since I'm a good citizen, I want to generate unique IDs for each of these elements and set up ARIA attributes to link them: aria-controls="tab-page-someuniqueid".

It's easy to do this once in ready, but what if the user adds tabs later? I used to have to add a mutation observer, which still wouldn't catch the case where one of my light DOM children is a <content> element that may have children distributed into it.

Now I can do something like:

Polymer.dom(this.$.tabContainer).observeNodes(tabsChanged);

Which is pretty nifty, right?

@arthurevans
Copy link

See also: Chris's PR, above, for example niftiness.

@samccone
Copy link
Contributor

Wooot for observeNodes makes sense thx @arthurevans , is there a way to unregister an observation?


nm I found unobserveNodes

@cdata
Copy link
Contributor

cdata commented Oct 14, 2015

@sorvell @arthurevans The asynchrony involved in using a MutationObserver to measure added and removed items suggests that IronSelectableBehavior might be redesigned to handle items that "don't exist yet" a little more gracefully. This is because an item "not existing" could mean A) the item doesn't actually exist as a child of the selectable, or B) the item exists but the MutationObserver hasn't told us about it yet. Right now, IronSelectableBehavior is designed around the assumption that the set of items is whatever you get when you querySelectorAll for items, and this is a fundamentally different approach that does not take full advantage of the change notifications you get from observeNodes.

@samccone
Copy link
Contributor

Q: should unobserveNodes automatically (Polymer do this for us) be called when an element is detached?

@cdata
Copy link
Contributor

cdata commented Oct 14, 2015

@samccone I don't think that you necessarily want that always, although I admit it is usually dubious for a user to want to respond to these types of changes while detached.

@samccone
Copy link
Contributor

I only wonder because of the potential for users to shoot themselves in the foot memory leak wise with this non private API.

@cdata
Copy link
Contributor

cdata commented Oct 15, 2015

In support of what you are saying, listeners automatically "unlisten" when you detach (I think).

@cdata
Copy link
Contributor

cdata commented Oct 15, 2015

Okay, I take that back. listeners does not automatically "unlisten" upon detach.

@samccone
Copy link
Contributor

yeah so, imho unregistering automatically is a huge win for users from a memory and leak standpoint.. with the ability to conditionally opt out of this behavior

Can anyone come up with a case why this should not act this way?

@ebidel
Copy link
Contributor

ebidel commented Oct 15, 2015

Can you open an issue to discuss? This PR probably isn't the right place to
suggest new features :)

On Wed, Oct 14, 2015 at 5:17 PM Sam Saccone [email protected]
wrote:

yeah so, imho unregistering automatically is a huge win for users from a
memory and leak standpoint.. with the ability to conditionally opt out of
this behavior

Can anyone come up with a case why this should not act this way?


Reply to this email directly or view it on GitHub
#2548 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants