diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..b968eb3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,4 @@
+.gitignore
+/dist
+.git
+/example
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..480d45d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,3 @@
+# .prettierrc
+semi: false
+useTabs: false
\ No newline at end of file
diff --git a/README.md b/README.md
index d825db6..86ec12e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,43 @@
# Embeddable NFTs
Easily embed OpenSea listings in your website!
+### Component inputs
+
+`vertical` - If this is present the card will be rendered vertically.
+
+`width` - The width of the embeddable. Ex. values `100%` `250px`
+
+`height` - The height of the embeddable. Ex. values `40vh` `300px`
+
+`contractAddress`\*- The token Id of the asset.
+
+`tokenId`\* - The token Id of the asset.
+
+`network` - The name of the network the asset is on `mainnet` or `rinkeby`. Defaults to `mainnet`.
+
+\*Required inputs
+
+Example:
+```
+
+
+```
+
### Development
-For developers looking to contribute or modify the code use the following commands:
+For developers looking to contribute or modify the code, or view the example use the following commands:
```bash
git clone https://github.com/ProjectOpenSea/embeddable_nfts.git
cd embeddable_nfts
npm install
- npm start
+ npm run dev:demo
```
#### Development server
-This project uses [rollup.js](https://rollupjs.org/guide/en/) for building and running a development server. Once the server starts, any changes made will trigger a rebuild after which those changes should be reflected in your browser.
+This project uses webpack for building and running a development server. Once the server starts, any changes made will trigger a rebuild after which those changes should be reflected in your browser.
diff --git a/babel.config.js b/babel.config.js
index 2516bf6..e5d35f1 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,16 +1,16 @@
const presets = [
- "@babel/preset-typescript",
+ '@babel/preset-typescript',
[
- "@babel/preset-env",
+ '@babel/preset-env',
{
- "targets": "last 2 Chrome version",
- "modules": false
+ targets: 'last 2 Chrome version',
+ modules: false
}
]
]
const plugins = [
'@babel/plugin-proposal-class-properties',
- ['@babel/proposal-decorators', { decoratorsBeforeExport: true } ],
-];
+ ['@babel/proposal-decorators', {decoratorsBeforeExport: true}]
+]
-module.exports = { plugins, presets };
+module.exports = {plugins, presets}
diff --git a/dist/nft-card.js b/dist/nft-card.js
index a3f7700..878dfc6 100644
--- a/dist/nft-card.js
+++ b/dist/nft-card.js
@@ -1,3161 +1,209 @@
-
-(function(l, r) { if (l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (window.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.head.appendChild(r) })(window.document);
-(function (exports) {
- 'use strict';
-
- function _toArray(arr) {
- return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();
- }
-
- function _arrayWithHoles(arr) {
- if (Array.isArray(arr)) return arr;
- }
-
- function _iterableToArray(iter) {
- if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
- }
-
- function _nonIterableRest() {
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
- }
-
- function _toPrimitive(input, hint) {
- if (typeof input !== "object" || input === null) return input;
- var prim = input[Symbol.toPrimitive];
-
- if (prim !== undefined) {
- var res = prim.call(input, hint || "default");
- if (typeof res !== "object") return res;
- throw new TypeError("@@toPrimitive must return a primitive value.");
- }
-
- return (hint === "string" ? String : Number)(input);
- }
-
- function _toPropertyKey(arg) {
- var key = _toPrimitive(arg, "string");
-
- return typeof key === "symbol" ? key : String(key);
- }
-
- function _decorate(decorators, factory, superClass, mixins) {
- var api = _getDecoratorsApi();
-
- if (mixins) {
- for (var i = 0; i < mixins.length; i++) {
- api = mixins[i](api);
- }
- }
-
- var r = factory(function initialize(O) {
- api.initializeInstanceElements(O, decorated.elements);
- }, superClass);
- var decorated = api.decorateClass(_coalesceClassElements(r.d.map(_createElementDescriptor)), decorators);
- api.initializeClassElements(r.F, decorated.elements);
- return api.runClassFinishers(r.F, decorated.finishers);
- }
-
- function _getDecoratorsApi() {
- _getDecoratorsApi = function () {
- return api;
- };
-
- var api = {
- elementsDefinitionOrder: [["method"], ["field"]],
- initializeInstanceElements: function (O, elements) {
- ["method", "field"].forEach(function (kind) {
- elements.forEach(function (element) {
- if (element.kind === kind && element.placement === "own") {
- this.defineClassElement(O, element);
- }
- }, this);
- }, this);
- },
- initializeClassElements: function (F, elements) {
- var proto = F.prototype;
- ["method", "field"].forEach(function (kind) {
- elements.forEach(function (element) {
- var placement = element.placement;
-
- if (element.kind === kind && (placement === "static" || placement === "prototype")) {
- var receiver = placement === "static" ? F : proto;
- this.defineClassElement(receiver, element);
- }
- }, this);
- }, this);
- },
- defineClassElement: function (receiver, element) {
- var descriptor = element.descriptor;
-
- if (element.kind === "field") {
- var initializer = element.initializer;
- descriptor = {
- enumerable: descriptor.enumerable,
- writable: descriptor.writable,
- configurable: descriptor.configurable,
- value: initializer === void 0 ? void 0 : initializer.call(receiver)
- };
- }
-
- Object.defineProperty(receiver, element.key, descriptor);
- },
- decorateClass: function (elements, decorators) {
- var newElements = [];
- var finishers = [];
- var placements = {
- static: [],
- prototype: [],
- own: []
- };
- elements.forEach(function (element) {
- this.addElementPlacement(element, placements);
- }, this);
- elements.forEach(function (element) {
- if (!_hasDecorators(element)) return newElements.push(element);
- var elementFinishersExtras = this.decorateElement(element, placements);
- newElements.push(elementFinishersExtras.element);
- newElements.push.apply(newElements, elementFinishersExtras.extras);
- finishers.push.apply(finishers, elementFinishersExtras.finishers);
- }, this);
-
- if (!decorators) {
- return {
- elements: newElements,
- finishers: finishers
- };
- }
-
- var result = this.decorateConstructor(newElements, decorators);
- finishers.push.apply(finishers, result.finishers);
- result.finishers = finishers;
- return result;
- },
- addElementPlacement: function (element, placements, silent) {
- var keys = placements[element.placement];
-
- if (!silent && keys.indexOf(element.key) !== -1) {
- throw new TypeError("Duplicated element (" + element.key + ")");
- }
-
- keys.push(element.key);
- },
- decorateElement: function (element, placements) {
- var extras = [];
- var finishers = [];
-
- for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {
- var keys = placements[element.placement];
- keys.splice(keys.indexOf(element.key), 1);
- var elementObject = this.fromElementDescriptor(element);
- var elementFinisherExtras = this.toElementFinisherExtras((0, decorators[i])(elementObject) || elementObject);
- element = elementFinisherExtras.element;
- this.addElementPlacement(element, placements);
-
- if (elementFinisherExtras.finisher) {
- finishers.push(elementFinisherExtras.finisher);
- }
-
- var newExtras = elementFinisherExtras.extras;
-
- if (newExtras) {
- for (var j = 0; j < newExtras.length; j++) {
- this.addElementPlacement(newExtras[j], placements);
- }
-
- extras.push.apply(extras, newExtras);
- }
- }
-
- return {
- element: element,
- finishers: finishers,
- extras: extras
- };
- },
- decorateConstructor: function (elements, decorators) {
- var finishers = [];
-
- for (var i = decorators.length - 1; i >= 0; i--) {
- var obj = this.fromClassDescriptor(elements);
- var elementsAndFinisher = this.toClassDescriptor((0, decorators[i])(obj) || obj);
-
- if (elementsAndFinisher.finisher !== undefined) {
- finishers.push(elementsAndFinisher.finisher);
- }
-
- if (elementsAndFinisher.elements !== undefined) {
- elements = elementsAndFinisher.elements;
-
- for (var j = 0; j < elements.length - 1; j++) {
- for (var k = j + 1; k < elements.length; k++) {
- if (elements[j].key === elements[k].key && elements[j].placement === elements[k].placement) {
- throw new TypeError("Duplicated element (" + elements[j].key + ")");
- }
- }
- }
- }
- }
-
- return {
- elements: elements,
- finishers: finishers
- };
- },
- fromElementDescriptor: function (element) {
- var obj = {
- kind: element.kind,
- key: element.key,
- placement: element.placement,
- descriptor: element.descriptor
- };
- var desc = {
- value: "Descriptor",
- configurable: true
- };
- Object.defineProperty(obj, Symbol.toStringTag, desc);
- if (element.kind === "field") obj.initializer = element.initializer;
- return obj;
- },
- toElementDescriptors: function (elementObjects) {
- if (elementObjects === undefined) return;
- return _toArray(elementObjects).map(function (elementObject) {
- var element = this.toElementDescriptor(elementObject);
- this.disallowProperty(elementObject, "finisher", "An element descriptor");
- this.disallowProperty(elementObject, "extras", "An element descriptor");
- return element;
- }, this);
- },
- toElementDescriptor: function (elementObject) {
- var kind = String(elementObject.kind);
-
- if (kind !== "method" && kind !== "field") {
- throw new TypeError('An element descriptor\'s .kind property must be either "method" or' + ' "field", but a decorator created an element descriptor with' + ' .kind "' + kind + '"');
- }
-
- var key = _toPropertyKey(elementObject.key);
-
- var placement = String(elementObject.placement);
-
- if (placement !== "static" && placement !== "prototype" && placement !== "own") {
- throw new TypeError('An element descriptor\'s .placement property must be one of "static",' + ' "prototype" or "own", but a decorator created an element descriptor' + ' with .placement "' + placement + '"');
- }
-
- var descriptor = elementObject.descriptor;
- this.disallowProperty(elementObject, "elements", "An element descriptor");
- var element = {
- kind: kind,
- key: key,
- placement: placement,
- descriptor: Object.assign({}, descriptor)
- };
-
- if (kind !== "field") {
- this.disallowProperty(elementObject, "initializer", "A method descriptor");
- } else {
- this.disallowProperty(descriptor, "get", "The property descriptor of a field descriptor");
- this.disallowProperty(descriptor, "set", "The property descriptor of a field descriptor");
- this.disallowProperty(descriptor, "value", "The property descriptor of a field descriptor");
- element.initializer = elementObject.initializer;
- }
-
- return element;
- },
- toElementFinisherExtras: function (elementObject) {
- var element = this.toElementDescriptor(elementObject);
-
- var finisher = _optionalCallableProperty(elementObject, "finisher");
-
- var extras = this.toElementDescriptors(elementObject.extras);
- return {
- element: element,
- finisher: finisher,
- extras: extras
- };
- },
- fromClassDescriptor: function (elements) {
- var obj = {
- kind: "class",
- elements: elements.map(this.fromElementDescriptor, this)
- };
- var desc = {
- value: "Descriptor",
- configurable: true
- };
- Object.defineProperty(obj, Symbol.toStringTag, desc);
- return obj;
- },
- toClassDescriptor: function (obj) {
- var kind = String(obj.kind);
-
- if (kind !== "class") {
- throw new TypeError('A class descriptor\'s .kind property must be "class", but a decorator' + ' created a class descriptor with .kind "' + kind + '"');
- }
-
- this.disallowProperty(obj, "key", "A class descriptor");
- this.disallowProperty(obj, "placement", "A class descriptor");
- this.disallowProperty(obj, "descriptor", "A class descriptor");
- this.disallowProperty(obj, "initializer", "A class descriptor");
- this.disallowProperty(obj, "extras", "A class descriptor");
-
- var finisher = _optionalCallableProperty(obj, "finisher");
-
- var elements = this.toElementDescriptors(obj.elements);
- return {
- elements: elements,
- finisher: finisher
- };
- },
- runClassFinishers: function (constructor, finishers) {
- for (var i = 0; i < finishers.length; i++) {
- var newConstructor = (0, finishers[i])(constructor);
-
- if (newConstructor !== undefined) {
- if (typeof newConstructor !== "function") {
- throw new TypeError("Finishers must return a constructor.");
- }
-
- constructor = newConstructor;
- }
- }
-
- return constructor;
- },
- disallowProperty: function (obj, name, objectType) {
- if (obj[name] !== undefined) {
- throw new TypeError(objectType + " can't have a ." + name + " property.");
- }
- }
- };
- return api;
- }
-
- function _createElementDescriptor(def) {
- var key = _toPropertyKey(def.key);
-
- var descriptor;
-
- if (def.kind === "method") {
- descriptor = {
- value: def.value,
- writable: true,
- configurable: true,
- enumerable: false
- };
- } else if (def.kind === "get") {
- descriptor = {
- get: def.value,
- configurable: true,
- enumerable: false
- };
- } else if (def.kind === "set") {
- descriptor = {
- set: def.value,
- configurable: true,
- enumerable: false
- };
- } else if (def.kind === "field") {
- descriptor = {
- configurable: true,
- writable: true,
- enumerable: true
- };
- }
-
- var element = {
- kind: def.kind === "field" ? "field" : "method",
- key: key,
- placement: def.static ? "static" : def.kind === "field" ? "own" : "prototype",
- descriptor: descriptor
- };
- if (def.decorators) element.decorators = def.decorators;
- if (def.kind === "field") element.initializer = def.value;
- return element;
- }
-
- function _coalesceGetterSetter(element, other) {
- if (element.descriptor.get !== undefined) {
- other.descriptor.get = element.descriptor.get;
- } else {
- other.descriptor.set = element.descriptor.set;
- }
- }
-
- function _coalesceClassElements(elements) {
- var newElements = [];
-
- var isSameElement = function (other) {
- return other.kind === "method" && other.key === element.key && other.placement === element.placement;
- };
-
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- var other;
-
- if (element.kind === "method" && (other = newElements.find(isSameElement))) {
- if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
- if (_hasDecorators(element) || _hasDecorators(other)) {
- throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
- }
-
- other.descriptor = element.descriptor;
- } else {
- if (_hasDecorators(element)) {
- if (_hasDecorators(other)) {
- throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
- }
-
- other.decorators = element.decorators;
- }
-
- _coalesceGetterSetter(element, other);
- }
- } else {
- newElements.push(element);
- }
- }
-
- return newElements;
- }
-
- function _hasDecorators(element) {
- return element.decorators && element.decorators.length;
- }
-
- function _isDataDescriptor(desc) {
- return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
- }
-
- function _optionalCallableProperty(obj, name) {
- var value = obj[name];
-
- if (value !== undefined && typeof value !== "function") {
- throw new TypeError("Expected '" + name + "' to be a function");
- }
-
- return value;
- }
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- const directives = new WeakMap();
- /**
- * Brands a function as a directive factory function so that lit-html will call
- * the function during template rendering, rather than passing as a value.
- *
- * A _directive_ is a function that takes a Part as an argument. It has the
- * signature: `(part: Part) => void`.
- *
- * A directive _factory_ is a function that takes arguments for data and
- * configuration and returns a directive. Users of directive usually refer to
- * the directive factory as the directive. For example, "The repeat directive".
- *
- * Usually a template author will invoke a directive factory in their template
- * with relevant arguments, which will then return a directive function.
- *
- * Here's an example of using the `repeat()` directive factory that takes an
- * array and a function to render an item:
- *
- * ```js
- * html`
<${repeat(items, (item) => html`
${item}
`)}
`
- * ```
- *
- * When `repeat` is invoked, it returns a directive function that closes over
- * `items` and the template function. When the outer template is rendered, the
- * return directive function is called with the Part for the expression.
- * `repeat` then performs it's custom logic to render multiple items.
- *
- * @param f The directive factory function. Must be a function that returns a
- * function of the signature `(part: Part) => void`. The returned function will
- * be called with the part object.
- *
- * @example
- *
- * import {directive, html} from 'lit-html';
- *
- * const immutable = directive((v) => (part) => {
- * if (part.value !== v) {
- * part.setValue(v)
- * }
- * });
- */
- const directive = (f) => ((...args) => {
- const d = f(...args);
- directives.set(d, true);
- return d;
- });
- const isDirective = (o) => {
- return typeof o === 'function' && directives.has(o);
- };
- //# sourceMappingURL=directive.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * True if the custom elements polyfill is in use.
- */
- const isCEPolyfill = window.customElements !== undefined &&
- window.customElements.polyfillWrapFlushCallback !==
- undefined;
- /**
- * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from
- * `container`.
- */
- const removeNodes = (container, start, end = null) => {
- while (start !== end) {
- const n = start.nextSibling;
- container.removeChild(start);
- start = n;
- }
- };
- //# sourceMappingURL=dom.js.map
-
- /**
- * @license
- * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * A sentinel value that signals that a value was handled by a directive and
- * should not be written to the DOM.
- */
- const noChange = {};
- /**
- * A sentinel value that signals a NodePart to fully clear its content.
- */
- const nothing = {};
- //# sourceMappingURL=part.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * An expression marker with embedded unique key to avoid collision with
- * possible text in templates.
- */
- const marker = `{{lit-${String(Math.random()).slice(2)}}}`;
- /**
- * An expression marker used text-positions, multi-binding attributes, and
- * attributes with markup-like text values.
- */
- const nodeMarker = ``;
- const markerRegex = new RegExp(`${marker}|${nodeMarker}`);
- /**
- * Suffix appended to all bound attribute names.
- */
- const boundAttributeSuffix = '$lit$';
- /**
- * An updateable Template that tracks the location of dynamic parts.
- */
- class Template {
- constructor(result, element) {
- this.parts = [];
- this.element = element;
- const nodesToRemove = [];
- const stack = [];
- // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
- const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
- // Keeps track of the last index associated with a part. We try to delete
- // unnecessary nodes, but we never want to associate two different parts
- // to the same index. They must have a constant node between.
- let lastPartIndex = 0;
- let index = -1;
- let partIndex = 0;
- const { strings, values: { length } } = result;
- while (partIndex < length) {
- const node = walker.nextNode();
- if (node === null) {
- // We've exhausted the content inside a nested template element.
- // Because we still have parts (the outer for-loop), we know:
- // - There is a template in the stack
- // - The walker will find a nextNode outside the template
- walker.currentNode = stack.pop();
- continue;
- }
- index++;
- if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {
- if (node.hasAttributes()) {
- const attributes = node.attributes;
- const { length } = attributes;
- // Per
- // https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,
- // attributes are not guaranteed to be returned in document order.
- // In particular, Edge/IE can return them out of order, so we cannot
- // assume a correspondence between part index and attribute index.
- let count = 0;
- for (let i = 0; i < length; i++) {
- if (endsWith(attributes[i].name, boundAttributeSuffix)) {
- count++;
- }
- }
- while (count-- > 0) {
- // Get the template literal section leading up to the first
- // expression in this attribute
- const stringForPart = strings[partIndex];
- // Find the attribute name
- const name = lastAttributeNameRegex.exec(stringForPart)[2];
- // Find the corresponding attribute
- // All bound attributes have had a suffix added in
- // TemplateResult#getHTML to opt out of special attribute
- // handling. To look up the attribute value we also need to add
- // the suffix.
- const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;
- const attributeValue = node.getAttribute(attributeLookupName);
- node.removeAttribute(attributeLookupName);
- const statics = attributeValue.split(markerRegex);
- this.parts.push({ type: 'attribute', index, name, strings: statics });
- partIndex += statics.length - 1;
- }
- }
- if (node.tagName === 'TEMPLATE') {
- stack.push(node);
- walker.currentNode = node.content;
- }
- }
- else if (node.nodeType === 3 /* Node.TEXT_NODE */) {
- const data = node.data;
- if (data.indexOf(marker) >= 0) {
- const parent = node.parentNode;
- const strings = data.split(markerRegex);
- const lastIndex = strings.length - 1;
- // Generate a new text node for each literal section
- // These nodes are also used as the markers for node parts
- for (let i = 0; i < lastIndex; i++) {
- let insert;
- let s = strings[i];
- if (s === '') {
- insert = createMarker();
- }
- else {
- const match = lastAttributeNameRegex.exec(s);
- if (match !== null && endsWith(match[2], boundAttributeSuffix)) {
- s = s.slice(0, match.index) + match[1] +
- match[2].slice(0, -boundAttributeSuffix.length) + match[3];
- }
- insert = document.createTextNode(s);
- }
- parent.insertBefore(insert, node);
- this.parts.push({ type: 'node', index: ++index });
- }
- // If there's no text, we must insert a comment to mark our place.
- // Else, we can trust it will stick around after cloning.
- if (strings[lastIndex] === '') {
- parent.insertBefore(createMarker(), node);
- nodesToRemove.push(node);
- }
- else {
- node.data = strings[lastIndex];
- }
- // We have a part for each match found
- partIndex += lastIndex;
- }
- }
- else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {
- if (node.data === marker) {
- const parent = node.parentNode;
- // Add a new marker node to be the startNode of the Part if any of
- // the following are true:
- // * We don't have a previousSibling
- // * The previousSibling is already the start of a previous part
- if (node.previousSibling === null || index === lastPartIndex) {
- index++;
- parent.insertBefore(createMarker(), node);
- }
- lastPartIndex = index;
- this.parts.push({ type: 'node', index });
- // If we don't have a nextSibling, keep this node so we have an end.
- // Else, we can remove it to save future costs.
- if (node.nextSibling === null) {
- node.data = '';
- }
- else {
- nodesToRemove.push(node);
- index--;
- }
- partIndex++;
- }
- else {
- let i = -1;
- while ((i = node.data.indexOf(marker, i + 1)) !== -1) {
- // Comment node has a binding marker inside, make an inactive part
- // The binding won't work, but subsequent bindings will
- // TODO (justinfagnani): consider whether it's even worth it to
- // make bindings in comments work
- this.parts.push({ type: 'node', index: -1 });
- partIndex++;
- }
- }
- }
- }
- // Remove text binding nodes after the walk to not disturb the TreeWalker
- for (const n of nodesToRemove) {
- n.parentNode.removeChild(n);
- }
- }
- }
- const endsWith = (str, suffix) => {
- const index = str.length - suffix.length;
- return index >= 0 && str.slice(index) === suffix;
- };
- const isTemplatePartActive = (part) => part.index !== -1;
- // Allows `document.createComment('')` to be renamed for a
- // small manual size-savings.
- const createMarker = () => document.createComment('');
- /**
- * This regex extracts the attribute name preceding an attribute-position
- * expression. It does this by matching the syntax allowed for attributes
- * against the string literal directly preceding the expression, assuming that
- * the expression is in an attribute-value position.
- *
- * See attributes in the HTML spec:
- * https://www.w3.org/TR/html5/syntax.html#elements-attributes
- *
- * " \x09\x0a\x0c\x0d" are HTML space characters:
- * https://www.w3.org/TR/html5/infrastructure.html#space-characters
- *
- * "\0-\x1F\x7F-\x9F" are Unicode control characters, which includes every
- * space character except " ".
- *
- * So an attribute is:
- * * The name: any character except a control character, space character, ('),
- * ("), ">", "=", or "/"
- * * Followed by zero or more space characters
- * * Followed by "="
- * * Followed by zero or more space characters
- * * Followed by:
- * * Any character except space, ('), ("), "<", ">", "=", (`), or
- * * (") then any non-("), or
- * * (') then any non-(')
- */
- const lastAttributeNameRegex = /([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
- //# sourceMappingURL=template.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * An instance of a `Template` that can be attached to the DOM and updated
- * with new values.
- */
- class TemplateInstance {
- constructor(template, processor, options) {
- this.__parts = [];
- this.template = template;
- this.processor = processor;
- this.options = options;
- }
- update(values) {
- let i = 0;
- for (const part of this.__parts) {
- if (part !== undefined) {
- part.setValue(values[i]);
- }
- i++;
- }
- for (const part of this.__parts) {
- if (part !== undefined) {
- part.commit();
- }
- }
- }
- _clone() {
- // There are a number of steps in the lifecycle of a template instance's
- // DOM fragment:
- // 1. Clone - create the instance fragment
- // 2. Adopt - adopt into the main document
- // 3. Process - find part markers and create parts
- // 4. Upgrade - upgrade custom elements
- // 5. Update - set node, attribute, property, etc., values
- // 6. Connect - connect to the document. Optional and outside of this
- // method.
- //
- // We have a few constraints on the ordering of these steps:
- // * We need to upgrade before updating, so that property values will pass
- // through any property setters.
- // * We would like to process before upgrading so that we're sure that the
- // cloned fragment is inert and not disturbed by self-modifying DOM.
- // * We want custom elements to upgrade even in disconnected fragments.
- //
- // Given these constraints, with full custom elements support we would
- // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect
- //
- // But Safari dooes not implement CustomElementRegistry#upgrade, so we
- // can not implement that order and still have upgrade-before-update and
- // upgrade disconnected fragments. So we instead sacrifice the
- // process-before-upgrade constraint, since in Custom Elements v1 elements
- // must not modify their light DOM in the constructor. We still have issues
- // when co-existing with CEv0 elements like Polymer 1, and with polyfills
- // that don't strictly adhere to the no-modification rule because shadow
- // DOM, which may be created in the constructor, is emulated by being placed
- // in the light DOM.
- //
- // The resulting order is on native is: Clone, Adopt, Upgrade, Process,
- // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade
- // in one step.
- //
- // The Custom Elements v1 polyfill supports upgrade(), so the order when
- // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,
- // Connect.
- const fragment = isCEPolyfill ?
- this.template.element.content.cloneNode(true) :
- document.importNode(this.template.element.content, true);
- const stack = [];
- const parts = this.template.parts;
- // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null
- const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);
- let partIndex = 0;
- let nodeIndex = 0;
- let part;
- let node = walker.nextNode();
- // Loop through all the nodes and parts of a template
- while (partIndex < parts.length) {
- part = parts[partIndex];
- if (!isTemplatePartActive(part)) {
- this.__parts.push(undefined);
- partIndex++;
- continue;
- }
- // Progress the tree walker until we find our next part's node.
- // Note that multiple parts may share the same node (attribute parts
- // on a single element), so this loop may not run at all.
- while (nodeIndex < part.index) {
- nodeIndex++;
- if (node.nodeName === 'TEMPLATE') {
- stack.push(node);
- walker.currentNode = node.content;
- }
- if ((node = walker.nextNode()) === null) {
- // We've exhausted the content inside a nested template element.
- // Because we still have parts (the outer for-loop), we know:
- // - There is a template in the stack
- // - The walker will find a nextNode outside the template
- walker.currentNode = stack.pop();
- node = walker.nextNode();
- }
- }
- // We've arrived at our part's node.
- if (part.type === 'node') {
- const part = this.processor.handleTextExpression(this.options);
- part.insertAfterNode(node.previousSibling);
- this.__parts.push(part);
- }
- else {
- this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));
- }
- partIndex++;
- }
- if (isCEPolyfill) {
- document.adoptNode(fragment);
- customElements.upgrade(fragment);
- }
- return fragment;
- }
- }
- //# sourceMappingURL=template-instance.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- const commentMarker = ` ${marker} `;
- /**
- * The return type of `html`, which holds a Template and the values from
- * interpolated expressions.
- */
- class TemplateResult {
- constructor(strings, values, type, processor) {
- this.strings = strings;
- this.values = values;
- this.type = type;
- this.processor = processor;
- }
- /**
- * Returns a string of HTML used to create a `` element.
- */
- getHTML() {
- const l = this.strings.length - 1;
- let html = '';
- let isCommentBinding = false;
- for (let i = 0; i < l; i++) {
- const s = this.strings[i];
- // For each binding we want to determine the kind of marker to insert
- // into the template source before it's parsed by the browser's HTML
- // parser. The marker type is based on whether the expression is in an
- // attribute, text, or comment poisition.
- // * For node-position bindings we insert a comment with the marker
- // sentinel as its text content, like .
- // * For attribute bindings we insert just the marker sentinel for the
- // first binding, so that we support unquoted attribute bindings.
- // Subsequent bindings can use a comment marker because multi-binding
- // attributes must be quoted.
- // * For comment bindings we insert just the marker sentinel so we don't
- // close the comment.
- //
- // The following code scans the template source, but is *not* an HTML
- // parser. We don't need to track the tree structure of the HTML, only
- // whether a binding is inside a comment, and if not, if it appears to be
- // the first binding in an attribute.
- const commentOpen = s.lastIndexOf('', commentOpen + 1) === -1;
- // Check to see if we have an attribute-like sequence preceeding the
- // expression. This can match "name=value" like structures in text,
- // comments, and attribute values, so there can be false-positives.
- const attributeMatch = lastAttributeNameRegex.exec(s);
- if (attributeMatch === null) {
- // We're only in this branch if we don't have a attribute-like
- // preceeding sequence. For comments, this guards against unusual
- // attribute values like
. Cases like
- // are handled correctly in the attribute branch
- // below.
- html += s + (isCommentBinding ? commentMarker : nodeMarker);
- }
- else {
- // For attributes we use just a marker sentinel, and also append a
- // $lit$ suffix to the name to opt-out of attribute-specific parsing
- // that IE and Edge do for style and certain SVG attributes.
- html += s.substr(0, attributeMatch.index) + attributeMatch[1] +
- attributeMatch[2] + boundAttributeSuffix + attributeMatch[3] +
- marker;
- }
- }
- html += this.strings[l];
- return html;
- }
- getTemplateElement() {
- const template = document.createElement('template');
- template.innerHTML = this.getHTML();
- return template;
- }
- }
- //# sourceMappingURL=template-result.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- const isPrimitive = (value) => {
- return (value === null ||
- !(typeof value === 'object' || typeof value === 'function'));
- };
- const isIterable = (value) => {
- return Array.isArray(value) ||
- // tslint:disable-next-line:no-any
- !!(value && value[Symbol.iterator]);
- };
- /**
- * Writes attribute values to the DOM for a group of AttributeParts bound to a
- * single attibute. The value is only set once even if there are multiple parts
- * for an attribute.
- */
- class AttributeCommitter {
- constructor(element, name, strings) {
- this.dirty = true;
- this.element = element;
- this.name = name;
- this.strings = strings;
- this.parts = [];
- for (let i = 0; i < strings.length - 1; i++) {
- this.parts[i] = this._createPart();
- }
- }
- /**
- * Creates a single part. Override this to create a differnt type of part.
- */
- _createPart() {
- return new AttributePart(this);
- }
- _getValue() {
- const strings = this.strings;
- const l = strings.length - 1;
- let text = '';
- for (let i = 0; i < l; i++) {
- text += strings[i];
- const part = this.parts[i];
- if (part !== undefined) {
- const v = part.value;
- if (isPrimitive(v) || !isIterable(v)) {
- text += typeof v === 'string' ? v : String(v);
- }
- else {
- for (const t of v) {
- text += typeof t === 'string' ? t : String(t);
- }
- }
- }
- }
- text += strings[l];
- return text;
- }
- commit() {
- if (this.dirty) {
- this.dirty = false;
- this.element.setAttribute(this.name, this._getValue());
- }
- }
- }
- /**
- * A Part that controls all or part of an attribute value.
- */
- class AttributePart {
- constructor(committer) {
- this.value = undefined;
- this.committer = committer;
- }
- setValue(value) {
- if (value !== noChange && (!isPrimitive(value) || value !== this.value)) {
- this.value = value;
- // If the value is a not a directive, dirty the committer so that it'll
- // call setAttribute. If the value is a directive, it'll dirty the
- // committer if it calls setValue().
- if (!isDirective(value)) {
- this.committer.dirty = true;
- }
- }
- }
- commit() {
- while (isDirective(this.value)) {
- const directive = this.value;
- this.value = noChange;
- directive(this);
- }
- if (this.value === noChange) {
- return;
- }
- this.committer.commit();
- }
- }
- /**
- * A Part that controls a location within a Node tree. Like a Range, NodePart
- * has start and end locations and can set and update the Nodes between those
- * locations.
- *
- * NodeParts support several value types: primitives, Nodes, TemplateResults,
- * as well as arrays and iterables of those types.
- */
- class NodePart {
- constructor(options) {
- this.value = undefined;
- this.__pendingValue = undefined;
- this.options = options;
- }
- /**
- * Appends this part into a container.
- *
- * This part must be empty, as its contents are not automatically moved.
- */
- appendInto(container) {
- this.startNode = container.appendChild(createMarker());
- this.endNode = container.appendChild(createMarker());
- }
- /**
- * Inserts this part after the `ref` node (between `ref` and `ref`'s next
- * sibling). Both `ref` and its next sibling must be static, unchanging nodes
- * such as those that appear in a literal section of a template.
- *
- * This part must be empty, as its contents are not automatically moved.
- */
- insertAfterNode(ref) {
- this.startNode = ref;
- this.endNode = ref.nextSibling;
- }
- /**
- * Appends this part into a parent part.
- *
- * This part must be empty, as its contents are not automatically moved.
- */
- appendIntoPart(part) {
- part.__insert(this.startNode = createMarker());
- part.__insert(this.endNode = createMarker());
- }
- /**
- * Inserts this part after the `ref` part.
- *
- * This part must be empty, as its contents are not automatically moved.
- */
- insertAfterPart(ref) {
- ref.__insert(this.startNode = createMarker());
- this.endNode = ref.endNode;
- ref.endNode = this.startNode;
- }
- setValue(value) {
- this.__pendingValue = value;
- }
- commit() {
- while (isDirective(this.__pendingValue)) {
- const directive = this.__pendingValue;
- this.__pendingValue = noChange;
- directive(this);
- }
- const value = this.__pendingValue;
- if (value === noChange) {
- return;
- }
- if (isPrimitive(value)) {
- if (value !== this.value) {
- this.__commitText(value);
- }
- }
- else if (value instanceof TemplateResult) {
- this.__commitTemplateResult(value);
- }
- else if (value instanceof Node) {
- this.__commitNode(value);
- }
- else if (isIterable(value)) {
- this.__commitIterable(value);
- }
- else if (value === nothing) {
- this.value = nothing;
- this.clear();
- }
- else {
- // Fallback, will render the string representation
- this.__commitText(value);
- }
- }
- __insert(node) {
- this.endNode.parentNode.insertBefore(node, this.endNode);
- }
- __commitNode(value) {
- if (this.value === value) {
- return;
- }
- this.clear();
- this.__insert(value);
- this.value = value;
- }
- __commitText(value) {
- const node = this.startNode.nextSibling;
- value = value == null ? '' : value;
- // If `value` isn't already a string, we explicitly convert it here in case
- // it can't be implicitly converted - i.e. it's a symbol.
- const valueAsString = typeof value === 'string' ? value : String(value);
- if (node === this.endNode.previousSibling &&
- node.nodeType === 3 /* Node.TEXT_NODE */) {
- // If we only have a single text node between the markers, we can just
- // set its value, rather than replacing it.
- // TODO(justinfagnani): Can we just check if this.value is primitive?
- node.data = valueAsString;
- }
- else {
- this.__commitNode(document.createTextNode(valueAsString));
- }
- this.value = value;
- }
- __commitTemplateResult(value) {
- const template = this.options.templateFactory(value);
- if (this.value instanceof TemplateInstance &&
- this.value.template === template) {
- this.value.update(value.values);
- }
- else {
- // Make sure we propagate the template processor from the TemplateResult
- // so that we use its syntax extension, etc. The template factory comes
- // from the render function options so that it can control template
- // caching and preprocessing.
- const instance = new TemplateInstance(template, value.processor, this.options);
- const fragment = instance._clone();
- instance.update(value.values);
- this.__commitNode(fragment);
- this.value = instance;
- }
- }
- __commitIterable(value) {
- // For an Iterable, we create a new InstancePart per item, then set its
- // value to the item. This is a little bit of overhead for every item in
- // an Iterable, but it lets us recurse easily and efficiently update Arrays
- // of TemplateResults that will be commonly returned from expressions like:
- // array.map((i) => html`${i}`), by reusing existing TemplateInstances.
- // If _value is an array, then the previous render was of an
- // iterable and _value will contain the NodeParts from the previous
- // render. If _value is not an array, clear this part and make a new
- // array for NodeParts.
- if (!Array.isArray(this.value)) {
- this.value = [];
- this.clear();
- }
- // Lets us keep track of how many items we stamped so we can clear leftover
- // items from a previous render
- const itemParts = this.value;
- let partIndex = 0;
- let itemPart;
- for (const item of value) {
- // Try to reuse an existing part
- itemPart = itemParts[partIndex];
- // If no existing part, create a new one
- if (itemPart === undefined) {
- itemPart = new NodePart(this.options);
- itemParts.push(itemPart);
- if (partIndex === 0) {
- itemPart.appendIntoPart(this);
- }
- else {
- itemPart.insertAfterPart(itemParts[partIndex - 1]);
- }
- }
- itemPart.setValue(item);
- itemPart.commit();
- partIndex++;
- }
- if (partIndex < itemParts.length) {
- // Truncate the parts array so _value reflects the current state
- itemParts.length = partIndex;
- this.clear(itemPart && itemPart.endNode);
- }
- }
- clear(startNode = this.startNode) {
- removeNodes(this.startNode.parentNode, startNode.nextSibling, this.endNode);
- }
- }
- /**
- * Implements a boolean attribute, roughly as defined in the HTML
- * specification.
- *
- * If the value is truthy, then the attribute is present with a value of
- * ''. If the value is falsey, the attribute is removed.
- */
- class BooleanAttributePart {
- constructor(element, name, strings) {
- this.value = undefined;
- this.__pendingValue = undefined;
- if (strings.length !== 2 || strings[0] !== '' || strings[1] !== '') {
- throw new Error('Boolean attributes can only contain a single expression');
- }
- this.element = element;
- this.name = name;
- this.strings = strings;
- }
- setValue(value) {
- this.__pendingValue = value;
- }
- commit() {
- while (isDirective(this.__pendingValue)) {
- const directive = this.__pendingValue;
- this.__pendingValue = noChange;
- directive(this);
- }
- if (this.__pendingValue === noChange) {
- return;
- }
- const value = !!this.__pendingValue;
- if (this.value !== value) {
- if (value) {
- this.element.setAttribute(this.name, '');
- }
- else {
- this.element.removeAttribute(this.name);
- }
- this.value = value;
- }
- this.__pendingValue = noChange;
- }
- }
- /**
- * Sets attribute values for PropertyParts, so that the value is only set once
- * even if there are multiple parts for a property.
- *
- * If an expression controls the whole property value, then the value is simply
- * assigned to the property under control. If there are string literals or
- * multiple expressions, then the strings are expressions are interpolated into
- * a string first.
- */
- class PropertyCommitter extends AttributeCommitter {
- constructor(element, name, strings) {
- super(element, name, strings);
- this.single =
- (strings.length === 2 && strings[0] === '' && strings[1] === '');
- }
- _createPart() {
- return new PropertyPart(this);
- }
- _getValue() {
- if (this.single) {
- return this.parts[0].value;
- }
- return super._getValue();
- }
- commit() {
- if (this.dirty) {
- this.dirty = false;
- // tslint:disable-next-line:no-any
- this.element[this.name] = this._getValue();
- }
- }
- }
- class PropertyPart extends AttributePart {
- }
- // Detect event listener options support. If the `capture` property is read
- // from the options object, then options are supported. If not, then the thrid
- // argument to add/removeEventListener is interpreted as the boolean capture
- // value so we should only pass the `capture` property.
- let eventOptionsSupported = false;
- try {
- const options = {
- get capture() {
- eventOptionsSupported = true;
- return false;
- }
- };
- // tslint:disable-next-line:no-any
- window.addEventListener('test', options, options);
- // tslint:disable-next-line:no-any
- window.removeEventListener('test', options, options);
- }
- catch (_e) {
- }
- class EventPart {
- constructor(element, eventName, eventContext) {
- this.value = undefined;
- this.__pendingValue = undefined;
- this.element = element;
- this.eventName = eventName;
- this.eventContext = eventContext;
- this.__boundHandleEvent = (e) => this.handleEvent(e);
- }
- setValue(value) {
- this.__pendingValue = value;
- }
- commit() {
- while (isDirective(this.__pendingValue)) {
- const directive = this.__pendingValue;
- this.__pendingValue = noChange;
- directive(this);
- }
- if (this.__pendingValue === noChange) {
- return;
- }
- const newListener = this.__pendingValue;
- const oldListener = this.value;
- const shouldRemoveListener = newListener == null ||
- oldListener != null &&
- (newListener.capture !== oldListener.capture ||
- newListener.once !== oldListener.once ||
- newListener.passive !== oldListener.passive);
- const shouldAddListener = newListener != null && (oldListener == null || shouldRemoveListener);
- if (shouldRemoveListener) {
- this.element.removeEventListener(this.eventName, this.__boundHandleEvent, this.__options);
- }
- if (shouldAddListener) {
- this.__options = getOptions(newListener);
- this.element.addEventListener(this.eventName, this.__boundHandleEvent, this.__options);
- }
- this.value = newListener;
- this.__pendingValue = noChange;
- }
- handleEvent(event) {
- if (typeof this.value === 'function') {
- this.value.call(this.eventContext || this.element, event);
- }
- else {
- this.value.handleEvent(event);
- }
- }
- }
- // We copy options because of the inconsistent behavior of browsers when reading
- // the third argument of add/removeEventListener. IE11 doesn't support options
- // at all. Chrome 41 only reads `capture` if the argument is an object.
- const getOptions = (o) => o &&
- (eventOptionsSupported ?
- { capture: o.capture, passive: o.passive, once: o.once } :
- o.capture);
- //# sourceMappingURL=parts.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * Creates Parts when a template is instantiated.
- */
- class DefaultTemplateProcessor {
- /**
- * Create parts for an attribute-position binding, given the event, attribute
- * name, and string literals.
- *
- * @param element The element containing the binding
- * @param name The attribute name
- * @param strings The string literals. There are always at least two strings,
- * event for fully-controlled bindings with a single expression.
- */
- handleAttributeExpressions(element, name, strings, options) {
- const prefix = name[0];
- if (prefix === '.') {
- const committer = new PropertyCommitter(element, name.slice(1), strings);
- return committer.parts;
- }
- if (prefix === '@') {
- return [new EventPart(element, name.slice(1), options.eventContext)];
- }
- if (prefix === '?') {
- return [new BooleanAttributePart(element, name.slice(1), strings)];
- }
- const committer = new AttributeCommitter(element, name, strings);
- return committer.parts;
- }
- /**
- * Create parts for a text-position binding.
- * @param templateFactory
- */
- handleTextExpression(options) {
- return new NodePart(options);
- }
- }
- const defaultTemplateProcessor = new DefaultTemplateProcessor();
- //# sourceMappingURL=default-template-processor.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- /**
- * The default TemplateFactory which caches Templates keyed on
- * result.type and result.strings.
- */
- function templateFactory(result) {
- let templateCache = templateCaches.get(result.type);
- if (templateCache === undefined) {
- templateCache = {
- stringsArray: new WeakMap(),
- keyString: new Map()
- };
- templateCaches.set(result.type, templateCache);
- }
- let template = templateCache.stringsArray.get(result.strings);
- if (template !== undefined) {
- return template;
- }
- // If the TemplateStringsArray is new, generate a key from the strings
- // This key is shared between all templates with identical content
- const key = result.strings.join(marker);
- // Check if we already have a Template for this key
- template = templateCache.keyString.get(key);
- if (template === undefined) {
- // If we have not seen this key before, create a new Template
- template = new Template(result, result.getTemplateElement());
- // Cache the Template for this key
- templateCache.keyString.set(key, template);
- }
- // Cache all future queries for this TemplateStringsArray
- templateCache.stringsArray.set(result.strings, template);
- return template;
- }
- const templateCaches = new Map();
- //# sourceMappingURL=template-factory.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- const parts = new WeakMap();
- /**
- * Renders a template result or other value to a container.
- *
- * To update a container with new values, reevaluate the template literal and
- * call `render` with the new result.
- *
- * @param result Any value renderable by NodePart - typically a TemplateResult
- * created by evaluating a template tag like `html` or `svg`.
- * @param container A DOM parent to render to. The entire contents are either
- * replaced, or efficiently updated if the same result type was previous
- * rendered there.
- * @param options RenderOptions for the entire render tree rendered to this
- * container. Render options must *not* change between renders to the same
- * container, as those changes will not effect previously rendered DOM.
- */
- const render = (result, container, options) => {
- let part = parts.get(container);
- if (part === undefined) {
- removeNodes(container, container.firstChild);
- parts.set(container, part = new NodePart(Object.assign({ templateFactory }, options)));
- part.appendInto(container);
- }
- part.setValue(result);
- part.commit();
- };
- //# sourceMappingURL=render.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- // IMPORTANT: do not change the property name or the assignment expression.
- // This line will be used in regexes to search for lit-html usage.
- // TODO(justinfagnani): inject version number at build time
- (window['litHtmlVersions'] || (window['litHtmlVersions'] = [])).push('1.1.2');
- /**
- * Interprets a template literal as an HTML template that can efficiently
- * render to and update a container.
- */
- const html = (strings, ...values) => new TemplateResult(strings, values, 'html', defaultTemplateProcessor);
- //# sourceMappingURL=lit-html.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- const walkerNodeFilter = 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */;
- /**
- * Removes the list of nodes from a Template safely. In addition to removing
- * nodes from the Template, the Template part indices are updated to match
- * the mutated Template DOM.
- *
- * As the template is walked the removal state is tracked and
- * part indices are adjusted as needed.
- *
- * div
- * div#1 (remove) <-- start removing (removing node is div#1)
- * div
- * div#2 (remove) <-- continue removing (removing node is still div#1)
- * div
- * div <-- stop removing since previous sibling is the removing node (div#1,
- * removed 4 nodes)
- */
- function removeNodesFromTemplate(template, nodesToRemove) {
- const { element: { content }, parts } = template;
- const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
- let partIndex = nextActiveIndexInTemplateParts(parts);
- let part = parts[partIndex];
- let nodeIndex = -1;
- let removeCount = 0;
- const nodesToRemoveInTemplate = [];
- let currentRemovingNode = null;
- while (walker.nextNode()) {
- nodeIndex++;
- const node = walker.currentNode;
- // End removal if stepped past the removing node
- if (node.previousSibling === currentRemovingNode) {
- currentRemovingNode = null;
- }
- // A node to remove was found in the template
- if (nodesToRemove.has(node)) {
- nodesToRemoveInTemplate.push(node);
- // Track node we're removing
- if (currentRemovingNode === null) {
- currentRemovingNode = node;
- }
- }
- // When removing, increment count by which to adjust subsequent part indices
- if (currentRemovingNode !== null) {
- removeCount++;
- }
- while (part !== undefined && part.index === nodeIndex) {
- // If part is in a removed node deactivate it by setting index to -1 or
- // adjust the index as needed.
- part.index = currentRemovingNode !== null ? -1 : part.index - removeCount;
- // go to the next active part.
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
- part = parts[partIndex];
- }
- }
- nodesToRemoveInTemplate.forEach((n) => n.parentNode.removeChild(n));
- }
- const countNodes = (node) => {
- let count = (node.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */) ? 0 : 1;
- const walker = document.createTreeWalker(node, walkerNodeFilter, null, false);
- while (walker.nextNode()) {
- count++;
- }
- return count;
- };
- const nextActiveIndexInTemplateParts = (parts, startIndex = -1) => {
- for (let i = startIndex + 1; i < parts.length; i++) {
- const part = parts[i];
- if (isTemplatePartActive(part)) {
- return i;
- }
- }
- return -1;
- };
- /**
- * Inserts the given node into the Template, optionally before the given
- * refNode. In addition to inserting the node into the Template, the Template
- * part indices are updated to match the mutated Template DOM.
- */
- function insertNodeIntoTemplate(template, node, refNode = null) {
- const { element: { content }, parts } = template;
- // If there's no refNode, then put node at end of template.
- // No part indices need to be shifted in this case.
- if (refNode === null || refNode === undefined) {
- content.appendChild(node);
- return;
- }
- const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);
- let partIndex = nextActiveIndexInTemplateParts(parts);
- let insertCount = 0;
- let walkerIndex = -1;
- while (walker.nextNode()) {
- walkerIndex++;
- const walkerNode = walker.currentNode;
- if (walkerNode === refNode) {
- insertCount = countNodes(node);
- refNode.parentNode.insertBefore(node, refNode);
- }
- while (partIndex !== -1 && parts[partIndex].index === walkerIndex) {
- // If we've inserted the node, simply adjust all subsequent parts
- if (insertCount > 0) {
- while (partIndex !== -1) {
- parts[partIndex].index += insertCount;
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
- }
- return;
- }
- partIndex = nextActiveIndexInTemplateParts(parts, partIndex);
- }
- }
- }
- //# sourceMappingURL=modify-template.js.map
-
- /**
- * @license
- * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at
- * http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at
- * http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at
- * http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at
- * http://polymer.github.io/PATENTS.txt
- */
- // Get a key to lookup in `templateCaches`.
- const getTemplateCacheKey = (type, scopeName) => `${type}--${scopeName}`;
- let compatibleShadyCSSVersion = true;
- if (typeof window.ShadyCSS === 'undefined') {
- compatibleShadyCSSVersion = false;
- }
- else if (typeof window.ShadyCSS.prepareTemplateDom === 'undefined') {
- console.warn(`Incompatible ShadyCSS version detected. ` +
- `Please update to at least @webcomponents/webcomponentsjs@2.0.2 and ` +
- `@webcomponents/shadycss@1.3.1.`);
- compatibleShadyCSSVersion = false;
- }
- /**
- * Template factory which scopes template DOM using ShadyCSS.
- * @param scopeName {string}
- */
- const shadyTemplateFactory = (scopeName) => (result) => {
- const cacheKey = getTemplateCacheKey(result.type, scopeName);
- let templateCache = templateCaches.get(cacheKey);
- if (templateCache === undefined) {
- templateCache = {
- stringsArray: new WeakMap(),
- keyString: new Map()
- };
- templateCaches.set(cacheKey, templateCache);
- }
- let template = templateCache.stringsArray.get(result.strings);
- if (template !== undefined) {
- return template;
- }
- const key = result.strings.join(marker);
- template = templateCache.keyString.get(key);
- if (template === undefined) {
- const element = result.getTemplateElement();
- if (compatibleShadyCSSVersion) {
- window.ShadyCSS.prepareTemplateDom(element, scopeName);
- }
- template = new Template(result, element);
- templateCache.keyString.set(key, template);
- }
- templateCache.stringsArray.set(result.strings, template);
- return template;
- };
- const TEMPLATE_TYPES = ['html', 'svg'];
- /**
- * Removes all style elements from Templates for the given scopeName.
- */
- const removeStylesFromLitTemplates = (scopeName) => {
- TEMPLATE_TYPES.forEach((type) => {
- const templates = templateCaches.get(getTemplateCacheKey(type, scopeName));
- if (templates !== undefined) {
- templates.keyString.forEach((template) => {
- const { element: { content } } = template;
- // IE 11 doesn't support the iterable param Set constructor
- const styles = new Set();
- Array.from(content.querySelectorAll('style')).forEach((s) => {
- styles.add(s);
- });
- removeNodesFromTemplate(template, styles);
- });
- }
- });
- };
- const shadyRenderSet = new Set();
- /**
- * For the given scope name, ensures that ShadyCSS style scoping is performed.
- * This is done just once per scope name so the fragment and template cannot
- * be modified.
- * (1) extracts styles from the rendered fragment and hands them to ShadyCSS
- * to be scoped and appended to the document
- * (2) removes style elements from all lit-html Templates for this scope name.
- *
- * Note,
-
+
-
-
+ ${this.loading?B`loading`:B`
+
+ `}
- `;
- }
- }]
- };
- }, LitElement);
-
- exports.NftCard = NftCard;
-
- return exports;
-
-}({}));
-//# sourceMappingURL=nft-card.js.map
+ `}}]}}),ht);return t.NftCard=qt,t}({});//# sourceMappingURL=nft-card.js.map
diff --git a/dist/nft-card.js.map b/dist/nft-card.js.map
index d537000..1ec867b 100644
--- a/dist/nft-card.js.map
+++ b/dist/nft-card.js.map
@@ -1 +1 @@
-{"version":3,"file":"nft-card.js","sources":["../node_modules/lit-html/lib/directive.js","../node_modules/lit-html/lib/dom.js","../node_modules/lit-html/lib/part.js","../node_modules/lit-html/lib/template.js","../node_modules/lit-html/lib/template-instance.js","../node_modules/lit-html/lib/template-result.js","../node_modules/lit-html/lib/parts.js","../node_modules/lit-html/lib/default-template-processor.js","../node_modules/lit-html/lib/template-factory.js","../node_modules/lit-html/lib/render.js","../node_modules/lit-html/lit-html.js","../node_modules/lit-html/lib/modify-template.js","../node_modules/lit-html/lib/shady-render.js","../node_modules/lit-element/lib/updating-element.js","../node_modules/lit-element/lib/decorators.js","../node_modules/lit-element/lib/css-tag.js","../node_modules/lit-element/lit-element.js","../node_modules/lit-html/directives/style-map.js","../src/pill.ts","../src/nft-card-front.ts","../src/nft-card-back.ts","../src/nft-card.ts"],"sourcesContent":["/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\nconst directives = new WeakMap();\n/**\n * Brands a function as a directive factory function so that lit-html will call\n * the function during template rendering, rather than passing as a value.\n *\n * A _directive_ is a function that takes a Part as an argument. It has the\n * signature: `(part: Part) => void`.\n *\n * A directive _factory_ is a function that takes arguments for data and\n * configuration and returns a directive. Users of directive usually refer to\n * the directive factory as the directive. For example, \"The repeat directive\".\n *\n * Usually a template author will invoke a directive factory in their template\n * with relevant arguments, which will then return a directive function.\n *\n * Here's an example of using the `repeat()` directive factory that takes an\n * array and a function to render an item:\n *\n * ```js\n * html`
<${repeat(items, (item) => html`
${item}
`)}
`\n * ```\n *\n * When `repeat` is invoked, it returns a directive function that closes over\n * `items` and the template function. When the outer template is rendered, the\n * return directive function is called with the Part for the expression.\n * `repeat` then performs it's custom logic to render multiple items.\n *\n * @param f The directive factory function. Must be a function that returns a\n * function of the signature `(part: Part) => void`. The returned function will\n * be called with the part object.\n *\n * @example\n *\n * import {directive, html} from 'lit-html';\n *\n * const immutable = directive((v) => (part) => {\n * if (part.value !== v) {\n * part.setValue(v)\n * }\n * });\n */\nexport const directive = (f) => ((...args) => {\n const d = f(...args);\n directives.set(d, true);\n return d;\n});\nexport const isDirective = (o) => {\n return typeof o === 'function' && directives.has(o);\n};\n//# sourceMappingURL=directive.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * True if the custom elements polyfill is in use.\n */\nexport const isCEPolyfill = window.customElements !== undefined &&\n window.customElements.polyfillWrapFlushCallback !==\n undefined;\n/**\n * Reparents nodes, starting from `start` (inclusive) to `end` (exclusive),\n * into another container (could be the same container), before `before`. If\n * `before` is null, it appends the nodes to the container.\n */\nexport const reparentNodes = (container, start, end = null, before = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.insertBefore(start, before);\n start = n;\n }\n};\n/**\n * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from\n * `container`.\n */\nexport const removeNodes = (container, start, end = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.removeChild(start);\n start = n;\n }\n};\n//# sourceMappingURL=dom.js.map","/**\n * @license\n * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * A sentinel value that signals that a value was handled by a directive and\n * should not be written to the DOM.\n */\nexport const noChange = {};\n/**\n * A sentinel value that signals a NodePart to fully clear its content.\n */\nexport const nothing = {};\n//# sourceMappingURL=part.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * An expression marker with embedded unique key to avoid collision with\n * possible text in templates.\n */\nexport const marker = `{{lit-${String(Math.random()).slice(2)}}}`;\n/**\n * An expression marker used text-positions, multi-binding attributes, and\n * attributes with markup-like text values.\n */\nexport const nodeMarker = ``;\nexport const markerRegex = new RegExp(`${marker}|${nodeMarker}`);\n/**\n * Suffix appended to all bound attribute names.\n */\nexport const boundAttributeSuffix = '$lit$';\n/**\n * An updateable Template that tracks the location of dynamic parts.\n */\nexport class Template {\n constructor(result, element) {\n this.parts = [];\n this.element = element;\n const nodesToRemove = [];\n const stack = [];\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n // Keeps track of the last index associated with a part. We try to delete\n // unnecessary nodes, but we never want to associate two different parts\n // to the same index. They must have a constant node between.\n let lastPartIndex = 0;\n let index = -1;\n let partIndex = 0;\n const { strings, values: { length } } = result;\n while (partIndex < length) {\n const node = walker.nextNode();\n if (node === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n continue;\n }\n index++;\n if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {\n if (node.hasAttributes()) {\n const attributes = node.attributes;\n const { length } = attributes;\n // Per\n // https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,\n // attributes are not guaranteed to be returned in document order.\n // In particular, Edge/IE can return them out of order, so we cannot\n // assume a correspondence between part index and attribute index.\n let count = 0;\n for (let i = 0; i < length; i++) {\n if (endsWith(attributes[i].name, boundAttributeSuffix)) {\n count++;\n }\n }\n while (count-- > 0) {\n // Get the template literal section leading up to the first\n // expression in this attribute\n const stringForPart = strings[partIndex];\n // Find the attribute name\n const name = lastAttributeNameRegex.exec(stringForPart)[2];\n // Find the corresponding attribute\n // All bound attributes have had a suffix added in\n // TemplateResult#getHTML to opt out of special attribute\n // handling. To look up the attribute value we also need to add\n // the suffix.\n const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;\n const attributeValue = node.getAttribute(attributeLookupName);\n node.removeAttribute(attributeLookupName);\n const statics = attributeValue.split(markerRegex);\n this.parts.push({ type: 'attribute', index, name, strings: statics });\n partIndex += statics.length - 1;\n }\n }\n if (node.tagName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n }\n else if (node.nodeType === 3 /* Node.TEXT_NODE */) {\n const data = node.data;\n if (data.indexOf(marker) >= 0) {\n const parent = node.parentNode;\n const strings = data.split(markerRegex);\n const lastIndex = strings.length - 1;\n // Generate a new text node for each literal section\n // These nodes are also used as the markers for node parts\n for (let i = 0; i < lastIndex; i++) {\n let insert;\n let s = strings[i];\n if (s === '') {\n insert = createMarker();\n }\n else {\n const match = lastAttributeNameRegex.exec(s);\n if (match !== null && endsWith(match[2], boundAttributeSuffix)) {\n s = s.slice(0, match.index) + match[1] +\n match[2].slice(0, -boundAttributeSuffix.length) + match[3];\n }\n insert = document.createTextNode(s);\n }\n parent.insertBefore(insert, node);\n this.parts.push({ type: 'node', index: ++index });\n }\n // If there's no text, we must insert a comment to mark our place.\n // Else, we can trust it will stick around after cloning.\n if (strings[lastIndex] === '') {\n parent.insertBefore(createMarker(), node);\n nodesToRemove.push(node);\n }\n else {\n node.data = strings[lastIndex];\n }\n // We have a part for each match found\n partIndex += lastIndex;\n }\n }\n else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {\n if (node.data === marker) {\n const parent = node.parentNode;\n // Add a new marker node to be the startNode of the Part if any of\n // the following are true:\n // * We don't have a previousSibling\n // * The previousSibling is already the start of a previous part\n if (node.previousSibling === null || index === lastPartIndex) {\n index++;\n parent.insertBefore(createMarker(), node);\n }\n lastPartIndex = index;\n this.parts.push({ type: 'node', index });\n // If we don't have a nextSibling, keep this node so we have an end.\n // Else, we can remove it to save future costs.\n if (node.nextSibling === null) {\n node.data = '';\n }\n else {\n nodesToRemove.push(node);\n index--;\n }\n partIndex++;\n }\n else {\n let i = -1;\n while ((i = node.data.indexOf(marker, i + 1)) !== -1) {\n // Comment node has a binding marker inside, make an inactive part\n // The binding won't work, but subsequent bindings will\n // TODO (justinfagnani): consider whether it's even worth it to\n // make bindings in comments work\n this.parts.push({ type: 'node', index: -1 });\n partIndex++;\n }\n }\n }\n }\n // Remove text binding nodes after the walk to not disturb the TreeWalker\n for (const n of nodesToRemove) {\n n.parentNode.removeChild(n);\n }\n }\n}\nconst endsWith = (str, suffix) => {\n const index = str.length - suffix.length;\n return index >= 0 && str.slice(index) === suffix;\n};\nexport const isTemplatePartActive = (part) => part.index !== -1;\n// Allows `document.createComment('')` to be renamed for a\n// small manual size-savings.\nexport const createMarker = () => document.createComment('');\n/**\n * This regex extracts the attribute name preceding an attribute-position\n * expression. It does this by matching the syntax allowed for attributes\n * against the string literal directly preceding the expression, assuming that\n * the expression is in an attribute-value position.\n *\n * See attributes in the HTML spec:\n * https://www.w3.org/TR/html5/syntax.html#elements-attributes\n *\n * \" \\x09\\x0a\\x0c\\x0d\" are HTML space characters:\n * https://www.w3.org/TR/html5/infrastructure.html#space-characters\n *\n * \"\\0-\\x1F\\x7F-\\x9F\" are Unicode control characters, which includes every\n * space character except \" \".\n *\n * So an attribute is:\n * * The name: any character except a control character, space character, ('),\n * (\"), \">\", \"=\", or \"/\"\n * * Followed by zero or more space characters\n * * Followed by \"=\"\n * * Followed by zero or more space characters\n * * Followed by:\n * * Any character except space, ('), (\"), \"<\", \">\", \"=\", (`), or\n * * (\") then any non-(\"), or\n * * (') then any non-(')\n */\nexport const lastAttributeNameRegex = /([ \\x09\\x0a\\x0c\\x0d])([^\\0-\\x1F\\x7F-\\x9F \"'>=/]+)([ \\x09\\x0a\\x0c\\x0d]*=[ \\x09\\x0a\\x0c\\x0d]*(?:[^ \\x09\\x0a\\x0c\\x0d\"'`<>=]*|\"[^\"]*|'[^']*))$/;\n//# sourceMappingURL=template.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module lit-html\n */\nimport { isCEPolyfill } from './dom.js';\nimport { isTemplatePartActive } from './template.js';\n/**\n * An instance of a `Template` that can be attached to the DOM and updated\n * with new values.\n */\nexport class TemplateInstance {\n constructor(template, processor, options) {\n this.__parts = [];\n this.template = template;\n this.processor = processor;\n this.options = options;\n }\n update(values) {\n let i = 0;\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.setValue(values[i]);\n }\n i++;\n }\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.commit();\n }\n }\n }\n _clone() {\n // There are a number of steps in the lifecycle of a template instance's\n // DOM fragment:\n // 1. Clone - create the instance fragment\n // 2. Adopt - adopt into the main document\n // 3. Process - find part markers and create parts\n // 4. Upgrade - upgrade custom elements\n // 5. Update - set node, attribute, property, etc., values\n // 6. Connect - connect to the document. Optional and outside of this\n // method.\n //\n // We have a few constraints on the ordering of these steps:\n // * We need to upgrade before updating, so that property values will pass\n // through any property setters.\n // * We would like to process before upgrading so that we're sure that the\n // cloned fragment is inert and not disturbed by self-modifying DOM.\n // * We want custom elements to upgrade even in disconnected fragments.\n //\n // Given these constraints, with full custom elements support we would\n // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect\n //\n // But Safari dooes not implement CustomElementRegistry#upgrade, so we\n // can not implement that order and still have upgrade-before-update and\n // upgrade disconnected fragments. So we instead sacrifice the\n // process-before-upgrade constraint, since in Custom Elements v1 elements\n // must not modify their light DOM in the constructor. We still have issues\n // when co-existing with CEv0 elements like Polymer 1, and with polyfills\n // that don't strictly adhere to the no-modification rule because shadow\n // DOM, which may be created in the constructor, is emulated by being placed\n // in the light DOM.\n //\n // The resulting order is on native is: Clone, Adopt, Upgrade, Process,\n // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade\n // in one step.\n //\n // The Custom Elements v1 polyfill supports upgrade(), so the order when\n // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,\n // Connect.\n const fragment = isCEPolyfill ?\n this.template.element.content.cloneNode(true) :\n document.importNode(this.template.element.content, true);\n const stack = [];\n const parts = this.template.parts;\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n let partIndex = 0;\n let nodeIndex = 0;\n let part;\n let node = walker.nextNode();\n // Loop through all the nodes and parts of a template\n while (partIndex < parts.length) {\n part = parts[partIndex];\n if (!isTemplatePartActive(part)) {\n this.__parts.push(undefined);\n partIndex++;\n continue;\n }\n // Progress the tree walker until we find our next part's node.\n // Note that multiple parts may share the same node (attribute parts\n // on a single element), so this loop may not run at all.\n while (nodeIndex < part.index) {\n nodeIndex++;\n if (node.nodeName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n if ((node = walker.nextNode()) === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n node = walker.nextNode();\n }\n }\n // We've arrived at our part's node.\n if (part.type === 'node') {\n const part = this.processor.handleTextExpression(this.options);\n part.insertAfterNode(node.previousSibling);\n this.__parts.push(part);\n }\n else {\n this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));\n }\n partIndex++;\n }\n if (isCEPolyfill) {\n document.adoptNode(fragment);\n customElements.upgrade(fragment);\n }\n return fragment;\n }\n}\n//# sourceMappingURL=template-instance.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module lit-html\n */\nimport { reparentNodes } from './dom.js';\nimport { boundAttributeSuffix, lastAttributeNameRegex, marker, nodeMarker } from './template.js';\nconst commentMarker = ` ${marker} `;\n/**\n * The return type of `html`, which holds a Template and the values from\n * interpolated expressions.\n */\nexport class TemplateResult {\n constructor(strings, values, type, processor) {\n this.strings = strings;\n this.values = values;\n this.type = type;\n this.processor = processor;\n }\n /**\n * Returns a string of HTML used to create a `` element.\n */\n getHTML() {\n const l = this.strings.length - 1;\n let html = '';\n let isCommentBinding = false;\n for (let i = 0; i < l; i++) {\n const s = this.strings[i];\n // For each binding we want to determine the kind of marker to insert\n // into the template source before it's parsed by the browser's HTML\n // parser. The marker type is based on whether the expression is in an\n // attribute, text, or comment poisition.\n // * For node-position bindings we insert a comment with the marker\n // sentinel as its text content, like .\n // * For attribute bindings we insert just the marker sentinel for the\n // first binding, so that we support unquoted attribute bindings.\n // Subsequent bindings can use a comment marker because multi-binding\n // attributes must be quoted.\n // * For comment bindings we insert just the marker sentinel so we don't\n // close the comment.\n //\n // The following code scans the template source, but is *not* an HTML\n // parser. We don't need to track the tree structure of the HTML, only\n // whether a binding is inside a comment, and if not, if it appears to be\n // the first binding in an attribute.\n const commentOpen = s.lastIndexOf('', commentOpen + 1) === -1;\n // Check to see if we have an attribute-like sequence preceeding the\n // expression. This can match \"name=value\" like structures in text,\n // comments, and attribute values, so there can be false-positives.\n const attributeMatch = lastAttributeNameRegex.exec(s);\n if (attributeMatch === null) {\n // We're only in this branch if we don't have a attribute-like\n // preceeding sequence. For comments, this guards against unusual\n // attribute values like
. Cases like\n // are handled correctly in the attribute branch\n // below.\n html += s + (isCommentBinding ? commentMarker : nodeMarker);\n }\n else {\n // For attributes we use just a marker sentinel, and also append a\n // $lit$ suffix to the name to opt-out of attribute-specific parsing\n // that IE and Edge do for style and certain SVG attributes.\n html += s.substr(0, attributeMatch.index) + attributeMatch[1] +\n attributeMatch[2] + boundAttributeSuffix + attributeMatch[3] +\n marker;\n }\n }\n html += this.strings[l];\n return html;\n }\n getTemplateElement() {\n const template = document.createElement('template');\n template.innerHTML = this.getHTML();\n return template;\n }\n}\n/**\n * A TemplateResult for SVG fragments.\n *\n * This class wraps HTML in an `