mirror of
https://github.com/jlengrand/open-wc.git
synced 2026-03-10 08:31:19 +00:00
fix(scoped-elements): define unused lazy scoped elements
This commit is contained in:
committed by
Lars den Bakker
parent
4ac8a8501f
commit
5b863a2bba
@@ -17,6 +17,19 @@ import { shadyTemplateFactory } from './shadyTemplateFactory.js';
|
||||
*/
|
||||
const templateCaches = new WeakMap();
|
||||
|
||||
/**
|
||||
* Retrieves or creates a templateCache for a specific key
|
||||
* @param {Function} key
|
||||
* @returns {Map<TemplateStringsArray, TemplateStringsArray>}
|
||||
*/
|
||||
const getTemplateCache = key => {
|
||||
if (!templateCaches.has(key)) {
|
||||
templateCaches.set(key, new Map());
|
||||
}
|
||||
|
||||
return templateCaches.get(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tags caches
|
||||
*
|
||||
@@ -24,6 +37,19 @@ const templateCaches = new WeakMap();
|
||||
*/
|
||||
const tagsCaches = new WeakMap();
|
||||
|
||||
/**
|
||||
* Retrieves or creates a tagsCache for a specific key
|
||||
* @param {object} key
|
||||
* @returns {Map<string, string>}
|
||||
*/
|
||||
const getTagsCache = key => {
|
||||
if (!tagsCaches.has(key)) {
|
||||
tagsCaches.set(key, new Map());
|
||||
}
|
||||
|
||||
return tagsCaches.get(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms an array of TemplateResults or arrays into another one with resolved scoped elements
|
||||
*
|
||||
@@ -91,15 +117,8 @@ export const ScopedElementsMixin = dedupeMixin(
|
||||
}
|
||||
const { scopeName } = options;
|
||||
|
||||
if (!templateCaches.has(this)) {
|
||||
templateCaches.set(this, new Map());
|
||||
}
|
||||
if (!tagsCaches.has(this)) {
|
||||
tagsCaches.set(this, new Map());
|
||||
}
|
||||
|
||||
const templateCache = templateCaches.get(this);
|
||||
const tagsCache = tagsCaches.get(this);
|
||||
const templateCache = getTemplateCache(this);
|
||||
const tagsCache = getTagsCache(this);
|
||||
const { scopedElements } = this;
|
||||
|
||||
// @ts-ignore
|
||||
@@ -121,7 +140,7 @@ export const ScopedElementsMixin = dedupeMixin(
|
||||
* @param {typeof HTMLElement} klass
|
||||
*/
|
||||
defineScopedElement(tagName, klass) {
|
||||
return defineScopedElement(tagName, klass, tagsCaches.get(this.constructor));
|
||||
return defineScopedElement(tagName, klass, getTagsCache(this.constructor));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,8 +153,8 @@ export const ScopedElementsMixin = dedupeMixin(
|
||||
const klass = this.scopedElements[tagName];
|
||||
|
||||
return klass
|
||||
? registerElement(tagName, klass, tagsCaches.get(this))
|
||||
: tagsCaches.get(this).get(tagName);
|
||||
? registerElement(tagName, klass, getTagsCache(this))
|
||||
: getTagsCache(this).get(tagName);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -76,5 +76,9 @@ export function registerElement(tagName, klass, tagsCache = undefined) {
|
||||
export function defineScopedElement(tagName, klass, tagsCache) {
|
||||
const tag = tagsCache.get(tagName);
|
||||
|
||||
defineElement(tag, klass, customElements);
|
||||
if (tag) {
|
||||
defineElement(tag, klass, customElements);
|
||||
} else {
|
||||
tagsCache.set(tagName, registerElement(tagName, klass, tagsCache));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +294,58 @@ describe('ScopedElementsMixin', () => {
|
||||
expect(el.shadowRoot.children[1]).to.be.an.instanceOf(FeatureB);
|
||||
});
|
||||
|
||||
it("support define a lazy element even if it's not used in previous templates", async () => {
|
||||
class LazyElement extends LitElement {
|
||||
render() {
|
||||
return html`
|
||||
<div>Lazy element</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
const tag = defineCE(
|
||||
class extends ScopedElementsMixin(LitElement) {
|
||||
static get scopedElements() {
|
||||
return {
|
||||
'feature-a': FeatureA,
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const defineScopedElement = this.defineScopedElement.bind(this);
|
||||
|
||||
this.loading = new Promise(resolve => {
|
||||
defineScopedElement('lazy-element', LazyElement);
|
||||
|
||||
resolve(
|
||||
html`
|
||||
<lazy-element></lazy-element>
|
||||
`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<feature-a></feature-a>
|
||||
${until(
|
||||
this.loading,
|
||||
html`
|
||||
<div>Loading...</div>
|
||||
`,
|
||||
)}
|
||||
`;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const el = await fixture(`<${tag}></${tag}>`);
|
||||
|
||||
await waitUntil(() => el.shadowRoot.children[1] instanceof LazyElement);
|
||||
});
|
||||
|
||||
describe('getScopedTagName', () => {
|
||||
it('should return the scoped tag name for a registered element', async () => {
|
||||
const chars = `-|\\.|[0-9]|[a-z]`;
|
||||
|
||||
Reference in New Issue
Block a user