UNPKG

@leofavre/flip-card-component

Version:

A flip card web component.

1,373 lines (1,146 loc) 68.1 kB
function _templateObject() { var data = _taggedTemplateLiteral(["\n <style>\n :host {\n height: auto !important;\n margin: 0 !important;\n padding: 0 !important;\n background: transparent !important;\n}\n\n.flip-card--wrapper {\n position: relative;\n display: block;\n width: 100%;\n height: 0;\n padding-bottom: calc(1 / (var(--flip-card-proportion, 1/1)) * 100%);\n perspective: var(--flip-card-perspective, 1200px);\n}\n\n.flip-card--surface {\n position: absolute;\n width: 100%;\n height: 100%;\n transform-style: preserve-3d;\n transition: transform var(--flip-card-speed, 0.32s) ease-in-out;\n}\n\n:host([revealed]) .flip-card--surface {\n transform: rotateY(180deg);\n}\n\n.flip-card--side {\n position: absolute;\n width: 100%;\n height: 100%;\n backface-visibility: hidden;\n overflow: hidden;\n border-radius: var(--flip-card-border-radius, 0px);\n border: var(--flip-card-border, none);\n}\n\n.flip-card--side-back {\n display: flex;\n width: 100%;\n height: 100%;\n background: var(--flip-card-background, grey);\n}\n\n.flip-card--side-front {\n transform: rotateY(-180deg);\n}\n\n </style>\n <div class=\"flip-card--wrapper\">\n <div class=\"flip-card--surface\">\n <div class=\"flip-card--side flip-card--side-front\"><slot></slot></div>\n <div class=\"flip-card--side flip-card--side-back\"></div>\n </div>\n </div>\n"]); _templateObject = function _templateObject() { return data; }; return data; } function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } (function () { 'use strict'; /** * @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 */ var directives = new WeakMap(); var isDirective = function isDirective(o) { return typeof o === 'function' && directives.has(o); }; /** * @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 */ var isCEPolyfill = window.customElements !== undefined && window.customElements.polyfillWrapFlushCallback !== undefined; /** * Removes nodes, starting from `startNode` (inclusive) to `endNode` * (exclusive), from `container`. */ var removeNodes = function removeNodes(container, startNode) { var endNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var node = startNode; while (node !== endNode) { var n = node.nextSibling; container.removeChild(node); node = n; } }; /** * A sentinel value that signals that a value was handled by a directive and * should not be written to the DOM. */ var noChange = {}; /** * @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. */ var marker = "{{lit-".concat(String(Math.random()).slice(2), "}}"); /** * An expression marker used text-positions, not attribute positions, * in template. */ var nodeMarker = "<!--".concat(marker, "-->"); var markerRegex = new RegExp("".concat(marker, "|").concat(nodeMarker)); var rewritesStyleAttribute = function () { var el = document.createElement('div'); el.setAttribute('style', '{{bad value}}'); return el.getAttribute('style') !== '{{bad value}}'; }(); /** * An updateable Template that tracks the location of dynamic parts. */ var Template = function Template(result, element) { var _this = this; _classCallCheck(this, Template); this.parts = []; this.element = element; var index = -1; var partIndex = 0; var nodesToRemove = []; var _prepareTemplate = function _prepareTemplate(template) { var content = template.content; // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be // null var walker = document.createTreeWalker(content, 133 /* NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT */ , null, false); // The actual previous node, accounting for removals: if a node is removed // it will never be the previousNode. var previousNode; // Used to set previousNode at the top of the loop. var currentNode; while (walker.nextNode()) { index++; previousNode = currentNode; var node = currentNode = walker.currentNode; if (node.nodeType === 1 /* Node.ELEMENT_NODE */ ) { if (node.hasAttributes()) { var attributes = node.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 correspondance between part index and attribute index. var count = 0; for (var i = 0; i < attributes.length; i++) { if (attributes[i].value.indexOf(marker) >= 0) { count++; } } while (count-- > 0) { // Get the template literal section leading up to the first // expression in this attribute var stringForPart = result.strings[partIndex]; // Find the attribute name var name = lastAttributeNameRegex.exec(stringForPart)[2]; // Find the corresponding attribute // If the attribute name contains special characters, lower-case // it so that on XML nodes with case-sensitive getAttribute() we // can still find the attribute, which will have been lower-cased // by the parser. // // If the attribute name doesn't contain special character, it's // important to _not_ lower-case it, in case the name is // case-sensitive, like with XML attributes like "viewBox". var attributeLookupName = rewritesStyleAttribute && name === 'style' ? 'style$' : /^[a-zA-Z-]*$/.test(name) ? name : name.toLowerCase(); var attributeValue = node.getAttribute(attributeLookupName); var strings = attributeValue.split(markerRegex); _this.parts.push({ type: 'attribute', index: index, name: name, strings: strings }); node.removeAttribute(attributeLookupName); partIndex += strings.length - 1; } } if (node.tagName === 'TEMPLATE') { _prepareTemplate(node); } } else if (node.nodeType === 3 /* Node.TEXT_NODE */ ) { var nodeValue = node.nodeValue; if (nodeValue.indexOf(marker) < 0) { continue; } var parent = node.parentNode; var _strings = nodeValue.split(markerRegex); var lastIndex = _strings.length - 1; // We have a part for each match found partIndex += lastIndex; // Generate a new text node for each literal section // These nodes are also used as the markers for node parts for (var _i = 0; _i < lastIndex; _i++) { parent.insertBefore(_strings[_i] === '' ? createMarker() : document.createTextNode(_strings[_i]), node); _this.parts.push({ type: 'node', index: index++ }); } parent.insertBefore(_strings[lastIndex] === '' ? createMarker() : document.createTextNode(_strings[lastIndex]), node); nodesToRemove.push(node); } else if (node.nodeType === 8 /* Node.COMMENT_NODE */ ) { if (node.nodeValue === marker) { var _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 // * previousSibling is being removed (thus it's not the // `previousNode`) // * previousSibling is not a Text node // // TODO(justinfagnani): We should be able to use the previousNode // here as the marker node and reduce the number of extra nodes we // add to a template. See // https://github.com/PolymerLabs/lit-html/issues/147 var previousSibling = node.previousSibling; if (previousSibling === null || previousSibling !== previousNode || previousSibling.nodeType !== Node.TEXT_NODE) { _parent.insertBefore(createMarker(), node); } else { index--; } _this.parts.push({ type: 'node', index: index++ }); nodesToRemove.push(node); // If we don't have a nextSibling add a marker node. // We don't have to check if the next node is going to be removed, // because that node will induce a new marker if so. if (node.nextSibling === null) { _parent.insertBefore(createMarker(), node); } else { index--; } currentNode = previousNode; partIndex++; } else { var _i2 = -1; while ((_i2 = node.nodeValue.indexOf(marker, _i2 + 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 }); } } } } }; _prepareTemplate(element); // Remove text binding nodes after the walk to not disturb the TreeWalker for (var _i3 = 0; _i3 < nodesToRemove.length; _i3++) { var n = nodesToRemove[_i3]; n.parentNode.removeChild(n); } }; var isTemplatePartActive = function isTemplatePartActive(part) { return part.index !== -1; }; // Allows `document.createComment('')` to be renamed for a // small manual size-savings. var createMarker = function createMarker() { return 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#attributes-0 * * "\0-\x1F\x7F-\x9F" are Unicode control characters * * " \x09\x0a\x0c\x0d" are HTML space characters: * https://www.w3.org/TR/html5/infrastructure.html#space-character * * 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-(') */ var lastAttributeNameRegex = /([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F \x09\x0a\x0c\x0d"'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/; /** * @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. */ var TemplateInstance = /*#__PURE__*/ function () { function TemplateInstance(template, processor, options) { _classCallCheck(this, TemplateInstance); this._parts = []; this.template = template; this.processor = processor; this.options = options; } _createClass(TemplateInstance, [{ key: "update", value: function update(values) { var i = 0; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this._parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var part = _step.value; if (part !== undefined) { part.setValue(values[i]); } i++; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = this._parts[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _part = _step2.value; if (_part !== undefined) { _part.commit(); } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } }, { key: "_clone", value: function _clone() { var _this2 = this; // When using the Custom Elements polyfill, clone the node, rather than // importing it, to keep the fragment in the template's document. This // leaves the fragment inert so custom elements won't upgrade and // potentially modify their contents by creating a polyfilled ShadowRoot // while we traverse the tree. var fragment = isCEPolyfill ? this.template.element.content.cloneNode(true) : document.importNode(this.template.element.content, true); var parts = this.template.parts; var partIndex = 0; var nodeIndex = 0; var _prepareInstance = function _prepareInstance(fragment) { // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be // null var walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */ , null, false); var node = walker.nextNode(); // Loop through all the nodes and parts of a template while (partIndex < parts.length && node !== null) { var part = parts[partIndex]; // Consecutive Parts may have the same node index, in the case of // multiple bound attributes on an element. So each iteration we either // increment the nodeIndex, if we aren't on a node with a part, or the // partIndex if we are. By not incrementing the nodeIndex when we find a // part, we allow for the next part to be associated with the current // node if neccessasry. if (!isTemplatePartActive(part)) { _this2._parts.push(undefined); partIndex++; } else if (nodeIndex === part.index) { if (part.type === 'node') { var _part2 = _this2.processor.handleTextExpression(_this2.options); _part2.insertAfterNode(node); _this2._parts.push(_part2); } else { var _this2$_parts; (_this2$_parts = _this2._parts).push.apply(_this2$_parts, _toConsumableArray(_this2.processor.handleAttributeExpressions(node, part.name, part.strings, _this2.options))); } partIndex++; } else { nodeIndex++; if (node.nodeName === 'TEMPLATE') { _prepareInstance(node.content); } node = walker.nextNode(); } } }; _prepareInstance(fragment); if (isCEPolyfill) { document.adoptNode(fragment); customElements.upgrade(fragment); } return fragment; } }]); return TemplateInstance; }(); /** * @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 return type of `html`, which holds a Template and the values from * interpolated expressions. */ var TemplateResult = /*#__PURE__*/ function () { function TemplateResult(strings, values, type, processor) { _classCallCheck(this, TemplateResult); this.strings = strings; this.values = values; this.type = type; this.processor = processor; } /** * Returns a string of HTML used to create a `<template>` element. */ _createClass(TemplateResult, [{ key: "getHTML", value: function getHTML() { var l = this.strings.length - 1; var html = ''; var isTextBinding = true; for (var i = 0; i < l; i++) { var s = this.strings[i]; html += s; var close = s.lastIndexOf('>'); // We're in a text position if the previous string closed its last tag, an // attribute position if the string opened an unclosed tag, and unchanged // if the string had no brackets at all: // // "...>...": text position. open === -1, close > -1 // "...<...": attribute position. open > -1 // "...": no change. open === -1, close === -1 isTextBinding = (close > -1 || isTextBinding) && s.indexOf('<', close + 1) === -1; if (!isTextBinding && rewritesStyleAttribute) { html = html.replace(lastAttributeNameRegex, function (match, p1, p2, p3) { return p2 === 'style' ? "".concat(p1, "style$").concat(p3) : match; }); } html += isTextBinding ? nodeMarker : marker; } html += this.strings[l]; return html; } }, { key: "getTemplateElement", value: function getTemplateElement() { var template = document.createElement('template'); template.innerHTML = this.getHTML(); return template; } }]); return TemplateResult; }(); /** * @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 */ var isPrimitive = function isPrimitive(value) { return value === null || !(_typeof(value) === 'object' || typeof value === 'function'); }; /** * Sets attribute values for AttributeParts, so that the value is only set once * even if there are multiple parts for an attribute. */ var AttributeCommitter = /*#__PURE__*/ function () { function AttributeCommitter(element, name, strings) { _classCallCheck(this, AttributeCommitter); this.dirty = true; this.element = element; this.name = name; this.strings = strings; this.parts = []; for (var 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. */ _createClass(AttributeCommitter, [{ key: "_createPart", value: function _createPart() { return new AttributePart(this); } }, { key: "_getValue", value: function _getValue() { var strings = this.strings; var l = strings.length - 1; var text = ''; for (var i = 0; i < l; i++) { text += strings[i]; var part = this.parts[i]; if (part !== undefined) { var v = part.value; if (v != null && (Array.isArray(v) || typeof v !== 'string' && v[Symbol.iterator])) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = v[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var t = _step3.value; text += typeof t === 'string' ? t : String(t); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } else { text += typeof v === 'string' ? v : String(v); } } } text += strings[l]; return text; } }, { key: "commit", value: function commit() { if (this.dirty) { this.dirty = false; this.element.setAttribute(this.name, this._getValue()); } } }]); return AttributeCommitter; }(); var AttributePart = /*#__PURE__*/ function () { function AttributePart(comitter) { _classCallCheck(this, AttributePart); this.value = undefined; this.committer = comitter; } _createClass(AttributePart, [{ key: "setValue", value: function 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; } } } }, { key: "commit", value: function commit() { while (isDirective(this.value)) { var directive$$1 = this.value; this.value = noChange; directive$$1(this); } if (this.value === noChange) { return; } this.committer.commit(); } }]); return AttributePart; }(); var NodePart = /*#__PURE__*/ function () { function NodePart(options) { _classCallCheck(this, NodePart); this.value = undefined; this._pendingValue = undefined; this.options = options; } /** * Inserts this part into a container. * * This part must be empty, as its contents are not automatically moved. */ _createClass(NodePart, [{ key: "appendInto", value: function appendInto(container) { this.startNode = container.appendChild(createMarker()); this.endNode = container.appendChild(createMarker()); } /** * Inserts this part 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. */ }, { key: "insertAfterNode", value: function 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. */ }, { key: "appendIntoPart", value: function appendIntoPart(part) { part._insert(this.startNode = createMarker()); part._insert(this.endNode = createMarker()); } /** * Appends this part after `ref` * * This part must be empty, as its contents are not automatically moved. */ }, { key: "insertAfterPart", value: function insertAfterPart(ref) { ref._insert(this.startNode = createMarker()); this.endNode = ref.endNode; ref.endNode = this.startNode; } }, { key: "setValue", value: function setValue(value) { this._pendingValue = value; } }, { key: "commit", value: function commit() { while (isDirective(this._pendingValue)) { var directive$$1 = this._pendingValue; this._pendingValue = noChange; directive$$1(this); } var 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 (Array.isArray(value) || value[Symbol.iterator]) { this._commitIterable(value); } else if (value.then !== undefined) { this._commitPromise(value); } else { // Fallback, will render the string representation this._commitText(value); } } }, { key: "_insert", value: function _insert(node) { this.endNode.parentNode.insertBefore(node, this.endNode); } }, { key: "_commitNode", value: function _commitNode(value) { if (this.value === value) { return; } this.clear(); this._insert(value); this.value = value; } }, { key: "_commitText", value: function _commitText(value) { var node = this.startNode.nextSibling; value = value == null ? '' : value; if (node === this.endNode.previousSibling && node.nodeType === 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.textContent = value; } else { this._commitNode(document.createTextNode(typeof value === 'string' ? value : String(value))); } this.value = value; } }, { key: "_commitTemplateResult", value: function _commitTemplateResult(value) { var template = this.options.templateFactory(value); if (this.value && 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. var instance = new TemplateInstance(template, value.processor, this.options); var fragment = instance._clone(); instance.update(value.values); this._commitNode(fragment); this.value = instance; } } }, { key: "_commitIterable", value: function _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 var itemParts = this.value; var partIndex = 0; var itemPart; var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = value[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var item = _step4.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++; } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return != null) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } if (partIndex < itemParts.length) { // Truncate the parts array so _value reflects the current state itemParts.length = partIndex; this.clear(itemPart && itemPart.endNode); } } }, { key: "_commitPromise", value: function _commitPromise(value) { var _this3 = this; this.value = value; value.then(function (v) { if (_this3.value === value) { _this3.setValue(v); _this3.commit(); } }); } }, { key: "clear", value: function clear() { var startNode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.startNode; removeNodes(this.startNode.parentNode, startNode.nextSibling, this.endNode); } }]); return NodePart; }(); /** * 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. */ var BooleanAttributePart = /*#__PURE__*/ function () { function BooleanAttributePart(element, name, strings) { _classCallCheck(this, BooleanAttributePart); 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; } _createClass(BooleanAttributePart, [{ key: "setValue", value: function setValue(value) { this._pendingValue = value; } }, { key: "commit", value: function commit() { while (isDirective(this._pendingValue)) { var directive$$1 = this._pendingValue; this._pendingValue = noChange; directive$$1(this); } if (this._pendingValue === noChange) { return; } var 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; } }]); return BooleanAttributePart; }(); /** * 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. */ var PropertyCommitter = /*#__PURE__*/ function (_AttributeCommitter) { _inherits(PropertyCommitter, _AttributeCommitter); function PropertyCommitter(element, name, strings) { var _this4; _classCallCheck(this, PropertyCommitter); _this4 = _possibleConstructorReturn(this, _getPrototypeOf(PropertyCommitter).call(this, element, name, strings)); _this4.single = strings.length === 2 && strings[0] === '' && strings[1] === ''; return _this4; } _createClass(PropertyCommitter, [{ key: "_createPart", value: function _createPart() { return new PropertyPart(this); } }, { key: "_getValue", value: function _getValue() { if (this.single) { return this.parts[0].value; } return _get(_getPrototypeOf(PropertyCommitter.prototype), "_getValue", this).call(this); } }, { key: "commit", value: function commit() { if (this.dirty) { this.dirty = false; this.element[this.name] = this._getValue(); } } }]); return PropertyCommitter; }(AttributeCommitter); var PropertyPart = /*#__PURE__*/ function (_AttributePart) { _inherits(PropertyPart, _AttributePart); function PropertyPart() { _classCallCheck(this, PropertyPart); return _possibleConstructorReturn(this, _getPrototypeOf(PropertyPart).apply(this, arguments)); } return PropertyPart; }(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. var eventOptionsSupported = false; try { var options = { get capture() { eventOptionsSupported = true; return false; } }; window.addEventListener('test', options, options); window.removeEventListener('test', options, options); } catch (_e) {} var EventPart = /*#__PURE__*/ function () { function EventPart(element, eventName, eventContext) { _classCallCheck(this, EventPart); this.value = undefined; this._pendingValue = undefined; this.element = element; this.eventName = eventName; this.eventContext = eventContext; } _createClass(EventPart, [{ key: "setValue", value: function setValue(value) { this._pendingValue = value; } }, { key: "commit", value: function commit() { while (isDirective(this._pendingValue)) { var directive$$1 = this._pendingValue; this._pendingValue = noChange; directive$$1(this); } if (this._pendingValue === noChange) { return; } var newListener = this._pendingValue; var oldListener = this.value; var shouldRemoveListener = newListener == null || oldListener != null && (newListener.capture !== oldListener.capture || newListener.once !== oldListener.once || newListener.passive !== oldListener.passive); var shouldAddListener = newListener != null && (oldListener == null || shouldRemoveListener); if (shouldRemoveListener) { this.element.removeEventListener(this.eventName, this, this._options); } this._options = getOptions(newListener); if (shouldAddListener) { this.element.addEventListener(this.eventName, this, this._options); } this.value = newListener; this._pendingValue = noChange; } }, { key: "handleEvent", value: function handleEvent(event) { var listener = typeof this.value === 'function' ? this.value : typeof this.value.handleEvent === 'function' ? this.value.handleEvent : function () { return null; }; listener.call(this.eventContext || this.element, event); } }]); return EventPart; }(); // 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. var getOptions = function getOptions(o) { return o && (eventOptionsSupported ? { capture: o.capture, passive: o.passive, once: o.once } : o.capture); }; /** * @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. */ var DefaultTemplateProcessor = /*#__PURE__*/ function () { function DefaultTemplateProcessor() { _classCallCheck(this, DefaultTemplateProcessor); } _createClass(DefaultTemplateProcessor, [{ key: "handleAttributeExpressions", /** * 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. */ value: function handleAttributeExpressions(element, name, strings, options) { var prefix = name[0]; if (prefix === '.') { var _comitter = new PropertyCommitter(element, name.slice(1), strings); return _comitter.parts; } if (prefix === '@') { return [new EventPart(element, name.slice(1), options.eventContext)]; } if (prefix === '?') { return [new BooleanAttributePart(element, name.slice(1), strings)]; } var comitter = new AttributeCommitter(element, name, strings); return comitter.parts; } /** * Create parts for a text-position binding. * @param templateFactory */ }, { key: "handleTextExpression", value: function handleTextExpression(options) { return new NodePart(options); } }]); return DefaultTemplateProcessor; }(); var defaultTemplateProcessor = new DefaultTemplateProcessor(); /** * @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) { var templateCache = templateCaches.get(result.type); if (templateCache === undefined) { templateCache = new Map(); templateCaches.set(result.type, templateCache); } var template = templateCache.get(result.strings); if (template === undefined) { template = new Template(result, result.getTemplateElement()); templateCache.set(result.strings, template); } return template; } // The first argument to JS template tags retain identity across multiple // calls to a tag for the same literal, so we can cache work done per literal // in a Map. var templateCaches = new 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 */ var parts = new WeakMap(); /** * Renders a template to a container. * * To update a container with new values, reevaluate the template literal and * call `render` with the new result. * * @param result 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 ren