Skip to content

Commit 217ccae

Browse files
committed
Fix tests
1 parent e936aa7 commit 217ccae

File tree

12 files changed

+165
-186
lines changed

12 files changed

+165
-186
lines changed

src/localize.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ export function msg(parts, ...args) {
165165
return getString(parts, args).replace(EXP_REGEX, (_, index) => args[index]);
166166
}
167167

168-
const PLACEHOLDER_SVG = getPlaceholder("svg");
169168
const PLACEHOLDER_MSG = getPlaceholder("msg");
169+
const PLACEHOLDER_SVG = getPlaceholder("svg");
170170

171171
msg.html = function html(parts, ...args) {
172172
const input = getString(parts, args);
@@ -186,7 +186,7 @@ msg.svg = function svg(parts, ...args) {
186186
return compile(
187187
input.replace(EXP_REGEX, (_, index) => getPlaceholder(index)),
188188
args,
189-
input + PLACEHOLDER_SVG + PLACEHOLDER_MSG,
189+
input + PLACEHOLDER_MSG + PLACEHOLDER_SVG,
190190
true,
191191
true,
192192
);

src/render.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export const shadowOptions = new WeakMap();
2+
13
export default function render(desc) {
24
if (desc.reflect) {
35
throw TypeError(`'reflect' option is not supported for 'render' property`);
@@ -22,7 +24,7 @@ export default function render(desc) {
2224
},
2325
};
2426

25-
const shadowOptions = desc.shadow
27+
const shadow = desc.shadow
2628
? {
2729
mode: desc.shadow.mode || "open",
2830
delegatesFocus: desc.shadow.delegatesFocus || false,
@@ -32,7 +34,9 @@ export default function render(desc) {
3234
return {
3335
value: (host) => {
3436
const updateDOM = fn(host);
35-
return () => updateDOM(host, shadowOptions);
37+
shadowOptions.set(host, shadow);
38+
39+
return () => updateDOM(host);
3640
},
3741
...rest,
3842
};

src/template/core.js

+101-83
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { stringifyElement } from "../utils.js";
22
import { get as getMessage, isLocalizeEnabled } from "../localize.js";
3+
import { shadowOptions } from "../render.js";
34

45
import * as layout from "./layout.js";
56
import {
@@ -17,7 +18,7 @@ const PLACEHOLDER_REGEXP_EQUAL = new RegExp(`^${PLACEHOLDER_REGEXP_TEXT}$`);
1718
const PLACEHOLDER_REGEXP_ALL = new RegExp(PLACEHOLDER_REGEXP_TEXT, "g");
1819
const PLACEHOLDER_REGEXP_ONLY = /^[^A-Za-z]+$/;
1920

20-
function createContent(parts) {
21+
function createContents(parts) {
2122
let signature = parts[0];
2223
let tableMode = false;
2324
for (let index = 1; index < parts.length; index += 1) {
@@ -190,17 +191,18 @@ function updateStyleElement(target, styles) {
190191
}
191192

192193
export function compileTemplate(rawParts, isSVG, isMsg, useLayout) {
193-
const content = isMsg ? rawParts : createContent(rawParts);
194-
194+
const contents = isMsg ? rawParts : createContents(rawParts);
195195
let template = globalThis.document.createElement("template");
196-
template.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
197196

198197
if (isSVG) {
198+
template.innerHTML = `<svg>${contents}</svg>`;
199199
const svgRoot = template.content.firstChild;
200200
template.content.removeChild(svgRoot);
201201
for (const node of Array.from(svgRoot.childNodes)) {
202202
template.content.appendChild(node);
203203
}
204+
} else {
205+
template.innerHTML = contents;
204206
}
205207

206208
let hostLayout;
@@ -445,108 +447,124 @@ export function compileTemplate(rawParts, isSVG, isMsg, useLayout) {
445447
.map((e) => `<${e}>`)
446448
.join(", ")} element${
447449
notDefinedElements.length > 1 ? "s" : ""
448-
} found in the template:\n${beautifyTemplateLog(content, -1)}`,
450+
} found in the template:\n${beautifyTemplateLog(contents, -1)}`,
449451
);
450452
}
451453

452454
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+
}
478472

479-
renderIndex += 1;
480-
}
473+
let meta = getMeta(target);
481474

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]];
484495
}
485496

486-
removeTemplate(target);
497+
renderIndex += 1;
498+
}
487499

488-
meta = getMeta(target);
500+
if (meta.hostLayout) {
501+
host.classList.remove(meta.hostLayout);
502+
}
489503

490-
meta.template = template;
491-
meta.markers = markers;
504+
removeTemplate(target);
492505

493-
if (target.nodeType === globalThis.Node.TEXT_NODE) {
494-
updateStyleElement(target);
506+
meta = getMeta(target);
495507

496-
meta.startNode = fragment.childNodes[0];
497-
meta.endNode = fragment.childNodes[fragment.childNodes.length - 1];
508+
meta.template = template;
509+
meta.markers = markers;
498510

499-
let previousChild = target;
511+
if (target.nodeType === globalThis.Node.TEXT_NODE) {
512+
updateStyleElement(target);
500513

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];
513516

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;
515530
}
516531

517-
if (useLayout) layout.inject(target);
532+
target.appendChild(fragment);
518533
}
519534

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+
}
525543

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;
529547

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+
}
534552

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+
);
543561

