File tree Expand file tree Collapse file tree 8 files changed +717
-16
lines changed Expand file tree Collapse file tree 8 files changed +717
-16
lines changed Original file line number Diff line number Diff line change 55dist
66es
77lib
8+ temp
Original file line number Diff line number Diff line change 77 idNodeMap ,
88 INode ,
99} from './types' ;
10+ import { isElement } from './utils' ;
1011
1112const tagMap : tagMap = {
1213 script : 'noscript' ,
@@ -177,6 +178,25 @@ function buildNode(
177178 }
178179 }
179180 }
181+ if ( n . isShadowHost ) {
182+ /**
183+ * Since node is newly rebuilt, it should be a normal element
184+ * without shadowRoot.
185+ * But if there are some weird situations that has defined
186+ * custom element in the scope before we rebuild node, it may
187+ * register the shadowRoot earlier.
188+ * The logic in the 'else' block is just a try-my-best solution
189+ * for the corner case, please let we know if it is wrong and
190+ * we can remove it.
191+ */
192+ if ( ! node . shadowRoot ) {
193+ node . attachShadow ( { mode : 'open' } ) ;
194+ } else {
195+ while ( node . shadowRoot . firstChild ) {
196+ node . shadowRoot . removeChild ( node . shadowRoot . firstChild ) ;
197+ }
198+ }
199+ }
180200 return node ;
181201 case NodeType . Text :
182202 return doc . createTextNode (
@@ -240,7 +260,11 @@ export function buildNodeWithSN(
240260 continue ;
241261 }
242262
243- node . appendChild ( childNode ) ;
263+ if ( childN . isShadow && isElement ( node ) && node . shadowRoot ) {
264+ node . shadowRoot . appendChild ( childNode ) ;
265+ } else {
266+ node . appendChild ( childNode ) ;
267+ }
244268 if ( afterAppend ) {
245269 afterAppend ( childNode ) ;
246270 }
Original file line number Diff line number Diff line change 88 MaskInputOptions ,
99 SlimDOMOptions ,
1010} from './types' ;
11+ import { isElement } from './utils' ;
1112
1213let _id = 1 ;
1314const tagNameRegex = RegExp ( '[^a-z0-9-_]' ) ;
@@ -622,26 +623,38 @@ export function serializeNodeWithId(
622623 ) {
623624 preserveWhiteSpace = false ;
624625 }
626+ const bypassOptions = {
627+ doc,
628+ map,
629+ blockClass,
630+ blockSelector,
631+ skipChild,
632+ inlineStylesheet,
633+ maskInputOptions,
634+ slimDOMOptions,
635+ recordCanvas,
636+ preserveWhiteSpace,
637+ onSerialize,
638+ onIframeLoad,
639+ iframeLoadTimeout,
640+ } ;
625641 for ( const childN of Array . from ( n . childNodes ) ) {
626- const serializedChildNode = serializeNodeWithId ( childN , {
627- doc,
628- map,
629- blockClass,
630- blockSelector,
631- skipChild,
632- inlineStylesheet,
633- maskInputOptions,
634- slimDOMOptions,
635- recordCanvas,
636- preserveWhiteSpace,
637- onSerialize,
638- onIframeLoad,
639- iframeLoadTimeout,
640- } ) ;
642+ const serializedChildNode = serializeNodeWithId ( childN , bypassOptions ) ;
641643 if ( serializedChildNode ) {
642644 serializedNode . childNodes . push ( serializedChildNode ) ;
643645 }
644646 }
647+
648+ if ( isElement ( n ) && n . shadowRoot ) {
649+ serializedNode . isShadowHost = true ;
650+ for ( const childN of Array . from ( n . shadowRoot . childNodes ) ) {
651+ const serializedChildNode = serializeNodeWithId ( childN , bypassOptions ) ;
652+ if ( serializedChildNode ) {
653+ serializedChildNode . isShadow = true ;
654+ serializedNode . childNodes . push ( serializedChildNode ) ;
655+ }
656+ }
657+ }
645658 }
646659
647660 if (
Original file line number Diff line number Diff line change @@ -56,6 +56,8 @@ export type serializedNode = (
5656 | commentNode
5757) & {
5858 rootId ?: number ;
59+ isShadowHost ?: boolean ;
60+ isShadow ?: boolean ;
5961} ;
6062
6163export type serializedNodeWithId = serializedNode & { id : number } ;
Original file line number Diff line number Diff line change 1+ import { INode } from './types' ;
2+
3+ export function isElement ( n : Node | INode ) : n is Element {
4+ return n . nodeType === n . ELEMENT_NODE ;
5+ }
You can’t perform that action at this time.
0 commit comments