Skip to content

Commit 15b2872

Browse files
authored
fix: Move menu item content outside drawer (openscd#1683)
1 parent da8324e commit 15b2872

File tree

4 files changed

+202
-124
lines changed

4 files changed

+202
-124
lines changed

packages/openscd/src/addons/Layout.ts

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import '@material/mwc-dialog';
5252
import '@material/mwc-switch';
5353
import '@material/mwc-select';
5454
import '@material/mwc-textfield';
55-
import { nothing } from 'lit';
55+
import { pluginTag } from '../plugin-tag.js';
5656

5757
import {OscdPluginManager} from "./plugin-manager/plugin-manager.js";
5858
import "./plugin-manager/plugin-manager.js";
@@ -85,6 +85,7 @@ export class OscdLayout extends LitElement {
8585
@state() activeEditor: Plugin | undefined = this.calcActiveEditors()[0];
8686

8787
@query('#menu') menuUI!: Drawer;
88+
@query('#menuContent') menuContent!: List;
8889
@query('#pluginManager') pluginUI!: OscdPluginManager;
8990
@query('#pluginList') pluginList!: List;
9091
@query('#pluginAdd') pluginDownloadUI!: OscdCustomPluginDialog;
@@ -98,8 +99,8 @@ export class OscdLayout extends LitElement {
9899
@oscd-run-menu=${this.handleRunMenuByEvent}
99100
>
100101
<slot></slot>
101-
${this.renderHeader()} ${this.renderAside()} ${this.renderContent()}
102-
${this.renderLanding()} ${this.renderPlugging()}
102+
${this.renderHeader()} ${this.renderAside()} ${this.renderMenuContent()}
103+
${this.renderContent()} ${this.renderLanding()} ${this.renderPlugging()}
103104
</div>
104105
`;
105106
}
@@ -109,6 +110,11 @@ export class OscdLayout extends LitElement {
109110
return html` ${this.renderPluginUI()} ${this.renderDownloadUI()} `;
110111
}
111112

113+
private getMenuContent(src: string) {
114+
const tag = pluginTag(src);
115+
return this.menuContent.querySelector(tag);
116+
}
117+
112118
/** Renders the "Add Custom Plug-in" UI*/
113119
protected renderDownloadUI(): TemplateResult {
114120
return html`
@@ -280,9 +286,16 @@ export class OscdLayout extends LitElement {
280286
this.menuUI
281287
.querySelector('mwc-list')!
282288
.items.filter(item => item.className === 'validator')
283-
.map(item =>
284-
(<Validator>(<unknown>item.nextElementSibling)).validate()
285-
)
289+
.map(item => {
290+
const src = item.dataset.src ?? '';
291+
const menuContentElement = this.getMenuContent(src);
292+
293+
if (!menuContentElement) {
294+
return;
295+
}
296+
297+
return (menuContentElement as unknown as Validator).validate()
298+
})
286299
).then();
287300
this.dispatchEvent(newPendingStateEvent(this.validated));
288301
});
@@ -300,16 +313,14 @@ export class OscdLayout extends LitElement {
300313
return {
301314
icon: plugin.icon || pluginIcons['menu'],
302315
name: plugin.name,
316+
src: plugin.src,
303317
action: ae => {
304-
this.dispatchEvent(
305-
newPendingStateEvent(
306-
(<MenuPlugin>(
307-
(<unknown>(
308-
(<List>ae.target).items[ae.detail.index].nextElementSibling
309-
))
310-
)).run()
311-
)
312-
);
318+
const menuContentElement = this.getMenuContent(plugin.src);
319+
if (!menuContentElement) {
320+
return;
321+
}
322+
323+
this.dispatchEvent(newPendingStateEvent((menuContentElement as unknown as MenuPlugin).run()))
313324
},
314325
disabled: (): boolean => plugin.requireDoc! && this.doc === null,
315326
content: () => {
@@ -326,18 +337,16 @@ export class OscdLayout extends LitElement {
326337
return {
327338
icon: plugin.icon || pluginIcons['validator'],
328339
name: plugin.name,
340+
src: plugin.src,
329341
action: ae => {
330342
this.dispatchEvent(newEmptyIssuesEvent(plugin.src));
331343

332-
this.dispatchEvent(
333-
newPendingStateEvent(
334-
(<Validator>(
335-
(<unknown>(
336-
(<List>ae.target).items[ae.detail.index].nextElementSibling
337-
))
338-
)).validate()
339-
)
340-
);
344+
const menuContentElement = this.getMenuContent(plugin.src);
345+
if (!menuContentElement) {
346+
return;
347+
}
348+
349+
this.dispatchEvent(newPendingStateEvent((menuContentElement as unknown as Validator).validate()))
341350
},
342351
disabled: (): boolean => this.doc === null,
343352
content: plugin.content ?? (() => html``),
@@ -358,14 +367,14 @@ export class OscdLayout extends LitElement {
358367
iconid="${me.icon}"
359368
graphic="icon"
360369
data-name="${me.name}"
370+
data-src="${me.src ?? ''}"
361371
.disabled=${me.disabled?.() || !me.action}
362372
><mwc-icon slot="graphic">${me.icon}</mwc-icon>
363373
<span>${get(me.name)}</span>
364374
${me.hint
365375
? html`<span slot="secondary"><tt>${me.hint}</tt></span>`
366376
: ''}
367377
</mwc-list-item>
368-
${me.content ? me.content() : nothing}
369378
`;
370379
}
371380

@@ -400,6 +409,18 @@ export class OscdLayout extends LitElement {
400409
</mwc-top-app-bar-fixed>`;
401410
}
402411

412+
protected renderMenuContent(): TemplateResult {
413+
return html`
414+
<div id="menuContent">
415+
${
416+
this.menu
417+
.filter(p => (p as MenuItem).content)
418+
.map(p => (p as MenuItem).content())
419+
}
420+
</div>
421+
`;
422+
}
423+
403424
/**
404425
* Renders a drawer toolbar featuring the scl filename, enabled menu plugins,
405426
* settings, help, scl history and plug-ins management
@@ -502,10 +523,13 @@ export class OscdLayout extends LitElement {
502523
// TODO: this is a workaround, fix it
503524
this.menuUI.open = true;
504525
const menuEntry = this.menuUI.querySelector(`[data-name="${e.detail.name}"]`) as HTMLElement
505-
const menuElement = menuEntry.nextElementSibling
506-
if(!menuElement){ return; } // TODO: log error
507526

508-
(menuElement as unknown as MenuPlugin).run()
527+
const menuContentElement = this.getMenuContent(menuEntry.dataset.src ?? '');
528+
if (!menuContentElement) {
529+
return;
530+
}
531+
532+
(menuContentElement as unknown as MenuPlugin).run();
509533
}
510534

511535
/**

packages/openscd/src/open-scd.ts

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { HistoryState, historyStateEvent } from './addons/History.js';
5151
import { InstalledOfficialPlugin, MenuPosition, PluginKind, Plugin } from "./plugin.js"
5252
import { ConfigurePluginEvent, ConfigurePluginDetail, newConfigurePluginEvent } from './plugin.events.js';
5353
import { newLogEvent } from '@openscd/core/foundation/deprecated/history';
54+
import { pluginTag } from './plugin-tag.js';
5455

5556

5657

@@ -445,33 +446,13 @@ export class OpenSCD extends LitElement {
445446

446447
// PLUGGING INTERFACES
447448
@state() private pluginTags = new Map<string, string>();
448-
/**
449-
* Hashes `uri` using cyrb64 analogous to
450-
* https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js .
451-
* @returns a valid customElement tagName containing the URI hash.
452-
*/
449+
453450
private pluginTag(uri: string): string {
454451
if (!this.pluginTags.has(uri)) {
455-
let h1 = 0xdeadbeef,
456-
h2 = 0x41c6ce57;
457-
for (let i = 0, ch; i < uri.length; i++) {
458-
ch = uri.charCodeAt(i);
459-
h1 = Math.imul(h1 ^ ch, 2654435761);
460-
h2 = Math.imul(h2 ^ ch, 1597334677);
461-
}
462-
h1 =
463-
Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
464-
Math.imul(h2 ^ (h2 >>> 13), 3266489909);
465-
h2 =
466-
Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
467-
Math.imul(h1 ^ (h1 >>> 13), 3266489909);
468-
this.pluginTags.set(
469-
uri,
470-
'oscd-plugin' +
471-
((h2 >>> 0).toString(16).padStart(8, '0') +
472-
(h1 >>> 0).toString(16).padStart(8, '0'))
473-
);
452+
const tag = pluginTag(uri);
453+
this.pluginTags.set(uri, tag);
474454
}
455+
475456
return this.pluginTags.get(uri)!;
476457
}
477458

@@ -492,6 +473,7 @@ declare global {
492473
export interface MenuItem {
493474
icon: string;
494475
name: string;
476+
src?: string;
495477
hint?: string;
496478
actionItem?: boolean;
497479
action?: (event: CustomEvent<ActionDetail>) => void;

packages/openscd/src/plugin-tag.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
/**
3+
* Hashes `uri` using cyrb64 analogous to
4+
* https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js .
5+
* @returns a valid customElement tagName containing the URI hash.
6+
*/
7+
export function pluginTag(uri: string): string {
8+
let h1 = 0xdeadbeef,
9+
h2 = 0x41c6ce57;
10+
for (let i = 0, ch; i < uri.length; i++) {
11+
ch = uri.charCodeAt(i);
12+
h1 = Math.imul(h1 ^ ch, 2654435761);
13+
h2 = Math.imul(h2 ^ ch, 1597334677);
14+
}
15+
h1 =
16+
Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
17+
Math.imul(h2 ^ (h2 >>> 13), 3266489909);
18+
h2 =
19+
Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
20+
Math.imul(h1 ^ (h1 >>> 13), 3266489909);
21+
return 'oscd-plugin' +
22+
((h2 >>> 0).toString(16).padStart(8, '0') +
23+
(h1 >>> 0).toString(16).padStart(8, '0'))
24+
}

0 commit comments

Comments
 (0)