From 510f8b931f63325674eedd8877dd7e846da8028b Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Sun, 10 Nov 2024 11:04:01 +0100 Subject: [PATCH] fix(core): no registration of same class twice w/o scoped-registries polyfill --- .../core/src/ScopedElementsMixin.js | 4 +-- .../core/test/ScopedElementsMixin.test.js | 35 ++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/ui/components/core/src/ScopedElementsMixin.js b/packages/ui/components/core/src/ScopedElementsMixin.js index 34deefb0a..d01236086 100644 --- a/packages/ui/components/core/src/ScopedElementsMixin.js +++ b/packages/ui/components/core/src/ScopedElementsMixin.js @@ -89,8 +89,8 @@ const ScopedElementsMixinImplementation = superclass => */ defineScopedElement(tagName, classToBeRegistered) { const registeredClass = this.registry.get(tagName); - const isAlreadyRegistered = registeredClass && registeredClass === classToBeRegistered; - if (isAlreadyRegistered && !supportsScopedRegistry()) { + const isNewClassWithSameName = registeredClass && registeredClass !== classToBeRegistered; + if (!supportsScopedRegistry() && isNewClassWithSameName) { // eslint-disable-next-line no-console console.error( [ diff --git a/packages/ui/components/core/test/ScopedElementsMixin.test.js b/packages/ui/components/core/test/ScopedElementsMixin.test.js index bbebe3736..7aea78c1f 100644 --- a/packages/ui/components/core/test/ScopedElementsMixin.test.js +++ b/packages/ui/components/core/test/ScopedElementsMixin.test.js @@ -6,9 +6,9 @@ import { } from '@lit-labs/testing/fixtures.js'; import { LitElement, html } from 'lit'; import sinon from 'sinon'; -import { browserDetection } from '../src/browserDetection.js'; import { ScopedElementsMixin, supportsScopedRegistry } from '../src/ScopedElementsMixin.js'; +import { browserDetection } from '../src/browserDetection.js'; const hasRealScopedRegistrySupport = supportsScopedRegistry(); const originalShadowRootProps = { @@ -78,6 +78,8 @@ describe('ScopedElementsMixin', () => { describe('When scoped registries are supported', () => { it('registers elements on local registry', async () => { + if (!hasRealScopedRegistrySupport) return; + const ceDefineSpy = sinon.spy(customElements, 'define'); const el = /** @type {ScopedElementsHost} */ ( @@ -127,5 +129,36 @@ describe('ScopedElementsMixin', () => { expect(ceDefineSpy.calledWith('scoped-elements-child-no-reg')).to.be.true; ceDefineSpy.restore(); }); + + it('fails when different classes are registered under different name', async () => { + class ScopedElementsHostNoReg2 extends ScopedElementsMixin(LitElement) { + static scopedElements = { 'scoped-elements-child-no-reg': class extends HTMLElement {} }; + + render() { + return html``; + } + } + customElements.define('scoped-elements-host-no-reg-2', ScopedElementsHostNoReg2); + + const errorSpy = sinon.spy(console, 'error'); + /** @type {ScopedElementsHostNoReg2} */ ( + await fixture(html``) + ); + /** @type {ScopedElementsHostNoReg2} */ ( + await fixture(html``) + ); + + expect(errorSpy.args[0][0]).to.equal( + [ + 'You are trying to re-register the "scoped-elements-child-no-reg" custom element with a different class via ScopedElementsMixin.', + 'This is only possible with a CustomElementRegistry.', + 'Your browser does not support this feature so you will need to load a polyfill for it.', + 'Load "@webcomponents/scoped-custom-element-registry" before you register ANY web component to the global customElements registry.', + 'e.g. add "" as your first script tag.', + 'For more details you can visit https://open-wc.org/docs/development/scoped-elements/', + ].join('\n'), + ); + errorSpy.restore(); + }); }); });