|
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 {
|
@@ -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 : createContent(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