Use method hash for controller alias if not provided

This commit is contained in:
Niels Lyngsø
2024-02-27 17:28:17 +01:00
parent 5d30c0f69f
commit fb77dcb12f
11 changed files with 89 additions and 15 deletions

View File

@@ -1 +1 @@
export type UmbControllerAlias = string | symbol | undefined;
export type UmbControllerAlias = string | number | symbol | undefined;

View File

@@ -6,9 +6,9 @@ import type { UmbControllerHost } from './controller-host.interface.js';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
@customElement('test-my-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
export class UmbTestControllerImplementation extends UmbControllerHostMixin(class {}) {
class UmbTestControllerImplementation extends UmbControllerHostMixin(class {}) {
testIsConnected = false;
testIsDestroyed = false;
@@ -47,9 +47,7 @@ export class UmbTestControllerImplementation extends UmbControllerHostMixin(clas
}
describe('UmbController', () => {
type NewType = UmbControllerHostElement;
let hostElement: NewType;
let hostElement: UmbControllerHostElement;
beforeEach(() => {
hostElement = document.createElement('test-my-controller-host') as UmbControllerHostElement;

View File

@@ -16,7 +16,7 @@ import { UmbSwitchCondition } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@customElement('umb-test-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestExtensionController extends UmbBaseExtensionInitializer {
constructor(

View File

@@ -9,9 +9,9 @@ import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { type ManifestSection, UmbSwitchCondition } from '@umbraco-cms/backoffice/extension-registry';
@customElement('umb-test-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
export class UmbTestApiController extends UmbBaseController {
class UmbTestApiController extends UmbBaseController {
public i_am_test_api_controller = true;
constructor(host: UmbControllerHost) {

View File

@@ -1,13 +1,13 @@
import { expect, fixture } from '@open-wc/testing';
import { UmbExtensionRegistry } from '../registry/extension.registry.js';
import { UmbExtensionElementInitializer } from './index.js';
import type { UmbControllerHostElement} from '@umbraco-cms/backoffice/controller-api';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api';
import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { type ManifestSection, UmbSwitchCondition } from '@umbraco-cms/backoffice/extension-registry';
@customElement('umb-test-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
describe('UmbExtensionElementController', () => {
describe('Manifest without conditions', () => {

View File

@@ -0,0 +1,58 @@
import { expect } from '@open-wc/testing';
import { UmbObjectState } from './states/object-state.js';
import { UmbObserverController } from './observer.controller.js';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api';
@customElement('test-my-observer-controller-host')
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
describe('UmbObserverController', () => {
describe('Observer Controllers against other Observer Controllers', () => {
let hostElement: UmbTestControllerHostElement;
beforeEach(() => {
hostElement = document.createElement('test-my-observer-controller-host') as UmbTestControllerHostElement;
});
it('controller is replaced by another controller using the same string as controller-alias', () => {
const state = new UmbObjectState(undefined);
const observable = state.asObservable();
const callbackMethod = (state: unknown) => {};
const firstCtrl = new UmbObserverController(hostElement, observable, callbackMethod, 'my-test-alias');
const secondCtrl = new UmbObserverController(hostElement, observable, callbackMethod, 'my-test-alias');
expect(hostElement.hasController(firstCtrl)).to.be.false;
expect(hostElement.hasController(secondCtrl)).to.be.true;
});
it('controller is replaced by another controller using the the same symbol as controller-alias', () => {
const state = new UmbObjectState(undefined);
const observable = state.asObservable();
const callbackMethod = (state: unknown) => {};
const mySymbol = Symbol();
const firstCtrl = new UmbObserverController(hostElement, observable, callbackMethod, mySymbol);
const secondCtrl = new UmbObserverController(hostElement, observable, callbackMethod, mySymbol);
expect(hostElement.hasController(firstCtrl)).to.be.false;
expect(hostElement.hasController(secondCtrl)).to.be.true;
});
it('controller is replacing another controller when using the same callback method and no controller-alias', () => {
const state = new UmbObjectState(undefined);
const observable = state.asObservable();
const callbackMethod = (state: unknown) => {};
const firstCtrl = new UmbObserverController(hostElement, observable, callbackMethod);
const secondCtrl = new UmbObserverController(hostElement, observable, callbackMethod);
expect(hostElement.hasController(firstCtrl)).to.be.false;
expect(hostElement.hasController(secondCtrl)).to.be.true;
});
});
});

View File

@@ -1,4 +1,5 @@
import { type ObserverCallback, UmbObserver } from './observer.js';
import { simpleHashCode } from './utils/simple-hash-code.function.js';
import type { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import type { UmbController, UmbControllerAlias, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -18,7 +19,8 @@ export class UmbObserverController<T = unknown> extends UmbObserver<T> implement
) {
super(source, callback);
this.#host = host;
this.#alias = alias;
// Fallback to use a hash of the provided method:
this.#alias = alias ?? simpleHashCode(callback.toString());
// Lets check if controller is already here:
// No we don't want this, as multiple different controllers might be looking at the same source.

View File

@@ -8,3 +8,4 @@ export * from './naive-object-comparison.function.js';
export * from './observe-multiple.function.js';
export * from './partial-update-frozen-array.function.js';
export * from './push-to-unique-array.function.js';
export * from './simple-hash-code.function.js';

View File

@@ -0,0 +1,15 @@
/**
* Returns a hash code from a string
* @param {String} str - The string to hash.
* @return {Number} - A 32bit integer
*/
export function simpleHashCode(str: string) {
let hash = 0,
i = 0;
const len = str.length;
while (i < len) {
hash = (hash << 5) - hash + str.charCodeAt(i++);
hash |= 0; // Convert to 32bit integer
}
return hash;
}

View File

@@ -2,12 +2,12 @@ import { expect } from '@open-wc/testing';
import { UmbCollectionViewManager } from './collection-view.manager.js';
import { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api';
import type { ManifestCollectionView} from '@umbraco-cms/backoffice/extension-registry';
import type { ManifestCollectionView } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
@customElement('test-my-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
const VIEW_1_ALIAS = 'UmbTest.CollectionView.1';
const VIEW_2_ALIAS = 'UmbTest.CollectionView.2';

View File

@@ -5,7 +5,7 @@ import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbControllerHostElementMixin } from '@umbraco-cms/backoffice/controller-api';
@customElement('test-my-controller-host')
export class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {}
describe('UmbSelectionManager', () => {
let manager: UmbSelectionManager;