Files
polymer/lib/elements/dom-module.html
T
2017-02-28 10:37:04 -08:00

120 lines
3.7 KiB
HTML

<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 any dom-module element. Use the `import(id, selector)`
* method to locate dom within this database. For 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 = document.createElement('dom-module').import('foo', 'img');
*
* @extends HTMLElement
* @memberof Polymer
*/
class DomModule extends HTMLElement {
static get observedAttributes() { return ['id'] }
/**
* Retrieves the dom specified by `selector` in the module specified by
* `id`. For example, this.import('foo', 'img');
* @method register
* @param {string} id
* @param {string=} selector
* @return {Element} Returns the dom which matches `selector` in the module
* 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;
}
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;
this.__assetpath = Polymer.ResolveUrl.resolveUrl(
this.getAttribute('assetpath') || '', owner.baseURI);
}
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')`.
* @method register
* @param {string=} id The id at which to register the dom-module.
*/
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>