@rxdi/lit-html 0.7.157 → 0.7.158

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/async.d.ts +3 -3
  2. package/dist/async.js +4 -4
  3. package/dist/decorators/component.decorator.d.ts +1 -2
  4. package/dist/decorators/component.decorator.js +3 -3
  5. package/dist/index.d.ts +28 -17
  6. package/dist/index.js +28 -17
  7. package/package.json +4 -2
  8. package/dist/lit-element/decorators.d.ts +0 -14
  9. package/dist/lit-element/decorators.js +0 -32
  10. package/dist/lit-element/experimental-hydrate-support.d.ts +0 -6
  11. package/dist/lit-element/experimental-hydrate-support.js +0 -65
  12. package/dist/lit-element/index.d.ts +0 -7
  13. package/dist/lit-element/index.js +0 -25
  14. package/dist/lit-element/lit-element.d.ts +0 -157
  15. package/dist/lit-element/lit-element.js +0 -258
  16. package/dist/lit-element/polyfill-support.d.ts +0 -24
  17. package/dist/lit-element/polyfill-support.js +0 -58
  18. package/dist/lit-element/private-ssr-support.d.ts +0 -21
  19. package/dist/lit-element/private-ssr-support.js +0 -25
  20. package/dist/lit-html/async-directive.d.ts +0 -170
  21. package/dist/lit-html/async-directive.js +0 -250
  22. package/dist/lit-html/directive-helpers.d.ts +0 -105
  23. package/dist/lit-html/directive-helpers.js +0 -192
  24. package/dist/lit-html/directive.d.ts +0 -65
  25. package/dist/lit-html/directive.js +0 -52
  26. package/dist/lit-html/directives/async-append.d.ts +0 -38
  27. package/dist/lit-html/directives/async-append.js +0 -55
  28. package/dist/lit-html/directives/async-replace.d.ts +0 -39
  29. package/dist/lit-html/directives/async-replace.js +0 -112
  30. package/dist/lit-html/directives/cache.d.ts +0 -34
  31. package/dist/lit-html/directives/cache.js +0 -80
  32. package/dist/lit-html/directives/class-map.d.ts +0 -44
  33. package/dist/lit-html/directives/class-map.js +0 -92
  34. package/dist/lit-html/directives/guard.d.ts +0 -59
  35. package/dist/lit-html/directives/guard.js +0 -82
  36. package/dist/lit-html/directives/if-defined.d.ts +0 -13
  37. package/dist/lit-html/directives/if-defined.js +0 -17
  38. package/dist/lit-html/directives/live.d.ts +0 -42
  39. package/dist/lit-html/directives/live.js +0 -79
  40. package/dist/lit-html/directives/private-async-helpers.d.ts +0 -57
  41. package/dist/lit-html/directives/private-async-helpers.js +0 -117
  42. package/dist/lit-html/directives/ref.d.ts +0 -65
  43. package/dist/lit-html/directives/ref.js +0 -113
  44. package/dist/lit-html/directives/repeat.d.ts +0 -63
  45. package/dist/lit-html/directives/repeat.js +0 -416
  46. package/dist/lit-html/directives/style-map.d.ts +0 -46
  47. package/dist/lit-html/directives/style-map.js +0 -102
  48. package/dist/lit-html/directives/template-content.d.ts +0 -25
  49. package/dist/lit-html/directives/template-content.js +0 -33
  50. package/dist/lit-html/directives/unsafe-html.d.ts +0 -26
  51. package/dist/lit-html/directives/unsafe-html.js +0 -64
  52. package/dist/lit-html/directives/unsafe-svg.d.ts +0 -26
  53. package/dist/lit-html/directives/unsafe-svg.js +0 -26
  54. package/dist/lit-html/directives/until.d.ts +0 -43
  55. package/dist/lit-html/directives/until.js +0 -137
  56. package/dist/lit-html/experimental-hydrate.d.ts +0 -50
  57. package/dist/lit-html/experimental-hydrate.js +0 -322
  58. package/dist/lit-html/lit-html.d.ts +0 -335
  59. package/dist/lit-html/lit-html.js +0 -1259
  60. package/dist/lit-html/polyfill-support.d.ts +0 -67
  61. package/dist/lit-html/polyfill-support.js +0 -185
  62. package/dist/lit-html/private-ssr-support.d.ts +0 -52
  63. package/dist/lit-html/private-ssr-support.js +0 -54
  64. package/dist/lit-html/static.d.ts +0 -58
  65. package/dist/lit-html/static.js +0 -114
  66. package/dist/reactive-element/css-tag.d.ts +0 -64
  67. package/dist/reactive-element/css-tag.js +0 -125
  68. package/dist/reactive-element/decorators/base.d.ts +0 -47
  69. package/dist/reactive-element/decorators/base.js +0 -70
  70. package/dist/reactive-element/decorators/custom-element.d.ts +0 -26
  71. package/dist/reactive-element/decorators/custom-element.js +0 -47
  72. package/dist/reactive-element/decorators/event-options.d.ts +0 -37
  73. package/dist/reactive-element/decorators/event-options.js +0 -47
  74. package/dist/reactive-element/decorators/index.d.ts +0 -14
  75. package/dist/reactive-element/decorators/index.js +0 -32
  76. package/dist/reactive-element/decorators/property.d.ts +0 -40
  77. package/dist/reactive-element/decorators/property.js +0 -92
  78. package/dist/reactive-element/decorators/query-all.d.ts +0 -31
  79. package/dist/reactive-element/decorators/query-all.js +0 -46
  80. package/dist/reactive-element/decorators/query-assigned-nodes.d.ts +0 -33
  81. package/dist/reactive-element/decorators/query-assigned-nodes.js +0 -55
  82. package/dist/reactive-element/decorators/query-async.d.ts +0 -39
  83. package/dist/reactive-element/decorators/query-async.js +0 -71
  84. package/dist/reactive-element/decorators/query.d.ts +0 -32
  85. package/dist/reactive-element/decorators/query.js +0 -60
  86. package/dist/reactive-element/decorators/state.d.ts +0 -24
  87. package/dist/reactive-element/decorators/state.js +0 -29
  88. package/dist/reactive-element/index.d.ts +0 -5
  89. package/dist/reactive-element/index.js +0 -17
  90. package/dist/reactive-element/polyfill-support.d.ts +0 -40
  91. package/dist/reactive-element/polyfill-support.js +0 -89
  92. package/dist/reactive-element/reactive-controller.d.ts +0 -76
  93. package/dist/reactive-element/reactive-controller.js +0 -7
  94. package/dist/reactive-element/reactive-element.d.ts +0 -653
  95. package/dist/reactive-element/reactive-element.js +0 -979