544-
throw error;
545-
}
562+
throw error;
546563
}
564+
}
547565

548-
meta.prevArgs = args;
549-
},
550-
{ useShadow },
551-
);
566+
meta.prevArgs = args;
567+
568+
return target;
569+
};
552570
}

src/template/helpers/resolve.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,14 @@ import resolveValue from "../resolvers/value.js";
22

33
const promiseMap = new WeakMap();
44
export default function resolve(promise, placeholder, delay = 200) {
5-
return function fn(host, shadowOptions, target) {
5+
return function fn(host, target) {
66
const useLayout = fn.useLayout;
77
let timeout;
88

99
if (placeholder) {
1010
timeout = setTimeout(() => {
1111
timeout = undefined;
12-
resolveValue(
13-
host,
14-
target,
15-
placeholder,
16-
undefined,
17-
useLayout,
18-
shadowOptions,
19-
);
12+
resolveValue(host, target, placeholder, undefined, useLayout);
2013
}, delay);
2114
}
2215

@@ -32,7 +25,6 @@ export default function resolve(promise, placeholder, delay = 200) {
3225
value,
3326
placeholder && !timeout ? placeholder : undefined,
3427
useLayout,
35-
shadowOptions,
3628
);
3729
promiseMap.set(target, null);
3830
}

src/template/index.js

+6-24
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,27 @@ import * as methods from "./methods.js";
66

77
const PLACEHOLDER = getPlaceholder();
88
const PLACEHOLDER_SVG = getPlaceholder("svg");
9+
const PLACEHOLDER_LAYOUT = getPlaceholder("layout");
910

1011
const templates = new Map();
1112
export function compile(parts, args, id, isSVG, isMsg) {
12-
function fn(host, shadow, target) {
13-
id = id + fn.useLayout;
13+
function fn(host, target) {
14+
if (fn.useLayout) id += id + PLACEHOLDER_LAYOUT;
1415

1516
let render = templates.get(id);
1617
if (!render) {
1718
render = compileTemplate(parts, isSVG, isMsg, fn.useLayout);
1819
templates.set(id, render);
1920
}
2021

21-
if (target) {
22-
if (
23-
(render.useShadow || fn.styleSheets) &&
24-
shadow !== false &&
25-
!host.shadowRoot
26-
) {
27-
throw TypeError(
28-
`Nested template with styles or <slot> element found - use options to explicitly define shadow DOM mode`,
29-
);
30-
}
31-
} else {
32-
if (shadow === undefined && (render.useShadow || fn.styleSheets)) {
33-
shadow = { mode: "open" };
34-
}
35-
target = host.shadowRoot || (shadow && host.attachShadow(shadow)) || host;
36-
}
37-
3822
if (fn.plugins) {
39-
fn.plugins.reduce(
23+
return fn.plugins.reduce(
4024
(acc, plugin) => plugin(acc),
41-
() => render(host, target, args, fn.styleSheets, shadow),
25+
() => render(host, target, args, fn.styleSheets),
4226
)(host, target);
4327
} else {
44-
render(host, target, args, fn.styleSheets, shadow);
28+
return render(host, target, args, fn.styleSheets);
4529
}
46-
47-
return target;
4830
}
4931

5032
return Object.assign(fn, methods);

0 commit comments

Comments
 (0)