Skip to content

Add importMeta getter to derive importPath from modules. Fixes #5163 #5172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 3, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions lib/mixins/element-mixin.html
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,33 @@
*/
static get importPath() {
if (!this.hasOwnProperty(JSCompiler_renameProperty('_importPath', this))) {
const meta = this.importMeta;
if (meta) {
this._importPath = meta.url.slice(0, meta.url.lastIndexOf('/') + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use resolveUrl.pathFromUrl

} else {
const module = Polymer.DomModule && Polymer.DomModule.import(/** @type {PolymerElementConstructor} */ (this).is);
this._importPath = module ? module.assetpath : '' ||
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath;
if (module) {
this._importPath = module ? module.assetpath : '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be just module.assetpath, as the condition already asserted for module

} else {
this._importPath = Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath;
}
}
}
return this._importPath;
}

/**
* When an element definition is being loaded from an ES module, users
* may override this getter to return the `import.meta` object from that
* module, which will be used to derive the `importPath` for the element.
* When implementing `importMeta`, users should not implement `importPath`.
*
* @return {!Object} The `import.meta` object for the element's module
*/
static get importMeta() {
return null;
}

constructor() {
super();
/** @type {HTMLTemplateElement} */
Expand Down Expand Up @@ -447,14 +467,13 @@
_initializeProperties() {
Polymer.telemetry.instanceCount++;
this.constructor.finalize();
const importPath = this.constructor.importPath;
// note: finalize template when we have access to `localName` to
// avoid dependence on `is` for polyfilling styling.
this.constructor._finalizeTemplate(/** @type {!HTMLElement} */(this).localName);
super._initializeProperties();
// set path defaults
this.rootPath = Polymer.rootPath;
this.importPath = importPath;
this.importPath = this.constructor.importPath;
// apply property defaults...
let p$ = propertyDefaults(this.constructor);
if (!p$) {
Expand Down
12 changes: 8 additions & 4 deletions test/unit/resolveurl.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@
<script>
suite('ResolveUrl', function() {

test('Urls in styles and attributes', function() {
var el = document.createElement('p-r');
const testStylesAndAttributes = (elementName, folder) => () => {
var el = document.createElement(elementName);
document.body.appendChild(el);
var resolvedUrl = /sub\/foo\.z/;
var resolvedUrl = new RegExp(`${folder}/foo\\.z`);
var styleHashUrl = /url\('#bar'\)/;
var styleAbsUrl = /url\('\/zot'\)/;
var style = el.shadowRoot.querySelector('style') || document.querySelector('style[scope=p-r]');
Expand All @@ -78,7 +78,11 @@
assert.equal(el.$.absolute.getAttribute('href'), '/foo.z', 'absolute urls should not be resolved');
assert.equal(el.$.protocol.getAttribute('href'), 'data:foo.z', 'urls with other protocols should not be resolved');
document.body.removeChild(el);
});
};

test('Urls in styles and attributes', testStylesAndAttributes('p-r', 'sub'));

test('Urls in styles and attributes (importMeta)', testStylesAndAttributes('p-r-im', 'http://foo.com/mymodule'));

test('url changes via setting importPath/rootPath on element instance', function() {
var el = document.createElement('p-r');
Expand Down
9 changes: 9 additions & 0 deletions test/unit/sub/resolveurl-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
static get is() { return 'p-r'; }
}
customElements.define(PR.is, PR);

class PRImportMeta extends PR {
static get importMeta() {
// Idiomatically, this would be `return import.meta`, but for purposes
// of stubbing the test without actual modules, it's shimmed
return { url: 'http://foo.com/mymodule/index.js' }
}
}
customElements.define('p-r-im', PRImportMeta);
</script>

<dom-module id="p-r-ap" assetpath="../../assets/"></dom-module>
Expand Down