@@ -1,1259 +0,0 @@
1
- "use strict";
2
- /**
3
- * @license
4
- * Copyright 2017 Google LLC
5
- * SPDX-License-Identifier: BSD-3-Clause
6
- */
7
- var _a, _b, _c, _d, _e;
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports._$LH = exports.render = exports.nothing = exports.noChange = exports.svg = exports.html = exports.INTERNAL = void 0;
10
- const DEV_MODE = true;
11
- const ENABLE_EXTRA_SECURITY_HOOKS = true;
12
- const ENABLE_SHADYDOM_NOPATCH = true;
13
- /**
14
- * `true` if we're building for google3 with temporary back-compat helpers.
15
- * This export is not present in prod builds.
16
- * @internal
17
- */
18
- exports.INTERNAL = true;
19
- let issueWarning;
20
- if (DEV_MODE) {
21
- (_a = globalThis.litIssuedWarnings) !== null && _a !== void 0 ? _a : (globalThis.litIssuedWarnings = new Set());
22
- // Issue a warning, if we haven't already.
23
- issueWarning = (code, warning) => {
24
- warning += code
25
- ? ` See https://lit.dev/msg/${code} for more information.`
26
- : '';
27
- if (!globalThis.litIssuedWarnings.has(warning)) {
28
- console.warn(warning);
29
- globalThis.litIssuedWarnings.add(warning);
30
- }
31
- };
32
- issueWarning('dev-mode', `Lit is in dev mode. Not recommended for production!`);
33
- }
34
- const wrap = ENABLE_SHADYDOM_NOPATCH &&
35
- ((_b = window.ShadyDOM) === null || _b === void 0 ? void 0 : _b.inUse) &&
36
- ((_c = window.ShadyDOM) === null || _c === void 0 ? void 0 : _c.noPatch) === true
37
- ? window.ShadyDOM.wrap
38
- : (node) => node;
39
- const trustedTypes = globalThis['trustedTypes'];
40
- /**
41
- * Our TrustedTypePolicy for HTML which is declared using the html template
42
- * tag function.
43
- *
44
- * That HTML is a developer-authored constant, and is parsed with innerHTML
45
- * before any untrusted expressions have been mixed in. Therefor it is
46
- * considered safe by construction.
47
- */
48
- const policy = trustedTypes
49
- ? trustedTypes.createPolicy('lit-html', {
50
- createHTML: (s) => s,
51
- })
52
- : undefined;
53
- const identityFunction = (value) => value;
54
- const noopSanitizer = (_node, _name, _type) => identityFunction;
55
- /** Sets the global sanitizer factory. */
56
- const setSanitizer = (newSanitizer) => {
57
- if (!ENABLE_EXTRA_SECURITY_HOOKS) {
58
- return;
59
- }
60
- if (sanitizerFactoryInternal !== noopSanitizer) {
61
- throw new Error(`Attempted to overwrite existing lit-html security policy.` +
62
- ` setSanitizeDOMValueFactory should be called at most once.`);
63
- }
64
- sanitizerFactoryInternal = newSanitizer;
65
- };
66
- /**
67
- * Only used in internal tests, not a part of the public API.
68
- */
69
- const _testOnlyClearSanitizerFactoryDoNotCallOrElse = () => {
70
- sanitizerFactoryInternal = noopSanitizer;
71
- };
72
- const createSanitizer = (node, name, type) => {
73
- return sanitizerFactoryInternal(node, name, type);
74
- };
75
- // Added to an attribute name to mark the attribute as bound so we can find
76
- // it easily.
77
- const boundAttributeSuffix = '$lit$';
78
- // This marker is used in many syntactic positions in HTML, so it must be
79
- // a valid element name and attribute name. We don't support dynamic names (yet)
80
- // but this at least ensures that the parse tree is closer to the template
81
- // intention.
82
- const marker = `lit$${String(Math.random()).slice(9)}$`;
83
- // String used to tell if a comment is a marker comment
84
- const markerMatch = '?' + marker;
85
- // Text used to insert a comment marker node. We use processing instruction
86
- // syntax because it's slightly smaller, but parses as a comment node.
87
- const nodeMarker = `<${markerMatch}>`;
88
- const d = document;
89
- // Creates a dynamic marker. We never have to search for these in the DOM.
90
- const createMarker = (v = '') => d.createComment(v);
91
- const isPrimitive = (value) => value === null || (typeof value != 'object' && typeof value != 'function');
92
- const isArray = Array.isArray;
93
- const isIterable = (value) => {
94
- var _a;
95
- return isArray(value) ||
96
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
- typeof ((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.iterator]) === 'function';
98
- };
99
- const SPACE_CHAR = `[ \t\n\f\r]`;
100
- const ATTR_VALUE_CHAR = `[^ \t\n\f\r"'\`<>=]`;
101
- const NAME_CHAR = `[^\\s"'>=/]`;
102
- // These regexes represent the five parsing states that we care about in the
103
- // Template's HTML scanner. They match the *end* of the state they're named
104
- // after.
105
- // Depending on the match, we transition to a new state. If there's no match,
106
- // we stay in the same state.
107
- // Note that the regexes are stateful. We utilize lastIndex and sync it
108
- // across the multiple regexes used. In addition to the five regexes below
109
- // we also dynamically create a regex to find the matching end tags for raw
110
- // text elements.
111
- /**
112
- * End of text is: `<` followed by:
113
- * (comment start) or (tag) or (dynamic tag binding)
114
- */
115
- const textEndRegex = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g;
116
- const COMMENT_START = 1;
117
- const TAG_NAME = 2;
118
- const DYNAMIC_TAG_NAME = 3;
119
- const commentEndRegex = /-->/g;
120
- /**
121
- * Comments not started with <!--, like </{, can be ended by a single `>`
122
- */
123
- const comment2EndRegex = />/g;
124
- /**
125
- * The tagEnd regex matches the end of the "inside an opening" tag syntax
126
- * position. It either matches a `>`, an attribute-like sequence, or the end
127
- * of the string after a space (attribute-name position ending).
128
- *
129
- * See attributes in the HTML spec:
130
- * https://www.w3.org/TR/html5/syntax.html#elements-attributes
131
- *
132
- * " \t\n\f\r" are HTML space characters:
133
- * https://infra.spec.whatwg.org/#ascii-whitespace
134
- *
135
- * So an attribute is:
136
- * * The name: any character except a whitespace character, ("), ('), ">",
137
- * "=", or "/". Note: this is different from the HTML spec which also excludes control characters.
138
- * * Followed by zero or more space characters
139
- * * Followed by "="
140
- * * Followed by zero or more space characters
141
- * * Followed by:
142
- * * Any character except space, ('), ("), "<", ">", "=", (`), or
143
- * * (") then any non-("), or
144
- * * (') then any non-(')
145
- */
146
- const tagEndRegex = new RegExp(`>|${SPACE_CHAR}(?:(${NAME_CHAR}+)(${SPACE_CHAR}*=${SPACE_CHAR}*(?:${ATTR_VALUE_CHAR}|("|')|))|$)`, 'g');
147
- const ENTIRE_MATCH = 0;
148
- const ATTRIBUTE_NAME = 1;
149
- const SPACES_AND_EQUALS = 2;
150
- const QUOTE_CHAR = 3;
151
- const singleQuoteAttrEndRegex = /'/g;
152
- const doubleQuoteAttrEndRegex = /"/g;
153
- /**
154
- * Matches the raw text elements.
155
- *
156
- * Comments are not parsed within raw text elements, so we need to search their
157
- * text content for marker strings.
158
- */
159
- const rawTextElement = /^(?:script|style|textarea)$/i;
160
- /** TemplateResult types */
161
- const HTML_RESULT = 1;
162
- const SVG_RESULT = 2;
163
- // TemplatePart types
164
- // IMPORTANT: these must match the values in PartType
165
- const ATTRIBUTE_PART = 1;
166
- const CHILD_PART = 2;
167
- const PROPERTY_PART = 3;
168
- const BOOLEAN_ATTRIBUTE_PART = 4;
169
- const EVENT_PART = 5;
170
- const ELEMENT_PART = 6;
171
- const COMMENT_PART = 7;
172
- /**
173
- * Generates a template literal tag function that returns a TemplateResult with
174
- * the given result type.
175
- */
176
- const tag = (type) => (strings, ...values) => {
177
- // Warn against templates octal escape sequences
178
- // We do this here rather than in render so that the warning is closer to the
179
- // template definition.
180
- if (DEV_MODE && strings.some((s) => s === undefined)) {
181
- console.warn('Some template strings are undefined.\n' +
182
- 'This is probably caused by illegal octal escape sequences.');
183
- }
184
- return {
185
- // This property needs to remain unminified.
186
- ['_$litType$']: type,
187
- strings,
188
- values,
189
- };
190
- };
191
- /**
192
- * Interprets a template literal as an HTML template that can efficiently
193
- * render to and update a container.
194
- *
195
- * ```ts
196
- * const header = (title: string) => html`<h1>${title}</h1>`;
197
- * ```
198
- *
199
- * The `html` tag returns a description of the DOM to render as a value. It is
200
- * lazy, meaning no work is done until the template is rendered. When rendering,
201
- * if a template comes from the same expression as a previously rendered result,
202
- * it's efficiently updated instead of replaced.
203
- */
204
- exports.html = tag(HTML_RESULT);
205
- /**
206
- * Interprets a template literal as an SVG template that can efficiently
207
- * render to and update a container.
208
- */
209
- exports.svg = tag(SVG_RESULT);
210
- /**
211
- * A sentinel value that signals that a value was handled by a directive and
212
- * should not be written to the DOM.
213
- */
214
- exports.noChange = Symbol.for('lit-noChange');
215
- /**
216
- * A sentinel value that signals a ChildPart to fully clear its content.
217
- *
218
- * ```ts
219
- * const button = html`${
220
- * user.isAdmin
221
- * ? html`<button>DELETE</button>`
222
- * : nothing
223
- * }`;
224
- * ```
225
- *
226
- * Prefer using `nothing` over other falsy values as it provides a consistent
227
- * behavior between various expression binding contexts.
228
- *
229
- * In child expressions, `undefined`, `null`, `''`, and `nothing` all behave the
230
- * same and render no nodes. In attribute expressions, `nothing` _removes_ the
231
- * attribute, while `undefined` and `null` will render an empty string. In
232
- * property expressions `nothing` becomes `undefined`.
233
- */
234
- exports.nothing = Symbol.for('lit-nothing');
235
- /**
236
- * The cache of prepared templates, keyed by the tagged TemplateStringsArray
237
- * and _not_ accounting for the specific template tag used. This means that
238
- * template tags cannot be dynamic - the must statically be one of html, svg,
239
- * or attr. This restriction simplifies the cache lookup, which is on the hot
240
- * path for rendering.
241
- */
242
- const templateCache = new WeakMap();
243
- /**
244
- * Renders a value, usually a lit-html TemplateResult, to the container.
245
- * @param value
246
- * @param container
247
- * @param options
248
- */
249
- const render = (value, container, options) => {
250
- var _a, _b, _c;
251
- const partOwnerNode = (_a = options === null || options === void 0 ? void 0 : options.renderBefore) !== null && _a !== void 0 ? _a : container;
252
- // This property needs to remain unminified.
253
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
254
- let part = partOwnerNode['_$litPart$'];
255
- if (part === undefined) {
256
- const endNode = (_b = options === null || options === void 0 ? void 0 : options.renderBefore) !== null && _b !== void 0 ? _b : null;
257
- // Internal modification: don't clear container to match lit-html 2.0
258
- if (exports.INTERNAL &&
259
- ((_c = options) === null || _c === void 0 ? void 0 : _c.clearContainerForLit2MigrationOnly) ===
260
- true) {
261
- let n = container.firstChild;
262
- // Clear only up to the `endNode` aka `renderBefore` node.
263
- while (n && n !== endNode) {
264
- const next = n.nextSibling;
265
- n.remove();
266
- n = next;
267
- }
268
- }
269
- // This property needs to remain unminified.
270
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
271
- partOwnerNode['_$litPart$'] = part = new ChildPart(container.insertBefore(createMarker(), endNode), endNode, undefined, options !== null && options !== void 0 ? options : {});
272
- }
273
- part._$setValue(value);
274
- return part;
275
- };
276
- exports.render = render;
277
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
278
- exports.render.setSanitizer = setSanitizer;
279
- exports.render.createSanitizer = createSanitizer;
280
- if (DEV_MODE) {
281
- exports.render._testOnlyClearSanitizerFactoryDoNotCallOrElse =
282
- _testOnlyClearSanitizerFactoryDoNotCallOrElse;
283
- }
284
- }
285
- const walker = d.createTreeWalker(d, 129 /* NodeFilter.SHOW_{ELEMENT|COMMENT} */, null, false);
286
- let sanitizerFactoryInternal = noopSanitizer;
287
- /**
288
- * Returns an HTML string for the given TemplateStringsArray and result type
289
- * (HTML or SVG), along with the case-sensitive bound attribute names in
290
- * template order. The HTML contains comment comment markers denoting the
291
- * `ChildPart`s and suffixes on bound attributes denoting the `AttributeParts`.
292
- *
293
- * @param strings template strings array
294
- * @param type HTML or SVG
295
- * @return Array containing `[html, attrNames]` (array returned for terseness,
296
- * to avoid object fields since this code is shared with non-minified SSR
297
- * code)
298
- */
299
- const getTemplateHtml = (strings, type) => {
300
- // Insert makers into the template HTML to represent the position of
301
- // bindings. The following code scans the template strings to determine the
302
- // syntactic position of the bindings. They can be in text position, where
303
- // we insert an HTML comment, attribute value position, where we insert a
304
- // sentinel string and re-write the attribute name, or inside a tag where
305
- // we insert the sentinel string.
306
- const l = strings.length - 1;
307
- // Stores the case-sensitive bound attribute names in the order of their
308
- // parts. ElementParts are also reflected in this array as undefined
309
- // rather than a string, to disambiguate from attribute bindings.
310
- const attrNames = [];
311
- let html = type === SVG_RESULT ? '<svg>' : '';
312
- // When we're inside a raw text tag (not it's text content), the regex
313
- // will still be tagRegex so we can find attributes, but will switch to
314
- // this regex when the tag ends.
315
- let rawTextEndRegex;
316
- // The current parsing state, represented as a reference to one of the
317
- // regexes
318
- let regex = textEndRegex;
319
- for (let i = 0; i < l; i++) {
320
- const s = strings[i];
321
- // The index of the end of the last attribute name. When this is
322
- // positive at end of a string, it means we're in an attribute value
323
- // position and need to rewrite the attribute name.
324
- // We also use a special value of -2 to indicate that we encountered
325
- // the end of a string in attribute name position.
326
- let attrNameEndIndex = -1;
327
- let attrName;
328
- let lastIndex = 0;
329
- let match;
330
- // The conditions in this loop handle the current parse state, and the
331
- // assignments to the `regex` variable are the state transitions.
332
- while (lastIndex < s.length) {
333
- // Make sure we start searching from where we previously left off
334
- regex.lastIndex = lastIndex;
335
- match = regex.exec(s);
336
- if (match === null) {
337
- break;
338
- }
339
- lastIndex = regex.lastIndex;
340
- if (regex === textEndRegex) {
341
- if (match[COMMENT_START] === '!--') {
342
- regex = commentEndRegex;
343
- }
344
- else if (match[COMMENT_START] !== undefined) {
345
- // We started a weird comment, like </{
346
- regex = comment2EndRegex;
347
- }
348
- else if (match[TAG_NAME] !== undefined) {
349
- if (rawTextElement.test(match[TAG_NAME])) {
350
- // Record if we encounter a raw-text element. We'll switch to
351
- // this regex at the end of the tag.
352
- rawTextEndRegex = new RegExp(`</${match[TAG_NAME]}`, 'g');
353
- }
354
- regex = tagEndRegex;
355
- }
356
- else if (match[DYNAMIC_TAG_NAME] !== undefined) {
357
- if (DEV_MODE) {
358
- throw new Error('Bindings in tag names are not supported. Please use static templates instead. ' +
359
- 'See https://lit.dev/docs/templates/expressions/#static-expressions');
360
- }
361
- regex = tagEndRegex;
362
- }
363
- }
364
- else if (regex === tagEndRegex) {
365
- if (match[ENTIRE_MATCH] === '>') {
366
- // End of a tag. If we had started a raw-text element, use that
367
- // regex
368
- regex = rawTextEndRegex !== null && rawTextEndRegex !== void 0 ? rawTextEndRegex : textEndRegex;
369
- // We may be ending an unquoted attribute value, so make sure we
370
- // clear any pending attrNameEndIndex
371
- attrNameEndIndex = -1;
372
- }
373
- else if (match[ATTRIBUTE_NAME] === undefined) {
374
- // Attribute name position
375
- attrNameEndIndex = -2;
376
- }
377
- else {
378
- attrNameEndIndex = regex.lastIndex - match[SPACES_AND_EQUALS].length;
379
- attrName = match[ATTRIBUTE_NAME];
380
- regex =
381
- match[QUOTE_CHAR] === undefined
382
- ? tagEndRegex
383
- : match[QUOTE_CHAR] === '"'
384
- ? doubleQuoteAttrEndRegex
385
- : singleQuoteAttrEndRegex;
386
- }
387
- }
388
- else if (regex === doubleQuoteAttrEndRegex ||
389
- regex === singleQuoteAttrEndRegex) {
390
- regex = tagEndRegex;
391
- }
392
- else if (regex === commentEndRegex || regex === comment2EndRegex) {
393
- regex = textEndRegex;
394
- }
395
- else {
396
- // Not one of the five state regexes, so it must be the dynamically
397
- // created raw text regex and we're at the close of that element.
398
- regex = tagEndRegex;
399
- rawTextEndRegex = undefined;
400
- }
401
- }
402
- if (DEV_MODE) {
403
- // If we have a attrNameEndIndex, which indicates that we should
404
- // rewrite the attribute name, assert that we're in a valid attribute
405
- // position - either in a tag, or a quoted attribute value.
406
- console.assert(attrNameEndIndex === -1 ||
407
- regex === tagEndRegex ||
408
- regex === singleQuoteAttrEndRegex ||
409
- regex === doubleQuoteAttrEndRegex, 'unexpected parse state B');
410
- }
411
- // We have four cases:
412
- // 1. We're in text position, and not in a raw text element
413
- // (regex === textEndRegex): insert a comment marker.
414
- // 2. We have a non-negative attrNameEndIndex which means we need to
415
- // rewrite the attribute name to add a bound attribute suffix.
416
- // 3. We're at the non-first binding in a multi-binding attribute, use a
417
- // plain marker.
418
- // 4. We're somewhere else inside the tag. If we're in attribute name
419
- // position (attrNameEndIndex === -2), add a sequential suffix to
420
- // generate a unique attribute name.
421
- // Detect a binding next to self-closing tag end and insert a space to
422
- // separate the marker from the tag end:
423
- const end = regex === tagEndRegex && strings[i + 1].startsWith('/>') ? ' ' : '';
424
- html +=
425
- regex === textEndRegex
426
- ? s + nodeMarker
427
- : attrNameEndIndex >= 0
428
- ? (attrNames.push(attrName),
429
- s.slice(0, attrNameEndIndex) +
430
- boundAttributeSuffix +
431
- s.slice(attrNameEndIndex)) +
432
- marker +
433
- end
434
- : s +
435
- marker +
436
- (attrNameEndIndex === -2 ? (attrNames.push(undefined), i) : end);
437
- }
438
- const htmlResult = html + (strings[l] || '<?>') + (type === SVG_RESULT ? '</svg>' : '');
439
- // Returned as an array for terseness
440
- return [
441
- policy !== undefined
442
- ? policy.createHTML(htmlResult)
443
- : htmlResult,
444
- attrNames,
445
- ];
446
- };
447
- class Template {
448
- constructor(
449
- // This property needs to remain unminified.
450
- { strings, ['_$litType$']: type }, options) {
451
- /** @internal */
452
- this.parts = [];
453
- let node;
454
- let nodeIndex = 0;
455
- let attrNameIndex = 0;
456
- const partCount = strings.length - 1;
457
- const parts = this.parts;
458
- // Create template element
459
- const [html, attrNames] = getTemplateHtml(strings, type);
460
- this.el = Template.createElement(html, options);
461
- walker.currentNode = this.el.content;
462
- // Reparent SVG nodes into template root
463
- if (type === SVG_RESULT) {
464
- const content = this.el.content;
465
- const svgElement = content.firstChild;
466
- svgElement.remove();
467
- content.append(...svgElement.childNodes);
468
- }
469
- // Walk the template to find binding markers and create TemplateParts
470
- while ((node = walker.nextNode()) !== null && parts.length < partCount) {
471
- if (node.nodeType === 1) {
472
- if (DEV_MODE) {
473
- const tag = node.localName;
474
- // Warn if `textarea` includes an expression and throw if `template`
475
- // does since these are not supported. We do this by checking
476
- // innerHTML for anything that looks like a marker. This catches
477
- // cases like bindings in textarea there markers turn into text nodes.
478
- if (/^(?:textarea|template)$/i.test(tag) &&
479
- node.innerHTML.includes(marker)) {
480
- const m = `Expressions are not supported inside \`${tag}\` ` +
481
- `elements. See https://lit.dev/msg/expression-in-${tag} for more ` +
482
- `information.`;
483
- if (tag === 'template') {
484
- throw new Error(m);
485
- }
486
- else
487
- issueWarning('', m);
488
- }
489
- }
490
- // TODO (justinfagnani): for attempted dynamic tag names, we don't
491
- // increment the bindingIndex, and it'll be off by 1 in the element
492
- // and off by two after it.
493
- if (node.hasAttributes()) {
494
- // We defer removing bound attributes because on IE we might not be
495
- // iterating attributes in their template order, and would sometimes
496
- // remove an attribute that we still need to create a part for.
497
- const attrsToRemove = [];
498
- for (const name of node.getAttributeNames()) {
499
- // `name` is the name of the attribute we're iterating over, but not
500
- // _neccessarily_ the name of the attribute we will create a part
501
- // for. They can be different in browsers that don't iterate on
502
- // attributes in source order. In that case the attrNames array
503
- // contains the attribute name we'll process next. We only need the
504
- // attribute name here to know if we should process a bound attribute
505
- // on this element.
506
- if (name.endsWith(boundAttributeSuffix) ||
507
- name.startsWith(marker)) {
508
- const realName = attrNames[attrNameIndex++];
509
- attrsToRemove.push(name);
510
- if (realName !== undefined) {
511
- // Lowercase for case-sensitive SVG attributes like viewBox
512
- const value = node.getAttribute(realName.toLowerCase() + boundAttributeSuffix);
513
- const statics = value.split(marker);
514
- const m = /([.?@])?(.*)/.exec(realName);
515
- parts.push({
516
- type: ATTRIBUTE_PART,
517
- index: nodeIndex,
518
- name: m[2],
519
- strings: statics,
520
- ctor: m[1] === '.'
521
- ? PropertyPart
522
- : m[1] === '?'
523
- ? BooleanAttributePart
524
- : m[1] === '@'
525
- ? EventPart
526
- : AttributePart,
527
- });
528
- }
529
- else {
530
- parts.push({
531
- type: ELEMENT_PART,
532
- index: nodeIndex,
533
- });
534
- }
535
- }
536
- }
537
- for (const name of attrsToRemove) {
538
- node.removeAttribute(name);
539
- }
540
- }
541
- // TODO (justinfagnani): benchmark the regex against testing for each
542
- // of the 3 raw text element names.
543
- if (rawTextElement.test(node.tagName)) {
544
- // For raw text elements we need to split the text content on
545
- // markers, create a Text node for each segment, and create
546
- // a TemplatePart for each marker.
547
- const strings = node.textContent.split(marker);
548
- const lastIndex = strings.length - 1;
549
- if (lastIndex > 0) {
550
- node.textContent = trustedTypes
551
- ? trustedTypes.emptyScript
552
- : '';
553
- // Generate a new text node for each literal section
554
- // These nodes are also used as the markers for node parts
555
- // We can't use empty text nodes as markers because they're
556
- // normalized when cloning in IE (could simplify when
557
- // IE is no longer supported)
558
- for (let i = 0; i < lastIndex; i++) {
559
- node.append(strings[i], createMarker());
560
- // Walk past the marker node we just added
561
- walker.nextNode();
562
- parts.push({ type: CHILD_PART, index: ++nodeIndex });
563
- }
564
- // Note because this marker is added after the walker's current
565
- // node, it will be walked to in the outer loop (and ignored), so
566
- // we don't need to adjust nodeIndex here
567
- node.append(strings[lastIndex], createMarker());
568
- }
569
- }
570
- }
571
- else if (node.nodeType === 8) {
572
- const data = node.data;
573
- if (data === markerMatch) {
574
- parts.push({ type: CHILD_PART, index: nodeIndex });
575
- }
576
- else {
577
- let i = -1;
578
- while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
579
- // Comment node has a binding marker inside, make an inactive part
580
- // The binding won't work, but subsequent bindings will
581
- parts.push({ type: COMMENT_PART, index: nodeIndex });
582
- // Move to the end of the match
583
- i += marker.length - 1;
584
- }
585
- }
586
- }
587
- nodeIndex++;
588
- }
589
- }
590
- // Overridden via `litHtmlPolyfillSupport` to provide platform support.
591
- /** @nocollapse */
592
- static createElement(html, _options) {
593
- const el = d.createElement('template');
594
- el.innerHTML = html;
595
- return el;
596
- }
597
- }
598
- function resolveDirective(part, value, parent = part, attributeIndex) {
599
- var _a, _b, _c;
600
- var _d;
601
- // Bail early if the value is explicitly noChange. Note, this means any
602
- // nested directive is still attached and is not run.
603
- if (value === exports.noChange) {
604
- return value;
605
- }
606
- let currentDirective = attributeIndex !== undefined
607
- ? (_a = parent.__directives) === null || _a === void 0 ? void 0 : _a[attributeIndex]
608
- : parent.__directive;
609
- const nextDirectiveConstructor = isPrimitive(value)
610
- ? undefined
611
- : // This property needs to remain unminified.
612
- value['_$litDirective$'];
613
- if ((currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective.constructor) !== nextDirectiveConstructor) {
614
- // This property needs to remain unminified.
615
- (_b = currentDirective === null || currentDirective === void 0 ? void 0 : currentDirective['_$notifyDirectiveConnectionChanged']) === null || _b === void 0 ? void 0 : _b.call(currentDirective, false);
616
- if (nextDirectiveConstructor === undefined) {
617
- currentDirective = undefined;
618
- }
619
- else {
620
- currentDirective = new nextDirectiveConstructor(part);
621
- currentDirective._$initialize(part, parent, attributeIndex);
622
- }
623
- if (attributeIndex !== undefined) {
624
- ((_c = (_d = parent).__directives) !== null && _c !== void 0 ? _c : (_d.__directives = []))[attributeIndex] =
625
- currentDirective;
626
- }
627
- else {
628
- parent.__directive = currentDirective;
629
- }
630
- }
631
- if (currentDirective !== undefined) {
632
- value = resolveDirective(part, currentDirective._$resolve(part, value.values), currentDirective, attributeIndex);
633
- }
634
- return value;
635
- }
636
- /**
637
- * An updateable instance of a Template. Holds references to the Parts used to
638
- * update the template instance.
639
- */
640
- class TemplateInstance {
641
- constructor(template, parent) {
642
- /** @internal */
643
- this._parts = [];
644
- /** @internal */
645
- this._$disconnectableChildren = undefined;
646
- this._$template = template;
647
- this._$parent = parent;
648
- }
649
- // Called by ChildPart parentNode getter
650
- get parentNode() {
651
- return this._$parent.parentNode;
652
- }
653
- // See comment in Disconnectable interface for why this is a getter
654
- get _$isConnected() {
655
- return this._$parent._$isConnected;
656
- }
657
- // This method is separate from the constructor because we need to return a
658
- // DocumentFragment and we don't want to hold onto it with an instance field.
659
- _clone(options) {
660
- var _a;
661
- const { el: { content }, parts: parts, } = this._$template;
662
- const fragment = ((_a = options === null || options === void 0 ? void 0 : options.creationScope) !== null && _a !== void 0 ? _a : d).importNode(content, true);
663
- walker.currentNode = fragment;
664
- let node = walker.nextNode();
665
- let nodeIndex = 0;
666
- let partIndex = 0;
667
- let templatePart = parts[0];
668
- while (templatePart !== undefined) {
669
- if (nodeIndex === templatePart.index) {
670
- let part;
671
- if (templatePart.type === CHILD_PART) {
672
- part = new ChildPart(node, node.nextSibling, this, options);
673
- }
674
- else if (templatePart.type === ATTRIBUTE_PART) {
675
- part = new templatePart.ctor(node, templatePart.name, templatePart.strings, this, options);
676
- }
677
- else if (templatePart.type === ELEMENT_PART) {
678
- part = new ElementPart(node, this, options);
679
- }
680
- this._parts.push(part);
681
- templatePart = parts[++partIndex];
682
- }
683
- if (nodeIndex !== (templatePart === null || templatePart === void 0 ? void 0 : templatePart.index)) {
684
- node = walker.nextNode();
685
- nodeIndex++;
686
- }
687
- }
688
- return fragment;
689
- }
690
- _update(values) {
691
- let i = 0;
692
- for (const part of this._parts) {
693
- if (part !== undefined) {
694
- if (part.strings !== undefined) {
695
- part._$setValue(values, part, i);
696
- // The number of values the part consumes is part.strings.length - 1
697
- // since values are in between template spans. We increment i by 1
698
- // later in the loop, so increment it by part.strings.length - 2 here
699
- i += part.strings.length - 2;
700
- }
701
- else {
702
- part._$setValue(values[i]);
703
- }
704
- }
705
- i++;
706
- }
707
- }
708
- }
709
- class ChildPart {
710
- constructor(startNode, endNode, parent, options) {
711
- var _a;
712
- this.type = CHILD_PART;
713
- this._$committedValue = exports.nothing;
714
- // The following fields will be patched onto ChildParts when required by
715
- // AsyncDirective
716
- /** @internal */
717
- this._$disconnectableChildren = undefined;
718
- this._$startNode = startNode;
719
- this._$endNode = endNode;
720
- this._$parent = parent;
721
- this.options = options;
722
- // Note __isConnected is only ever accessed on RootParts (i.e. when there is
723
- // no _$parent); the value on a non-root-part is "don't care", but checking
724
- // for parent would be more code
725
- this.__isConnected = (_a = options === null || options === void 0 ? void 0 : options.isConnected) !== null && _a !== void 0 ? _a : true;
726
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
727
- // Explicitly initialize for consistent class shape.
728
- this._textSanitizer = undefined;
729
- }
730
- }
731
- // See comment in Disconnectable interface for why this is a getter
732
- get _$isConnected() {
733
- var _a, _b;
734
- // ChildParts that are not at the root should always be created with a
735
- // parent; only RootChildNode's won't, so they return the local isConnected
736
- // state
737
- return (_b = (_a = this._$parent) === null || _a === void 0 ? void 0 : _a._$isConnected) !== null && _b !== void 0 ? _b : this.__isConnected;
738
- }
739
- /**
740
- * The parent node into which the part renders its content.
741
- *
742
- * A ChildPart's content consists of a range of adjacent child nodes of
743
- * `.parentNode`, possibly bordered by 'marker nodes' (`.startNode` and
744
- * `.endNode`).
745
- *
746
- * - If both `.startNode` and `.endNode` are non-null, then the part's content
747
- * consists of all siblings between `.startNode` and `.endNode`, exclusively.
748
- *
749
- * - If `.startNode` is non-null but `.endNode` is null, then the part's
750
- * content consists of all siblings following `.startNode`, up to and
751
- * including the last child of `.parentNode`. If `.endNode` is non-null, then
752
- * `.startNode` will always be non-null.
753
- *
754
- * - If both `.endNode` and `.startNode` are null, then the part's content
755
- * consists of all child nodes of `.parentNode`.
756
- */
757
- get parentNode() {
758
- let parentNode = wrap(this._$startNode).parentNode;
759
- const parent = this._$parent;
760
- if (parent !== undefined &&
761
- parentNode.nodeType === 11 /* Node.DOCUMENT_FRAGMENT */) {
762
- // If the parentNode is a DocumentFragment, it may be because the DOM is
763
- // still in the cloned fragment during initial render; if so, get the real
764
- // parentNode the part will be committed into by asking the parent.
765
- parentNode = parent.parentNode;
766
- }
767
- return parentNode;
768
- }
769
- /**
770
- * The part's leading marker node, if any. See `.parentNode` for more
771
- * information.
772
- */
773
- get startNode() {
774
- return this._$startNode;
775
- }
776
- /**
777
- * The part's trailing marker node, if any. See `.parentNode` for more
778
- * information.
779
- */
780
- get endNode() {
781
- return this._$endNode;
782
- }
783
- _$setValue(value, directiveParent = this) {
784
- if (DEV_MODE && this.parentNode === null) {
785
- throw new Error(`This \`ChildPart\` has no \`parentNode\` and therefore cannot accept a value. This likely means the element containing the part was manipulated in an unsupported way outside of Lit's control such that the part's marker nodes were ejected from DOM. For example, setting the element's \`innerHTML\` or \`textContent\` can do this.`);
786
- }
787
- value = resolveDirective(this, value, directiveParent);
788
- if (isPrimitive(value)) {
789
- // Non-rendering child values. It's important that these do not render
790
- // empty text nodes to avoid issues with preventing default <slot>
791
- // fallback content.
792
- if (value === exports.nothing || value == null || value === '') {
793
- if (this._$committedValue !== exports.nothing) {
794
- this._$clear();
795
- }
796
- this._$committedValue = exports.nothing;
797
- }
798
- else if (value !== this._$committedValue && value !== exports.noChange) {
799
- this._commitText(value);
800
- }
801
- // This property needs to remain unminified.
802
- }
803
- else if (value['_$litType$'] !== undefined) {
804
- this._commitTemplateResult(value);
805
- }
806
- else if (value.nodeType !== undefined) {
807
- this._commitNode(value);
808
- }
809
- else if (isIterable(value)) {
810
- this._commitIterable(value);
811
- }
812
- else {
813
- // Fallback, will render the string representation
814
- this._commitText(value);
815
- }
816
- }
817
- _insert(node, ref = this._$endNode) {
818
- return wrap(wrap(this._$startNode).parentNode).insertBefore(node, ref);
819
- }
820
- _commitNode(value) {
821
- var _a;
822
- if (this._$committedValue !== value) {
823
- this._$clear();
824
- if (ENABLE_EXTRA_SECURITY_HOOKS &&
825
- sanitizerFactoryInternal !== noopSanitizer) {
826
- const parentNodeName = (_a = this._$startNode.parentNode) === null || _a === void 0 ? void 0 : _a.nodeName;
827
- if (parentNodeName === 'STYLE' || parentNodeName === 'SCRIPT') {
828
- let message = 'Forbidden';
829
- if (DEV_MODE) {
830
- if (parentNodeName === 'STYLE') {
831
- message =
832
- `Lit does not support binding inside style nodes. ` +
833
- `This is a security risk, as style injection attacks can ` +
834
- `exfiltrate data and spoof UIs. ` +
835
- `Consider instead using css\`...\` literals ` +
836
- `to compose styles, and make do dynamic styling with ` +
837
- `css custom properties, ::parts, <slot>s, ` +
838
- `and by mutating the DOM rather than stylesheets.`;
839
- }
840
- else {
841
- message =
842
- `Lit does not support binding inside script nodes. ` +
843
- `This is a security risk, as it could allow arbitrary ` +
844
- `code execution.`;
845
- }
846
- }
847
- throw new Error(message);
848
- }
849
- }
850
- this._$committedValue = this._insert(value);
851
- }
852
- }
853
- _commitText(value) {
854
- // If the committed value is a primitive it means we called _commitText on
855
- // the previous render, and we know that this._$startNode.nextSibling is a
856
- // Text node. We can now just replace the text content (.data) of the node.
857
- if (this._$committedValue !== exports.nothing &&
858
- isPrimitive(this._$committedValue)) {
859
- const node = wrap(this._$startNode).nextSibling;
860
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
861
- if (this._textSanitizer === undefined) {
862
- this._textSanitizer = createSanitizer(node, 'data', 'property');
863
- }
864
- value = this._textSanitizer(value);
865
- }
866
- node.data = value;
867
- }
868
- else {
869
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
870
- const textNode = document.createTextNode('');
871
- this._commitNode(textNode);
872
- // When setting text content, for security purposes it matters a lot
873
- // what the parent is. For example, <style> and <script> need to be
874
- // handled with care, while <span> does not. So first we need to put a
875
- // text node into the document, then we can sanitize its contentx.
876
- if (this._textSanitizer === undefined) {
877
- this._textSanitizer = createSanitizer(textNode, 'data', 'property');
878
- }
879
- value = this._textSanitizer(value);
880
- textNode.data = value;
881
- }
882
- else {
883
- this._commitNode(d.createTextNode(value));
884
- }
885
- }
886
- this._$committedValue = value;
887
- }
888
- _commitTemplateResult(result) {
889
- var _a;
890
- // This property needs to remain unminified.
891
- const { values, ['_$litType$']: type } = result;
892
- // If $litType$ is a number, result is a plain TemplateResult and we get
893
- // the template from the template cache. If not, result is a
894
- // CompiledTemplateResult and _$litType$ is a CompiledTemplate and we need
895
- // to create the <template> element the first time we see it.
896
- const template = typeof type === 'number'
897
- ? this._$getTemplate(result)
898
- : (type.el === undefined &&
899
- (type.el = Template.createElement(type.h, this.options)),
900
- type);
901
- if (((_a = this._$committedValue) === null || _a === void 0 ? void 0 : _a._$template) === template) {
902
- this._$committedValue._update(values);
903
- }
904
- else {
905
- const instance = new TemplateInstance(template, this);
906
- const fragment = instance._clone(this.options);
907
- instance._update(values);
908
- this._commitNode(fragment);
909
- this._$committedValue = instance;
910
- }
911
- }
912
- // Overridden via `litHtmlPolyfillSupport` to provide platform support.
913
- /** @internal */
914
- _$getTemplate(result) {
915
- let template = templateCache.get(result.strings);
916
- if (template === undefined) {
917
- templateCache.set(result.strings, (template = new Template(result)));
918
- }
919
- return template;
920
- }
921
- _commitIterable(value) {
922
- // For an Iterable, we create a new InstancePart per item, then set its
923
- // value to the item. This is a little bit of overhead for every item in
924
- // an Iterable, but it lets us recurse easily and efficiently update Arrays
925
- // of TemplateResults that will be commonly returned from expressions like:
926
- // array.map((i) => html`${i}`), by reusing existing TemplateInstances.
927
- // If value is an array, then the previous render was of an
928
- // iterable and value will contain the ChildParts from the previous
929
- // render. If value is not an array, clear this part and make a new
930
- // array for ChildParts.
931
- if (!isArray(this._$committedValue)) {
932
- this._$committedValue = [];
933
- this._$clear();
934
- }
935
- // Lets us keep track of how many items we stamped so we can clear leftover
936
- // items from a previous render
937
- const itemParts = this._$committedValue;
938
- let partIndex = 0;
939
- let itemPart;
940
- for (const item of value) {
941
- if (partIndex === itemParts.length) {
942
- // If no existing part, create a new one
943
- // TODO (justinfagnani): test perf impact of always creating two parts
944
- // instead of sharing parts between nodes
945
- // https://github.com/lit/lit/issues/1266
946
- itemParts.push((itemPart = new ChildPart(this._insert(createMarker()), this._insert(createMarker()), this, this.options)));
947
- }
948
- else {
949
- // Reuse an existing part
950
- itemPart = itemParts[partIndex];
951
- }
952
- itemPart._$setValue(item);
953
- partIndex++;
954
- }
955
- if (partIndex < itemParts.length) {
956
- // itemParts always have end nodes
957
- this._$clear(itemPart && wrap(itemPart._$endNode).nextSibling, partIndex);
958
- // Truncate the parts array so _value reflects the current state
959
- itemParts.length = partIndex;
960
- }
961
- }
962
- /**
963
- * Removes the nodes contained within this Part from the DOM.
964
- *
965
- * @param start Start node to clear from, for clearing a subset of the part's
966
- * DOM (used when truncating iterables)
967
- * @param from When `start` is specified, the index within the iterable from
968
- * which ChildParts are being removed, used for disconnecting directives in
969
- * those Parts.
970
- *
971
- * @internal
972
- */
973
- _$clear(start = wrap(this._$startNode).nextSibling, from) {
974
- var _a;
975
- (_a = this._$notifyConnectionChanged) === null || _a === void 0 ? void 0 : _a.call(this, false, true, from);
976
- while (start && start !== this._$endNode) {
977
- const n = wrap(start).nextSibling;
978
- wrap(start).remove();
979
- start = n;
980
- }
981
- }
982
- /**
983
- * Implementation of RootPart's `isConnected`. Note that this metod
984
- * should only be called on `RootPart`s (the `ChildPart` returned from a
985
- * top-level `render()` call). It has no effect on non-root ChildParts.
986
- * @param isConnected Whether to set
987
- * @internal
988
- */
989
- setConnected(isConnected) {
990
- var _a;
991
- if (this._$parent === undefined) {
992
- this.__isConnected = isConnected;
993
- (_a = this._$notifyConnectionChanged) === null || _a === void 0 ? void 0 : _a.call(this, isConnected);
994
- }
995
- else if (DEV_MODE) {
996
- throw new Error('part.setConnected() may only be called on a ' +
997
- 'RootPart returned from render().');
998
- }
999
- }
1000
- }
1001
- class AttributePart {
1002
- constructor(element, name, strings, parent, options) {
1003
- this.type = ATTRIBUTE_PART;
1004
- /** @internal */
1005
- this._$committedValue = exports.nothing;
1006
- /** @internal */
1007
- this._$disconnectableChildren = undefined;
1008
- this.element = element;
1009
- this.name = name;
1010
- this._$parent = parent;
1011
- this.options = options;
1012
- if (strings.length > 2 || strings[0] !== '' || strings[1] !== '') {
1013
- this._$committedValue = new Array(strings.length - 1).fill(new String());
1014
- this.strings = strings;
1015
- }
1016
- else {
1017
- this._$committedValue = exports.nothing;
1018
- }
1019
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
1020
- this._sanitizer = undefined;
1021
- }
1022
- }
1023
- get tagName() {
1024
- return this.element.tagName;
1025
- }
1026
- // See comment in Disconnectable interface for why this is a getter
1027
- get _$isConnected() {
1028
- return this._$parent._$isConnected;
1029
- }
1030
- /**
1031
- * Sets the value of this part by resolving the value from possibly multiple
1032
- * values and static strings and committing it to the DOM.
1033
- * If this part is single-valued, `this._strings` will be undefined, and the
1034
- * method will be called with a single value argument. If this part is
1035
- * multi-value, `this._strings` will be defined, and the method is called
1036
- * with the value array of the part's owning TemplateInstance, and an offset
1037
- * into the value array from which the values should be read.
1038
- * This method is overloaded this way to eliminate short-lived array slices
1039
- * of the template instance values, and allow a fast-path for single-valued
1040
- * parts.
1041
- *
1042
- * @param value The part value, or an array of values for multi-valued parts
1043
- * @param valueIndex the index to start reading values from. `undefined` for
1044
- * single-valued parts
1045
- * @param noCommit causes the part to not commit its value to the DOM. Used
1046
- * in hydration to prime attribute parts with their first-rendered value,
1047
- * but not set the attribute, and in SSR to no-op the DOM operation and
1048
- * capture the value for serialization.
1049
- *
1050
- * @internal
1051
- */
1052
- _$setValue(value, directiveParent = this, valueIndex, noCommit) {
1053
- const strings = this.strings;
1054
- // Whether any of the values has changed, for dirty-checking
1055
- let change = false;
1056
- if (strings === undefined) {
1057
- // Single-value binding case
1058
- value = resolveDirective(this, value, directiveParent, 0);
1059
- change =
1060
- !isPrimitive(value) ||
1061
- (value !== this._$committedValue && value !== exports.noChange);
1062
- if (change) {
1063
- this._$committedValue = value;
1064
- }
1065
- }
1066
- else {
1067
- // Interpolation case
1068
- const values = value;
1069
- value = strings[0];
1070
- let i, v;
1071
- for (i = 0; i < strings.length - 1; i++) {
1072
- v = resolveDirective(this, values[valueIndex + i], directiveParent, i);
1073
- if (v === exports.noChange) {
1074
- // If the user-provided value is `noChange`, use the previous value
1075
- v = this._$committedValue[i];
1076
- }
1077
- change || (change = !isPrimitive(v) || v !== this._$committedValue[i]);
1078
- if (v === exports.nothing) {
1079
- value = exports.nothing;
1080
- }
1081
- else if (value !== exports.nothing) {
1082
- value += (v !== null && v !== void 0 ? v : '') + strings[i + 1];
1083
- }
1084
- // We always record each value, even if one is `nothing`, for future
1085
- // change detection.
1086
- this._$committedValue[i] = v;
1087
- }
1088
- }
1089
- if (change && !noCommit) {
1090
- this._commitValue(value);
1091
- }
1092
- }
1093
- /** @internal */
1094
- _commitValue(value) {
1095
- if (value === exports.nothing) {
1096
- wrap(this.element).removeAttribute(this.name);
1097
- }
1098
- else {
1099
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
1100
- if (this._sanitizer === undefined) {
1101
- this._sanitizer = sanitizerFactoryInternal(this.element, this.name, 'attribute');
1102
- }
1103
- value = this._sanitizer(value !== null && value !== void 0 ? value : '');
1104
- }
1105
- wrap(this.element).setAttribute(this.name, (value !== null && value !== void 0 ? value : ''));
1106
- }
1107
- }
1108
- }
1109
- class PropertyPart extends AttributePart {
1110
- constructor() {
1111
- super(...arguments);
1112
- this.type = PROPERTY_PART;
1113
- }
1114
- /** @internal */
1115
- _commitValue(value) {
1116
- if (ENABLE_EXTRA_SECURITY_HOOKS) {
1117
- if (this._sanitizer === undefined) {
1118
- this._sanitizer = sanitizerFactoryInternal(this.element, this.name, 'property');
1119
- }
1120
- value = this._sanitizer(value);
1121
- }
1122
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1123
- this.element[this.name] = value === exports.nothing ? undefined : value;
1124
- }
1125
- }
1126
- class BooleanAttributePart extends AttributePart {
1127
- constructor() {
1128
- super(...arguments);
1129
- this.type = BOOLEAN_ATTRIBUTE_PART;
1130
- }
1131
- /** @internal */
1132
- _commitValue(value) {
1133
- if (value && value !== exports.nothing) {
1134
- wrap(this.element).setAttribute(this.name, '');
1135
- }
1136
- else {
1137
- wrap(this.element).removeAttribute(this.name);
1138
- }
1139
- }
1140
- }
1141
- class EventPart extends AttributePart {
1142
- constructor(element, name, strings, parent, options) {
1143
- super(element, name, strings, parent, options);
1144
- this.type = EVENT_PART;
1145
- if (DEV_MODE && this.strings !== undefined) {
1146
- throw new Error(`A \`<${element.localName}>\` has a \`@${name}=...\` listener with ` +
1147
- 'invalid content. Event listeners in templates must have exactly ' +
1148
- 'one expression and no surrounding text.');
1149
- }
1150
- }
1151
- // EventPart does not use the base _$setValue/_resolveValue implementation
1152
- // since the dirty checking is more complex
1153
- /** @internal */
1154
- _$setValue(newListener, directiveParent = this) {
1155
- var _a;
1156
- newListener =
1157
- (_a = resolveDirective(this, newListener, directiveParent, 0)) !== null && _a !== void 0 ? _a : exports.nothing;
1158
- if (newListener === exports.noChange) {
1159
- return;
1160
- }
1161
- const oldListener = this._$committedValue;
1162
- // If the new value is nothing or any options change we have to remove the
1163
- // part as a listener.
1164
- const shouldRemoveListener = (newListener === exports.nothing && oldListener !== exports.nothing) ||
1165
- newListener.capture !==
1166
- oldListener.capture ||
1167
- newListener.once !==
1168
- oldListener.once ||
1169
- newListener.passive !==
1170
- oldListener.passive;
1171
- // If the new value is not nothing and we removed the listener, we have
1172
- // to add the part as a listener.
1173
- const shouldAddListener = newListener !== exports.nothing &&
1174
- (oldListener === exports.nothing || shouldRemoveListener);
1175
- if (shouldRemoveListener) {
1176
- this.element.removeEventListener(this.name, this, oldListener);
1177
- }
1178
- if (shouldAddListener) {
1179
- // Beware: IE11 and Chrome 41 don't like using the listener as the
1180
- // options object. Figure out how to deal w/ this in IE11 - maybe
1181
- // patch addEventListener?
1182
- this.element.addEventListener(this.name, this, newListener);
1183
- }
1184
- this._$committedValue = newListener;
1185
- }
1186
- handleEvent(event) {
1187
- var _a, _b;
1188
- if (typeof this._$committedValue === 'function') {
1189
- this._$committedValue.call((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.host) !== null && _b !== void 0 ? _b : this.element, event);
1190
- }
1191
- else {
1192
- this._$committedValue.handleEvent(event);
1193
- }
1194
- }
1195
- }
1196
- class ElementPart {
1197
- constructor(element, parent, options) {
1198
- this.element = element;
1199
- this.type = ELEMENT_PART;
1200
- /** @internal */
1201
- this._$disconnectableChildren = undefined;
1202
- this._$parent = parent;
1203
- this.options = options;
1204
- }
1205
- // See comment in Disconnectable interface for why this is a getter
1206
- get _$isConnected() {
1207
- return this._$parent._$isConnected;
1208
- }
1209
- _$setValue(value) {
1210
- resolveDirective(this, value);
1211
- }
1212
- }
1213
- /**
1214
- * END USERS SHOULD NOT RELY ON THIS OBJECT.
1215
- *
1216
- * Private exports for use by other Lit packages, not intended for use by
1217
- * external users.
1218
- *
1219
- * We currently do not make a mangled rollup build of the lit-ssr code. In order
1220
- * to keep a number of (otherwise private) top-level exports mangled in the
1221
- * client side code, we export a _$LH object containing those members (or
1222
- * helper methods for accessing private fields of those members), and then
1223
- * re-export them for use in lit-ssr. This keeps lit-ssr agnostic to whether the
1224
- * client-side code is being used in `dev` mode or `prod` mode.
1225
- *
1226
- * This has a unique name, to disambiguate it from private exports in
1227
- * lit-element, which re-exports all of lit-html.
1228
- *
1229
- * @private
1230
- */
1231
- exports._$LH = {
1232
- // Used in lit-ssr
1233
- _boundAttributeSuffix: boundAttributeSuffix,
1234
- _marker: marker,
1235
- _markerMatch: markerMatch,
1236
- _HTML_RESULT: HTML_RESULT,
1237
- _getTemplateHtml: getTemplateHtml,
1238
- // Used in hydrate
1239
- _TemplateInstance: TemplateInstance,
1240
- _isIterable: isIterable,
1241
- _resolveDirective: resolveDirective,
1242
- // Used in tests and private-ssr-support
1243
- _ChildPart: ChildPart,
1244
- _AttributePart: AttributePart,
1245
- _BooleanAttributePart: BooleanAttributePart,
1246
- _EventPart: EventPart,
1247
- _PropertyPart: PropertyPart,
1248
- _ElementPart: ElementPart,
1249
- };
1250
- // Apply polyfills if available
1251
- (_d = globalThis[`litHtmlPolyfillSupport${DEV_MODE ? `DevMode` : ``}`]) === null || _d === void 0 ? void 0 : _d.call(globalThis, Template, ChildPart);
1252
- // IMPORTANT: do not change the property name or the assignment expression.
1253
- // This line will be used in regexes to search for lit-html usage.
1254
- // TODO(justinfagnani): inject version number at build time
1255
- ((_e = globalThis.litHtmlVersions) !== null && _e !== void 0 ? _e : (globalThis.litHtmlVersions = [])).push('2.0.0');
1256
- if (DEV_MODE && globalThis.litHtmlVersions.length > 1) {
1257
- issueWarning('multiple-versions', `Multiple versions of Lit loaded. ` +
1258
- `Loading multiple versions is not recommended.`);
1259
- }