From 2cb3bde4c86fccf2f2cd0090ec280a79d74f4b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 4 Jan 2023 10:41:40 +0100 Subject: [PATCH] remove single purpose mixins --- .../consume/context-consumer.mixin.ts | 111 ------------------ .../provide/context-provider.element.ts | 7 +- .../provide/context-provider.mixin.test.ts | 45 ------- .../provide/context-provider.mixin.ts | 52 -------- 4 files changed, 3 insertions(+), 212 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/core/context-api/consume/context-consumer.mixin.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.test.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.ts diff --git a/src/Umbraco.Web.UI.Client/src/core/context-api/consume/context-consumer.mixin.ts b/src/Umbraco.Web.UI.Client/src/core/context-api/consume/context-consumer.mixin.ts deleted file mode 100644 index 63e44ead40..0000000000 --- a/src/Umbraco.Web.UI.Client/src/core/context-api/consume/context-consumer.mixin.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { HTMLElementConstructor } from '../../models'; -import { UmbContextConsumer } from './context-consumer'; - -export declare class UmbContextConsumerInterface { - consumeContext(alias: string, callback: (_instance: any) => void): void; - consumeAllContexts(contextAliases: string[], callback: (_instances: ResolvedContexts) => void): void; - whenAvailableOrChanged(contextAliases: string[], callback?: () => void): void; -} - -// TODO: can we use this aliases to generate the key of this type -interface ResolvedContexts { - [key: string]: any; -} - -/** - * This mixin enables the component to consume contexts. - * This is done by calling the `consumeContext` method. - * - * @param {Object} superClass - superclass to be extended. - * @mixin - */ -export const UmbContextConsumerMixin = (superClass: T) => { - class UmbContextConsumerClass extends superClass { - // all context requesters in the element - _consumers: Map = new Map(); - // all successfully resolved context requests - _resolved: Map = new Map(); - - _attached = false; - - /** - * Setup a subscription for a context. The callback is called when the context is resolved. - * @param {string} alias - * @param {method} callback Callback method called when context is resolved. - */ - consumeContext(alias: string, callback: (_instance: any) => void): void { - this._createContextConsumers([alias], (resolvedContexts) => { - callback(resolvedContexts[alias]); - }); - } - - /** - * Setup a subscription for multiple contexts. The callback is called when all contexts are resolved. - * @param {string} aliases - * @param {method} callback Callback method called when all contexts are resolved. - */ - consumeAllContexts(_contextAliases: Array, callback: (_instances: ResolvedContexts) => void) { - this._createContextConsumers(_contextAliases, (resolvedContexts) => { - callback?.(resolvedContexts); - }); - } - - private _createContextConsumers(aliases: Array, resolvedCallback: (_instances: ResolvedContexts) => void) { - aliases.forEach((alias) => { - const consumer = new UmbContextConsumer(this, alias, (_instance: any) => { - this._resolved.set(alias, _instance); - - const result: ResolvedContexts = {}; - - //check if all contexts are resolved - const resolvedContexts = aliases.map((alias) => (result[alias] = this._resolved.get(alias))); - const allResolved = resolvedContexts.every((context) => context !== undefined); - - if (allResolved) { - resolvedCallback(result); - } - }); - - if (this._consumers.has(alias)) { - const consumers = this._consumers.get(alias); - consumers?.push(consumer); - } else { - this._consumers.set(alias, [consumer]); - } - - if (this._attached) { - consumer.hostConnected(); - } - }); - } - - // TODO: remove requester.. - - connectedCallback() { - super.connectedCallback?.(); - this._attached = true; - this._consumers.forEach((consumers) => consumers.forEach((consumer) => consumer.hostConnected())); - } - - disconnectedCallback() { - super.disconnectedCallback?.(); - this._attached = false; - this._consumers.forEach((consumers) => consumers.forEach((consumer) => consumer.hostDisconnected())); - this._resolved.clear(); - } - - // might return a object, so you can unsubscribe. - whenAvailableOrChanged(_contextAliases: string[]) { - // TODO: To be done. - } - } - - return UmbContextConsumerClass as unknown as HTMLElementConstructor & T; -}; - -declare global { - interface HTMLElement { - connectedCallback(): void; - disconnectedCallback(): void; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.element.ts b/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.element.ts index 575e81f818..cf8d3da2c1 100644 --- a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.element.ts @@ -1,10 +1,9 @@ -import { html, LitElement } from 'lit'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; - -import { UmbContextProviderMixin } from './context-provider.mixin'; +import { UmbLitElement } from '@umbraco-cms/element'; @customElement('umb-context-provider') -export class UmbContextProviderElement extends UmbContextProviderMixin(LitElement) { +export class UmbContextProviderElement extends UmbLitElement { /** * The value to provide to the context. * @required diff --git a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.test.ts b/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.test.ts deleted file mode 100644 index c68277e517..0000000000 --- a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { expect, fixture, html } from '@open-wc/testing'; -import { UmbContextProvider } from './context-provider'; -import { UmbContextProviderMixin } from './context-provider.mixin'; - -class MyClass { - prop: string; - - constructor(text: string) { - this.prop = text; - } -} - -class MyTestProviderElement extends UmbContextProviderMixin(HTMLElement) { - constructor() { - super(); - this.provideContext('my-test-context-1', new MyClass('context value 1')); - this.provideContext('my-test-context-2', new MyClass('context value 2')); - } -} - -customElements.define('my-test-provider-element', MyTestProviderElement); - -describe('UmbContextProviderMixin', async () => { - let element: MyTestProviderElement; - let _providers: Map; - - beforeEach(async () => { - element = await fixture(html``); - _providers = (element as any)['_providers']; - }); - - it('sets all providers to element', () => { - expect(_providers.has('my-test-context-1')).to.be.true; - expect(_providers.has('my-test-context-2')).to.be.true; - }); - - it('can not set context with same key as already existing context', () => { - const provider = _providers.get('my-test-context-1'); - expect(provider).to.not.be.undefined; - if (!provider) return; - expect((provider['_instance'] as MyClass).prop).to.eq('context value 1'); - element.provideContext('my-test-context-1', new MyClass('new context value 1')); - expect((provider['_instance'] as MyClass).prop).to.eq('context value 1'); - }); -}); diff --git a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.ts b/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.ts deleted file mode 100644 index 8647039eb0..0000000000 --- a/src/Umbraco.Web.UI.Client/src/core/context-api/provide/context-provider.mixin.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { HTMLElementConstructor } from '../../models'; -import { UmbContextProvider } from './context-provider'; - -export declare class UmbContextProviderMixinInterface { - provideContext(alias: string, instance: unknown): void; -} - -export const UmbContextProviderMixin = (superClass: T) => { - class UmbContextProviderClass extends superClass { - _providers: Map = new Map(); - - _attached = false; - - provideContext(alias: string, instance: unknown) { - // TODO: Consider if its right to re-publish the context? - const existingProvider = this._providers.get(alias); - if (existingProvider) { - existingProvider.hostDisconnected(); - } - - const provider = new UmbContextProvider(this, alias, instance); - this._providers.set(alias, provider); - // TODO: if already connected then attach the new one. - if (this._attached) { - provider.hostConnected(); - } - } - - // TODO: unprovide method to enforce a detach? - - connectedCallback() { - super.connectedCallback?.(); - this._attached = true; - this._providers.forEach((provider) => provider.hostConnected()); - } - - disconnectedCallback() { - super.disconnectedCallback?.(); - this._attached = false; - this._providers.forEach((provider) => provider.hostDisconnected()); - } - } - - return UmbContextProviderClass as unknown as HTMLElementConstructor & T; -}; - -declare global { - interface HTMLElement { - connectedCallback(): void; - disconnectedCallback(): void; - } -}