@internetarchive/histogram-date-range 0.1.1-alpha → 0.1.2-alpha

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.
@@ -1,2537 +1,12 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
4
- * This code may only be used under the BSD style license found at
5
- * http://polymer.github.io/LICENSE.txt
6
- * The complete set of authors may be found at
7
- * http://polymer.github.io/AUTHORS.txt
8
- * The complete set of contributors may be found at
9
- * http://polymer.github.io/CONTRIBUTORS.txt
10
- * Code distributed by Google as part of the polymer project is also
11
- * subject to an additional IP rights grant found at
12
- * http://polymer.github.io/PATENTS.txt
13
- */
14
- /**
15
- * True if the custom elements polyfill is in use.
16
- */
17
- const isCEPolyfill = typeof window !== 'undefined' &&
18
- window.customElements != null &&
19
- window.customElements.polyfillWrapFlushCallback !==
20
- undefined;
21
- /**
22
- * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from
23
- * `container`.
24
- */
25
- const removeNodes = (container, start, end = null) => {
26
- while (start !== end) {
27
- const n = start.nextSibling;
28
- container.removeChild(start);
29
- start = n;
30
- }
31
- };
32
-
33
- /**
34
- * @license
35
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
36
- * This code may only be used under the BSD style license found at
37
- * http://polymer.github.io/LICENSE.txt
38
- * The complete set of authors may be found at
39
- * http://polymer.github.io/AUTHORS.txt
40
- * The complete set of contributors may be found at
41
- * http://polymer.github.io/CONTRIBUTORS.txt
42
- * Code distributed by Google as part of the polymer project is also
43
- * subject to an additional IP rights grant found at
44
- * http://polymer.github.io/PATENTS.txt
45
- */
46
- /**
47
- * An expression marker with embedded unique key to avoid collision with
48
- * possible text in templates.
49
- */
50
- const marker = `{{lit-${String(Math.random()).slice(2)}}}`;
51
- /**
52
- * An expression marker used text-positions, multi-binding attributes, and
53
- * attributes with markup-like text values.
54
- */
55
- const nodeMarker = `<!--${marker}-->`;
56
- const markerRegex = new RegExp(`${marker}|${nodeMarker}`);
57
- /**
58
- * Suffix appended to all bound attribute names.
59
- */
60
- const boundAttributeSuffix = '$lit$';
61
- /**
62
- * An updatable Template that tracks the location of dynamic parts.
63
- */
64
- class Template {
65
- constructor(result, element) {
66
- this.parts = [];
67
- this.element = element;
68
- const nodesToRemove = [];
69
- const stack = [];
70
- // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
71
- const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
72
- // Keeps track of the last index associated with a part. We try to delete
73
- // unnecessary nodes, but we never want to associate two different parts
74
- // to the same index. They must have a constant node between.
75
- let lastPartIndex = 0;
76
- let index = -1;
77
- let partIndex = 0;
78
- const { strings, values: { length } } = result;
79
- while (partIndex < length) {
80
- const node = walker.nextNode();
81
- if (node === null) {
82
- // We've exhausted the content inside a nested template element.
83
- // Because we still have parts (the outer for-loop), we know:
84
- // - There is a template in the stack
85
- // - The walker will find a nextNode outside the template
86
- walker.currentNode = stack.pop();
87
- continue;
88
- }
89
- index++;
90
- if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {
91
- if (node.hasAttributes()) {
92
- const attributes = node.attributes;
93
- const { length } = attributes;
94
- // Per
95
- // https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,
96
- // attributes are not guaranteed to be returned in document order.
97
- // In particular, Edge/IE can return them out of order, so we cannot
98
- // assume a correspondence between part index and attribute index.
99
- let count = 0;
100
- for (let i = 0; i < length; i++) {
101
- if (endsWith(attributes[i].name, boundAttributeSuffix)) {
102
- count++;
103
- }
104
- }
105
- while (count-- > 0) {
106
- // Get the template literal section leading up to the first
107
- // expression in this attribute
108
- const stringForPart = strings[partIndex];
109
- // Find the attribute name
110
- const name = lastAttributeNameRegex.exec(stringForPart)[2];
111
- // Find the corresponding attribute
112
- // All bound attributes have had a suffix added in
113
- // TemplateResult#getHTML to opt out of special attribute
114
- // handling. To look up the attribute value we also need to add
115
- // the suffix.
116
- const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;
117
- const attributeValue = node.getAttribute(attributeLookupName);
118
- node.removeAttribute(attributeLookupName);
119
- const statics = attributeValue.split(markerRegex);
120
- this.parts.push({ type: 'attribute', index, name, strings: statics });
121
- partIndex += statics.length - 1;
122
- }
123
- }
124
- if (node.tagName === 'TEMPLATE') {
125
- stack.push(node);
126
- walker.currentNode = node.content;
127
- }
128
- }
129
- else if (node.nodeType === 3 /* Node.TEXT_NODE */) {
130
- const data = node.data;
131
- if (data.indexOf(marker) >= 0) {
132
- const parent = node.parentNode;
133
- const strings = data.split(markerRegex);
134
- const lastIndex = strings.length - 1;
135
- // Generate a new text node for each literal section
136
- // These nodes are also used as the markers for node parts
137
- for (let i = 0; i < lastIndex; i++) {
138
- let insert;
139
- let s = strings[i];
140
- if (s === '') {
141
- insert = createMarker();
142
- }
143
- else {
144
- const match = lastAttributeNameRegex.exec(s);
145
- if (match !== null && endsWith(match[2], boundAttributeSuffix)) {
146
- s = s.slice(0, match.index) + match[1] +
147
- match[2].slice(0, -boundAttributeSuffix.length) + match[3];
148
- }
149
- insert = document.createTextNode(s);
150
- }
151
- parent.insertBefore(insert, node);
152
- this.parts.push({ type: 'node', index: ++index });
153
- }
154
- // If there's no text, we must insert a comment to mark our place.
155
- // Else, we can trust it will stick around after cloning.
156
- if (strings[lastIndex] === '') {
157
- parent.insertBefore(createMarker(), node);
158
- nodesToRemove.push(node);
159
- }
160
- else {
161
- node.data = strings[lastIndex];
162
- }
163
- // We have a part for each match found
164
- partIndex += lastIndex;
165
- }
166
- }
167
- else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {
168
- if (node.data === marker) {
169
- const parent = node.parentNode;
170
- // Add a new marker node to be the startNode of the Part if any of
171
- // the following are true:
172
- // * We don't have a previousSibling
173
- // * The previousSibling is already the start of a previous part
174
- if (node.previousSibling === null || index === lastPartIndex) {
175
- index++;
176
- parent.insertBefore(createMarker(), node);
177
- }
178
- lastPartIndex = index;
179
- this.parts.push({ type: 'node', index });
180
- // If we don't have a nextSibling, keep this node so we have an end.
181
- // Else, we can remove it to save future costs.
182
- if (node.nextSibling === null) {
183
- node.data = '';
184
- }
185
- else {
186
- nodesToRemove.push(node);
187
- index--;
188
- }
189
- partIndex++;
190
- }
191
- else {
192
- let i = -1;
193
- while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
194
- // Comment node has a binding marker inside, make an inactive part
195
- // The binding won't work, but subsequent bindings will
196
- // TODO (justinfagnani): consider whether it's even worth it to
197
- // make bindings in comments work
198
- this.parts.push({ type: 'node', index: -1 });
199
- partIndex++;
200
- }
201
- }
202
- }
203
- }
204
- // Remove text binding nodes after the walk to not disturb the TreeWalker
205
- for (const n of nodesToRemove) {
206
- n.parentNode.removeChild(n);
207
- }
208
- }
209
- }
210
- const endsWith = (str, suffix) => {
211
- const index = str.length - suffix.length;
212
- return index >= 0 && str.slice(index) === suffix;
213
- };
214
- const isTemplatePartActive = (part) => part.index !== -1;
215
- // Allows `document.createComment('')` to be renamed for a
216
- // small manual size-savings.
217
- const createMarker = () => document.createComment('');
218
- /**
219
- * This regex extracts the attribute name preceding an attribute-position
220
- * expression. It does this by matching the syntax allowed for attributes
221
- * against the string literal directly preceding the expression, assuming that
222
- * the expression is in an attribute-value position.
223
- *
224
- * See attributes in the HTML spec:
225
- * https://www.w3.org/TR/html5/syntax.html#elements-attributes
226
- *
227
- * " \x09\x0a\x0c\x0d" are HTML space characters:
228
- * https://www.w3.org/TR/html5/infrastructure.html#space-characters
229
- *
230
- * "\0-\x1F\x7F-\x9F" are Unicode control characters, which includes every
231
- * space character except " ".
232
- *
233
- * So an attribute is:
234
- * * The name: any character except a control character, space character, ('),
235
- * ("), ">", "=", or "/"
236
- * * Followed by zero or more space characters
237
- * * Followed by "="
238
- * * Followed by zero or more space characters
239
- * * Followed by:
240
- * * Any character except space, ('), ("), "<", ">", "=", (`), or
241
- * * (") then any non-("), or
242
- * * (') then any non-(')
243
- */
244
- const lastAttributeNameRegex =
245
- // eslint-disable-next-line no-control-regex
246
- /([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
247
-
248
- /**
249
- * @license
250
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
251
- * This code may only be used under the BSD style license found at
252
- * http://polymer.github.io/LICENSE.txt
253
- * The complete set of authors may be found at
254
- * http://polymer.github.io/AUTHORS.txt
255
- * The complete set of contributors may be found at
256
- * http://polymer.github.io/CONTRIBUTORS.txt
257
- * Code distributed by Google as part of the polymer project is also
258
- * subject to an additional IP rights grant found at
259
- * http://polymer.github.io/PATENTS.txt
260
- */
261
- const walkerNodeFilter = 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */;
262
- /**
263
- * Removes the list of nodes from a Template safely. In addition to removing
264
- * nodes from the Template, the Template part indices are updated to match
265
- * the mutated Template DOM.
266
- *
267
- * As the template is walked the removal state is tracked and
268
- * part indices are adjusted as needed.
269
- *
270
- * div
271
- * div#1 (remove) <-- start removing (removing node is div#1)
272
- * div
273
- * div#2 (remove) <-- continue removing (removing node is still div#1)
274
- * div
275
- * div <-- stop removing since previous sibling is the removing node (div#1,
276
- * removed 4 nodes)
277
- */
278
- function removeNodesFromTemplate(template, nodesToRemove) {
279
- const { element: { content }, parts } = template;
280
- const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
281
- let partIndex = nextActiveIndexInTemplateParts(parts);
282
- let part = parts[partIndex];
283
- let nodeIndex = -1;
284
- let removeCount = 0;
285
- const nodesToRemoveInTemplate = [];
286
- let currentRemovingNode = null;
287
- while (walker.nextNode()) {
288
- nodeIndex++;
289
- const node = walker.currentNode;
290
- // End removal if stepped past the removing node
291
- if (node.previousSibling === currentRemovingNode) {
292
- currentRemovingNode = null;
293
- }
294
- // A node to remove was found in the template
295
- if (nodesToRemove.has(node)) {
296
- nodesToRemoveInTemplate.push(node);
297
- // Track node we're removing
298
- if (currentRemovingNode === null) {
299
- currentRemovingNode = node;
300
- }
301
- }
302
- // When removing, increment count by which to adjust subsequent part indices
303
- if (currentRemovingNode !== null) {
304
- removeCount++;
305
- }
306
- while (part !== undefined && part.index === nodeIndex) {
307
- // If part is in a removed node deactivate it by setting index to -1 or
308
- // adjust the index as needed.
309
- part.index = currentRemovingNode !== null ? -1 : part.index - removeCount;
310
- // go to the next active part.
311
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
312
- part = parts[partIndex];
313
- }
314
- }
315
- nodesToRemoveInTemplate.forEach((n) => n.parentNode.removeChild(n));
316
- }
317
- const countNodes = (node) => {
318
- let count = (node.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */) ? 0 : 1;
319
- const walker = document.createTreeWalker(node, walkerNodeFilter, null, false);
320
- while (walker.nextNode()) {
321
- count++;
322
- }
323
- return count;
324
- };
325
- const nextActiveIndexInTemplateParts = (parts, startIndex = -1) => {
326
- for (let i = startIndex + 1; i < parts.length; i++) {
327
- const part = parts[i];
328
- if (isTemplatePartActive(part)) {
329
- return i;
330
- }
331
- }
332
- return -1;
333
- };
334
- /**
335
- * Inserts the given node into the Template, optionally before the given
336
- * refNode. In addition to inserting the node into the Template, the Template
337
- * part indices are updated to match the mutated Template DOM.
338
- */
339
- function insertNodeIntoTemplate(template, node, refNode = null) {
340
- const { element: { content }, parts } = template;
341
- // If there's no refNode, then put node at end of template.
342
- // No part indices need to be shifted in this case.
343
- if (refNode === null || refNode === undefined) {
344
- content.appendChild(node);
345
- return;
346
- }
347
- const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
348
- let partIndex = nextActiveIndexInTemplateParts(parts);
349
- let insertCount = 0;
350
- let walkerIndex = -1;
351
- while (walker.nextNode()) {
352
- walkerIndex++;
353
- const walkerNode = walker.currentNode;
354
- if (walkerNode === refNode) {
355
- insertCount = countNodes(node);
356
- refNode.parentNode.insertBefore(node, refNode);
357
- }
358
- while (partIndex !== -1 && parts[partIndex].index === walkerIndex) {
359
- // If we've inserted the node, simply adjust all subsequent parts
360
- if (insertCount > 0) {
361
- while (partIndex !== -1) {
362
- parts[partIndex].index += insertCount;
363
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
364
- }
365
- return;
366
- }
367
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
368
- }
369
- }
370
- }
371
-
372
- /**
373
- * @license
374
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
375
- * This code may only be used under the BSD style license found at
376
- * http://polymer.github.io/LICENSE.txt
377
- * The complete set of authors may be found at
378
- * http://polymer.github.io/AUTHORS.txt
379
- * The complete set of contributors may be found at
380
- * http://polymer.github.io/CONTRIBUTORS.txt
381
- * Code distributed by Google as part of the polymer project is also
382
- * subject to an additional IP rights grant found at
383
- * http://polymer.github.io/PATENTS.txt
384
- */
385
- const directives = new WeakMap();
386
- const isDirective = (o) => {
387
- return typeof o === 'function' && directives.has(o);
388
- };
389
-
390
- /**
391
- * @license
392
- * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
393
- * This code may only be used under the BSD style license found at
394
- * http://polymer.github.io/LICENSE.txt
395
- * The complete set of authors may be found at
396
- * http://polymer.github.io/AUTHORS.txt
397
- * The complete set of contributors may be found at
398
- * http://polymer.github.io/CONTRIBUTORS.txt
399
- * Code distributed by Google as part of the polymer project is also
400
- * subject to an additional IP rights grant found at
401
- * http://polymer.github.io/PATENTS.txt
402
- */
403
- /**
404
- * A sentinel value that signals that a value was handled by a directive and
405
- * should not be written to the DOM.
406
- */
407
- const noChange = {};
408
- /**
409
- * A sentinel value that signals a NodePart to fully clear its content.
410
- */
411
- const nothing = {};
412
-
413
- /**
414
- * @license
415
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
416
- * This code may only be used under the BSD style license found at
417
- * http://polymer.github.io/LICENSE.txt
418
- * The complete set of authors may be found at
419
- * http://polymer.github.io/AUTHORS.txt
420
- * The complete set of contributors may be found at
421
- * http://polymer.github.io/CONTRIBUTORS.txt
422
- * Code distributed by Google as part of the polymer project is also
423
- * subject to an additional IP rights grant found at
424
- * http://polymer.github.io/PATENTS.txt
425
- */
426
- /**
427
- * An instance of a `Template` that can be attached to the DOM and updated
428
- * with new values.
429
- */
430
- class TemplateInstance {
431
- constructor(template, processor, options) {
432
- this.__parts = [];
433
- this.template = template;
434
- this.processor = processor;
435
- this.options = options;
436
- }
437
- update(values) {
438
- let i = 0;
439
- for (const part of this.__parts) {
440
- if (part !== undefined) {
441
- part.setValue(values[i]);
442
- }
443
- i++;
444
- }
445
- for (const part of this.__parts) {
446
- if (part !== undefined) {
447
- part.commit();
448
- }
449
- }
450
- }
451
- _clone() {
452
- // There are a number of steps in the lifecycle of a template instance's
453
- // DOM fragment:
454
- // 1. Clone - create the instance fragment
455
- // 2. Adopt - adopt into the main document
456
- // 3. Process - find part markers and create parts
457
- // 4. Upgrade - upgrade custom elements
458
- // 5. Update - set node, attribute, property, etc., values
459
- // 6. Connect - connect to the document. Optional and outside of this
460
- // method.
461
- //
462
- // We have a few constraints on the ordering of these steps:
463
- // * We need to upgrade before updating, so that property values will pass
464
- // through any property setters.
465
- // * We would like to process before upgrading so that we're sure that the
466
- // cloned fragment is inert and not disturbed by self-modifying DOM.
467
- // * We want custom elements to upgrade even in disconnected fragments.
468
- //
469
- // Given these constraints, with full custom elements support we would
470
- // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect
471
- //
472
- // But Safari does not implement CustomElementRegistry#upgrade, so we
473
- // can not implement that order and still have upgrade-before-update and
474
- // upgrade disconnected fragments. So we instead sacrifice the
475
- // process-before-upgrade constraint, since in Custom Elements v1 elements
476
- // must not modify their light DOM in the constructor. We still have issues
477
- // when co-existing with CEv0 elements like Polymer 1, and with polyfills
478
- // that don't strictly adhere to the no-modification rule because shadow
479
- // DOM, which may be created in the constructor, is emulated by being placed
480
- // in the light DOM.
481
- //
482
- // The resulting order is on native is: Clone, Adopt, Upgrade, Process,
483
- // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade
484
- // in one step.
485
- //
486
- // The Custom Elements v1 polyfill supports upgrade(), so the order when
487
- // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,
488
- // Connect.
489
- const fragment = isCEPolyfill ?
490
- this.template.element.content.cloneNode(true) :
491
- document.importNode(this.template.element.content, true);
492
- const stack = [];
493
- const parts = this.template.parts;
494
- // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
495
- const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
496
- let partIndex = 0;
497
- let nodeIndex = 0;
498
- let part;
499
- let node = walker.nextNode();
500
- // Loop through all the nodes and parts of a template
501
- while (partIndex < parts.length) {
502
- part = parts[partIndex];
503
- if (!isTemplatePartActive(part)) {
504
- this.__parts.push(undefined);
505
- partIndex++;
506
- continue;
507
- }
508
- // Progress the tree walker until we find our next part's node.
509
- // Note that multiple parts may share the same node (attribute parts
510
- // on a single element), so this loop may not run at all.
511
- while (nodeIndex < part.index) {
512
- nodeIndex++;
513
- if (node.nodeName === 'TEMPLATE') {
514
- stack.push(node);
515
- walker.currentNode = node.content;
516
- }
517
- if ((node = walker.nextNode()) === null) {
518
- // We've exhausted the content inside a nested template element.
519
- // Because we still have parts (the outer for-loop), we know:
520
- // - There is a template in the stack
521
- // - The walker will find a nextNode outside the template
522
- walker.currentNode = stack.pop();
523
- node = walker.nextNode();
524
- }
525
- }
526
- // We've arrived at our part's node.
527
- if (part.type === 'node') {
528
- const part = this.processor.handleTextExpression(this.options);
529
- part.insertAfterNode(node.previousSibling);
530
- this.__parts.push(part);
531
- }
532
- else {
533
- this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));
534
- }
535
- partIndex++;
536
- }
537
- if (isCEPolyfill) {
538
- document.adoptNode(fragment);
539
- customElements.upgrade(fragment);
540
- }
541
- return fragment;
542
- }
543
- }
544
-
545
- /**
546
- * @license
547
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
548
- * This code may only be used under the BSD style license found at
549
- * http://polymer.github.io/LICENSE.txt
550
- * The complete set of authors may be found at
551
- * http://polymer.github.io/AUTHORS.txt
552
- * The complete set of contributors may be found at
553
- * http://polymer.github.io/CONTRIBUTORS.txt
554
- * Code distributed by Google as part of the polymer project is also
555
- * subject to an additional IP rights grant found at
556
- * http://polymer.github.io/PATENTS.txt
557
- */
558
- /**
559
- * Our TrustedTypePolicy for HTML which is declared using the html template
560
- * tag function.
561
- *
562
- * That HTML is a developer-authored constant, and is parsed with innerHTML
563
- * before any untrusted expressions have been mixed in. Therefor it is
564
- * considered safe by construction.
565
- */
566
- const policy = window.trustedTypes &&
567
- trustedTypes.createPolicy('lit-html', { createHTML: (s) => s });
568
- const commentMarker = ` ${marker} `;
569
- /**
570
- * The return type of `html`, which holds a Template and the values from
571
- * interpolated expressions.
572
- */
573
- class TemplateResult {
574
- constructor(strings, values, type, processor) {
575
- this.strings = strings;
576
- this.values = values;
577
- this.type = type;
578
- this.processor = processor;
579
- }
580
- /**
581
- * Returns a string of HTML used to create a `<template>` element.
582
- */
583
- getHTML() {
584
- const l = this.strings.length - 1;
585
- let html = '';
586
- let isCommentBinding = false;
587
- for (let i = 0; i < l; i++) {
588
- const s = this.strings[i];
589
- // For each binding we want to determine the kind of marker to insert
590
- // into the template source before it's parsed by the browser's HTML
591
- // parser. The marker type is based on whether the expression is in an
592
- // attribute, text, or comment position.
593
- // * For node-position bindings we insert a comment with the marker
594
- // sentinel as its text content, like <!--{{lit-guid}}-->.
595
- // * For attribute bindings we insert just the marker sentinel for the
596
- // first binding, so that we support unquoted attribute bindings.
597
- // Subsequent bindings can use a comment marker because multi-binding
598
- // attributes must be quoted.
599
- // * For comment bindings we insert just the marker sentinel so we don't
600
- // close the comment.
601
- //
602
- // The following code scans the template source, but is *not* an HTML
603
- // parser. We don't need to track the tree structure of the HTML, only
604
- // whether a binding is inside a comment, and if not, if it appears to be
605
- // the first binding in an attribute.
606
- const commentOpen = s.lastIndexOf('<!--');
607
- // We're in comment position if we have a comment open with no following
608
- // comment close. Because <-- can appear in an attribute value there can
609
- // be false positives.
610
- isCommentBinding = (commentOpen > -1 || isCommentBinding) &&
611
- s.indexOf('-->', commentOpen + 1) === -1;
612
- // Check to see if we have an attribute-like sequence preceding the
613
- // expression. This can match "name=value" like structures in text,
614
- // comments, and attribute values, so there can be false-positives.
615
- const attributeMatch = lastAttributeNameRegex.exec(s);
616
- if (attributeMatch === null) {
617
- // We're only in this branch if we don't have a attribute-like
618
- // preceding sequence. For comments, this guards against unusual
619
- // attribute values like <div foo="<!--${'bar'}">. Cases like
620
- // <!-- foo=${'bar'}--> are handled correctly in the attribute branch
621
- // below.
622
- html += s + (isCommentBinding ? commentMarker : nodeMarker);
623
- }
624
- else {
625
- // For attributes we use just a marker sentinel, and also append a
626
- // $lit$ suffix to the name to opt-out of attribute-specific parsing
627
- // that IE and Edge do for style and certain SVG attributes.
628
- html += s.substr(0, attributeMatch.index) + attributeMatch[1] +
629
- attributeMatch[2] + boundAttributeSuffix + attributeMatch[3] +
630
- marker;
631
- }
632
- }
633
- html += this.strings[l];
634
- return html;
635
- }
636
- getTemplateElement() {
637
- const template = document.createElement('template');
638
- let value = this.getHTML();
639
- if (policy !== undefined) {
640
- // this is secure because `this.strings` is a TemplateStringsArray.
641
- // TODO: validate this when
642
- // https://github.com/tc39/proposal-array-is-template-object is
643
- // implemented.
644
- value = policy.createHTML(value);
645
- }
646
- template.innerHTML = value;
647
- return template;
648
- }
649
- }
650
-
651
- /**
652
- * @license
653
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
654
- * This code may only be used under the BSD style license found at
655
- * http://polymer.github.io/LICENSE.txt
656
- * The complete set of authors may be found at
657
- * http://polymer.github.io/AUTHORS.txt
658
- * The complete set of contributors may be found at
659
- * http://polymer.github.io/CONTRIBUTORS.txt
660
- * Code distributed by Google as part of the polymer project is also
661
- * subject to an additional IP rights grant found at
662
- * http://polymer.github.io/PATENTS.txt
663
- */
664
- const isPrimitive = (value) => {
665
- return (value === null ||
666
- !(typeof value === 'object' || typeof value === 'function'));
667
- };
668
- const isIterable = (value) => {
669
- return Array.isArray(value) ||
670
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
671
- !!(value && value[Symbol.iterator]);
672
- };
673
- /**
674
- * Writes attribute values to the DOM for a group of AttributeParts bound to a
675
- * single attribute. The value is only set once even if there are multiple parts
676
- * for an attribute.
677
- */
678
- class AttributeCommitter {
679
- constructor(element, name, strings) {
680
- this.dirty = true;
681
- this.element = element;
682
- this.name = name;
683
- this.strings = strings;
684
- this.parts = [];
685
- for (let i = 0; i < strings.length - 1; i++) {
686
- this.parts[i] = this._createPart();
687
- }
688
- }
689
- /**
690
- * Creates a single part. Override this to create a differnt type of part.
691
- */
692
- _createPart() {
693
- return new AttributePart(this);
694
- }
695
- _getValue() {
696
- const strings = this.strings;
697
- const l = strings.length - 1;
698
- const parts = this.parts;
699
- // If we're assigning an attribute via syntax like:
700
- // attr="${foo}" or attr=${foo}
701
- // but not
702
- // attr="${foo} ${bar}" or attr="${foo} baz"
703
- // then we don't want to coerce the attribute value into one long
704
- // string. Instead we want to just return the value itself directly,
705
- // so that sanitizeDOMValue can get the actual value rather than
706
- // String(value)
707
- // The exception is if v is an array, in which case we do want to smash
708
- // it together into a string without calling String() on the array.
709
- //
710
- // This also allows trusted values (when using TrustedTypes) being
711
- // assigned to DOM sinks without being stringified in the process.
712
- if (l === 1 && strings[0] === '' && strings[1] === '') {
713
- const v = parts[0].value;
714
- if (typeof v === 'symbol') {
715
- return String(v);
716
- }
717
- if (typeof v === 'string' || !isIterable(v)) {
718
- return v;
719
- }
720
- }
721
- let text = '';
722
- for (let i = 0; i < l; i++) {
723
- text += strings[i];
724
- const part = parts[i];
725
- if (part !== undefined) {
726
- const v = part.value;
727
- if (isPrimitive(v) || !isIterable(v)) {
728
- text += typeof v === 'string' ? v : String(v);
729
- }
730
- else {
731
- for (const t of v) {
732
- text += typeof t === 'string' ? t : String(t);
733
- }
734
- }
735
- }
736
- }
737
- text += strings[l];
738
- return text;
739
- }
740
- commit() {
741
- if (this.dirty) {
742
- this.dirty = false;
743
- this.element.setAttribute(this.name, this._getValue());
744
- }
745
- }
746
- }
747
- /**
748
- * A Part that controls all or part of an attribute value.
749
- */
750
- class AttributePart {
751
- constructor(committer) {
752
- this.value = undefined;
753
- this.committer = committer;
754
- }
755
- setValue(value) {
756
- if (value !== noChange && (!isPrimitive(value) || value !== this.value)) {
757
- this.value = value;
758
- // If the value is a not a directive, dirty the committer so that it'll
759
- // call setAttribute. If the value is a directive, it'll dirty the
760
- // committer if it calls setValue().
761
- if (!isDirective(value)) {
762
- this.committer.dirty = true;
763
- }
764
- }
765
- }
766
- commit() {
767
- while (isDirective(this.value)) {
768
- const directive = this.value;
769
- this.value = noChange;
770
- directive(this);
771
- }
772
- if (this.value === noChange) {
773
- return;
774
- }
775
- this.committer.commit();
776
- }
777
- }
778
- /**
779
- * A Part that controls a location within a Node tree. Like a Range, NodePart
780
- * has start and end locations and can set and update the Nodes between those
781
- * locations.
782
- *
783
- * NodeParts support several value types: primitives, Nodes, TemplateResults,
784
- * as well as arrays and iterables of those types.
785
- */
786
- class NodePart {
787
- constructor(options) {
788
- this.value = undefined;
789
- this.__pendingValue = undefined;
790
- this.options = options;
791
- }
792
- /**
793
- * Appends this part into a container.
794
- *
795
- * This part must be empty, as its contents are not automatically moved.
796
- */
797
- appendInto(container) {
798
- this.startNode = container.appendChild(createMarker());
799
- this.endNode = container.appendChild(createMarker());
800
- }
801
- /**
802
- * Inserts this part after the `ref` node (between `ref` and `ref`'s next
803
- * sibling). Both `ref` and its next sibling must be static, unchanging nodes
804
- * such as those that appear in a literal section of a template.
805
- *
806
- * This part must be empty, as its contents are not automatically moved.
807
- */
808
- insertAfterNode(ref) {
809
- this.startNode = ref;
810
- this.endNode = ref.nextSibling;
811
- }
812
- /**
813
- * Appends this part into a parent part.
814
- *
815
- * This part must be empty, as its contents are not automatically moved.
816
- */
817
- appendIntoPart(part) {
818
- part.__insert(this.startNode = createMarker());
819
- part.__insert(this.endNode = createMarker());
820
- }
821
- /**
822
- * Inserts this part after the `ref` part.
823
- *
824
- * This part must be empty, as its contents are not automatically moved.
825
- */
826
- insertAfterPart(ref) {
827
- ref.__insert(this.startNode = createMarker());
828
- this.endNode = ref.endNode;
829
- ref.endNode = this.startNode;
830
- }
831
- setValue(value) {
832
- this.__pendingValue = value;
833
- }
834
- commit() {
835
- if (this.startNode.parentNode === null) {
836
- return;
837
- }
838
- while (isDirective(this.__pendingValue)) {
839
- const directive = this.__pendingValue;
840
- this.__pendingValue = noChange;
841
- directive(this);
842
- }
843
- const value = this.__pendingValue;
844
- if (value === noChange) {
845
- return;
846
- }
847
- if (isPrimitive(value)) {
848
- if (value !== this.value) {
849
- this.__commitText(value);
850
- }
851
- }
852
- else if (value instanceof TemplateResult) {
853
- this.__commitTemplateResult(value);
854
- }
855
- else if (value instanceof Node) {
856
- this.__commitNode(value);
857
- }
858
- else if (isIterable(value)) {
859
- this.__commitIterable(value);
860
- }
861
- else if (value === nothing) {
862
- this.value = nothing;
863
- this.clear();
864
- }
865
- else {
866
- // Fallback, will render the string representation
867
- this.__commitText(value);
868
- }
869
- }
870
- __insert(node) {
871
- this.endNode.parentNode.insertBefore(node, this.endNode);
872
- }
873
- __commitNode(value) {
874
- if (this.value === value) {
875
- return;
876
- }
877
- this.clear();
878
- this.__insert(value);
879
- this.value = value;
880
- }
881
- __commitText(value) {
882
- const node = this.startNode.nextSibling;
883
- value = value == null ? '' : value;
884
- // If `value` isn't already a string, we explicitly convert it here in case
885
- // it can't be implicitly converted - i.e. it's a symbol.
886
- const valueAsString = typeof value === 'string' ? value : String(value);
887
- if (node === this.endNode.previousSibling &&
888
- node.nodeType === 3 /* Node.TEXT_NODE */) {
889
- // If we only have a single text node between the markers, we can just
890
- // set its value, rather than replacing it.
891
- // TODO(justinfagnani): Can we just check if this.value is primitive?
892
- node.data = valueAsString;
893
- }
894
- else {
895
- this.__commitNode(document.createTextNode(valueAsString));
896
- }
897
- this.value = value;
898
- }
899
- __commitTemplateResult(value) {
900
- const template = this.options.templateFactory(value);
901
- if (this.value instanceof TemplateInstance &&
902
- this.value.template === template) {
903
- this.value.update(value.values);
904
- }
905
- else {
906
- // Make sure we propagate the template processor from the TemplateResult
907
- // so that we use its syntax extension, etc. The template factory comes
908
- // from the render function options so that it can control template
909
- // caching and preprocessing.
910
- const instance = new TemplateInstance(template, value.processor, this.options);
911
- const fragment = instance._clone();
912
- instance.update(value.values);
913
- this.__commitNode(fragment);
914
- this.value = instance;
915
- }
916
- }
917
- __commitIterable(value) {
918
- // For an Iterable, we create a new InstancePart per item, then set its
919
- // value to the item. This is a little bit of overhead for every item in
920
- // an Iterable, but it lets us recurse easily and efficiently update Arrays
921
- // of TemplateResults that will be commonly returned from expressions like:
922
- // array.map((i) => html`${i}`), by reusing existing TemplateInstances.
923
- // If _value is an array, then the previous render was of an
924
- // iterable and _value will contain the NodeParts from the previous
925
- // render. If _value is not an array, clear this part and make a new
926
- // array for NodeParts.
927
- if (!Array.isArray(this.value)) {
928
- this.value = [];
929
- this.clear();
930
- }
931
- // Lets us keep track of how many items we stamped so we can clear leftover
932
- // items from a previous render
933
- const itemParts = this.value;
934
- let partIndex = 0;
935
- let itemPart;
936
- for (const item of value) {
937
- // Try to reuse an existing part
938
- itemPart = itemParts[partIndex];
939
- // If no existing part, create a new one
940
- if (itemPart === undefined) {
941
- itemPart = new NodePart(this.options);
942
- itemParts.push(itemPart);
943
- if (partIndex === 0) {
944
- itemPart.appendIntoPart(this);
945
- }
946
- else {
947
- itemPart.insertAfterPart(itemParts[partIndex - 1]);
948
- }
949
- }
950
- itemPart.setValue(item);
951
- itemPart.commit();
952
- partIndex++;
953
- }
954
- if (partIndex < itemParts.length) {
955
- // Truncate the parts array so _value reflects the current state
956
- itemParts.length = partIndex;
957
- this.clear(itemPart && itemPart.endNode);
958
- }
959
- }
960
- clear(startNode = this.startNode) {
961
- removeNodes(this.startNode.parentNode, startNode.nextSibling, this.endNode);
962
- }
963
- }
964
- /**
965
- * Implements a boolean attribute, roughly as defined in the HTML
966
- * specification.
967
- *
968
- * If the value is truthy, then the attribute is present with a value of
969
- * ''. If the value is falsey, the attribute is removed.
970
- */
971
- class BooleanAttributePart {
972
- constructor(element, name, strings) {
973
- this.value = undefined;
974
- this.__pendingValue = undefined;
975
- if (strings.length !== 2 || strings[0] !== '' || strings[1] !== '') {
976
- throw new Error('Boolean attributes can only contain a single expression');
977
- }
978
- this.element = element;
979
- this.name = name;
980
- this.strings = strings;
981
- }
982
- setValue(value) {
983
- this.__pendingValue = value;
984
- }
985
- commit() {
986
- while (isDirective(this.__pendingValue)) {
987
- const directive = this.__pendingValue;
988
- this.__pendingValue = noChange;
989
- directive(this);
990
- }
991
- if (this.__pendingValue === noChange) {
992
- return;
993
- }
994
- const value = !!this.__pendingValue;
995
- if (this.value !== value) {
996
- if (value) {
997
- this.element.setAttribute(this.name, '');
998
- }
999
- else {
1000
- this.element.removeAttribute(this.name);
1001
- }
1002
- this.value = value;
1003
- }
1004
- this.__pendingValue = noChange;
1005
- }
1006
- }
1007
- /**
1008
- * Sets attribute values for PropertyParts, so that the value is only set once
1009
- * even if there are multiple parts for a property.
1010
- *
1011
- * If an expression controls the whole property value, then the value is simply
1012
- * assigned to the property under control. If there are string literals or
1013
- * multiple expressions, then the strings are expressions are interpolated into
1014
- * a string first.
1015
- */
1016
- class PropertyCommitter extends AttributeCommitter {
1017
- constructor(element, name, strings) {
1018
- super(element, name, strings);
1019
- this.single =
1020
- (strings.length === 2 && strings[0] === '' && strings[1] === '');
1021
- }
1022
- _createPart() {
1023
- return new PropertyPart(this);
1024
- }
1025
- _getValue() {
1026
- if (this.single) {
1027
- return this.parts[0].value;
1028
- }
1029
- return super._getValue();
1030
- }
1031
- commit() {
1032
- if (this.dirty) {
1033
- this.dirty = false;
1034
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1035
- this.element[this.name] = this._getValue();
1036
- }
1037
- }
1038
- }
1039
- class PropertyPart extends AttributePart {
1040
- }
1041
- // Detect event listener options support. If the `capture` property is read
1042
- // from the options object, then options are supported. If not, then the third
1043
- // argument to add/removeEventListener is interpreted as the boolean capture
1044
- // value so we should only pass the `capture` property.
1045
- let eventOptionsSupported = false;
1046
- // Wrap into an IIFE because MS Edge <= v41 does not support having try/catch
1047
- // blocks right into the body of a module
1048
- (() => {
1049
- try {
1050
- const options = {
1051
- get capture() {
1052
- eventOptionsSupported = true;
1053
- return false;
1054
- }
1055
- };
1056
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1057
- window.addEventListener('test', options, options);
1058
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1059
- window.removeEventListener('test', options, options);
1060
- }
1061
- catch (_e) {
1062
- // event options not supported
1063
- }
1064
- })();
1065
- class EventPart {
1066
- constructor(element, eventName, eventContext) {
1067
- this.value = undefined;
1068
- this.__pendingValue = undefined;
1069
- this.element = element;
1070
- this.eventName = eventName;
1071
- this.eventContext = eventContext;
1072
- this.__boundHandleEvent = (e) => this.handleEvent(e);
1073
- }
1074
- setValue(value) {
1075
- this.__pendingValue = value;
1076
- }
1077
- commit() {
1078
- while (isDirective(this.__pendingValue)) {
1079
- const directive = this.__pendingValue;
1080
- this.__pendingValue = noChange;
1081
- directive(this);
1082
- }
1083
- if (this.__pendingValue === noChange) {
1084
- return;
1085
- }
1086
- const newListener = this.__pendingValue;
1087
- const oldListener = this.value;
1088
- const shouldRemoveListener = newListener == null ||
1089
- oldListener != null &&
1090
- (newListener.capture !== oldListener.capture ||
1091
- newListener.once !== oldListener.once ||
1092
- newListener.passive !== oldListener.passive);
1093
- const shouldAddListener = newListener != null && (oldListener == null || shouldRemoveListener);
1094
- if (shouldRemoveListener) {
1095
- this.element.removeEventListener(this.eventName, this.__boundHandleEvent, this.__options);
1096
- }
1097
- if (shouldAddListener) {
1098
- this.__options = getOptions(newListener);
1099
- this.element.addEventListener(this.eventName, this.__boundHandleEvent, this.__options);
1100
- }
1101
- this.value = newListener;
1102
- this.__pendingValue = noChange;
1103
- }
1104
- handleEvent(event) {
1105
- if (typeof this.value === 'function') {
1106
- this.value.call(this.eventContext || this.element, event);
1107
- }
1108
- else {
1109
- this.value.handleEvent(event);
1110
- }
1111
- }
1112
- }
1113
- // We copy options because of the inconsistent behavior of browsers when reading
1114
- // the third argument of add/removeEventListener. IE11 doesn't support options
1115
- // at all. Chrome 41 only reads `capture` if the argument is an object.
1116
- const getOptions = (o) => o &&
1117
- (eventOptionsSupported ?
1118
- { capture: o.capture, passive: o.passive, once: o.once } :
1119
- o.capture);
1120
-
1121
- /**
1122
- * @license
1123
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1124
- * This code may only be used under the BSD style license found at
1125
- * http://polymer.github.io/LICENSE.txt
1126
- * The complete set of authors may be found at
1127
- * http://polymer.github.io/AUTHORS.txt
1128
- * The complete set of contributors may be found at
1129
- * http://polymer.github.io/CONTRIBUTORS.txt
1130
- * Code distributed by Google as part of the polymer project is also
1131
- * subject to an additional IP rights grant found at
1132
- * http://polymer.github.io/PATENTS.txt
1133
- */
1134
- /**
1135
- * The default TemplateFactory which caches Templates keyed on
1136
- * result.type and result.strings.
1137
- */
1138
- function templateFactory(result) {
1139
- let templateCache = templateCaches.get(result.type);
1140
- if (templateCache === undefined) {
1141
- templateCache = {
1142
- stringsArray: new WeakMap(),
1143
- keyString: new Map()
1144
- };
1145
- templateCaches.set(result.type, templateCache);
1146
- }
1147
- let template = templateCache.stringsArray.get(result.strings);
1148
- if (template !== undefined) {
1149
- return template;
1150
- }
1151
- // If the TemplateStringsArray is new, generate a key from the strings
1152
- // This key is shared between all templates with identical content
1153
- const key = result.strings.join(marker);
1154
- // Check if we already have a Template for this key
1155
- template = templateCache.keyString.get(key);
1156
- if (template === undefined) {
1157
- // If we have not seen this key before, create a new Template
1158
- template = new Template(result, result.getTemplateElement());
1159
- // Cache the Template for this key
1160
- templateCache.keyString.set(key, template);
1161
- }
1162
- // Cache all future queries for this TemplateStringsArray
1163
- templateCache.stringsArray.set(result.strings, template);
1164
- return template;
1165
- }
1166
- const templateCaches = new Map();
1167
-
1168
- /**
1169
- * @license
1170
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1171
- * This code may only be used under the BSD style license found at
1172
- * http://polymer.github.io/LICENSE.txt
1173
- * The complete set of authors may be found at
1174
- * http://polymer.github.io/AUTHORS.txt
1175
- * The complete set of contributors may be found at
1176
- * http://polymer.github.io/CONTRIBUTORS.txt
1177
- * Code distributed by Google as part of the polymer project is also
1178
- * subject to an additional IP rights grant found at
1179
- * http://polymer.github.io/PATENTS.txt
1180
- */
1181
- const parts = new WeakMap();
1182
- /**
1183
- * Renders a template result or other value to a container.
1184
- *
1185
- * To update a container with new values, reevaluate the template literal and
1186
- * call `render` with the new result.
1187
- *
1188
- * @param result Any value renderable by NodePart - typically a TemplateResult
1189
- * created by evaluating a template tag like `html` or `svg`.
1190
- * @param container A DOM parent to render to. The entire contents are either
1191
- * replaced, or efficiently updated if the same result type was previous
1192
- * rendered there.
1193
- * @param options RenderOptions for the entire render tree rendered to this
1194
- * container. Render options must *not* change between renders to the same
1195
- * container, as those changes will not effect previously rendered DOM.
1196
- */
1197
- const render = (result, container, options) => {
1198
- let part = parts.get(container);
1199
- if (part === undefined) {
1200
- removeNodes(container, container.firstChild);
1201
- parts.set(container, part = new NodePart(Object.assign({ templateFactory }, options)));
1202
- part.appendInto(container);
1203
- }
1204
- part.setValue(result);
1205
- part.commit();
1206
- };
1207
-
1208
- /**
1209
- * @license
1210
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1211
- * This code may only be used under the BSD style license found at
1212
- * http://polymer.github.io/LICENSE.txt
1213
- * The complete set of authors may be found at
1214
- * http://polymer.github.io/AUTHORS.txt
1215
- * The complete set of contributors may be found at
1216
- * http://polymer.github.io/CONTRIBUTORS.txt
1217
- * Code distributed by Google as part of the polymer project is also
1218
- * subject to an additional IP rights grant found at
1219
- * http://polymer.github.io/PATENTS.txt
1220
- */
1221
- /**
1222
- * Creates Parts when a template is instantiated.
1223
- */
1224
- class DefaultTemplateProcessor {
1225
- /**
1226
- * Create parts for an attribute-position binding, given the event, attribute
1227
- * name, and string literals.
1228
- *
1229
- * @param element The element containing the binding
1230
- * @param name The attribute name
1231
- * @param strings The string literals. There are always at least two strings,
1232
- * event for fully-controlled bindings with a single expression.
1233
- */
1234
- handleAttributeExpressions(element, name, strings, options) {
1235
- const prefix = name[0];
1236
- if (prefix === '.') {
1237
- const committer = new PropertyCommitter(element, name.slice(1), strings);
1238
- return committer.parts;
1239
- }
1240
- if (prefix === '@') {
1241
- return [new EventPart(element, name.slice(1), options.eventContext)];
1242
- }
1243
- if (prefix === '?') {
1244
- return [new BooleanAttributePart(element, name.slice(1), strings)];
1245
- }
1246
- const committer = new AttributeCommitter(element, name, strings);
1247
- return committer.parts;
1248
- }
1249
- /**
1250
- * Create parts for a text-position binding.
1251
- * @param templateFactory
1252
- */
1253
- handleTextExpression(options) {
1254
- return new NodePart(options);
1255
- }
1256
- }
1257
- const defaultTemplateProcessor = new DefaultTemplateProcessor();
1258
-
1259
- /**
1260
- * @license
1261
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1262
- * This code may only be used under the BSD style license found at
1263
- * http://polymer.github.io/LICENSE.txt
1264
- * The complete set of authors may be found at
1265
- * http://polymer.github.io/AUTHORS.txt
1266
- * The complete set of contributors may be found at
1267
- * http://polymer.github.io/CONTRIBUTORS.txt
1268
- * Code distributed by Google as part of the polymer project is also
1269
- * subject to an additional IP rights grant found at
1270
- * http://polymer.github.io/PATENTS.txt
1271
- */
1272
- // IMPORTANT: do not change the property name or the assignment expression.
1273
- // This line will be used in regexes to search for lit-html usage.
1274
- // TODO(justinfagnani): inject version number at build time
1275
- if (typeof window !== 'undefined') {
1276
- (window['litHtmlVersions'] || (window['litHtmlVersions'] = [])).push('1.3.0');
1277
- }
1278
- /**
1279
- * Interprets a template literal as an HTML template that can efficiently
1280
- * render to and update a container.
1281
- */
1282
- const html = (strings, ...values) => new TemplateResult(strings, values, 'html', defaultTemplateProcessor);
1283
-
1284
- /**
1285
- * @license
1286
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1287
- * This code may only be used under the BSD style license found at
1288
- * http://polymer.github.io/LICENSE.txt
1289
- * The complete set of authors may be found at
1290
- * http://polymer.github.io/AUTHORS.txt
1291
- * The complete set of contributors may be found at
1292
- * http://polymer.github.io/CONTRIBUTORS.txt
1293
- * Code distributed by Google as part of the polymer project is also
1294
- * subject to an additional IP rights grant found at
1295
- * http://polymer.github.io/PATENTS.txt
1296
- */
1297
- // Get a key to lookup in `templateCaches`.
1298
- const getTemplateCacheKey = (type, scopeName) => `${type}--${scopeName}`;
1299
- let compatibleShadyCSSVersion = true;
1300
- if (typeof window.ShadyCSS === 'undefined') {
1301
- compatibleShadyCSSVersion = false;
1302
- }
1303
- else if (typeof window.ShadyCSS.prepareTemplateDom === 'undefined') {
1304
- console.warn(`Incompatible ShadyCSS version detected. ` +
1305
- `Please update to at least @webcomponents/webcomponentsjs@2.0.2 and ` +
1306
- `@webcomponents/shadycss@1.3.1.`);
1307
- compatibleShadyCSSVersion = false;
1308
- }
1309
- /**
1310
- * Template factory which scopes template DOM using ShadyCSS.
1311
- * @param scopeName {string}
1312
- */
1313
- const shadyTemplateFactory = (scopeName) => (result) => {
1314
- const cacheKey = getTemplateCacheKey(result.type, scopeName);
1315
- let templateCache = templateCaches.get(cacheKey);
1316
- if (templateCache === undefined) {
1317
- templateCache = {
1318
- stringsArray: new WeakMap(),
1319
- keyString: new Map()
1320
- };
1321
- templateCaches.set(cacheKey, templateCache);
1322
- }
1323
- let template = templateCache.stringsArray.get(result.strings);
1324
- if (template !== undefined) {
1325
- return template;
1326
- }
1327
- const key = result.strings.join(marker);
1328
- template = templateCache.keyString.get(key);
1329
- if (template === undefined) {
1330
- const element = result.getTemplateElement();
1331
- if (compatibleShadyCSSVersion) {
1332
- window.ShadyCSS.prepareTemplateDom(element, scopeName);
1333
- }
1334
- template = new Template(result, element);
1335
- templateCache.keyString.set(key, template);
1336
- }
1337
- templateCache.stringsArray.set(result.strings, template);
1338
- return template;
1339
- };
1340
- const TEMPLATE_TYPES = ['html', 'svg'];
1341
- /**
1342
- * Removes all style elements from Templates for the given scopeName.
1343
- */
1344
- const removeStylesFromLitTemplates = (scopeName) => {
1345
- TEMPLATE_TYPES.forEach((type) => {
1346
- const templates = templateCaches.get(getTemplateCacheKey(type, scopeName));
1347
- if (templates !== undefined) {
1348
- templates.keyString.forEach((template) => {
1349
- const { element: { content } } = template;
1350
- // IE 11 doesn't support the iterable param Set constructor
1351
- const styles = new Set();
1352
- Array.from(content.querySelectorAll('style')).forEach((s) => {
1353
- styles.add(s);
1354
- });
1355
- removeNodesFromTemplate(template, styles);
1356
- });
1357
- }
1358
- });
1359
- };
1360
- const shadyRenderSet = new Set();
1361
- /**
1362
- * For the given scope name, ensures that ShadyCSS style scoping is performed.
1363
- * This is done just once per scope name so the fragment and template cannot
1364
- * be modified.
1365
- * (1) extracts styles from the rendered fragment and hands them to ShadyCSS
1366
- * to be scoped and appended to the document
1367
- * (2) removes style elements from all lit-html Templates for this scope name.
1368
- *
1369
- * Note, <style> elements can only be placed into templates for the
1370
- * initial rendering of the scope. If <style> elements are included in templates
1371
- * dynamically rendered to the scope (after the first scope render), they will
1372
- * not be scoped and the <style> will be left in the template and rendered
1373
- * output.
1374
- */
1375
- const prepareTemplateStyles = (scopeName, renderedDOM, template) => {
1376
- shadyRenderSet.add(scopeName);
1377
- // If `renderedDOM` is stamped from a Template, then we need to edit that
1378
- // Template's underlying template element. Otherwise, we create one here
1379
- // to give to ShadyCSS, which still requires one while scoping.
1380
- const templateElement = !!template ? template.element : document.createElement('template');
1381
- // Move styles out of rendered DOM and store.
1382
- const styles = renderedDOM.querySelectorAll('style');
1383
- const { length } = styles;
1384
- // If there are no styles, skip unnecessary work
1385
- if (length === 0) {
1386
- // Ensure prepareTemplateStyles is called to support adding
1387
- // styles via `prepareAdoptedCssText` since that requires that
1388
- // `prepareTemplateStyles` is called.
1389
- //
1390
- // ShadyCSS will only update styles containing @apply in the template
1391
- // given to `prepareTemplateStyles`. If no lit Template was given,
1392
- // ShadyCSS will not be able to update uses of @apply in any relevant
1393
- // template. However, this is not a problem because we only create the
1394
- // template for the purpose of supporting `prepareAdoptedCssText`,
1395
- // which doesn't support @apply at all.
1396
- window.ShadyCSS.prepareTemplateStyles(templateElement, scopeName);
1397
- return;
1398
- }
1399
- const condensedStyle = document.createElement('style');
1400
- // Collect styles into a single style. This helps us make sure ShadyCSS
1401
- // manipulations will not prevent us from being able to fix up template
1402
- // part indices.
1403
- // NOTE: collecting styles is inefficient for browsers but ShadyCSS
1404
- // currently does this anyway. When it does not, this should be changed.
1405
- for (let i = 0; i < length; i++) {
1406
- const style = styles[i];
1407
- style.parentNode.removeChild(style);
1408
- condensedStyle.textContent += style.textContent;
1409
- }
1410
- // Remove styles from nested templates in this scope.
1411
- removeStylesFromLitTemplates(scopeName);
1412
- // And then put the condensed style into the "root" template passed in as
1413
- // `template`.
1414
- const content = templateElement.content;
1415
- if (!!template) {
1416
- insertNodeIntoTemplate(template, condensedStyle, content.firstChild);
1417
- }
1418
- else {
1419
- content.insertBefore(condensedStyle, content.firstChild);
1420
- }
1421
- // Note, it's important that ShadyCSS gets the template that `lit-html`
1422
- // will actually render so that it can update the style inside when
1423
- // needed (e.g. @apply native Shadow DOM case).
1424
- window.ShadyCSS.prepareTemplateStyles(templateElement, scopeName);
1425
- const style = content.querySelector('style');
1426
- if (window.ShadyCSS.nativeShadow && style !== null) {
1427
- // When in native Shadow DOM, ensure the style created by ShadyCSS is
1428
- // included in initially rendered output (`renderedDOM`).
1429
- renderedDOM.insertBefore(style.cloneNode(true), renderedDOM.firstChild);
1430
- }
1431
- else if (!!template) {
1432
- // When no style is left in the template, parts will be broken as a
1433
- // result. To fix this, we put back the style node ShadyCSS removed
1434
- // and then tell lit to remove that node from the template.
1435
- // There can be no style in the template in 2 cases (1) when Shady DOM
1436
- // is in use, ShadyCSS removes all styles, (2) when native Shadow DOM
1437
- // is in use ShadyCSS removes the style if it contains no content.
1438
- // NOTE, ShadyCSS creates its own style so we can safely add/remove
1439
- // `condensedStyle` here.
1440
- content.insertBefore(condensedStyle, content.firstChild);
1441
- const removes = new Set();
1442
- removes.add(condensedStyle);
1443
- removeNodesFromTemplate(template, removes);
1444
- }
1445
- };
1446
- /**
1447
- * Extension to the standard `render` method which supports rendering
1448
- * to ShadowRoots when the ShadyDOM (https://github.com/webcomponents/shadydom)
1449
- * and ShadyCSS (https://github.com/webcomponents/shadycss) polyfills are used
1450
- * or when the webcomponentsjs
1451
- * (https://github.com/webcomponents/webcomponentsjs) polyfill is used.
1452
- *
1453
- * Adds a `scopeName` option which is used to scope element DOM and stylesheets
1454
- * when native ShadowDOM is unavailable. The `scopeName` will be added to
1455
- * the class attribute of all rendered DOM. In addition, any style elements will
1456
- * be automatically re-written with this `scopeName` selector and moved out
1457
- * of the rendered DOM and into the document `<head>`.
1458
- *
1459
- * It is common to use this render method in conjunction with a custom element
1460
- * which renders a shadowRoot. When this is done, typically the element's
1461
- * `localName` should be used as the `scopeName`.
1462
- *
1463
- * In addition to DOM scoping, ShadyCSS also supports a basic shim for css
1464
- * custom properties (needed only on older browsers like IE11) and a shim for
1465
- * a deprecated feature called `@apply` that supports applying a set of css
1466
- * custom properties to a given location.
1467
- *
1468
- * Usage considerations:
1469
- *
1470
- * * Part values in `<style>` elements are only applied the first time a given
1471
- * `scopeName` renders. Subsequent changes to parts in style elements will have
1472
- * no effect. Because of this, parts in style elements should only be used for
1473
- * values that will never change, for example parts that set scope-wide theme
1474
- * values or parts which render shared style elements.
1475
- *
1476
- * * Note, due to a limitation of the ShadyDOM polyfill, rendering in a
1477
- * custom element's `constructor` is not supported. Instead rendering should
1478
- * either done asynchronously, for example at microtask timing (for example
1479
- * `Promise.resolve()`), or be deferred until the first time the element's
1480
- * `connectedCallback` runs.
1481
- *
1482
- * Usage considerations when using shimmed custom properties or `@apply`:
1483
- *
1484
- * * Whenever any dynamic changes are made which affect
1485
- * css custom properties, `ShadyCSS.styleElement(element)` must be called
1486
- * to update the element. There are two cases when this is needed:
1487
- * (1) the element is connected to a new parent, (2) a class is added to the
1488
- * element that causes it to match different custom properties.
1489
- * To address the first case when rendering a custom element, `styleElement`
1490
- * should be called in the element's `connectedCallback`.
1491
- *
1492
- * * Shimmed custom properties may only be defined either for an entire
1493
- * shadowRoot (for example, in a `:host` rule) or via a rule that directly
1494
- * matches an element with a shadowRoot. In other words, instead of flowing from
1495
- * parent to child as do native css custom properties, shimmed custom properties
1496
- * flow only from shadowRoots to nested shadowRoots.
1497
- *
1498
- * * When using `@apply` mixing css shorthand property names with
1499
- * non-shorthand names (for example `border` and `border-width`) is not
1500
- * supported.
1501
- */
1502
- const render$1 = (result, container, options) => {
1503
- if (!options || typeof options !== 'object' || !options.scopeName) {
1504
- throw new Error('The `scopeName` option is required.');
1505
- }
1506
- const scopeName = options.scopeName;
1507
- const hasRendered = parts.has(container);
1508
- const needsScoping = compatibleShadyCSSVersion &&
1509
- container.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */ &&
1510
- !!container.host;
1511
- // Handle first render to a scope specially...
1512
- const firstScopeRender = needsScoping && !shadyRenderSet.has(scopeName);
1513
- // On first scope render, render into a fragment; this cannot be a single
1514
- // fragment that is reused since nested renders can occur synchronously.
1515
- const renderContainer = firstScopeRender ? document.createDocumentFragment() : container;
1516
- render(result, renderContainer, Object.assign({ templateFactory: shadyTemplateFactory(scopeName) }, options));
1517
- // When performing first scope render,
1518
- // (1) We've rendered into a fragment so that there's a chance to
1519
- // `prepareTemplateStyles` before sub-elements hit the DOM
1520
- // (which might cause them to render based on a common pattern of
1521
- // rendering in a custom element's `connectedCallback`);
1522
- // (2) Scope the template with ShadyCSS one time only for this scope.
1523
- // (3) Render the fragment into the container and make sure the
1524
- // container knows its `part` is the one we just rendered. This ensures
1525
- // DOM will be re-used on subsequent renders.
1526
- if (firstScopeRender) {
1527
- const part = parts.get(renderContainer);
1528
- parts.delete(renderContainer);
1529
- // ShadyCSS might have style sheets (e.g. from `prepareAdoptedCssText`)
1530
- // that should apply to `renderContainer` even if the rendered value is
1531
- // not a TemplateInstance. However, it will only insert scoped styles
1532
- // into the document if `prepareTemplateStyles` has already been called
1533
- // for the given scope name.
1534
- const template = part.value instanceof TemplateInstance ?
1535
- part.value.template :
1536
- undefined;
1537
- prepareTemplateStyles(scopeName, renderContainer, template);
1538
- removeNodes(container, container.firstChild);
1539
- container.appendChild(renderContainer);
1540
- parts.set(container, part);
1541
- }
1542
- // After elements have hit the DOM, update styling if this is the
1543
- // initial render to this container.
1544
- // This is needed whenever dynamic changes are made so it would be
1545
- // safest to do every render; however, this would regress performance
1546
- // so we leave it up to the user to call `ShadyCSS.styleElement`
1547
- // for dynamic changes.
1548
- if (!hasRendered && needsScoping) {
1549
- window.ShadyCSS.styleElement(container.host);
1550
- }
1551
- };
1552
-
1553
- /**
1554
- * @license
1555
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
1556
- * This code may only be used under the BSD style license found at
1557
- * http://polymer.github.io/LICENSE.txt
1558
- * The complete set of authors may be found at
1559
- * http://polymer.github.io/AUTHORS.txt
1560
- * The complete set of contributors may be found at
1561
- * http://polymer.github.io/CONTRIBUTORS.txt
1562
- * Code distributed by Google as part of the polymer project is also
1563
- * subject to an additional IP rights grant found at
1564
- * http://polymer.github.io/PATENTS.txt
1565
- */
1566
- var _a;
1567
- /**
1568
- * Use this module if you want to create your own base class extending
1569
- * [[UpdatingElement]].
1570
- * @packageDocumentation
1571
- */
1572
- /*
1573
- * When using Closure Compiler, JSCompiler_renameProperty(property, object) is
1574
- * replaced at compile time by the munged name for object[property]. We cannot
1575
- * alias this function, so we have to use a small shim that has the same
1576
- * behavior when not compiling.
1577
- */
1578
- window.JSCompiler_renameProperty =
1579
- (prop, _obj) => prop;
1580
- const defaultConverter = {
1581
- toAttribute(value, type) {
1582
- switch (type) {
1583
- case Boolean:
1584
- return value ? '' : null;
1585
- case Object:
1586
- case Array:
1587
- // if the value is `null` or `undefined` pass this through
1588
- // to allow removing/no change behavior.
1589
- return value == null ? value : JSON.stringify(value);
1590
- }
1591
- return value;
1592
- },
1593
- fromAttribute(value, type) {
1594
- switch (type) {
1595
- case Boolean:
1596
- return value !== null;
1597
- case Number:
1598
- return value === null ? null : Number(value);
1599
- case Object:
1600
- case Array:
1601
- return JSON.parse(value);
1602
- }
1603
- return value;
1604
- }
1605
- };
1606
- /**
1607
- * Change function that returns true if `value` is different from `oldValue`.
1608
- * This method is used as the default for a property's `hasChanged` function.
1609
- */
1610
- const notEqual = (value, old) => {
1611
- // This ensures (old==NaN, value==NaN) always returns false
1612
- return old !== value && (old === old || value === value);
1613
- };
1614
- const defaultPropertyDeclaration = {
1615
- attribute: true,
1616
- type: String,
1617
- converter: defaultConverter,
1618
- reflect: false,
1619
- hasChanged: notEqual
1620
- };
1621
- const STATE_HAS_UPDATED = 1;
1622
- const STATE_UPDATE_REQUESTED = 1 << 2;
1623
- const STATE_IS_REFLECTING_TO_ATTRIBUTE = 1 << 3;
1624
- const STATE_IS_REFLECTING_TO_PROPERTY = 1 << 4;
1625
- /**
1626
- * The Closure JS Compiler doesn't currently have good support for static
1627
- * property semantics where "this" is dynamic (e.g.
1628
- * https://github.com/google/closure-compiler/issues/3177 and others) so we use
1629
- * this hack to bypass any rewriting by the compiler.
1630
- */
1631
- const finalized = 'finalized';
1632
- /**
1633
- * Base element class which manages element properties and attributes. When
1634
- * properties change, the `update` method is asynchronously called. This method
1635
- * should be supplied by subclassers to render updates as desired.
1636
- * @noInheritDoc
1637
- */
1638
- class UpdatingElement extends HTMLElement {
1639
- constructor() {
1640
- super();
1641
- this.initialize();
1642
- }
1643
- /**
1644
- * Returns a list of attributes corresponding to the registered properties.
1645
- * @nocollapse
1646
- */
1647
- static get observedAttributes() {
1648
- // note: piggy backing on this to ensure we're finalized.
1649
- this.finalize();
1650
- const attributes = [];
1651
- // Use forEach so this works even if for/of loops are compiled to for loops
1652
- // expecting arrays
1653
- this._classProperties.forEach((v, p) => {
1654
- const attr = this._attributeNameForProperty(p, v);
1655
- if (attr !== undefined) {
1656
- this._attributeToPropertyMap.set(attr, p);
1657
- attributes.push(attr);
1658
- }
1659
- });
1660
- return attributes;
1661
- }
1662
- /**
1663
- * Ensures the private `_classProperties` property metadata is created.
1664
- * In addition to `finalize` this is also called in `createProperty` to
1665
- * ensure the `@property` decorator can add property metadata.
1666
- */
1667
- /** @nocollapse */
1668
- static _ensureClassProperties() {
1669
- // ensure private storage for property declarations.
1670
- if (!this.hasOwnProperty(JSCompiler_renameProperty('_classProperties', this))) {
1671
- this._classProperties = new Map();
1672
- // NOTE: Workaround IE11 not supporting Map constructor argument.
1673
- const superProperties = Object.getPrototypeOf(this)._classProperties;
1674
- if (superProperties !== undefined) {
1675
- superProperties.forEach((v, k) => this._classProperties.set(k, v));
1676
- }
1677
- }
1678
- }
1679
- /**
1680
- * Creates a property accessor on the element prototype if one does not exist
1681
- * and stores a PropertyDeclaration for the property with the given options.
1682
- * The property setter calls the property's `hasChanged` property option
1683
- * or uses a strict identity check to determine whether or not to request
1684
- * an update.
1685
- *
1686
- * This method may be overridden to customize properties; however,
1687
- * when doing so, it's important to call `super.createProperty` to ensure
1688
- * the property is setup correctly. This method calls
1689
- * `getPropertyDescriptor` internally to get a descriptor to install.
1690
- * To customize what properties do when they are get or set, override
1691
- * `getPropertyDescriptor`. To customize the options for a property,
1692
- * implement `createProperty` like this:
1693
- *
1694
- * static createProperty(name, options) {
1695
- * options = Object.assign(options, {myOption: true});
1696
- * super.createProperty(name, options);
1697
- * }
1698
- *
1699
- * @nocollapse
1700
- */
1701
- static createProperty(name, options = defaultPropertyDeclaration) {
1702
- // Note, since this can be called by the `@property` decorator which
1703
- // is called before `finalize`, we ensure storage exists for property
1704
- // metadata.
1705
- this._ensureClassProperties();
1706
- this._classProperties.set(name, options);
1707
- // Do not generate an accessor if the prototype already has one, since
1708
- // it would be lost otherwise and that would never be the user's intention;
1709
- // Instead, we expect users to call `requestUpdate` themselves from
1710
- // user-defined accessors. Note that if the super has an accessor we will
1711
- // still overwrite it
1712
- if (options.noAccessor || this.prototype.hasOwnProperty(name)) {
1713
- return;
1714
- }
1715
- const key = typeof name === 'symbol' ? Symbol() : `__${name}`;
1716
- const descriptor = this.getPropertyDescriptor(name, key, options);
1717
- if (descriptor !== undefined) {
1718
- Object.defineProperty(this.prototype, name, descriptor);
1719
- }
1720
- }
1721
- /**
1722
- * Returns a property descriptor to be defined on the given named property.
1723
- * If no descriptor is returned, the property will not become an accessor.
1724
- * For example,
1725
- *
1726
- * class MyElement extends LitElement {
1727
- * static getPropertyDescriptor(name, key, options) {
1728
- * const defaultDescriptor =
1729
- * super.getPropertyDescriptor(name, key, options);
1730
- * const setter = defaultDescriptor.set;
1731
- * return {
1732
- * get: defaultDescriptor.get,
1733
- * set(value) {
1734
- * setter.call(this, value);
1735
- * // custom action.
1736
- * },
1737
- * configurable: true,
1738
- * enumerable: true
1739
- * }
1740
- * }
1741
- * }
1742
- *
1743
- * @nocollapse
1744
- */
1745
- static getPropertyDescriptor(name, key, options) {
1746
- return {
1747
- // tslint:disable-next-line:no-any no symbol in index
1748
- get() {
1749
- return this[key];
1750
- },
1751
- set(value) {
1752
- const oldValue = this[name];
1753
- this[key] = value;
1754
- this
1755
- .requestUpdateInternal(name, oldValue, options);
1756
- },
1757
- configurable: true,
1758
- enumerable: true
1759
- };
1760
- }
1761
- /**
1762
- * Returns the property options associated with the given property.
1763
- * These options are defined with a PropertyDeclaration via the `properties`
1764
- * object or the `@property` decorator and are registered in
1765
- * `createProperty(...)`.
1766
- *
1767
- * Note, this method should be considered "final" and not overridden. To
1768
- * customize the options for a given property, override `createProperty`.
1769
- *
1770
- * @nocollapse
1771
- * @final
1772
- */
1773
- static getPropertyOptions(name) {
1774
- return this._classProperties && this._classProperties.get(name) ||
1775
- defaultPropertyDeclaration;
1776
- }
1777
- /**
1778
- * Creates property accessors for registered properties and ensures
1779
- * any superclasses are also finalized.
1780
- * @nocollapse
1781
- */
1782
- static finalize() {
1783
- // finalize any superclasses
1784
- const superCtor = Object.getPrototypeOf(this);
1785
- if (!superCtor.hasOwnProperty(finalized)) {
1786
- superCtor.finalize();
1787
- }
1788
- this[finalized] = true;
1789
- this._ensureClassProperties();
1790
- // initialize Map populated in observedAttributes
1791
- this._attributeToPropertyMap = new Map();
1792
- // make any properties
1793
- // Note, only process "own" properties since this element will inherit
1794
- // any properties defined on the superClass, and finalization ensures
1795
- // the entire prototype chain is finalized.
1796
- if (this.hasOwnProperty(JSCompiler_renameProperty('properties', this))) {
1797
- const props = this.properties;
1798
- // support symbols in properties (IE11 does not support this)
1799
- const propKeys = [
1800
- ...Object.getOwnPropertyNames(props),
1801
- ...(typeof Object.getOwnPropertySymbols === 'function') ?
1802
- Object.getOwnPropertySymbols(props) :
1803
- []
1804
- ];
1805
- // This for/of is ok because propKeys is an array
1806
- for (const p of propKeys) {
1807
- // note, use of `any` is due to TypeSript lack of support for symbol in
1808
- // index types
1809
- // tslint:disable-next-line:no-any no symbol in index
1810
- this.createProperty(p, props[p]);
1811
- }
1812
- }
1813
- }
1814
- /**
1815
- * Returns the property name for the given attribute `name`.
1816
- * @nocollapse
1817
- */
1818
- static _attributeNameForProperty(name, options) {
1819
- const attribute = options.attribute;
1820
- return attribute === false ?
1821
- undefined :
1822
- (typeof attribute === 'string' ?
1823
- attribute :
1824
- (typeof name === 'string' ? name.toLowerCase() : undefined));
1825
- }
1826
- /**
1827
- * Returns true if a property should request an update.
1828
- * Called when a property value is set and uses the `hasChanged`
1829
- * option for the property if present or a strict identity check.
1830
- * @nocollapse
1831
- */
1832
- static _valueHasChanged(value, old, hasChanged = notEqual) {
1833
- return hasChanged(value, old);
1834
- }
1835
- /**
1836
- * Returns the property value for the given attribute value.
1837
- * Called via the `attributeChangedCallback` and uses the property's
1838
- * `converter` or `converter.fromAttribute` property option.
1839
- * @nocollapse
1840
- */
1841
- static _propertyValueFromAttribute(value, options) {
1842
- const type = options.type;
1843
- const converter = options.converter || defaultConverter;
1844
- const fromAttribute = (typeof converter === 'function' ? converter : converter.fromAttribute);
1845
- return fromAttribute ? fromAttribute(value, type) : value;
1846
- }
1847
- /**
1848
- * Returns the attribute value for the given property value. If this
1849
- * returns undefined, the property will *not* be reflected to an attribute.
1850
- * If this returns null, the attribute will be removed, otherwise the
1851
- * attribute will be set to the value.
1852
- * This uses the property's `reflect` and `type.toAttribute` property options.
1853
- * @nocollapse
1854
- */
1855
- static _propertyValueToAttribute(value, options) {
1856
- if (options.reflect === undefined) {
1857
- return;
1858
- }
1859
- const type = options.type;
1860
- const converter = options.converter;
1861
- const toAttribute = converter && converter.toAttribute ||
1862
- defaultConverter.toAttribute;
1863
- return toAttribute(value, type);
1864
- }
1865
- /**
1866
- * Performs element initialization. By default captures any pre-set values for
1867
- * registered properties.
1868
- */
1869
- initialize() {
1870
- this._updateState = 0;
1871
- this._updatePromise =
1872
- new Promise((res) => this._enableUpdatingResolver = res);
1873
- this._changedProperties = new Map();
1874
- this._saveInstanceProperties();
1875
- // ensures first update will be caught by an early access of
1876
- // `updateComplete`
1877
- this.requestUpdateInternal();
1878
- }
1879
- /**
1880
- * Fixes any properties set on the instance before upgrade time.
1881
- * Otherwise these would shadow the accessor and break these properties.
1882
- * The properties are stored in a Map which is played back after the
1883
- * constructor runs. Note, on very old versions of Safari (<=9) or Chrome
1884
- * (<=41), properties created for native platform properties like (`id` or
1885
- * `name`) may not have default values set in the element constructor. On
1886
- * these browsers native properties appear on instances and therefore their
1887
- * default value will overwrite any element default (e.g. if the element sets
1888
- * this.id = 'id' in the constructor, the 'id' will become '' since this is
1889
- * the native platform default).
1890
- */
1891
- _saveInstanceProperties() {
1892
- // Use forEach so this works even if for/of loops are compiled to for loops
1893
- // expecting arrays
1894
- this.constructor
1895
- ._classProperties.forEach((_v, p) => {
1896
- if (this.hasOwnProperty(p)) {
1897
- const value = this[p];
1898
- delete this[p];
1899
- if (!this._instanceProperties) {
1900
- this._instanceProperties = new Map();
1901
- }
1902
- this._instanceProperties.set(p, value);
1903
- }
1904
- });
1905
- }
1906
- /**
1907
- * Applies previously saved instance properties.
1908
- */
1909
- _applyInstanceProperties() {
1910
- // Use forEach so this works even if for/of loops are compiled to for loops
1911
- // expecting arrays
1912
- // tslint:disable-next-line:no-any
1913
- this._instanceProperties.forEach((v, p) => this[p] = v);
1914
- this._instanceProperties = undefined;
1915
- }
1916
- connectedCallback() {
1917
- // Ensure first connection completes an update. Updates cannot complete
1918
- // before connection.
1919
- this.enableUpdating();
1920
- }
1921
- enableUpdating() {
1922
- if (this._enableUpdatingResolver !== undefined) {
1923
- this._enableUpdatingResolver();
1924
- this._enableUpdatingResolver = undefined;
1925
- }
1926
- }
1927
- /**
1928
- * Allows for `super.disconnectedCallback()` in extensions while
1929
- * reserving the possibility of making non-breaking feature additions
1930
- * when disconnecting at some point in the future.
1931
- */
1932
- disconnectedCallback() {
1933
- }
1934
- /**
1935
- * Synchronizes property values when attributes change.
1936
- */
1937
- attributeChangedCallback(name, old, value) {
1938
- if (old !== value) {
1939
- this._attributeToProperty(name, value);
1940
- }
1941
- }
1942
- _propertyToAttribute(name, value, options = defaultPropertyDeclaration) {
1943
- const ctor = this.constructor;
1944
- const attr = ctor._attributeNameForProperty(name, options);
1945
- if (attr !== undefined) {
1946
- const attrValue = ctor._propertyValueToAttribute(value, options);
1947
- // an undefined value does not change the attribute.
1948
- if (attrValue === undefined) {
1949
- return;
1950
- }
1951
- // Track if the property is being reflected to avoid
1952
- // setting the property again via `attributeChangedCallback`. Note:
1953
- // 1. this takes advantage of the fact that the callback is synchronous.
1954
- // 2. will behave incorrectly if multiple attributes are in the reaction
1955
- // stack at time of calling. However, since we process attributes
1956
- // in `update` this should not be possible (or an extreme corner case
1957
- // that we'd like to discover).
1958
- // mark state reflecting
1959
- this._updateState = this._updateState | STATE_IS_REFLECTING_TO_ATTRIBUTE;
1960
- if (attrValue == null) {
1961
- this.removeAttribute(attr);
1962
- }
1963
- else {
1964
- this.setAttribute(attr, attrValue);
1965
- }
1966
- // mark state not reflecting
1967
- this._updateState = this._updateState & ~STATE_IS_REFLECTING_TO_ATTRIBUTE;
1968
- }
1969
- }
1970
- _attributeToProperty(name, value) {
1971
- // Use tracking info to avoid deserializing attribute value if it was
1972
- // just set from a property setter.
1973
- if (this._updateState & STATE_IS_REFLECTING_TO_ATTRIBUTE) {
1974
- return;
1975
- }
1976
- const ctor = this.constructor;
1977
- // Note, hint this as an `AttributeMap` so closure clearly understands
1978
- // the type; it has issues with tracking types through statics
1979
- // tslint:disable-next-line:no-unnecessary-type-assertion
1980
- const propName = ctor._attributeToPropertyMap.get(name);
1981
- if (propName !== undefined) {
1982
- const options = ctor.getPropertyOptions(propName);
1983
- // mark state reflecting
1984
- this._updateState = this._updateState | STATE_IS_REFLECTING_TO_PROPERTY;
1985
- this[propName] =
1986
- // tslint:disable-next-line:no-any
1987
- ctor._propertyValueFromAttribute(value, options);
1988
- // mark state not reflecting
1989
- this._updateState = this._updateState & ~STATE_IS_REFLECTING_TO_PROPERTY;
1990
- }
1991
- }
1992
- /**
1993
- * This protected version of `requestUpdate` does not access or return the
1994
- * `updateComplete` promise. This promise can be overridden and is therefore
1995
- * not free to access.
1996
- */
1997
- requestUpdateInternal(name, oldValue, options) {
1998
- let shouldRequestUpdate = true;
1999
- // If we have a property key, perform property update steps.
2000
- if (name !== undefined) {
2001
- const ctor = this.constructor;
2002
- options = options || ctor.getPropertyOptions(name);
2003
- if (ctor._valueHasChanged(this[name], oldValue, options.hasChanged)) {
2004
- if (!this._changedProperties.has(name)) {
2005
- this._changedProperties.set(name, oldValue);
2006
- }
2007
- // Add to reflecting properties set.
2008
- // Note, it's important that every change has a chance to add the
2009
- // property to `_reflectingProperties`. This ensures setting
2010
- // attribute + property reflects correctly.
2011
- if (options.reflect === true &&
2012
- !(this._updateState & STATE_IS_REFLECTING_TO_PROPERTY)) {
2013
- if (this._reflectingProperties === undefined) {
2014
- this._reflectingProperties = new Map();
2015
- }
2016
- this._reflectingProperties.set(name, options);
2017
- }
2018
- }
2019
- else {
2020
- // Abort the request if the property should not be considered changed.
2021
- shouldRequestUpdate = false;
2022
- }
2023
- }
2024
- if (!this._hasRequestedUpdate && shouldRequestUpdate) {
2025
- this._updatePromise = this._enqueueUpdate();
2026
- }
2027
- }
2028
- /**
2029
- * Requests an update which is processed asynchronously. This should
2030
- * be called when an element should update based on some state not triggered
2031
- * by setting a property. In this case, pass no arguments. It should also be
2032
- * called when manually implementing a property setter. In this case, pass the
2033
- * property `name` and `oldValue` to ensure that any configured property
2034
- * options are honored. Returns the `updateComplete` Promise which is resolved
2035
- * when the update completes.
2036
- *
2037
- * @param name {PropertyKey} (optional) name of requesting property
2038
- * @param oldValue {any} (optional) old value of requesting property
2039
- * @returns {Promise} A Promise that is resolved when the update completes.
2040
- */
2041
- requestUpdate(name, oldValue) {
2042
- this.requestUpdateInternal(name, oldValue);
2043
- return this.updateComplete;
2044
- }
2045
- /**
2046
- * Sets up the element to asynchronously update.
2047
- */
2048
- async _enqueueUpdate() {
2049
- this._updateState = this._updateState | STATE_UPDATE_REQUESTED;
2050
- try {
2051
- // Ensure any previous update has resolved before updating.
2052
- // This `await` also ensures that property changes are batched.
2053
- await this._updatePromise;
2054
- }
2055
- catch (e) {
2056
- // Ignore any previous errors. We only care that the previous cycle is
2057
- // done. Any error should have been handled in the previous update.
2058
- }
2059
- const result = this.performUpdate();
2060
- // If `performUpdate` returns a Promise, we await it. This is done to
2061
- // enable coordinating updates with a scheduler. Note, the result is
2062
- // checked to avoid delaying an additional microtask unless we need to.
2063
- if (result != null) {
2064
- await result;
2065
- }
2066
- return !this._hasRequestedUpdate;
2067
- }
2068
- get _hasRequestedUpdate() {
2069
- return (this._updateState & STATE_UPDATE_REQUESTED);
2070
- }
2071
- get hasUpdated() {
2072
- return (this._updateState & STATE_HAS_UPDATED);
2073
- }
2074
- /**
2075
- * Performs an element update. Note, if an exception is thrown during the
2076
- * update, `firstUpdated` and `updated` will not be called.
2077
- *
2078
- * You can override this method to change the timing of updates. If this
2079
- * method is overridden, `super.performUpdate()` must be called.
2080
- *
2081
- * For instance, to schedule updates to occur just before the next frame:
2082
- *
2083
- * ```
2084
- * protected async performUpdate(): Promise<unknown> {
2085
- * await new Promise((resolve) => requestAnimationFrame(() => resolve()));
2086
- * super.performUpdate();
2087
- * }
2088
- * ```
2089
- */
2090
- performUpdate() {
2091
- // Abort any update if one is not pending when this is called.
2092
- // This can happen if `performUpdate` is called early to "flush"
2093
- // the update.
2094
- if (!this._hasRequestedUpdate) {
2095
- return;
2096
- }
2097
- // Mixin instance properties once, if they exist.
2098
- if (this._instanceProperties) {
2099
- this._applyInstanceProperties();
2100
- }
2101
- let shouldUpdate = false;
2102
- const changedProperties = this._changedProperties;
2103
- try {
2104
- shouldUpdate = this.shouldUpdate(changedProperties);
2105
- if (shouldUpdate) {
2106
- this.update(changedProperties);
2107
- }
2108
- else {
2109
- this._markUpdated();
2110
- }
2111
- }
2112
- catch (e) {
2113
- // Prevent `firstUpdated` and `updated` from running when there's an
2114
- // update exception.
2115
- shouldUpdate = false;
2116
- // Ensure element can accept additional updates after an exception.
2117
- this._markUpdated();
2118
- throw e;
2119
- }
2120
- if (shouldUpdate) {
2121
- if (!(this._updateState & STATE_HAS_UPDATED)) {
2122
- this._updateState = this._updateState | STATE_HAS_UPDATED;
2123
- this.firstUpdated(changedProperties);
2124
- }
2125
- this.updated(changedProperties);
2126
- }
2127
- }
2128
- _markUpdated() {
2129
- this._changedProperties = new Map();
2130
- this._updateState = this._updateState & ~STATE_UPDATE_REQUESTED;
2131
- }
2132
- /**
2133
- * Returns a Promise that resolves when the element has completed updating.
2134
- * The Promise value is a boolean that is `true` if the element completed the
2135
- * update without triggering another update. The Promise result is `false` if
2136
- * a property was set inside `updated()`. If the Promise is rejected, an
2137
- * exception was thrown during the update.
2138
- *
2139
- * To await additional asynchronous work, override the `_getUpdateComplete`
2140
- * method. For example, it is sometimes useful to await a rendered element
2141
- * before fulfilling this Promise. To do this, first await
2142
- * `super._getUpdateComplete()`, then any subsequent state.
2143
- *
2144
- * @returns {Promise} The Promise returns a boolean that indicates if the
2145
- * update resolved without triggering another update.
2146
- */
2147
- get updateComplete() {
2148
- return this._getUpdateComplete();
2149
- }
2150
- /**
2151
- * Override point for the `updateComplete` promise.
2152
- *
2153
- * It is not safe to override the `updateComplete` getter directly due to a
2154
- * limitation in TypeScript which means it is not possible to call a
2155
- * superclass getter (e.g. `super.updateComplete.then(...)`) when the target
2156
- * language is ES5 (https://github.com/microsoft/TypeScript/issues/338).
2157
- * This method should be overridden instead. For example:
2158
- *
2159
- * class MyElement extends LitElement {
2160
- * async _getUpdateComplete() {
2161
- * await super._getUpdateComplete();
2162
- * await this._myChild.updateComplete;
2163
- * }
2164
- * }
2165
- */
2166
- _getUpdateComplete() {
2167
- return this._updatePromise;
2168
- }
2169
- /**
2170
- * Controls whether or not `update` should be called when the element requests
2171
- * an update. By default, this method always returns `true`, but this can be
2172
- * customized to control when to update.
2173
- *
2174
- * @param _changedProperties Map of changed properties with old values
2175
- */
2176
- shouldUpdate(_changedProperties) {
2177
- return true;
2178
- }
2179
- /**
2180
- * Updates the element. This method reflects property values to attributes.
2181
- * It can be overridden to render and keep updated element DOM.
2182
- * Setting properties inside this method will *not* trigger
2183
- * another update.
2184
- *
2185
- * @param _changedProperties Map of changed properties with old values
2186
- */
2187
- update(_changedProperties) {
2188
- if (this._reflectingProperties !== undefined &&
2189
- this._reflectingProperties.size > 0) {
2190
- // Use forEach so this works even if for/of loops are compiled to for
2191
- // loops expecting arrays
2192
- this._reflectingProperties.forEach((v, k) => this._propertyToAttribute(k, this[k], v));
2193
- this._reflectingProperties = undefined;
2194
- }
2195
- this._markUpdated();
2196
- }
2197
- /**
2198
- * Invoked whenever the element is updated. Implement to perform
2199
- * post-updating tasks via DOM APIs, for example, focusing an element.
2200
- *
2201
- * Setting properties inside this method will trigger the element to update
2202
- * again after this update cycle completes.
2203
- *
2204
- * @param _changedProperties Map of changed properties with old values
2205
- */
2206
- updated(_changedProperties) {
2207
- }
2208
- /**
2209
- * Invoked when the element is first updated. Implement to perform one time
2210
- * work on the element after update.
2211
- *
2212
- * Setting properties inside this method will trigger the element to update
2213
- * again after this update cycle completes.
2214
- *
2215
- * @param _changedProperties Map of changed properties with old values
2216
- */
2217
- firstUpdated(_changedProperties) {
2218
- }
2219
- }
2220
- _a = finalized;
2221
- /**
2222
- * Marks class as having finished creating properties.
2223
- */
2224
- UpdatingElement[_a] = true;
2225
-
2226
- /**
2227
- @license
2228
- Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
2229
- This code may only be used under the BSD style license found at
2230
- http://polymer.github.io/LICENSE.txt The complete set of authors may be found at
2231
- http://polymer.github.io/AUTHORS.txt The complete set of contributors may be
2232
- found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as
2233
- part of the polymer project is also subject to an additional IP rights grant
2234
- found at http://polymer.github.io/PATENTS.txt
2235
- */
2236
- /**
2237
- * Whether the current browser supports `adoptedStyleSheets`.
2238
- */
2239
- const supportsAdoptingStyleSheets = (window.ShadowRoot) &&
2240
- (window.ShadyCSS === undefined || window.ShadyCSS.nativeShadow) &&
2241
- ('adoptedStyleSheets' in Document.prototype) &&
2242
- ('replace' in CSSStyleSheet.prototype);
2243
- const constructionToken = Symbol();
2244
- class CSSResult {
2245
- constructor(cssText, safeToken) {
2246
- if (safeToken !== constructionToken) {
2247
- throw new Error('CSSResult is not constructable. Use `unsafeCSS` or `css` instead.');
2248
- }
2249
- this.cssText = cssText;
2250
- }
2251
- // Note, this is a getter so that it's lazy. In practice, this means
2252
- // stylesheets are not created until the first element instance is made.
2253
- get styleSheet() {
2254
- if (this._styleSheet === undefined) {
2255
- // Note, if `supportsAdoptingStyleSheets` is true then we assume
2256
- // CSSStyleSheet is constructable.
2257
- if (supportsAdoptingStyleSheets) {
2258
- this._styleSheet = new CSSStyleSheet();
2259
- this._styleSheet.replaceSync(this.cssText);
2260
- }
2261
- else {
2262
- this._styleSheet = null;
2263
- }
2264
- }
2265
- return this._styleSheet;
2266
- }
2267
- toString() {
2268
- return this.cssText;
2269
- }
2270
- }
2271
- /**
2272
- * Wrap a value for interpolation in a [[`css`]] tagged template literal.
2273
- *
2274
- * This is unsafe because untrusted CSS text can be used to phone home
2275
- * or exfiltrate data to an attacker controlled site. Take care to only use
2276
- * this with trusted input.
2277
- */
2278
- const unsafeCSS = (value) => {
2279
- return new CSSResult(String(value), constructionToken);
2280
- };
2281
- const textFromCSSResult = (value) => {
2282
- if (value instanceof CSSResult) {
2283
- return value.cssText;
2284
- }
2285
- else if (typeof value === 'number') {
2286
- return value;
2287
- }
2288
- else {
2289
- throw new Error(`Value passed to 'css' function must be a 'css' function result: ${value}. Use 'unsafeCSS' to pass non-literal values, but
2290
- take care to ensure page security.`);
2291
- }
2292
- };
2293
- /**
2294
- * Template tag which which can be used with LitElement's [[LitElement.styles |
2295
- * `styles`]] property to set element styles. For security reasons, only literal
2296
- * string values may be used. To incorporate non-literal values [[`unsafeCSS`]]
2297
- * may be used inside a template string part.
2298
- */
2299
- const css = (strings, ...values) => {
2300
- const cssText = values.reduce((acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1], strings[0]);
2301
- return new CSSResult(cssText, constructionToken);
2302
- };
2303
-
2304
- /**
2305
- * @license
2306
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
2307
- * This code may only be used under the BSD style license found at
2308
- * http://polymer.github.io/LICENSE.txt
2309
- * The complete set of authors may be found at
2310
- * http://polymer.github.io/AUTHORS.txt
2311
- * The complete set of contributors may be found at
2312
- * http://polymer.github.io/CONTRIBUTORS.txt
2313
- * Code distributed by Google as part of the polymer project is also
2314
- * subject to an additional IP rights grant found at
2315
- * http://polymer.github.io/PATENTS.txt
2316
- */
2317
- // IMPORTANT: do not change the property name or the assignment expression.
2318
- // This line will be used in regexes to search for LitElement usage.
2319
- // TODO(justinfagnani): inject version number at build time
2320
- (window['litElementVersions'] || (window['litElementVersions'] = []))
2321
- .push('2.4.0');
2322
- /**
2323
- * Sentinal value used to avoid calling lit-html's render function when
2324
- * subclasses do not implement `render`
2325
- */
2326
- const renderNotImplemented = {};
2327
- /**
2328
- * Base element class that manages element properties and attributes, and
2329
- * renders a lit-html template.
2330
- *
2331
- * To define a component, subclass `LitElement` and implement a
2332
- * `render` method to provide the component's template. Define properties
2333
- * using the [[`properties`]] property or the [[`property`]] decorator.
2334
- */
2335
- class LitElement extends UpdatingElement {
2336
- /**
2337
- * Return the array of styles to apply to the element.
2338
- * Override this method to integrate into a style management system.
2339
- *
2340
- * @nocollapse
2341
- */
2342
- static getStyles() {
2343
- return this.styles;
2344
- }
2345
- /** @nocollapse */
2346
- static _getUniqueStyles() {
2347
- // Only gather styles once per class
2348
- if (this.hasOwnProperty(JSCompiler_renameProperty('_styles', this))) {
2349
- return;
2350
- }
2351
- // Take care not to call `this.getStyles()` multiple times since this
2352
- // generates new CSSResults each time.
2353
- // TODO(sorvell): Since we do not cache CSSResults by input, any
2354
- // shared styles will generate new stylesheet objects, which is wasteful.
2355
- // This should be addressed when a browser ships constructable
2356
- // stylesheets.
2357
- const userStyles = this.getStyles();
2358
- if (Array.isArray(userStyles)) {
2359
- // De-duplicate styles preserving the _last_ instance in the set.
2360
- // This is a performance optimization to avoid duplicated styles that can
2361
- // occur especially when composing via subclassing.
2362
- // The last item is kept to try to preserve the cascade order with the
2363
- // assumption that it's most important that last added styles override
2364
- // previous styles.
2365
- const addStyles = (styles, set) => styles.reduceRight((set, s) =>
2366
- // Note: On IE set.add() does not return the set
2367
- Array.isArray(s) ? addStyles(s, set) : (set.add(s), set), set);
2368
- // Array.from does not work on Set in IE, otherwise return
2369
- // Array.from(addStyles(userStyles, new Set<CSSResult>())).reverse()
2370
- const set = addStyles(userStyles, new Set());
2371
- const styles = [];
2372
- set.forEach((v) => styles.unshift(v));
2373
- this._styles = styles;
2374
- }
2375
- else {
2376
- this._styles = userStyles === undefined ? [] : [userStyles];
2377
- }
2378
- // Ensure that there are no invalid CSSStyleSheet instances here. They are
2379
- // invalid in two conditions.
2380
- // (1) the sheet is non-constructible (`sheet` of a HTMLStyleElement), but
2381
- // this is impossible to check except via .replaceSync or use
2382
- // (2) the ShadyCSS polyfill is enabled (:. supportsAdoptingStyleSheets is
2383
- // false)
2384
- this._styles = this._styles.map((s) => {
2385
- if (s instanceof CSSStyleSheet && !supportsAdoptingStyleSheets) {
2386
- // Flatten the cssText from the passed constructible stylesheet (or
2387
- // undetectable non-constructible stylesheet). The user might have
2388
- // expected to update their stylesheets over time, but the alternative
2389
- // is a crash.
2390
- const cssText = Array.prototype.slice.call(s.cssRules)
2391
- .reduce((css, rule) => css + rule.cssText, '');
2392
- return unsafeCSS(cssText);
2393
- }
2394
- return s;
2395
- });
2396
- }
2397
- /**
2398
- * Performs element initialization. By default this calls
2399
- * [[`createRenderRoot`]] to create the element [[`renderRoot`]] node and
2400
- * captures any pre-set values for registered properties.
2401
- */
2402
- initialize() {
2403
- super.initialize();
2404
- this.constructor._getUniqueStyles();
2405
- this.renderRoot = this.createRenderRoot();
2406
- // Note, if renderRoot is not a shadowRoot, styles would/could apply to the
2407
- // element's getRootNode(). While this could be done, we're choosing not to
2408
- // support this now since it would require different logic around de-duping.
2409
- if (window.ShadowRoot && this.renderRoot instanceof window.ShadowRoot) {
2410
- this.adoptStyles();
2411
- }
2412
- }
2413
- /**
2414
- * Returns the node into which the element should render and by default
2415
- * creates and returns an open shadowRoot. Implement to customize where the
2416
- * element's DOM is rendered. For example, to render into the element's
2417
- * childNodes, return `this`.
2418
- * @returns {Element|DocumentFragment} Returns a node into which to render.
2419
- */
2420
- createRenderRoot() {
2421
- return this.attachShadow({ mode: 'open' });
2422
- }
2423
- /**
2424
- * Applies styling to the element shadowRoot using the [[`styles`]]
2425
- * property. Styling will apply using `shadowRoot.adoptedStyleSheets` where
2426
- * available and will fallback otherwise. When Shadow DOM is polyfilled,
2427
- * ShadyCSS scopes styles and adds them to the document. When Shadow DOM
2428
- * is available but `adoptedStyleSheets` is not, styles are appended to the
2429
- * end of the `shadowRoot` to [mimic spec
2430
- * behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets).
2431
- */
2432
- adoptStyles() {
2433
- const styles = this.constructor._styles;
2434
- if (styles.length === 0) {
2435
- return;
2436
- }
2437
- // There are three separate cases here based on Shadow DOM support.
2438
- // (1) shadowRoot polyfilled: use ShadyCSS
2439
- // (2) shadowRoot.adoptedStyleSheets available: use it
2440
- // (3) shadowRoot.adoptedStyleSheets polyfilled: append styles after
2441
- // rendering
2442
- if (window.ShadyCSS !== undefined && !window.ShadyCSS.nativeShadow) {
2443
- window.ShadyCSS.ScopingShim.prepareAdoptedCssText(styles.map((s) => s.cssText), this.localName);
2444
- }
2445
- else if (supportsAdoptingStyleSheets) {
2446
- this.renderRoot.adoptedStyleSheets =
2447
- styles.map((s) => s instanceof CSSStyleSheet ? s : s.styleSheet);
2448
- }
2449
- else {
2450
- // This must be done after rendering so the actual style insertion is done
2451
- // in `update`.
2452
- this._needsShimAdoptedStyleSheets = true;
2453
- }
2454
- }
2455
- connectedCallback() {
2456
- super.connectedCallback();
2457
- // Note, first update/render handles styleElement so we only call this if
2458
- // connected after first update.
2459
- if (this.hasUpdated && window.ShadyCSS !== undefined) {
2460
- window.ShadyCSS.styleElement(this);
2461
- }
2462
- }
2463
- /**
2464
- * Updates the element. This method reflects property values to attributes
2465
- * and calls `render` to render DOM via lit-html. Setting properties inside
2466
- * this method will *not* trigger another update.
2467
- * @param _changedProperties Map of changed properties with old values
2468
- */
2469
- update(changedProperties) {
2470
- // Setting properties in `render` should not trigger an update. Since
2471
- // updates are allowed after super.update, it's important to call `render`
2472
- // before that.
2473
- const templateResult = this.render();
2474
- super.update(changedProperties);
2475
- // If render is not implemented by the component, don't call lit-html render
2476
- if (templateResult !== renderNotImplemented) {
2477
- this.constructor
2478
- .render(templateResult, this.renderRoot, { scopeName: this.localName, eventContext: this });
2479
- }
2480
- // When native Shadow DOM is used but adoptedStyles are not supported,
2481
- // insert styling after rendering to ensure adoptedStyles have highest
2482
- // priority.
2483
- if (this._needsShimAdoptedStyleSheets) {
2484
- this._needsShimAdoptedStyleSheets = false;
2485
- this.constructor._styles.forEach((s) => {
2486
- const style = document.createElement('style');
2487
- style.textContent = s.cssText;
2488
- this.renderRoot.appendChild(style);
2489
- });
2490
- }
2491
- }
2492
- /**
2493
- * Invoked on each update to perform rendering tasks. This method may return
2494
- * any value renderable by lit-html's `NodePart` - typically a
2495
- * `TemplateResult`. Setting properties inside this method will *not* trigger
2496
- * the element to update.
2497
- */
2498
- render() {
2499
- return renderNotImplemented;
2500
- }
2501
- }
2502
- /**
2503
- * Ensure this class is marked as `finalized` as an optimization ensuring
2504
- * it will not needlessly try to `finalize`.
2505
- *
2506
- * Note this property name is a string to prevent breaking Closure JS Compiler
2507
- * optimizations. See updating-element.ts for more information.
2508
- */
2509
- LitElement['finalized'] = true;
2510
- /**
2511
- * Reference to the underlying library method used to render the element's
2512
- * DOM. By default, points to the `render` method from lit-html's shady-render
2513
- * module.
2514
- *
2515
- * **Most users will never need to touch this property.**
2516
- *
2517
- * This property should not be confused with the `render` instance method,
2518
- * which should be overridden to define a template for the element.
2519
- *
2520
- * Advanced users creating a new base class based on LitElement can override
2521
- * this property to point to a custom render method with a signature that
2522
- * matches [shady-render's `render`
2523
- * method](https://lit-html.polymer-project.org/api/modules/shady_render.html#render).
2524
- *
2525
- * @nocollapse
2526
- */
2527
- LitElement.render = render$1;
1
+ import { s, r } from '../../common/lit-element-3254fb50.js';
2
+ import { $ } from '../../common/lit-html-1d707ff6.js';
2528
3
 
