140 lines
4.3 KiB
HTML
140 lines
4.3 KiB
HTML
<!--
|
|
@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
|
|
-->
|
|
|
|
<link rel="import" href="../utils/boot.html">
|
|
<link rel="import" href="../mixins/property-effects.html">
|
|
<link rel="import" href="../mixins/mutable-data.html">
|
|
<link rel="import" href="../mixins/gesture-event-listeners.html">
|
|
|
|
<script>
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
/**
|
|
* @constructor
|
|
* @extends {HTMLElement}
|
|
* @implements {Polymer_PropertyEffects}
|
|
* @implements {Polymer_OptionalMutableData}
|
|
* @implements {Polymer_GestureEventListeners}
|
|
*/
|
|
const domBindBase =
|
|
Polymer.GestureEventListeners(
|
|
Polymer.OptionalMutableData(
|
|
Polymer.PropertyEffects(HTMLElement)));
|
|
|
|
/**
|
|
* Custom element to allow using Polymer's template features (data binding,
|
|
* declarative event listeners, etc.) in the main document without defining
|
|
* a new custom element.
|
|
*
|
|
* `<template>` tags utilizing bindings may be wrapped with the `<dom-bind>`
|
|
* element, which will immediately stamp the wrapped template into the main
|
|
* document and bind elements to the `dom-bind` element itself as the
|
|
* binding scope.
|
|
*
|
|
* @polymer
|
|
* @customElement
|
|
* @appliesMixin Polymer.PropertyEffects
|
|
* @appliesMixin Polymer.OptionalMutableData
|
|
* @appliesMixin Polymer.GestureEventListeners
|
|
* @extends {domBindBase}
|
|
* @memberof Polymer
|
|
* @summary Custom element to allow using Polymer's template features (data
|
|
* binding, declarative event listeners, etc.) in the main document.
|
|
*/
|
|
class DomBind extends domBindBase {
|
|
|
|
static get observedAttributes() { return ['mutable-data']; }
|
|
|
|
constructor() {
|
|
super();
|
|
this.root = null;
|
|
this.$ = null;
|
|
this.__children = null;
|
|
}
|
|
|
|
/** @return {void} */
|
|
attributeChangedCallback() {
|
|
// assumes only one observed attribute
|
|
this.mutableData = true;
|
|
}
|
|
|
|
/** @return {void} */
|
|
connectedCallback() {
|
|
this.style.display = 'none';
|
|
this.render();
|
|
}
|
|
|
|
/** @return {void} */
|
|
disconnectedCallback() {
|
|
this.__removeChildren();
|
|
}
|
|
|
|
__insertChildren() {
|
|
this.parentNode.insertBefore(this.root, this);
|
|
}
|
|
|
|
__removeChildren() {
|
|
if (this.__children) {
|
|
for (let i=0; i<this.__children.length; i++) {
|
|
this.root.appendChild(this.__children[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Forces the element to render its content. This is typically only
|
|
* necessary to call if HTMLImports with the async attribute are used.
|
|
* @return {void}
|
|
*/
|
|
render() {
|
|
let template;
|
|
if (!this.__children) {
|
|
template = /** @type {HTMLTemplateElement} */(template || this.querySelector('template'));
|
|
if (!template) {
|
|
// Wait until childList changes and template should be there by then
|
|
let observer = new MutationObserver(() => {
|
|
template = /** @type {HTMLTemplateElement} */(this.querySelector('template'));
|
|
if (template) {
|
|
observer.disconnect();
|
|
this.render();
|
|
} else {
|
|
throw new Error('dom-bind requires a <template> child');
|
|
}
|
|
});
|
|
observer.observe(this, {childList: true});
|
|
return;
|
|
}
|
|
this.root = this._stampTemplate(template);
|
|
this.$ = this.root.$;
|
|
this.__children = [];
|
|
for (let n=this.root.firstChild; n; n=n.nextSibling) {
|
|
this.__children[this.__children.length] = n;
|
|
}
|
|
this._enableProperties();
|
|
}
|
|
this.__insertChildren();
|
|
this.dispatchEvent(new CustomEvent('dom-change', {
|
|
bubbles: true,
|
|
composed: true
|
|
}));
|
|
}
|
|
|
|
}
|
|
|
|
customElements.define('dom-bind', DomBind);
|
|
|
|
Polymer.DomBind = DomBind;
|
|
|
|
})();
|
|
|
|
</script>
|