feat: Update version to 2.2.5 and enhance CustomHeader handling in MegaMenu
This commit is contained in:
@@ -4,7 +4,7 @@ Zentrale, barrierearme Portalnavigation aus SharePoint Managed Metadata für Sha
|
|||||||
|
|
||||||
| Eigenschaft | Wert |
|
| Eigenschaft | Wert |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Version | 2.2.4 |
|
| Version | 2.2.5 |
|
||||||
| SharePoint Framework | 1.4.1 |
|
| SharePoint Framework | 1.4.1 |
|
||||||
| Node.js für den Build | 8.17.0 |
|
| Node.js für den Build | 8.17.0 |
|
||||||
| Moderne Seiten | SPFx Application Customizer |
|
| Moderne Seiten | SPFx Application Customizer |
|
||||||
@@ -272,6 +272,11 @@ MegaMenu/
|
|||||||
|
|
||||||
## Versionshistorie
|
## Versionshistorie
|
||||||
|
|
||||||
|
### 2.2.5
|
||||||
|
|
||||||
|
- Das Mega Menu wartet bei vertauschter Ladefolge auf `#CustomHeader` und verschiebt seine bereits gerenderte
|
||||||
|
Navigation automatisch in den Custom-Branding-Header.
|
||||||
|
|
||||||
### 2.2.4
|
### 2.2.4
|
||||||
|
|
||||||
- Der Ladehinweis wird auch dann zuverlässig entfernt, wenn der Custom-Branding-Host während des asynchronen Ladens erzeugt wird.
|
- Der Ladehinweis wird auch dann zuverlässig entfernt, wenn der Custom-Branding-Host während des asynchronen Ladens erzeugt wird.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# MegaMenu – Arbeitsplan Version 2.2.4
|
# MegaMenu – Arbeitsplan Version 2.2.5
|
||||||
|
|
||||||
Status: Implementierung abgeschlossen; Ship-Build auf der vorgesehenen Node-8-Buildumgebung ausstehend
|
Status: Implementierung abgeschlossen; Ship-Build auf der vorgesehenen Node-8-Buildumgebung ausstehend
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ Status: Implementierung abgeschlossen; Ship-Build auf der vorgesehenen Node-8-Bu
|
|||||||
- [x] Navigations-URLs validieren und unsichere Protokolle blockieren.
|
- [x] Navigations-URLs validieren und unsichere Protokolle blockieren.
|
||||||
- [x] Externe Links und `MegaMenu.OpenInNewWindow` sicher unterstützen.
|
- [x] Externe Links und `MegaMenu.OpenInNewWindow` sicher unterstützen.
|
||||||
- [x] Lade-, Leer- und Fehlerzustände verständlich und barrierearm darstellen.
|
- [x] Lade-, Leer- und Fehlerzustände verständlich und barrierearm darstellen.
|
||||||
|
- [x] Spät erzeugten Custom-Branding-Header beobachten und die Navigation ohne Reload dorthin verschieben.
|
||||||
|
|
||||||
## Lokale Term-Eigenschaften
|
## Lokale Term-Eigenschaften
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"solution": {
|
"solution": {
|
||||||
"name": "mega-menu-client-side-solution",
|
"name": "mega-menu-client-side-solution",
|
||||||
"id": "f4660e06-ce08-43ee-bfb7-5c4464e01133",
|
"id": "f4660e06-ce08-43ee-bfb7-5c4464e01133",
|
||||||
"version": "2.2.4.0",
|
"version": "2.2.5.0",
|
||||||
"includeClientSideAssets": true,
|
"includeClientSideAssets": true,
|
||||||
"skipFeatureDeployment": true
|
"skipFeatureDeployment": true
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mega-menu",
|
"name": "mega-menu",
|
||||||
"version": "2.2.4",
|
"version": "2.2.5",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mega-menu",
|
"name": "mega-menu",
|
||||||
"version": "2.2.4",
|
"version": "2.2.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -38,13 +38,14 @@ export default class MegaMenuApplicationCustomizer
|
|||||||
private _menuContainer: HTMLElement | undefined;
|
private _menuContainer: HTMLElement | undefined;
|
||||||
private _renderer: MegaMenuRenderer | undefined;
|
private _renderer: MegaMenuRenderer | undefined;
|
||||||
private _statusElement: HTMLElement | undefined;
|
private _statusElement: HTMLElement | undefined;
|
||||||
|
private _customHeaderObserver: MutationObserver | undefined;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
public onInit(): Promise<void> {
|
public onInit(): Promise<void> {
|
||||||
const debug: boolean = this._isDebugEnabled();
|
const debug: boolean = this._isDebugEnabled();
|
||||||
debugLog(debug, LOG_SOURCE, 'onInit started.', {
|
debugLog(debug, LOG_SOURCE, 'onInit started.', {
|
||||||
componentId: UserCustomActionMegaMenuId,
|
componentId: UserCustomActionMegaMenuId,
|
||||||
version: '2.2.4',
|
version: '2.2.5',
|
||||||
properties: this.properties || {},
|
properties: this.properties || {},
|
||||||
pageUrl: window.location.href,
|
pageUrl: window.location.href,
|
||||||
webUrl: this.context.pageContext.web.absoluteUrl,
|
webUrl: this.context.pageContext.web.absoluteUrl,
|
||||||
@@ -178,7 +179,9 @@ export default class MegaMenuApplicationCustomizer
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _getOrCreateContainer(id: string, placeholder: PlaceholderContent): HTMLElement {
|
private _getOrCreateContainer(id: string, placeholder: PlaceholderContent): HTMLElement {
|
||||||
const container = document.getElementById(id);
|
const container: HTMLElement = document.getElementById(id);
|
||||||
|
let host: HTMLElement = this._menuContainer || document.getElementById('MegaMenuHost') ||
|
||||||
|
document.getElementById('CustomNavigation');
|
||||||
|
|
||||||
if (container) {
|
if (container) {
|
||||||
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Existing host container found.', {
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Existing host container found.', {
|
||||||
@@ -186,31 +189,63 @@ export default class MegaMenuApplicationCustomizer
|
|||||||
containerId: container.id,
|
containerId: container.id,
|
||||||
containerClassName: container.className || ''
|
containerClassName: container.className || ''
|
||||||
});
|
});
|
||||||
let host: HTMLElement = document.getElementById('MegaMenuHost');
|
|
||||||
if (!host) {
|
if (!host) {
|
||||||
host = document.createElement('div');
|
host = document.createElement('div');
|
||||||
host.id = 'MegaMenuHost';
|
host.id = 'MegaMenuHost';
|
||||||
container.appendChild(host);
|
|
||||||
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'MegaMenuHost was created inside the existing host container.');
|
|
||||||
} else {
|
|
||||||
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Existing MegaMenuHost will be reused.');
|
|
||||||
}
|
}
|
||||||
|
if (host.parentElement !== container) { container.appendChild(host); }
|
||||||
|
this._stopCustomHeaderObserver();
|
||||||
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'MegaMenu host is located inside the existing CustomHeader.');
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'No external host container found; the Top placeholder will be used.', {
|
if (!host) {
|
||||||
|
host = document.createElement('div');
|
||||||
|
host.id = 'MegaMenuHost';
|
||||||
|
}
|
||||||
|
if (host.parentElement !== placeholder.domElement) { placeholder.domElement.appendChild(host); }
|
||||||
|
this._startCustomHeaderObserver(id);
|
||||||
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'No external host container found; using a temporary host in the Top placeholder.', {
|
||||||
requestedId: id
|
requestedId: id
|
||||||
});
|
});
|
||||||
return placeholder.domElement;
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _startCustomHeaderObserver(id: string): void {
|
||||||
|
if (this._customHeaderObserver || typeof MutationObserver === 'undefined') { return; }
|
||||||
|
this._customHeaderObserver = new MutationObserver((): void => {
|
||||||
|
const customHeader: HTMLElement = document.getElementById(id);
|
||||||
|
if (!customHeader || !this._menuContainer || this._menuContainer === customHeader) { return; }
|
||||||
|
if (this._menuContainer.parentElement !== customHeader) {
|
||||||
|
customHeader.appendChild(this._menuContainer);
|
||||||
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'MegaMenu host moved into the late CustomHeader.', {
|
||||||
|
containerId: this._menuContainer.id || ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this._stopCustomHeaderObserver();
|
||||||
|
});
|
||||||
|
this._customHeaderObserver.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Waiting for CustomHeader DOM registration.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private _stopCustomHeaderObserver(): void {
|
||||||
|
if (this._customHeaderObserver) {
|
||||||
|
this._customHeaderObserver.disconnect();
|
||||||
|
this._customHeaderObserver = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onDispose = (): void => {
|
private _onDispose = (): void => {
|
||||||
this.context.placeholderProvider.changedEvent.remove(this, this._renderPlaceHolders);
|
this.context.placeholderProvider.changedEvent.remove(this, this._renderPlaceHolders);
|
||||||
|
this._stopCustomHeaderObserver();
|
||||||
this._clearStatus();
|
this._clearStatus();
|
||||||
if (this._renderer) {
|
if (this._renderer) {
|
||||||
this._renderer.dispose();
|
this._renderer.dispose();
|
||||||
this._renderer = undefined;
|
this._renderer = undefined;
|
||||||
}
|
}
|
||||||
|
if (this._menuContainer && this._menuContainer.parentElement) {
|
||||||
|
this._menuContainer.parentElement.removeChild(this._menuContainer);
|
||||||
|
}
|
||||||
this._menuContainer = undefined;
|
this._menuContainer = undefined;
|
||||||
this._topPlaceholder = undefined;
|
this._topPlaceholder = undefined;
|
||||||
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Disposed custom top placeholder.');
|
debugLog(this._isDebugEnabled(), LOG_SOURCE, 'Disposed custom top placeholder.');
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ var applicationCustomizer = read('src/extensions/megaMenu/MegaMenuApplicationCus
|
|||||||
assert('modern loading status is cleared before menu render',
|
assert('modern loading status is cleared before menu render',
|
||||||
applicationCustomizer.indexOf('this._clearStatus();') >= 0 &&
|
applicationCustomizer.indexOf('this._clearStatus();') >= 0 &&
|
||||||
applicationCustomizer.indexOf('private _statusElement: HTMLElement | undefined;') >= 0);
|
applicationCustomizer.indexOf('private _statusElement: HTMLElement | undefined;') >= 0);
|
||||||
|
assert('late CustomHeader is observed and receives the menu host',
|
||||||
|
applicationCustomizer.indexOf('new MutationObserver') >= 0 &&
|
||||||
|
applicationCustomizer.indexOf('customHeader.appendChild(this._menuContainer)') >= 0 &&
|
||||||
|
applicationCustomizer.indexOf('this._stopCustomHeaderObserver();') >= 0);
|
||||||
[
|
[
|
||||||
'white',
|
'white',
|
||||||
'neutralLighter',
|
'neutralLighter',
|
||||||
|
|||||||
Reference in New Issue
Block a user