diff --git a/container/cypress/e2e/wc-container.cy.js b/container/cypress/e2e/wc-container.cy.js index 580fed0d2b..6202121eb3 100644 --- a/container/cypress/e2e/wc-container.cy.js +++ b/container/cypress/e2e/wc-container.cy.js @@ -72,6 +72,19 @@ describe('Web Container Test', () => { expect(stub.getCall(0)).to.be.calledWith('LuigiClient.getUserSettings()={"language":"de","date":""}'); }); }); + + it('LuigiClient API getAnchor for LuigiContainer', () => { + const stub = cy.stub(); + cy.on('window:alert', stub); + + cy.get('[data-test-id="luigi-client-api-test-01"]') + .shadow() + .contains('getAnchor') + .click() + .then(() => { + expect(stub.getCall(0)).to.be.calledWith('LuigiClient.getAnchor()="testanchor"'); + }); + }); }); describe('LuigiClient API LuigiCompoundContainer', () => { @@ -92,5 +105,16 @@ describe('Web Container Test', () => { expect(stub.getCall(0)).to.be.calledWith('LuigiClient.getUserSettings()={"language":"it","date":""}'); }); }); + it('LuigiClient API getAnchor for LuigiCompoundContainer', () => { + const stub = cy.stub(); + cy.on('window:alert', stub); + cy.get('[data-test-id="luigi-client-api-test-compound-01"]') + .shadow() + .contains('getAnchor') + .click() + .then(() => { + expect(stub.getCall(0)).to.be.calledWith('LuigiClient.getAnchor()="testAnchorCompound"'); + }); + }); }); }); diff --git a/container/src/LuigiCompoundContainer.svelte b/container/src/LuigiCompoundContainer.svelte index 5698997f6a..2a5b1847e7 100644 --- a/container/src/LuigiCompoundContainer.svelte +++ b/container/src/LuigiCompoundContainer.svelte @@ -16,9 +16,18 @@ reflect: false, attribute: 'user-settings' }, - searchParams: { type: 'Object', reflect: false, attribute: 'search-params' }, + anchor: { type: 'String', reflect: false, attribute: 'anchor' }, + searchParams: { + type: 'Object', + reflect: false, + attribute: 'search-params' + }, pathParams: { type: 'Object', reflect: false, attribute: 'path-params' }, - clientPermissions: { type: 'Object', reflect: false, attribute: 'client-permissions' } + clientPermissions: { + type: 'Object', + reflect: false, + attribute: 'client-permissions' + } } }} /> @@ -38,6 +47,7 @@ export let pathParams: any; export let clientPermissions: any; export let userSettings: any; + export let anchor: string; let containerInitialized = false; let mainComponent: HTMLElement; @@ -48,7 +58,14 @@ // Only needed for get rid of "unused export property" svelte compiler warnings export const unwarn = () => { - return nodeParams && searchParams && pathParams && clientPermissions && userSettings; + return ( + nodeParams && + searchParams && + pathParams && + clientPermissions && + userSettings && + anchor + ); }; const initialize = (thisComponent: any) => { diff --git a/container/src/LuigiContainer.svelte b/container/src/LuigiContainer.svelte index 3922c63beb..e39b552a3e 100644 --- a/container/src/LuigiContainer.svelte +++ b/container/src/LuigiContainer.svelte @@ -29,9 +29,18 @@ reflect: false, attribute: 'user-settings' }, - searchParams: { type: 'Object', reflect: false, attribute: 'search-params' }, + anchor: { type: 'String', reflect: false, attribute: 'anchor' }, + searchParams: { + type: 'Object', + reflect: false, + attribute: 'search-params' + }, pathParams: { type: 'Object', reflect: false, attribute: 'path-params' }, - clientPermissions: { type: 'Object', reflect: false, attribute: 'client-permissions' } + clientPermissions: { + type: 'Object', + reflect: false, + attribute: 'client-permissions' + } }, extend: customElementConstructor => { let notInitFn = name => { @@ -72,7 +81,7 @@ export let clientPermissions: any; export let userSettings: any; - + export let anchor: string; const iframeHandle: | { @@ -87,7 +96,17 @@ // Only needed for get rid of "unused export property" svelte compiler warnings export const unwarn = () => { - return locale && theme && activeFeatureToggleList && nodeParams && searchParams && pathParams && clientPermissions && userSettings; + return ( + locale && + theme && + activeFeatureToggleList && + nodeParams && + searchParams && + pathParams && + clientPermissions && + userSettings && + anchor + ); }; const initialize = (thisComponent: any) => { diff --git a/container/src/services/webcomponents.service.ts b/container/src/services/webcomponents.service.ts index 3c00a13106..897676596b 100644 --- a/container/src/services/webcomponents.service.ts +++ b/container/src/services/webcomponents.service.ts @@ -13,23 +13,23 @@ export class WebComponentService { containerService: ContainerService; thisComponent: any; - constructor () { + constructor() { this.containerService = new ContainerService(); } - dynamicImport (viewUrl: string) { + dynamicImport(viewUrl: string) { // Object.freeze() used as potential marker for bundlers other than webpack return Object.freeze(import(/* webpackIgnore: true */ viewUrl)); } - processViewUrl (viewUrl: string, data?: any): string { + processViewUrl(viewUrl: string, data?: any): string { return viewUrl; } /** Creates a web component with tagname wc_id and adds it to wcItemContainer, * if attached to wc_container */ - attachWC ( + attachWC( wc_id: string, wcItemPlaceholder: HTMLDivElement, wc_container, @@ -60,7 +60,7 @@ export class WebComponentService { * @param data the data to be sent * @param callback the callback function to be called */ - dispatchLuigiEvent (msg: string, data: any, callback?: Function) { + dispatchLuigiEvent(msg: string, data: any, callback?: Function) { this.containerService.dispatch(msg, this.thisComponent, data, callback); } @@ -72,7 +72,7 @@ export class WebComponentService { * @param wc_id a tagname that is used when creating the web component element * @returns an object with the Luigi Client API */ - createClientAPI (eventBusElement, nodeId: string, wc_id: string, component: HTMLElement, isSpecialMf?: boolean) { + createClientAPI(eventBusElement, nodeId: string, wc_id: string, component: HTMLElement, isSpecialMf?: boolean) { return { linkManager: () => { return { @@ -149,6 +149,9 @@ export class WebComponentService { } this.dispatchLuigiEvent(Events.SET_ANCHOR_LINK_REQUEST, anchor); }, + getAnchor: () => { + return this.thisComponent.getAttribute('anchor') || ''; + }, getCoreSearchParams: () => { let result = this.thisComponent.getAttribute('search-params') || {}; result = JSON.parse(result); @@ -170,7 +173,7 @@ export class WebComponentService { }; } - initWC (wc: HTMLElement | any, wc_id, eventBusElement, viewUrl: string, ctx, nodeId: string, isSpecialMf?: boolean) { + initWC(wc: HTMLElement | any, wc_id, eventBusElement, viewUrl: string, ctx, nodeId: string, isSpecialMf?: boolean) { const clientAPI = this.createClientAPI(eventBusElement, nodeId, wc_id, wc, isSpecialMf); if (wc.__postProcess) { @@ -189,7 +192,7 @@ export class WebComponentService { * returns a string that can be used as part of a tagname, only alphanumeric * characters and no whitespaces. */ - generateWCId (viewUrl: string) { + generateWCId(viewUrl: string) { let charRep = ''; const normalizedViewUrl = new URL(viewUrl, location.href).href; for (let i = 0; i < normalizedViewUrl.length; i++) { @@ -202,7 +205,7 @@ export class WebComponentService { * with the default export of the module or the first export extending HTMLElement if no default is * specified. * @returns a promise that gets resolved after successfull import */ - registerWCFromUrl (viewUrl: string, wc_id: string) { + registerWCFromUrl(viewUrl: string, wc_id: string) { const i18nViewUrl = this.processViewUrl(viewUrl); return new Promise((resolve, reject) => { if (this.checkWCUrl(i18nViewUrl)) { @@ -245,7 +248,7 @@ export class WebComponentService { * @param {*} viewUrl the source of the wc bundle * @param {*} onload callback function executed after script attached and loaded */ - includeSelfRegisteredWCFromUrl (node, viewUrl, onload) { + includeSelfRegisteredWCFromUrl(node, viewUrl, onload) { if (this.checkWCUrl(viewUrl)) { /** Append reg function to luigi object if not present */ if (!this.containerService.getContainerManager()._registerWebcomponent) { @@ -275,7 +278,7 @@ export class WebComponentService { * * @param {*} url the url string to check */ - checkWCUrl (url: string) { + checkWCUrl(url: string) { // if (url.indexOf('://') > 0 || url.trim().indexOf('//') === 0) { // const ur = new URL(url); // if (ur.host === window.location.host) { @@ -306,7 +309,7 @@ export class WebComponentService { /** Adds a web component defined by viewUrl to the wc_container and sets the node context. * If the web component is not defined yet, it gets imported. */ - renderWebComponent ( + renderWebComponent( viewUrl: string, wc_container: HTMLElement | any, context: any, @@ -353,7 +356,7 @@ export class WebComponentService { * * @param {DefaultCompoundRenderer} renderer */ - createCompoundContainerAsync (renderer: any, ctx: any): Promise { + createCompoundContainerAsync(renderer: any, ctx: any): Promise { return new Promise((resolve, reject) => { // remove after review // if (1) { @@ -390,7 +393,7 @@ export class WebComponentService { * @param {HTMLElement} wc_container the web component container dom element * @param {*} context the luigi node context */ - renderWebComponentCompound (navNode, wc_container: HTMLElement, context) { + renderWebComponentCompound(navNode, wc_container: HTMLElement, context) { let renderer; if (navNode.webcomponent && navNode.viewUrl) { renderer = new DefaultCompoundRenderer(); diff --git a/container/test-app/helloWorldWC.js b/container/test-app/helloWorldWC.js index aca9be4bb5..1c63e77f2c 100644 --- a/container/test-app/helloWorldWC.js +++ b/container/test-app/helloWorldWC.js @@ -37,6 +37,9 @@ export default class extends HTMLElement { const getUserSettingsBtn = document.createElement('template'); getUserSettingsBtn.innerHTML = ''; + const getAnchorBtn = document.createElement('template'); + getAnchorBtn.innerHTML = ''; + this._shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: false @@ -51,6 +54,7 @@ export default class extends HTMLElement { this._shadowRoot.appendChild(getPathParamsBtn.content.cloneNode(true)); this._shadowRoot.appendChild(getClientPermissionsBtn.content.cloneNode(true)); this._shadowRoot.appendChild(getUserSettingsBtn.content.cloneNode(true)); + this._shadowRoot.appendChild(getAnchorBtn.content.cloneNode(true)); for (let index = 0; index < 10; index++) { this._shadowRoot.appendChild(empty.content.cloneNode(true)); @@ -136,6 +140,14 @@ export default class extends HTMLElement { }); } }); + this.$getAnchorBtn = this._shadowRoot.querySelector('#getAnchor'); + this.$getAnchorBtn.addEventListener('click', () => { + let getAnchor = this.LuigiClient.getAnchor(); + this.LuigiClient.uxManager().showAlert({ + text: 'LuigiClient.getAnchor()=' + JSON.stringify(getAnchor), + type: 'info' + }); + }); } set context(ctx) { diff --git a/container/test-app/index.html b/container/test-app/index.html index 7a5f8d17b8..edccb7cea8 100644 --- a/container/test-app/index.html +++ b/container/test-app/index.html @@ -304,6 +304,7 @@ path-params='{"path":"param"}' client-permissions='{"permission": "testPermission"}' user-settings='{"language":"it", "date":""}' + anchor="testAnchorCompound" >
@@ -367,6 +368,7 @@ path-params='{"path":"param"}' client-permissions='{"permission": "testPermission"}' user-settings='{"language": "de", "date":""}' + anchor="testanchor" >
diff --git a/container/typings/LuigiCompoundContainer.svelte.d.ts b/container/typings/LuigiCompoundContainer.svelte.d.ts index bc491fcd6b..72b29fc31a 100644 --- a/container/typings/LuigiCompoundContainer.svelte.d.ts +++ b/container/typings/LuigiCompoundContainer.svelte.d.ts @@ -28,4 +28,9 @@ export default class LuigiCompoundContainer extends HTMLElement { * The user settings to be passed to the web-component-based micro frontend */ userSettings: UserSettings; -} \ No newline at end of file + + /** + * The anchor value to be passed to the web-component-based micro frontend. + */ + anchor: string; +} diff --git a/container/typings/LuigiContainer.svelte.d.ts b/container/typings/LuigiContainer.svelte.d.ts index 6ece0fae67..85150c3703 100644 --- a/container/typings/LuigiContainer.svelte.d.ts +++ b/container/typings/LuigiContainer.svelte.d.ts @@ -85,4 +85,9 @@ export default class LuigiContainer extends HTMLElement { * The user settings to be passed to the web-component-based micro frontend */ userSettings: UserSettings; + + /** + * The anchor value to be passed to the web-component-based micro frontend. + */ + anchor: string; } diff --git a/core/src/services/web-components.js b/core/src/services/web-components.js index 03ac198079..80384cf7c7 100644 --- a/core/src/services/web-components.js +++ b/core/src/services/web-components.js @@ -80,6 +80,9 @@ class WebComponentSvcClass { window.Luigi.routing().setAnchor(anchor); } }, + getAnchor: () => { + return window.Luigi.routing().getAnchor(); + }, getUserSettings: async () => { return await this.getUserSettingsForWc(eventBusElement._luigi_node); }