How do we detect if a shadow root was made with v0 or v1 API?

一笑奈何 提交于 2019-12-01 21:24:04
KevBot

I went a similar direction to Hayato Ito's answer. However, instead of creating slot elements, I target content elements. I was not able to find a way to detect the version off of any API method detection.

I targeted content elements since content elements do not natively have events for them, unlike slotchange on the slot event, which hopefully could lead to a small performance boost. Plus the function returns v1 a little faster if the browser does not support v0 at all.

function shadowType(shadowRoot) {
    if (!shadowRoot) {
        // closed shadow dom does not appear to have a shadowRoot...
        // It could be assumed that it is v1, but for now return undefined
        return;
    }

    const content = document.createElement('content');
    // In browsers that support v1, but not v0 (ex: Safari)
    if (!content.getDistributedNodes) {
        return 'v1';
    }

    content.setAttribute('select', 'test-shadow-dom-version');
    shadowRoot.appendChild(content);

    const testElement = document.createElement('test-shadow-dom-version');
    shadowRoot.host.appendChild(testElement);
    const type = (content.getDistributedNodes().length) ? 'v0' : 'v1';
    shadowRoot.removeChild(content);
    shadowRoot.host.removeChild(testElement);

    return type;
}

It definitely feels like a "hack", because of need to append random dom :(. I did test this in Chrome, Firefox, Safari, IE11, and Edge. I tested components made using the webcomponentsjs (v0) polyfill, and it correctly returned v0 for each component. I also tested those same browsers with just the shadydom (v1) polyfill with components created with the v1 spec, and received v1 in all of those browsers.

The following hack should work:

function isV1(shadowRoot) {
  const slot = document.createElement('slot');
  shadowRoot.appendChild(slot);
  slot.appendChild(document.createElement('div'));
  const assignedNodes = slot.assignedNodes({ flatten: true });
  slot.remove();
  return assignedNodes.length !== 0;
}

IMO, there is something wrong when you have to detect it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!