2529
4
  const IAActivityIndicatorMode = Object.freeze({
2530
5
  processing: 'processing',
2531
6
  complete: 'complete',
2532
7
  });
2533
8
 
2534
- class IAActivityIndicator extends LitElement {
9
+ class IAActivityIndicator extends s {
2535
10
  static get properties() {
2536
11
  return {
2537
12
  mode: { type: String },
@@ -2544,7 +19,7 @@ class IAActivityIndicator extends LitElement {
2544
19
  }
2545
20
 
2546
21
  render() {
2547
- return html`
22
+ return $`
2548
23
  <div class="${this.mode}">
2549
24
  <svg
2550
25
  viewBox="0 0 120 120"
@@ -2597,12 +72,12 @@ class IAActivityIndicator extends LitElement {
2597
72
  }
2598
73
 
2599
74
  static get styles() {
2600
- const checkmarkColorCss = css`var(--activityIndicatorCheckmarkColor, #31A481)`;
2601
- const completedRingColorCss = css`var(--activityIndicatorCompletedRingColor, #31A481)`;
2602
- const loadingRingColorCss = css`var(--activityIndicatorLoadingRingColor, #333333)`;
2603
- const loadingDotColorCss = css`var(--activityIndicatorLoadingDotColor, #333333)`;
75
+ const checkmarkColorCss = r`var(--activityIndicatorCheckmarkColor, #31A481)`;
76
+ const completedRingColorCss = r`var(--activityIndicatorCompletedRingColor, #31A481)`;
77
+ const loadingRingColorCss = r`var(--activityIndicatorLoadingRingColor, #333333)`;
78
+ const loadingDotColorCss = r`var(--activityIndicatorLoadingDotColor, #333333)`;
2604
79
 
2605
- return css`
80
+ return r`
2606
81
  #completed-ring {
2607
82
  fill: ${completedRingColorCss};
2608
83
  }