-
Notifications
You must be signed in to change notification settings - Fork 2k
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 support for ShadyDOM on-demand patching #5585
base: legacy-undefined-noBatch
Are you sure you want to change the base?
Add support for ShadyDOM on-demand patching #5585
Conversation
This is a polyfill optimization which defers class generation until first instance.
…fine` when the `Polymer` function is used.
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.
Approved, only a couple minor nits which I think are nbd.
lib/elements/dom-repeat.js
Outdated
@@ -347,11 +347,11 @@ export class DomRepeat extends domRepeatBase { | |||
/** @type {!HTMLElement} */ (this)); | |||
let template = this.template = thisAsTemplate._templateInfo ? | |||
thisAsTemplate : | |||
/** @type {!HTMLTemplateElement} */ (this.querySelector('template')); | |||
/** @type {!HTMLTemplateElement} */ (wrap(this).querySelector('template')); |
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.
nbd, but nothing should ever be in a dom-repeat
or dom-if
except for a template (i.e. no nested elements with SR's that would need to be filtered out), so this is basically fine to always be native qs
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.
Dome
lib/utils/templatize.js
Outdated
} else { | ||
const replace = n.__polymerReplaced__; | ||
if (replace) { | ||
wrap(wrap(replace).parentNode).replaceChild(n, replace); | ||
wrap(wrapIfNeeded(replace).parentNode).replaceChild(n, replace); |
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.
Not totally clear why the outer wrap
can't be wrapIfNeeded
. Adding a <slot>
to any random spot in a shadow root obviously wouldn't be automatically on-demand patched, but this is only putting a <slot>
back into a node that already had it (which I think means it is guaranteed to be patched)?
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.
Done.
lib/mixins/property-effects.js
Outdated
@@ -926,7 +926,7 @@ function setupCompoundStorage(node, binding) { | |||
// We may also want to consider doing this for `textContent` and | |||
// `innerHTML`. | |||
if (target === 'className') { | |||
node = wrap(node); | |||
node = wrapIfNeeded(node); |
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.
Seems like setting className
on an otherwise uninteresting element in a SR (i.e. didn't need to have inside/outside patched) needs to always be wrapped so we don't lose scoping (note _setUnmanagedPropertyToNode
below has similar code).
Might explain the test failure here? https://travis-ci.org/Polymer/polymer/builds/580988656#L780 (although unclear why this would only fail on Chrome 41?)
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.
Fixed. The issue is that patch
needs to be the fallback to wrapping so that this works when instance patching is required.
lib/utils/wrap.js
Outdated
@@ -22,3 +22,7 @@ export const wrap = (window['ShadyDOM'] && window['ShadyDOM']['noPatch'] && wind | |||
window['ShadyDOM']['wrap'] : | |||
(window['ShadyDOM'] ? (n) => ShadyDOM['patch'](n) : (n) => n); | |||
|
|||
// Wrapping a local operation (e.g. appendChild) is only needed iff noPatch is | |||
// explicitly true, and on-demand patching is not used. | |||
export const wrapIfNeeded = (window['ShadyDOM'] && window['ShadyDOM']['noPatch'] === true && window['ShadyDOM']['wrap']) ? |
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.
Let's add comment to list known cases where wrap
and not wrapIfNeeded
is required:
- When moving (
appendChild
/insertBefore
) a node without an explicitremoveChild
to an unpatched location: in this case it needs to be unlinked from logical tree, have its className unscoped, triggerslotchange
and, trigger distribution if it was a<slot>
- When setting
className
to an unpatched node: if it was in a SR it needs to go through ShadyCSS to avoid losing its scoping class - When calling
querySelector
on an unpatched node: it won't return scoped results - When getting
textContent
orinnerHTML
on an unpatched node: it won't return scoped results
Also, now wondering if wrap
and wrapAlways
might be better naming (and less annoying to boot)?
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.
Added.
* Fixes an issue when instance patching is required * Now uses ShadyDOM.wrapIfNeeded.
…ntMixn are pre-patched.
lib/utils/wrap.js
Outdated
* when setting `textContent` or `innerHTML`. | ||
*/ | ||
export const wrapIfNeeded = window['ShadyDOM'] && window['ShadyDOM']['wrapIfNeeded'] ? | ||
window['ShadyDOM']['wrapIfNeeded'] : n => n; |
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.
fall back to wrap
?
|
||
test('Polymer function does not return class when lazy define is used', function() { | ||
assert.notOk(window.XLazyDeclarative); | ||
assert.notOk(window.XLazyImperative); |
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.
window.XLazyImperative
was never assigned above
assert.ok(e.root.querySelector('span')); | ||
}); | ||
|
||
test('imperatively generated elements upgrade and customElements.get works after instance created', function() { |
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.
Add a test for something like
Polymer.telemetry.registrations.filter(r => r.is == 'x-lazy-imperative').length === 0
?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Do not merge until on webcomponents/polyfills#189.