@vaadin/bundles
Version:
Bundles of components and dependencies
1,240 lines (1,135 loc) • 12.2 MB
JavaScript
/******/ var __webpack_modules__ = ({
/***/ "./node_modules/@polymer/polymer/lib/elements/dom-module.js":
/*!******************************************************************!*\
!*** ./node_modules/@polymer/polymer/lib/elements/dom-module.js ***!
\******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DomModule": () => (/* binding */ DomModule)
/* harmony export */ });
/* harmony import */ var _utils_boot_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/boot.js */ "./node_modules/@polymer/polymer/lib/utils/boot.js");
/* harmony import */ var _utils_resolve_url_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/resolve-url.js */ "./node_modules/@polymer/polymer/lib/utils/resolve-url.js");
/* harmony import */ var _utils_settings_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/settings.js */ "./node_modules/@polymer/polymer/lib/utils/settings.js");
/**
@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
*/
let modules = {};
let lcModules = {};
/**
* Sets a dom-module into the global registry by id.
*
* @param {string} id dom-module id
* @param {DomModule} module dom-module instance
* @return {void}
*/
function setModule(id, module) {
// store id separate from lowercased id so that
// in all cases mixedCase id will stored distinctly
// and lowercase version is a fallback
modules[id] = lcModules[id.toLowerCase()] = module;
}
/**
* Retrieves a dom-module from the global registry by id.
*
* @param {string} id dom-module id
* @return {DomModule!} dom-module instance
*/
function findModule(id) {
return modules[id] || lcModules[id.toLowerCase()];
}
function styleOutsideTemplateCheck(inst) {
if (inst.querySelector('style')) {
console.warn('dom-module %s has style outside template', inst.id);
}
}
/**
* The `dom-module` element registers the dom it contains to the name given
* by the module's id attribute. It provides a unified database of dom
* accessible via its static `import` API.
*
* A key use case of `dom-module` is for providing custom element `<template>`s
* via HTML imports that are parsed by the native HTML parser, that can be
* relocated during a bundling pass and still looked up by `id`.
*
* Example:
*
* <dom-module id="foo">
* <img src="stuff.png">
* </dom-module>
*
* Then in code in some other location that cannot access the dom-module above
*
* let img = customElements.get('dom-module').import('foo', 'img');
*
* @customElement
* @extends HTMLElement
* @summary Custom element that provides a registry of relocatable DOM content
* by `id` that is agnostic to bundling.
* @unrestricted
*/
class DomModule extends HTMLElement {
/** @override */
static get observedAttributes() { return ['id']; }
/**
* Retrieves the element specified by the css `selector` in the module
* registered by `id`. For example, this.import('foo', 'img');
* @param {string} id The id of the dom-module in which to search.
* @param {string=} selector The css selector by which to find the element.
* @return {Element} Returns the element which matches `selector` in the
* module registered at the specified `id`.
*
* @export
* @nocollapse Referred to indirectly in style-gather.js
*/
static import(id, selector) {
if (id) {
let m = findModule(id);
if (m && selector) {
return m.querySelector(selector);
}
return m;
}
return null;
}
/* eslint-disable no-unused-vars */
/**
* @param {string} name Name of attribute.
* @param {?string} old Old value of attribute.
* @param {?string} value Current value of attribute.
* @param {?string} namespace Attribute namespace.
* @return {void}
* @override
*/
attributeChangedCallback(name, old, value, namespace) {
if (old !== value) {
this.register();
}
}
/* eslint-enable no-unused-args */
/**
* The absolute URL of the original location of this `dom-module`.
*
* This value will differ from this element's `ownerDocument` in the
* following ways:
* - Takes into account any `assetpath` attribute added during bundling
* to indicate the original location relative to the bundled location
* - Uses the HTMLImports polyfill's `importForElement` API to ensure
* the path is relative to the import document's location since
* `ownerDocument` is not currently polyfilled
*/
get assetpath() {
// Don't override existing assetpath.
if (!this.__assetpath) {
// note: assetpath set via an attribute must be relative to this
// element's location; accommodate polyfilled HTMLImports
const owner = window.HTMLImports && HTMLImports.importForElement ?
HTMLImports.importForElement(this) || document : this.ownerDocument;
const url = (0,_utils_resolve_url_js__WEBPACK_IMPORTED_MODULE_1__.resolveUrl)(
this.getAttribute('assetpath') || '', owner.baseURI);
this.__assetpath = (0,_utils_resolve_url_js__WEBPACK_IMPORTED_MODULE_1__.pathFromUrl)(url);
}
return this.__assetpath;
}
/**
* Registers the dom-module at a given id. This method should only be called
* when a dom-module is imperatively created. For
* example, `document.createElement('dom-module').register('foo')`.
* @param {string=} id The id at which to register the dom-module.
* @return {void}
*/
register(id) {
id = id || this.id;
if (id) {
// Under strictTemplatePolicy, reject and null out any re-registered
// dom-module since it is ambiguous whether first-in or last-in is trusted
if (_utils_settings_js__WEBPACK_IMPORTED_MODULE_2__.strictTemplatePolicy && findModule(id) !== undefined) {
setModule(id, null);
throw new Error(`strictTemplatePolicy: dom-module ${id} re-registered`);
}
this.id = id;
setModule(id, this);
styleOutsideTemplateCheck(this);
}
}
}
DomModule.prototype['modules'] = modules;
customElements.define('dom-module', DomModule);
/***/ }),
/***/ "./node_modules/@polymer/polymer/lib/elements/dom-repeat.js":
/*!******************************************************************!*\
!*** ./node_modules/@polymer/polymer/lib/elements/dom-repeat.js ***!
\******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DomRepeat": () => (/* binding */ DomRepeat)
/* harmony export */ });
/* harmony import */ var _polymer_element_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../polymer-element.js */ "./node_modules/@polymer/polymer/polymer-element.js");
/* harmony import */ var _utils_templatize_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/templatize.js */ "./node_modules/@polymer/polymer/lib/utils/templatize.js");
/* harmony import */ var _utils_debounce_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/debounce.js */ "./node_modules/@polymer/polymer/lib/utils/debounce.js");
/* harmony import */ var _utils_flush_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/flush.js */ "./node_modules/@polymer/polymer/lib/utils/flush.js");
/* harmony import */ var _mixins_mutable_data_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../mixins/mutable-data.js */ "./node_modules/@polymer/polymer/lib/mixins/mutable-data.js");
/* harmony import */ var _utils_path_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/path.js */ "./node_modules/@polymer/polymer/lib/utils/path.js");
/* harmony import */ var _utils_async_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/async.js */ "./node_modules/@polymer/polymer/lib/utils/async.js");
/* harmony import */ var _utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/wrap.js */ "./node_modules/@polymer/polymer/lib/utils/wrap.js");
/* harmony import */ var _utils_hide_template_controls_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/hide-template-controls.js */ "./node_modules/@polymer/polymer/lib/utils/hide-template-controls.js");
/* harmony import */ var _utils_settings_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/settings.js */ "./node_modules/@polymer/polymer/lib/utils/settings.js");
/**
@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
*/
// eslint-disable-line no-unused-vars
/**
* @constructor
* @implements {Polymer_OptionalMutableData}
* @extends {PolymerElement}
* @private
*/
const domRepeatBase = (0,_mixins_mutable_data_js__WEBPACK_IMPORTED_MODULE_4__.OptionalMutableData)(_polymer_element_js__WEBPACK_IMPORTED_MODULE_0__.PolymerElement);
/**
* The `<dom-repeat>` element will automatically stamp and binds one instance
* of template content to each object in a user-provided array.
* `dom-repeat` accepts an `items` property, and one instance of the template
* is stamped for each item into the DOM at the location of the `dom-repeat`
* element. The `item` property will be set on each instance's binding
* scope, thus templates should bind to sub-properties of `item`.
*
* Example:
*
* ```html
* <dom-module id="employee-list">
*
* <template>
*
* <div> Employee list: </div>
* <dom-repeat items="{{employees}}">
* <template>
* <div>First name: <span>{{item.first}}</span></div>
* <div>Last name: <span>{{item.last}}</span></div>
* </template>
* </dom-repeat>
*
* </template>
*
* </dom-module>
* ```
*
* With the following custom element definition:
*
* ```js
* class EmployeeList extends PolymerElement {
* static get is() { return 'employee-list'; }
* static get properties() {
* return {
* employees: {
* value() {
* return [
* {first: 'Bob', last: 'Smith'},
* {first: 'Sally', last: 'Johnson'},
* ...
* ];
* }
* }
* };
* }
* }
* ```
*
* Notifications for changes to items sub-properties will be forwarded to template
* instances, which will update via the normal structured data notification system.
*
* Mutations to the `items` array itself should be made using the Array
* mutation API's on the PropertyEffects mixin (`push`, `pop`, `splice`,
* `shift`, `unshift`), and template instances will be kept in sync with the
* data in the array.
*
* Events caught by event handlers within the `dom-repeat` template will be
* decorated with a `model` property, which represents the binding scope for
* each template instance. The model should be used to manipulate data on the
* instance, for example `event.model.set('item.checked', true);`.
*
* Alternatively, the model for a template instance for an element stamped by
* a `dom-repeat` can be obtained using the `modelForElement` API on the
* `dom-repeat` that stamped it, for example
* `this.$.domRepeat.modelForElement(event.target).set('item.checked', true);`.
* This may be useful for manipulating instance data of event targets obtained
* by event handlers on parents of the `dom-repeat` (event delegation).
*
* A view-specific filter/sort may be applied to each `dom-repeat` by supplying a
* `filter` and/or `sort` property. This may be a string that names a function on
* the host, or a function may be assigned to the property directly. The functions
* should implemented following the standard `Array` filter/sort API.
*
* In order to re-run the filter or sort functions based on changes to sub-fields
* of `items`, the `observe` property may be set as a space-separated list of
* `item` sub-fields that should cause a re-filter/sort when modified. If
* the filter or sort function depends on properties not contained in `items`,
* the user should observe changes to those properties and call `render` to update
* the view based on the dependency change.
*
* For example, for an `dom-repeat` with a filter of the following:
*
* ```js
* isEngineer(item) {
* return item.type == 'engineer' || item.manager.type == 'engineer';
* }
* ```
*
* Then the `observe` property should be configured as follows:
*
* ```html
* <dom-repeat items="{{employees}}" filter="isEngineer" observe="type manager.type">
* ```
*
* @customElement
* @polymer
* @extends {domRepeatBase}
* @appliesMixin OptionalMutableData
* @summary Custom element for stamping instance of a template bound to
* items in an array.
*/
class DomRepeat extends domRepeatBase {
// Not needed to find template; can be removed once the analyzer
// can find the tag name from customElements.define call
static get is() { return 'dom-repeat'; }
static get template() { return null; }
static get properties() {
/**
* Fired whenever DOM is added or removed by this template (by
* default, rendering occurs lazily). To force immediate rendering, call
* `render`.
*
* @event dom-change
*/
return {
/**
* An array containing items determining how many instances of the template
* to stamp and that that each template instance should bind to.
*/
items: {
type: Array
},
/**
* The name of the variable to add to the binding scope for the array
* element associated with a given template instance.
*/
as: {
type: String,
value: 'item'
},
/**
* The name of the variable to add to the binding scope with the index
* of the instance in the sorted and filtered list of rendered items.
* Note, for the index in the `this.items` array, use the value of the
* `itemsIndexAs` property.
*/
indexAs: {
type: String,
value: 'index'
},
/**
* The name of the variable to add to the binding scope with the index
* of the instance in the `this.items` array. Note, for the index of
* this instance in the sorted and filtered list of rendered items,
* use the value of the `indexAs` property.
*/
itemsIndexAs: {
type: String,
value: 'itemsIndex'
},
/**
* A function that should determine the sort order of the items. This
* property should either be provided as a string, indicating a method
* name on the element's host, or else be an actual function. The
* function should match the sort function passed to `Array.sort`.
* Using a sort function has no effect on the underlying `items` array.
*/
sort: {
type: Function,
observer: '__sortChanged'
},
/**
* A function that can be used to filter items out of the view. This
* property should either be provided as a string, indicating a method
* name on the element's host, or else be an actual function. The
* function should match the sort function passed to `Array.filter`.
* Using a filter function has no effect on the underlying `items` array.
*/
filter: {
type: Function,
observer: '__filterChanged'
},
/**
* When using a `filter` or `sort` function, the `observe` property
* should be set to a space-separated list of the names of item
* sub-fields that should trigger a re-sort or re-filter when changed.
* These should generally be fields of `item` that the sort or filter
* function depends on.
*/
observe: {
type: String,
observer: '__observeChanged'
},
/**
* When using a `filter` or `sort` function, the `delay` property
* determines a debounce time in ms after a change to observed item
* properties that must pass before the filter or sort is re-run.
* This is useful in rate-limiting shuffling of the view when
* item changes may be frequent.
*/
delay: Number,
/**
* Count of currently rendered items after `filter` (if any) has been applied.
* If "chunking mode" is enabled, `renderedItemCount` is updated each time a
* set of template instances is rendered.
*
*/
renderedItemCount: {
type: Number,
notify: !_utils_settings_js__WEBPACK_IMPORTED_MODULE_9__.suppressTemplateNotifications,
readOnly: true
},
/**
* When greater than zero, defines an initial count of template instances
* to render after setting the `items` array, before the next paint, and
* puts the `dom-repeat` into "chunking mode". The remaining items (and
* any future items as a result of pushing onto the array) will be created
* and rendered incrementally at each animation frame thereof until all
* instances have been rendered.
*/
initialCount: {
type: Number
},
/**
* When `initialCount` is used, this property defines a frame rate (in
* fps) to target by throttling the number of instances rendered each
* frame to not exceed the budget for the target frame rate. The
* framerate is effectively the number of `requestAnimationFrame`s that
* it tries to allow to actually fire in a given second. It does this
* by measuring the time between `rAF`s and continuously adjusting the
* number of items created each `rAF` to maintain the target framerate.
* Setting this to a higher number allows lower latency and higher
* throughput for event handlers and other tasks, but results in a
* longer time for the remaining items to complete rendering.
*/
targetFramerate: {
type: Number,
value: 20
},
_targetFrameTime: {
type: Number,
computed: '__computeFrameTime(targetFramerate)'
},
/**
* When the global `suppressTemplateNotifications` setting is used, setting
* `notifyDomChange: true` will enable firing `dom-change` events on this
* element.
*/
notifyDomChange: {
type: Boolean
},
/**
* When chunking is enabled via `initialCount` and the `items` array is
* set to a new array, this flag controls whether the previously rendered
* instances are reused or not.
*
* When `true`, any previously rendered template instances are updated in
* place to their new item values synchronously in one shot, and then any
* further items (if any) are chunked out. When `false`, the list is
* returned back to its `initialCount` (any instances over the initial
* count are discarded) and the remainder of the list is chunked back in.
* Set this to `true` to avoid re-creating the list and losing scroll
* position, although note that when changing the list to completely
* different data the render thread will be blocked until all existing
* instances are updated to their new data.
*/
reuseChunkedInstances: {
type: Boolean
}
};
}
static get observers() {
return [ '__itemsChanged(items.*)' ];
}
constructor() {
super();
this.__instances = [];
this.__renderDebouncer = null;
this.__itemsIdxToInstIdx = {};
this.__chunkCount = null;
this.__renderStartTime = null;
this.__itemsArrayChanged = false;
this.__shouldMeasureChunk = false;
this.__shouldContinueChunking = false;
this.__chunkingId = 0;
this.__sortFn = null;
this.__filterFn = null;
this.__observePaths = null;
/** @type {?function(new:TemplateInstanceBase, Object=)} */
this.__ctor = null;
this.__isDetached = true;
this.template = null;
/** @type {TemplateInfo} */
this._templateInfo;
}
/**
* @override
* @return {void}
*/
disconnectedCallback() {
super.disconnectedCallback();
this.__isDetached = true;
for (let i=0; i<this.__instances.length; i++) {
this.__detachInstance(i);
}
// Stop chunking if one was in progress
if (this.__chunkingId) {
cancelAnimationFrame(this.__chunkingId);
}
}
/**
* @override
* @return {void}
*/
connectedCallback() {
super.connectedCallback();
if (!(0,_utils_hide_template_controls_js__WEBPACK_IMPORTED_MODULE_8__.hideElementsGlobally)()) {
this.style.display = 'none';
}
// only perform attachment if the element was previously detached.
if (this.__isDetached) {
this.__isDetached = false;
let wrappedParent = (0,_utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__.wrap)((0,_utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__.wrap)(this).parentNode);
for (let i=0; i<this.__instances.length; i++) {
this.__attachInstance(i, wrappedParent);
}
// Restart chunking if one was in progress when disconnected
if (this.__chunkingId) {
this.__render();
}
}
}
__ensureTemplatized() {
// Templatizing (generating the instance constructor) needs to wait
// until ready, since won't have its template content handed back to
// it until then
if (!this.__ctor) {
// When `removeNestedTemplates` is true, the "template" is the element
// itself, which has been given a `_templateInfo` property
const thisAsTemplate = /** @type {!HTMLTemplateElement} */ (
/** @type {!HTMLElement} */ (this));
let template = this.template = thisAsTemplate._templateInfo ?
thisAsTemplate :
/** @type {!HTMLTemplateElement} */ (this.querySelector('template'));
if (!template) {
// Wait until childList changes and template should be there by then
let observer = new MutationObserver(() => {
if (this.querySelector('template')) {
observer.disconnect();
this.__render();
} else {
throw new Error('dom-repeat requires a <template> child');
}
});
observer.observe(this, {childList: true});
return false;
}
// Template instance props that should be excluded from forwarding
let instanceProps = {};
instanceProps[this.as] = true;
instanceProps[this.indexAs] = true;
instanceProps[this.itemsIndexAs] = true;
this.__ctor = (0,_utils_templatize_js__WEBPACK_IMPORTED_MODULE_1__.templatize)(template, this, {
mutableData: this.mutableData,
parentModel: true,
instanceProps: instanceProps,
/**
* @this {DomRepeat}
* @param {string} prop Property to set
* @param {*} value Value to set property to
*/
forwardHostProp: function(prop, value) {
let i$ = this.__instances;
for (let i=0, inst; (i<i$.length) && (inst=i$[i]); i++) {
inst.forwardHostProp(prop, value);
}
},
/**
* @this {DomRepeat}
* @param {Object} inst Instance to notify
* @param {string} prop Property to notify
* @param {*} value Value to notify
*/
notifyInstanceProp: function(inst, prop, value) {
if ((0,_utils_path_js__WEBPACK_IMPORTED_MODULE_5__.matches)(this.as, prop)) {
let idx = inst[this.itemsIndexAs];
if (prop == this.as) {
this.items[idx] = value;
}
let path = (0,_utils_path_js__WEBPACK_IMPORTED_MODULE_5__.translate)(this.as, `${JSCompiler_renameProperty('items', this)}.${idx}`, prop);
this.notifyPath(path, value);
}
}
});
}
return true;
}
__getMethodHost() {
// Technically this should be the owner of the outermost template.
// In shadow dom, this is always getRootNode().host, but we can
// approximate this via cooperation with our dataHost always setting
// `_methodHost` as long as there were bindings (or id's) on this
// instance causing it to get a dataHost.
return this.__dataHost._methodHost || this.__dataHost;
}
__functionFromPropertyValue(functionOrMethodName) {
if (typeof functionOrMethodName === 'string') {
let methodName = functionOrMethodName;
let obj = this.__getMethodHost();
return function() { return obj[methodName].apply(obj, arguments); };
}
return functionOrMethodName;
}
__sortChanged(sort) {
this.__sortFn = this.__functionFromPropertyValue(sort);
if (this.items) { this.__debounceRender(this.__render); }
}
__filterChanged(filter) {
this.__filterFn = this.__functionFromPropertyValue(filter);
if (this.items) { this.__debounceRender(this.__render); }
}
__computeFrameTime(rate) {
return Math.ceil(1000/rate);
}
__observeChanged() {
this.__observePaths = this.observe &&
this.observe.replace('.*', '.').split(' ');
}
__handleObservedPaths(path) {
// Handle cases where path changes should cause a re-sort/filter
if (this.__sortFn || this.__filterFn) {
if (!path) {
// Always re-render if the item itself changed
this.__debounceRender(this.__render, this.delay);
} else if (this.__observePaths) {
// Otherwise, re-render if the path changed matches an observed path
let paths = this.__observePaths;
for (let i=0; i<paths.length; i++) {
if (path.indexOf(paths[i]) === 0) {
this.__debounceRender(this.__render, this.delay);
}
}
}
}
}
__itemsChanged(change) {
if (this.items && !Array.isArray(this.items)) {
console.warn('dom-repeat expected array for `items`, found', this.items);
}
// If path was to an item (e.g. 'items.3' or 'items.3.foo'), forward the
// path to that instance synchronously (returns false for non-item paths)
if (!this.__handleItemPath(change.path, change.value)) {
// Otherwise, the array was reset ('items') or spliced ('items.splices'),
// so queue a render. Restart chunking when the items changed (for
// backward compatibility), unless `reuseChunkedInstances` option is set
if (change.path === 'items') {
this.__itemsArrayChanged = true;
}
this.__debounceRender(this.__render);
}
}
/**
* @param {function(this:DomRepeat)} fn Function to debounce.
* @param {number=} delay Delay in ms to debounce by.
*/
__debounceRender(fn, delay = 0) {
this.__renderDebouncer = _utils_debounce_js__WEBPACK_IMPORTED_MODULE_2__.Debouncer.debounce(
this.__renderDebouncer
, delay > 0 ? _utils_async_js__WEBPACK_IMPORTED_MODULE_6__.timeOut.after(delay) : _utils_async_js__WEBPACK_IMPORTED_MODULE_6__.microTask
, fn.bind(this));
(0,_utils_flush_js__WEBPACK_IMPORTED_MODULE_3__.enqueueDebouncer)(this.__renderDebouncer);
}
/**
* Forces the element to render its content. Normally rendering is
* asynchronous to a provoking change. This is done for efficiency so
* that multiple changes trigger only a single render. The render method
* should be called if, for example, template rendering is required to
* validate application state.
* @return {void}
*/
render() {
// Queue this repeater, then flush all in order
this.__debounceRender(this.__render);
(0,_utils_flush_js__WEBPACK_IMPORTED_MODULE_3__.flush)();
}
__render() {
if (!this.__ensureTemplatized()) {
// No template found yet
return;
}
let items = this.items || [];
// Sort and filter the items into a mapping array from instance->item
const isntIdxToItemsIdx = this.__sortAndFilterItems(items);
// If we're chunking, increase the limit if there are new instances to
// create and schedule the next chunk
const limit = this.__calculateLimit(isntIdxToItemsIdx.length);
// Create, update, and/or remove instances
this.__updateInstances(items, limit, isntIdxToItemsIdx);
// If we're chunking, schedule a rAF task to measure/continue chunking.
// Do this before any notifying events (renderedItemCount & dom-change)
// since those could modify items and enqueue a new full render which will
// pre-empt this measurement.
if (this.initialCount &&
(this.__shouldMeasureChunk || this.__shouldContinueChunking)) {
cancelAnimationFrame(this.__chunkingId);
this.__chunkingId = requestAnimationFrame(() => {
this.__chunkingId = null;
this.__continueChunking();
});
}
// Set rendered item count
this._setRenderedItemCount(this.__instances.length);
// Notify users
if (!_utils_settings_js__WEBPACK_IMPORTED_MODULE_9__.suppressTemplateNotifications || this.notifyDomChange) {
this.dispatchEvent(new CustomEvent('dom-change', {
bubbles: true,
composed: true
}));
}
}
__sortAndFilterItems(items) {
// Generate array maping the instance index to the items array index
let isntIdxToItemsIdx = new Array(items.length);
for (let i=0; i<items.length; i++) {
isntIdxToItemsIdx[i] = i;
}
// Apply user filter
if (this.__filterFn) {
isntIdxToItemsIdx = isntIdxToItemsIdx.filter((i, idx, array) =>
this.__filterFn(items[i], idx, array));
}
// Apply user sort
if (this.__sortFn) {
isntIdxToItemsIdx.sort((a, b) => this.__sortFn(items[a], items[b]));
}
return isntIdxToItemsIdx;
}
__calculateLimit(filteredItemCount) {
let limit = filteredItemCount;
const currentCount = this.__instances.length;
// When chunking, we increase the limit from the currently rendered count
// by the chunk count that is re-calculated after each rAF (with special
// cases for resetting the limit to initialCount after changing items)
if (this.initialCount) {
let newCount;
if (!this.__chunkCount ||
(this.__itemsArrayChanged && !this.reuseChunkedInstances)) {
// Limit next render to the initial count
limit = Math.min(filteredItemCount, this.initialCount);
// Subtract off any existing instances to determine the number of
// instances that will be created
newCount = Math.max(limit - currentCount, 0);
// Initialize the chunk size with how many items we're creating
this.__chunkCount = newCount || 1;
} else {
// The number of new instances that will be created is based on the
// existing instances, the new list size, and the chunk size
newCount = Math.min(
Math.max(filteredItemCount - currentCount, 0),
this.__chunkCount);
// Update the limit based on how many new items we're making, limited
// buy the total size of the list
limit = Math.min(currentCount + newCount, filteredItemCount);
}
// Record some state about chunking for use in `__continueChunking`
this.__shouldMeasureChunk = newCount === this.__chunkCount;
this.__shouldContinueChunking = limit < filteredItemCount;
this.__renderStartTime = performance.now();
}
this.__itemsArrayChanged = false;
return limit;
}
__continueChunking() {
// Simple auto chunkSize throttling algorithm based on feedback loop:
// measure actual time between frames and scale chunk count by ratio of
// target/actual frame time. Only modify chunk size if our measurement
// reflects the cost of a creating a full chunk's worth of instances; this
// avoids scaling up the chunk size if we e.g. quickly re-rendered instances
// in place
if (this.__shouldMeasureChunk) {
const renderTime = performance.now() - this.__renderStartTime;
const ratio = this._targetFrameTime / renderTime;
this.__chunkCount = Math.round(this.__chunkCount * ratio) || 1;
}
// Enqueue a new render if we haven't reached the full size of the list
if (this.__shouldContinueChunking) {
this.__debounceRender(this.__render);
}
}
__updateInstances(items, limit, isntIdxToItemsIdx) {
// items->inst map kept for item path forwarding
const itemsIdxToInstIdx = this.__itemsIdxToInstIdx = {};
let instIdx;
// Generate instances and assign items
for (instIdx=0; instIdx<limit; instIdx++) {
let inst = this.__instances[instIdx];
let itemIdx = isntIdxToItemsIdx[instIdx];
let item = items[itemIdx];
itemsIdxToInstIdx[itemIdx] = instIdx;
if (inst) {
inst._setPendingProperty(this.as, item);
inst._setPendingProperty(this.indexAs, instIdx);
inst._setPendingProperty(this.itemsIndexAs, itemIdx);
inst._flushProperties();
} else {
this.__insertInstance(item, instIdx, itemIdx);
}
}
// Remove any extra instances from previous state
for (let i=this.__instances.length-1; i>=instIdx; i--) {
this.__detachAndRemoveInstance(i);
}
}
__detachInstance(idx) {
let inst = this.__instances[idx];
const wrappedRoot = (0,_utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__.wrap)(inst.root);
for (let i=0; i<inst.children.length; i++) {
let el = inst.children[i];
wrappedRoot.appendChild(el);
}
return inst;
}
__attachInstance(idx, parent) {
let inst = this.__instances[idx];
// Note, this is pre-wrapped as an optimization
parent.insertBefore(inst.root, this);
}
__detachAndRemoveInstance(idx) {
this.__detachInstance(idx);
this.__instances.splice(idx, 1);
}
__stampInstance(item, instIdx, itemIdx) {
let model = {};
model[this.as] = item;
model[this.indexAs] = instIdx;
model[this.itemsIndexAs] = itemIdx;
return new this.__ctor(model);
}
__insertInstance(item, instIdx, itemIdx) {
const inst = this.__stampInstance(item, instIdx, itemIdx);
let beforeRow = this.__instances[instIdx + 1];
let beforeNode = beforeRow ? beforeRow.children[0] : this;
(0,_utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__.wrap)((0,_utils_wrap_js__WEBPACK_IMPORTED_MODULE_7__.wrap)(this).parentNode).insertBefore(inst.root, beforeNode);
this.__instances[instIdx] = inst;
return inst;
}
// Implements extension point from Templatize mixin
/**
* Shows or hides the template instance top level child elements. For
* text nodes, `textContent` is removed while "hidden" and replaced when
* "shown."
* @param {boolean} hidden Set to true to hide the children;
* set to false to show them.
* @return {void}
* @protected
*/
_showHideChildren(hidden) {
for (let i=0; i<this.__instances.length; i++) {
this.__instances[i]._showHideChildren(hidden);
}
}
// Called as a side effect of a host items.<key>.<path> path change,
// responsible for notifying item.<path> changes to inst for key
__handleItemPath(path, value) {
let itemsPath = path.slice(6); // 'items.'.length == 6
let dot = itemsPath.indexOf('.');
let itemsIdx = dot < 0 ? itemsPath : itemsPath.substring(0, dot);
// If path was index into array...
if (itemsIdx == parseInt(itemsIdx, 10)) {
let itemSubPath = dot < 0 ? '' : itemsPath.substring(dot+1);
// If the path is observed, it will trigger a full refresh
this.__handleObservedPaths(itemSubPath);
// Note, even if a rull refresh is triggered, always do the path
// notification because unless mutableData is used for dom-repeat
// and all elements in the instance subtree, a full refresh may
// not trigger the proper update.
let instIdx = this.__itemsIdxToInstIdx[itemsIdx];
let inst = this.__instances[instIdx];
if (inst) {
let itemPath = this.as + (itemSubPath ? '.' + itemSubPath : '');
// This is effectively `notifyPath`, but avoids some of the overhead
// of the public API
inst._setPendingPropertyOrPath(itemPath, value, false, true);
inst._flushProperties();
}
return true;
}
}
/**
* Returns the item associated with a given element stamped by
* this `dom-repeat`.
*
* Note, to modify sub-properties of the item,
* `modelForElement(el).set('item.<sub-prop>', value)`
* should be used.
*
* @param {!HTMLElement} el Element for which to return the item.
* @return {*} Item associated with the element.
*/
itemForElement(el) {
let instance = this.modelForElement(el);
return instance && instance[this.as];
}
/**
* Returns the inst index for a given element stamped by this `dom-repeat`.
* If `sort` is provided, the index will reflect the sorted order (rather
* than the original array order).
*
* @param {!HTMLElement} el Element for which to return the index.
* @return {?number} Row index associated with the element (note this may
* not correspond to the array index if a user `sort` is applied).
*/
indexForElement(el) {
let instance = this.modelForElement(el);
return instance && instance[this.indexAs];
}
/**
* Returns the template "model" associated with a given element, which
* serves as the binding scope for the template instance the element is
* contained in. A template model
* should be used to manipulate data associated with this template instance.
*
* Example:
*
* let model = modelForElement(el);
* if (model.index < 10) {
* model.set('item.checked', true);
* }
*
* @param {!HTMLElement} el Element for which to return a template model.
* @return {TemplateInstanceBase} Model representing the binding scope for
* the element.
*/
modelForElement(el) {
return (0,_utils_templatize_js__WEBPACK_IMPORTED_MODULE_1__.modelForElement)(this.template, el);
}
}
customElements.define(DomRepeat.is, DomRepeat);
/***/ }),
/***/ "./node_modules/@polymer/polymer/lib/mixins/element-mixin.js":
/*!*******************************************************************!*\
!*** ./node_modules/@polymer/polymer/lib/mixins/element-mixin.js ***!
\*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "ElementMixin": () => (/* binding */ ElementMixin),
/* harmony export */ "builtCSS": () => (/* binding */ builtCSS),
/* harmony export */ "updateStyles": () => (/* binding */ updateStyles),
/* harmony export */ "version": () => (/* binding */ version)
/* harmony export */ });
/* harmony import */ var _utils_boot_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/boot.js */ "./node_modules/@polymer/polymer/lib/utils/boot.js");
/* harmony import */ var _utils_settings_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/settings.js */ "./node_modules/@polymer/polymer/lib/utils/settings.js");
/* harmony import */ var _utils_mixin_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/mixin.js */ "./node_modules/@polymer/polymer/lib/utils/mixin.js");
/* harmony import */ var _utils_style_gather_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/style-gather.js */ "./node_modules/@polymer/polymer/lib/utils/style-gather.js");
/* harmony import */ var _utils_resolve_url_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/resolve-url.js */ "./node_modules/@polymer/polymer/lib/utils/resolve-url.js");
/* harmony import */ var _elements_dom_module_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../elements/dom-module.js */ "./node_modules/@polymer/polymer/lib/elements/dom-module.js");
/* harmony import */ var _property_effects_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./property-effects.js */ "./node_modules/@polymer/polymer/lib/mixins/property-effects.js");
/* harmony import */ var _properties_mixin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./properties-mixin.js */ "./node_modules/@polymer/polymer/lib/mixins/properties-mixin.js");
/* harmony import */ var _utils_wrap_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/wrap.js */ "./node_modules/@polymer/polymer/lib/utils/wrap.js");
/**
* @fileoverview
* @suppress {checkPrototypalTypes}
* @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
*/
/**
* Current Polymer version in Semver notation.
* @type {string} Semver notation of the current version of Polymer.
*/
const version = '3.5.2';
const builtCSS = window.ShadyCSS && window.ShadyCSS['cssBuild'];
/**
* Element class mixin that provides the core API for Polymer's meta-programming
* features including template stamping, data-binding, attribute deserialization,
* and property change observation.
*
* Subclassers may provide the following static getters to return metadata
* used to configure Polymer's features for the class:
*
* - `static get is()`: When the template is provided via a `dom-module`,
* users should return the `dom-module` id from a static `is` getter. If
* no template is needed or the template is provided directly via the
* `template` getter, there is no need to define `is` for the element.
*
* - `static get template()`: Users may provide the template directly (as
* opposed to via `dom-module`) by implementing a static `template` getter.
* The getter must return an `HTMLTemplateElement`.
*
* - `static get properties()`: Should return an object describing
* property-related metadata used by Polymer features (key: property name
* value: object containing property metadata). Valid keys in per-property
* metadata include:
* - `type` (String|Number|Object|Array|...): Used by
* `attributeChangedCallback` to determine how string-based attributes
* are deserialized to JavaScript property values.
* - `notify` (boolean): Causes a change in the property to fire a
* non-bubbling event called `<property>-changed`. Elements that have
* enabled two-way binding to the property use this event to observe changes.
* - `readOnly` (boolean): Creates a getter for the property, but no setter.
* To set a read-only property, use the private setter method
* `_setProperty(property, value)`.
* - `observer` (string): Observer method name that will be called when
* the property changes. The arguments of the method are
* `(value, previousValue)`.
* - `computed` (string): String describing method and dependent properties
* for computing the value of this property (e.g. `'computeFoo(bar, zot)'`).
* Computed properties are read-only by default and can only be changed
* via the return value of the computing method.
*
* - `static get observers()`: Array of strings describing multi-property
* observer methods and their dependent properties (e.g.
* `'observeABC(a, b, c)'`).
*
* The base class provides default implementations for the following standard
* custom element lifecycle callbacks; users may override these, but should
* call the super method to ensure
* - `constructor`: Run when the element is created or upgraded
* - `connectedCallback`: Run each time the element is connected to the
* document
* - `disconnectedCallback`: Run each time the element is disconnected from
* the document
* - `attributeChangedCallback`: Run each time an attribute in
* `observedAttributes` is set or removed (note: this element's default
* `observedAttributes` implementation will automatically return an array
* of dash-cased attributes based on `properties`)
*
* @mixinFunction
* @polymer
* @appliesMixin PropertyEffects
* @appliesMixin PropertiesMixin
* @property rootPath {string} Set to the value of `rootPath`,
* which defaults to the main document path
* @property importPath {string} Set to the value of the class's static
* `importPath` property, which defaults to the path of this element's
* `dom-module` (when `is` is used), but can be overridden for other
* import strategies.
* @summary Element class mixin that provides the core API for Polymer's
* meta-programming features.
* @template T
* @param {function(new:T)} superClass Class to apply mixin to.
* @return {function(new:T)} superClass with mixin applied.
*/
const ElementMixin = (0,_utils_mixin_js__WEBPACK_IMPORTED_MODULE_2__.dedupingMixin)(base => {
/**
* @constructor
* @implements {Polymer_PropertyEffects}
* @implements {Polymer_PropertiesMixin}
* @extends {HTMLElement}
* @private
*/
const polymerElementBase = (0,_properties_mixin_js__WEBPACK_IMPORTED_MODULE_7__.PropertiesMixin)((0,_property_effects_js__WEBPACK_IMPORTED_MODULE_6__.PropertyEffects)(base));
/**
* Returns a list of properties with default values.
* This list is created as an optimization since it is a subset of
* the list returned from `_properties`.
* This list is used in `_initializeProperties` to set property defaults.
*
* @param {PolymerElementConstructor} constructor Element class
* @return {PolymerElementProperties} Flattened properties for this class
* that have default values
* @private
*/
function propertyDefaults(constructor) {
if (!constructor.hasOwnProperty(
JSCompiler_renameProperty('__propertyDefaults', constructor))) {
constructor.__propertyDefaults = null;
let props = constructor._properties;
for (let p in props) {
let info = props[p];
if ('value' in info) {
constructor.__propertyDefaults = constructor.__propertyDefaults || {};
constructor.__propertyDefaults[p] = info;
}
}
}
return constructor.__propertyDefaults;
}
/**
* Returns a memoized version of the `observers` array.
* @param {PolymerElementConstructor} constructor Element class
* @return {Array} Array containing own observers for the given class
* @protected
*/
function ownObservers(constructor) {
if (!constructor.hasOwnProperty(
JSCompiler_renameProperty('__ownObservers', constructor))) {
constructor.__ownObservers =
constructor.hasOwnProperty(
JSCompiler_renameProperty('observers', constructor)) ?
/** @type {PolymerElementConstructor} */ (constructor).observers :
null;
}
return constructor.__ownObservers;
}
/**
* Creates effects for a property.
*
* Note, once a property has been set to
* `readOnly`, `computed`, `reflectToAttribute`, or `notify`
* these values may not be changed. For example, a subclass cannot
* alter these settings. However, additional `observers` may be added
* by subclasses.
*
* The info object should contain property metadata as follows:
*
* * `type`: {function} type to which an attribute matching the property
* is deserialized. Note the property is camel-cased from a dash-cased
* attribute. For example, 'foo-bar' attribute is deserialized to a
* property named 'fooBar'.
*
* * `readOnly`: {boolean} creates a readOnly property and
* makes a private setter for the private of the form '_setFoo' for a
* property 'foo',
*
* * `computed`: {string} creates a computed property. A computed property
* is also automatically set to `readOnly: true`. The value is calculated
* by running a method and arguments parsed from the given string. For
* example 'compute(foo)' will compute a given property when the
* 'foo' property changes by executing the 'compute' method. This method
* must return the computed value.
*
* * `reflectToAttribute`: {boolean} If true, the property value is reflected
* to an attribute of the same name. Note, the attribute is dash-cased
* so a property named 'fooBar' is reflected as 'foo-bar'.
*
* * `notify`: {boolean} sends a non-bubbling notification event when
* the property changes. For example, a property named 'foo' sends an
* event named 'foo-changed' with `event.detail` set to the value of
* the property.
*
* * observer: {string} name of a method that runs when the property
* changes. The arguments of the method are (value, previousValue).
*
* Note: Users may want control over modifying property
* effects via subclassing. For example, a user might want to make a
* reflectToAttribute property not do so in a subclass. We've chosen to
* disable this because it leads to additional complication.
* For example, a readOnly effect generates a special sette