Polymer / polymer

Our original Web Component library.
https://polymer-library.polymer-project.org/
BSD 3-Clause "New" or "Revised" License
22.05k stars 2.02k forks source link

delegatesFocus: true does not work in Polymer 3 even on latest Chrome #5574

Closed motss closed 3 years ago

motss commented 5 years ago

Description

This does not seem to work now. Have no idea if this is the correct way of using delegatesFocus: true in Polymer 3. Have been using this in Polymer 3 to delegate focus in all modern browsers (even those support native ShadowDOM) until few days ago as it is no longer rendering shadow root with this setting.

Update: It seems like this is broken with Polymer@v3.3.0 and using versions that is lower than that works just fine. Kindly advise what's the recommended way to enable delegatesFocus in v3.3.0.

Live Demo

https://jsbin.com/pocenaseto/edit?html,output

Steps to Reproduce

N/A

Expected Results

Attach shadow root with delegatesFocus set to true.

Actual Results

No shadow root if modify how shadow root is created.

Browsers Affected

Versions

arthurevans commented 4 years ago

I believe this is a result of this change: https://github.com/Polymer/polymer/commit/50ba9cea2b6034b33c283da88a6d0022aca6dfed#diff-c0938e89f08e8926f5cef28954a7118d

Moving the appendChild call inside the conditional means we fail to append the templated DOM if the shadow root already exists. This affects both of the methods documented here to create your own shadow root:

https://polymer-library.polymer-project.org/3.0/docs/devguide/dom-template#create-your-own-shadow-root

arthurevans commented 4 years ago

So the base _attachDom method is now doing some shadyDOM related work. However, if you don't call super._attachDom, you won't run into this particular issue.

Since (as far as I know) shady DOM doesn't support delegatesFocus, you could use a workaround like this to use your own shadow root where native shadow DOM is supported, and get the appropriate shady DOM goodness elsewhere.

_attachDom(dom) {
  if (window.ShadyDOM) {
    // shady DOM doesn't support delegatesFocus and the superclass 
    // does some shady DOM magic, so defer to superclass
    return super._attachDom(dom);
  } else {
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(dom);
    return this.shadowRoot;
  }
}
sorvell commented 4 years ago

This is a bug and a PR would be welcome. It should be something like:

_attachDom(dom) {
  const n = wrap(this);
  if (n.attachShadow) {
    if (dom) {
      if (!n.shadowRoot) {
        n.attachShadow({mode: 'open', shadyUpgradeFragment: dom});
      }
      n.shadowRoot.appendChild(dom);
    //...