[Bug]: Custom HTML elements attach a Shadow DOM
See original GitHub issuePreflight Checklist
- I have searched the issue tracker for a bug report that matches the one I want to file, without success.
What package is this bug report for?
rrweb-snapshot
Expected Behavior
Looks like rrweb is processing incorrectly custom elements.
Custom elements are not a part of Shadow DOM, but during recording, all these elements receive the following options: isShadow
and isShadowHost
. In some cases it may break replay.
Actual Behavior
Recording
Custom elements receive isShadow
and isShadowHost
options.
Custom HTML element:
<community_navigation-global-navigation-trigger className="cAltToggleNav slds-icon_x-small" data-aura-rendered-by="367:0"> <lightning-button-icon></lightning-button-icon> <community_navigation-back-navigation-button></community_navigation-back-navigation-button> </community_navigation-global-navigation-trigger>
The same elements at snapshot:
{"type": 2, "tagName": "community_navigation-global-navigation-trigger", "attributes": { "class": "cAltToggleNav slds-icon_x-small", "data-aura-rendered-by": "367:0" }, "childNodes": [{ "type": 2, "tagName": "lightning-button-icon", "attributes": {}, "childNodes": [], "id": 167, "isShadowHost": true, "isShadow": true }, { "type": 2, "tagName": "community_navigation-back-navigation-button", "attributes": {}, "childNodes": [], "id": 175, "**isShadowHost**": true, "isShadow": true }], "id": 166, "isShadowHost": true }
Replay
On investigate how Replayer handle isShadowHost and isShadow options i came across a next comment in the code:
Since node is newly rebuilt, it should be a normal element without shadowRoot. But if there are some weird situations that has defined custom element in the scope before we rebuild node, it may register the shadowRoot earlier. The logic in the ‘else’ block is just a try-my-best solution for the corner case, please let we know if it is wrong and we can remove it.
if (n.isShadowHost) { if (!node.shadowRoot) { node.attachShadow({ mode: 'open' }); } else { while (node.shadowRoot.firstChild) { node.shadowRoot.removeChild(node.shadowRoot.firstChild); } } }
Testcase Gist URL
No response
Additional Information
Replay where custom elements have isShadowHost and isShadow options:
Replay without those options:
Issue Analytics
- State:
- Created a year ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
Is this page using ShadyDOM polyfill?
Check on page:
window.ShadyDOM
. If object exists, check ifsettings.force
is set to true. If so, even if browser supports Shadow DOM, ShadyDOM is polyfilling it. I have noticed Google web properties like to polyfill Shadow DOMs regardless of native support.If this is the case, because of the accuracy of the polyfill,
rrweb
thinks it is a real shadow DOM (even though it is not). Hence, it is being created incorrectly on the viewer as a shadow DOM but in reality there are no shadow doms.In addition, the polyfill patches
Node.childNodes
getter and a series of DOM getters that will mess with rrweb’s ability to snapshot and record mutations correctly unless you get original functions from Node’s prototype (luckily it does not patch prototype)@lele0108 I followed your suggestion on this webpage https://www.partneradvantage.goog/GCPPRM/s/partnerselfregistration?language=en_US. Unfortunately, shadow dom on this site is poly filled but not by shadyDOM. I tracked the source code and found the implementation of shadow dom to be lwc’s synthetic-shadow. https://github.com/salesforce/lwc/blob/master/packages/%40lwc/synthetic-shadow/src/faux-shadow/element.ts#L81-L87 But thanks for your great suggestion! It really helps a lot.