1
1
import { stringifyElement } from "../utils.js" ;
2
2
import { get as getMessage , isLocalizeEnabled } from "../localize.js" ;
3
+ import { shadowOptions } from "../render.js" ;
3
4
4
5
import * as layout from "./layout.js" ;
5
6
import {
@@ -17,7 +18,7 @@ const PLACEHOLDER_REGEXP_EQUAL = new RegExp(`^${PLACEHOLDER_REGEXP_TEXT}$`);
17
18
const PLACEHOLDER_REGEXP_ALL = new RegExp ( PLACEHOLDER_REGEXP_TEXT , "g" ) ;
18
19
const PLACEHOLDER_REGEXP_ONLY = / ^ [ ^ A - Z a - z ] + $ / ;
19
20
20
- function createContent ( parts ) {
21
+ function createContents ( parts ) {
21
22
let signature = parts [ 0 ] ;
22
23
let tableMode = false ;
23
24
for ( let index = 1 ; index < parts . length ; index += 1 ) {
@@ -190,17 +191,18 @@ function updateStyleElement(target, styles) {
190
191
}
191
192
192
193
export function compileTemplate ( rawParts , isSVG , isMsg , useLayout ) {
193
- const content = isMsg ? rawParts : createContent ( rawParts ) ;
194
-
194
+ const contents = isMsg ? rawParts : createContents ( rawParts ) ;
195
195
let template = globalThis . document . createElement ( "template" ) ;
196
- template . innerHTML = isSVG ? `<svg>${ content } </svg>` : content ;
197
196
198
197
if ( isSVG ) {
198
+ template . innerHTML = `<svg>${ contents } </svg>` ;
199
199
const svgRoot = template . content . firstChild ;
200
200
template . content . removeChild ( svgRoot ) ;
201
201
for ( const node of Array . from ( svgRoot . childNodes ) ) {
202
202
template . content . appendChild ( node ) ;
203
203
}
204
+ } else {
205
+ template . innerHTML = contents ;
204
206
}
205
207
206
208
let hostLayout ;
@@ -445,108 +447,124 @@ export function compileTemplate(rawParts, isSVG, isMsg, useLayout) {
445
447
. map ( ( e ) => `<${ e } >` )
446
448
. join ( ", " ) } element${
447
449
notDefinedElements . length > 1 ? "s" : ""
448
- } found in the template:\n${ beautifyTemplateLog ( content , - 1 ) } `,
450
+ } found in the template:\n${ beautifyTemplateLog ( contents , - 1 ) } `,
449
451
) ;
450
452
}
451
453
452
454
const partsKeys = Object . keys ( parts ) ;
453
- return Object . assign (
454
- function updateTemplateInstance ( host , target , args , styleSheets , shadow ) {
455
- let meta = getMeta ( target ) ;
456
-
457
- if ( template !== meta . template ) {
458
- const fragment = globalThis . document . importNode ( template . content , true ) ;
459
- const renderWalker = createWalker ( fragment ) ;
460
- const markers = [ ] ;
461
-
462
- let renderIndex = 0 ;
463
- let keyIndex = 0 ;
464
- let currentPart = parts [ partsKeys [ keyIndex ] ] ;
465
-
466
- while ( renderWalker . nextNode ( ) ) {
467
- const node = renderWalker . currentNode ;
468
-
469
- while ( currentPart && currentPart [ 0 ] === renderIndex ) {
470
- markers . push ( {
471
- index : partsKeys [ keyIndex ] ,
472
- node,
473
- fn : currentPart [ 1 ] ,
474
- } ) ;
475
- keyIndex += 1 ;
476
- currentPart = parts [ partsKeys [ keyIndex ] ] ;
477
- }
455
+ return function updateTemplateInstance ( host , target , args , styleSheets ) {
456
+ let shadow = shadowOptions . get ( host ) ;
457
+ if ( target ) {
458
+ if (
459
+ target !== host &&
460
+ ! host . shadowRoot &&
461
+ shadow !== false &&
462
+ ( useShadow || styleSheets )
463
+ ) {
464
+ throw TypeError (
465
+ `Nested template with styles or <slot> element found - use 'shadow' options to explicitly define mode` ,
466
+ ) ;
467
+ }
468
+ } else {
469
+ shadow = shadow ?? ( ( useShadow || styleSheets ) && { mode : "open" } ) ;
470
+ target = host . shadowRoot || ( shadow && host . attachShadow ( shadow ) ) || host ;
471
+ }
478
472
479
- renderIndex += 1 ;
480
- }
473
+ let meta = getMeta ( target ) ;
481
474
482
- if ( meta . hostLayout ) {
483
- host . classList . remove ( meta . hostLayout ) ;
475
+ if ( template !== meta . template ) {
476
+ const fragment = globalThis . document . importNode ( template . content , true ) ;
477
+ const renderWalker = createWalker ( fragment ) ;
478
+ const markers = [ ] ;
479
+
480
+ let renderIndex = 0 ;
481
+ let keyIndex = 0 ;
482
+ let currentPart = parts [ partsKeys [ keyIndex ] ] ;
483
+
484
+ while ( renderWalker . nextNode ( ) ) {
485
+ const node = renderWalker . currentNode ;
486
+
487
+ while ( currentPart && currentPart [ 0 ] === renderIndex ) {
488
+ markers . push ( {
489
+ index : partsKeys [ keyIndex ] ,
490
+ node,
491
+ fn : currentPart [ 1 ] ,
492
+ } ) ;
493
+ keyIndex += 1 ;
494
+ currentPart = parts [ partsKeys [ keyIndex ] ] ;
484
495
}
485
496
486
- removeTemplate ( target ) ;
497
+ renderIndex += 1 ;
498
+ }
487
499
488
- meta = getMeta ( target ) ;
500
+ if ( meta . hostLayout ) {
501
+ host . classList . remove ( meta . hostLayout ) ;
502
+ }
489
503
490
- meta . template = template ;
491
- meta . markers = markers ;
504
+ removeTemplate ( target ) ;
492
505
493
- if ( target . nodeType === globalThis . Node . TEXT_NODE ) {
494
- updateStyleElement ( target ) ;
506
+ meta = getMeta ( target ) ;
495
507
496
- meta . startNode = fragment . childNodes [ 0 ] ;
497
- meta . endNode = fragment . childNodes [ fragment . childNodes . length - 1 ] ;
508
+ meta . template = template ;
509
+ meta . markers = markers ;
498
510
499
- let previousChild = target ;
511
+ if ( target . nodeType === globalThis . Node . TEXT_NODE ) {
512
+ updateStyleElement ( target ) ;
500
513
501
- let child = fragment . childNodes [ 0 ] ;
502
- while ( child ) {
503
- target . parentNode . insertBefore ( child , previousChild . nextSibling ) ;
504
- previousChild = child ;
505
- child = fragment . childNodes [ 0 ] ;
506
- }
507
- } else {
508
- if ( useLayout ) {
509
- const className = `${ hostLayout } -${ host === target ? "c" : "s" } ` ;
510
- host . classList . add ( className ) ;
511
- meta . hostLayout = className ;
512
- }
514
+ meta . startNode = fragment . childNodes [ 0 ] ;
515
+ meta . endNode = fragment . childNodes [ fragment . childNodes . length - 1 ] ;
513
516
514
- target . appendChild ( fragment ) ;
517
+ let previousChild = target ;
518
+
519
+ let child = fragment . childNodes [ 0 ] ;
520
+ while ( child ) {
521
+ target . parentNode . insertBefore ( child , previousChild . nextSibling ) ;
522
+ previousChild = child ;
523
+ child = fragment . childNodes [ 0 ] ;
524
+ }
525
+ } else {
526
+ if ( useLayout ) {
527
+ const className = `${ hostLayout } -${ host === target ? "c" : "s" } ` ;
528
+ host . classList . add ( className ) ;
529
+ meta . hostLayout = className ;
515
530
}
516
531
517
- if ( useLayout ) layout . inject ( target ) ;
532
+ target . appendChild ( fragment ) ;
518
533
}
519
534
520
- if ( target . adoptedStyleSheets ) {
521
- updateAdoptedStylesheets ( target , styleSheets ) ;
522
- } else {
523
- updateStyleElement ( target , styleSheets ) ;
524
- }
535
+ if ( useLayout ) layout . inject ( target ) ;
536
+ }
537
+
538
+ if ( target . adoptedStyleSheets ) {
539
+ updateAdoptedStylesheets ( target , styleSheets ) ;
540
+ } else {
541
+ updateStyleElement ( target , styleSheets ) ;
542
+ }
525
543
526
- for ( const marker of meta . markers ) {
527
- const value = args [ marker . index ] ;
528
- let prevValue = undefined ;
544
+ for ( const marker of meta . markers ) {
545
+ const value = args [ marker . index ] ;
546
+ let prevValue = undefined ;
529
547
530
- if ( meta . prevArgs ) {
531
- prevValue = meta . prevArgs [ marker . index ] ;
532
- if ( prevValue === value ) continue ;
533
- }
548
+ if ( meta . prevArgs ) {
549
+ prevValue = meta . prevArgs [ marker . index ] ;
550
+ if ( prevValue === value ) continue ;
551
+ }
534
552
535
- try {
536
- marker . fn ( host , marker . node , value , prevValue , useLayout , shadow ) ;
537
- } catch ( error ) {
538
- console . error (
539
- `Error while updating template expression in ${ stringifyElement (
540
- host ,
541
- ) } :\n${ beautifyTemplateLog ( content , marker . index ) } `,
542
- ) ;
553
+ try {
554
+ marker . fn ( host , marker . node , value , prevValue , useLayout ) ;
555
+ } catch ( error ) {
556
+ console . error (
557
+ `Error while updating template expression in ${ stringifyElement (
558
+ host ,
559
+ ) } :\n${ beautifyTemplateLog ( contents , marker . index ) } `,
560
+ ) ;
543
561
544
- throw error ;
545
- }
562
+ throw error ;
546
563
}
564
+ }
547
565
548
- meta . prevArgs = args ;
549
- } ,
550
- { useShadow } ,
551
- ) ;
566
+ meta . prevArgs = args ;
567
+
568
+ return target ;
569
+ } ;
552
570
}
0 commit comments