144 lines
4.8 KiB
HTML
144 lines
4.8 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="../utils/resolve-url.html">
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
|
|
let modules = {};
|
|
let lcModules = {};
|
|
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
|
|
* @memberof Polymer
|
|
* @summary Custom element that provides a registry of relocatable DOM content
|
|
* by `id` that is agnostic to bundling.
|
|
* @unrestricted
|
|
*/
|
|
class DomModule extends HTMLElement {
|
|
|
|
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`.
|
|
*/
|
|
static import(id, selector) {
|
|
if (id) {
|
|
let m = findModule(id);
|
|
if (m && selector) {
|
|
return m.querySelector(selector);
|
|
}
|
|
return m;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param {string} name Name of attribute.
|
|
* @param {?string} old Old value of attribute.
|
|
* @param {?string} value Current value of attribute.
|
|
* @return {void}
|
|
*/
|
|
attributeChangedCallback(name, old, value) {
|
|
if (old !== value) {
|
|
this.register();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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; accomodate polyfilled HTMLImports
|
|
const owner = window.HTMLImports && HTMLImports.importForElement ?
|
|
HTMLImports.importForElement(this) || document : this.ownerDocument;
|
|
const url = Polymer.ResolveUrl.resolveUrl(
|
|
this.getAttribute('assetpath') || '', owner.baseURI);
|
|
this.__assetpath = Polymer.ResolveUrl.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) {
|
|
this.id = id;
|
|
// store id separate from lowercased id so that
|
|
// in all cases mixedCase id will stored distinctly
|
|
// and lowercase version is a fallback
|
|
modules[id] = this;
|
|
lcModules[id.toLowerCase()] = this;
|
|
styleOutsideTemplateCheck(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
DomModule.prototype['modules'] = modules;
|
|
|
|
customElements.define('dom-module', DomModule);
|
|
|
|
// export
|
|
Polymer.DomModule = DomModule;
|
|
|
|
})();
|
|
</script>
|