@leofavre/flip-card-component
Version:
A flip card web component.
1,373 lines (1,146 loc) • 68.1 kB
JavaScript
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