Skip to content

Commit 689ff72

Browse files
authored
Merge pull request #5172 from Polymer/5163-kschaaf-import-meta
Add importMeta getter to derive importPath from modules. Fixes #5163
2 parents 53dd08d + c8c9e24 commit 689ff72

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

lib/mixins/element-mixin.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,24 +398,46 @@
398398

399399
/**
400400
* Path matching the url from which the element was imported.
401+
*
401402
* This path is used to resolve url's in template style cssText.
402403
* The `importPath` property is also set on element instances and can be
403404
* used to create bindings relative to the import path.
404-
* Defaults to the path matching the url containing a `dom-module` element
405-
* matching this element's static `is` property.
405+
* For elements defined in ES modules, users should implement `importMeta`
406+
* and this getter will return `import.meta.url`'s path. For elements
407+
* defined in HTML imports, this getter will return the path to the
408+
* document containing a `dom-module` element matching this element's
409+
* static `is` property.
410+
*
406411
* Note, this path should contain a trailing `/`.
407412
*
408413
* @return {string} The import path for this element class
409414
*/
410415
static get importPath() {
411416
if (!this.hasOwnProperty(JSCompiler_renameProperty('_importPath', this))) {
417+
const meta = this.importMeta;
418+
if (meta) {
419+
this._importPath = Polymer.ResolveUrl.pathFromUrl(meta.url);
420+
} else {
412421
const module = Polymer.DomModule && Polymer.DomModule.import(/** @type {PolymerElementConstructor} */ (this).is);
413-
this._importPath = module ? module.assetpath : '' ||
414-
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath;
422+
this._importPath = (module && module.assetpath) ||
423+
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath;
424+
}
415425
}
416426
return this._importPath;
417427
}
418428

429+
/**
430+
* When an element definition is being loaded from an ES module, users
431+
* may override this getter to return the `import.meta` object from that
432+
* module, which will be used to derive the `importPath` for the element.
433+
* When implementing `importMeta`, users should not implement `importPath`.
434+
*
435+
* @return {!Object} The `import.meta` object for the element's module
436+
*/
437+
static get importMeta() {
438+
return null;
439+
}
440+
419441
constructor() {
420442
super();
421443
/** @type {HTMLTemplateElement} */
@@ -447,14 +469,13 @@
447469
_initializeProperties() {
448470
Polymer.telemetry.instanceCount++;
449471
this.constructor.finalize();
450-
const importPath = this.constructor.importPath;
451472
// note: finalize template when we have access to `localName` to
452473
// avoid dependence on `is` for polyfilling styling.
453474
this.constructor._finalizeTemplate(/** @type {!HTMLElement} */(this).localName);
454475
super._initializeProperties();
455476
// set path defaults
456477
this.rootPath = Polymer.rootPath;
457-
this.importPath = importPath;
478+
this.importPath = this.constructor.importPath;
458479
// apply property defaults...
459480
let p$ = propertyDefaults(this.constructor);
460481
if (!p$) {

test/unit/resolveurl.html

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@
5252
<script>
5353
suite('ResolveUrl', function() {
5454

55-
test('Urls in styles and attributes', function() {
56-
var el = document.createElement('p-r');
55+
const testStylesAndAttributes = (elementName, folder) => () => {
56+
var el = document.createElement(elementName);
5757
document.body.appendChild(el);
58-
var resolvedUrl = /sub\/foo\.z/;
58+
var resolvedUrl = new RegExp(`${folder}/foo\\.z`);
5959
var styleHashUrl = /url\('#bar'\)/;
6060
var styleAbsUrl = /url\('\/zot'\)/;
61-
var style = el.shadowRoot.querySelector('style') || document.querySelector('style[scope=p-r]');
61+
var style = el.shadowRoot.querySelector('style') || document.querySelector(`style[scope=${elementName}]`);
6262
assert.match(style.textContent, resolvedUrl, 'url not relative to main document');
6363
assert.match(style.textContent, styleHashUrl, 'hash url incorrectly resolved');
6464
assert.match(style.textContent, styleAbsUrl, 'absolute url incorrectly resolved');
@@ -78,7 +78,11 @@
7878
assert.equal(el.$.absolute.getAttribute('href'), '/foo.z', 'absolute urls should not be resolved');
7979
assert.equal(el.$.protocol.getAttribute('href'), 'data:foo.z', 'urls with other protocols should not be resolved');
8080
document.body.removeChild(el);
81-
});
81+
};
82+
83+
test('Urls in styles and attributes', testStylesAndAttributes('p-r', 'sub'));
84+
85+
test('Urls in styles and attributes (importMeta)', testStylesAndAttributes('p-r-im', 'http://foo.com/mymodule'));
8286

8387
test('url changes via setting importPath/rootPath on element instance', function() {
8488
var el = document.createElement('p-r');

test/unit/sub/resolveurl-elements.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@
3838
static get is() { return 'p-r'; }
3939
}
4040
customElements.define(PR.is, PR);
41+
42+
class PRImportMeta extends PR {
43+
static get importMeta() {
44+
// Idiomatically, this would be `return import.meta`, but for purposes
45+
// of stubbing the test without actual modules, it's shimmed
46+
return { url: 'http://foo.com/mymodule/index.js' }
47+
}
48+
}
49+
customElements.define('p-r-im', PRImportMeta);
4150
</script>
4251

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

0 commit comments

Comments
 (0)