@eclipse-docks/core 0.7.127 → 0.7.132
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.js +7 -7
- package/dist/api/services.d.ts +3 -1
- package/dist/api/services.d.ts.map +1 -1
- package/dist/{api-Da9zQcfd.js → api-DImisUWV.js} +296 -305
- package/dist/api-DImisUWV.js.map +1 -0
- package/dist/assets/{js-runtime-worker-DAva_aXx.js.map → js-runtime-worker-X93bOre4.js.map} +1 -1
- package/dist/components/attribution.d.ts +1 -0
- package/dist/components/attribution.d.ts.map +1 -1
- package/dist/components/command.d.ts +0 -1
- package/dist/components/command.d.ts.map +1 -1
- package/dist/components/extensions.d.ts +3 -0
- package/dist/components/extensions.d.ts.map +1 -1
- package/dist/components/language-selector.d.ts.map +1 -1
- package/dist/components/layout-switcher.d.ts +1 -1
- package/dist/components/layout-switcher.d.ts.map +1 -1
- package/dist/components/npm-packages.d.ts +1 -0
- package/dist/components/npm-packages.d.ts.map +1 -1
- package/dist/components/release-history.d.ts +9 -2
- package/dist/components/release-history.d.ts.map +1 -1
- package/dist/components/tasks.d.ts.map +1 -1
- package/dist/core/apploader.d.ts +2 -9
- package/dist/core/apploader.d.ts.map +1 -1
- package/dist/core/contribution-targets.d.ts +1 -0
- package/dist/core/contribution-targets.d.ts.map +1 -1
- package/dist/core/dialogservice.d.ts +3 -1
- package/dist/core/dialogservice.d.ts.map +1 -1
- package/dist/core/dropdown-item.d.ts +8 -0
- package/dist/core/dropdown-item.d.ts.map +1 -1
- package/dist/core/events.js +1 -1
- package/dist/core/layout-panels.d.ts +25 -0
- package/dist/core/layout-panels.d.ts.map +1 -0
- package/dist/dialogs/navigable-info-dialog.d.ts.map +1 -1
- package/dist/dialogs/version-info-dialog.d.ts +18 -2
- package/dist/dialogs/version-info-dialog.d.ts.map +1 -1
- package/dist/{events-B_ZxkU_G.js → events-BAE5R6TH.js} +1 -1
- package/dist/{events-B_ZxkU_G.js.map → events-BAE5R6TH.js.map} +1 -1
- package/dist/{extensions.de-Ct1DIybE.js → extensions.de-O6Sx3_t4.js} +1 -1
- package/dist/{extensions.de-Ct1DIybE.js.map → extensions.de-O6Sx3_t4.js.map} +1 -1
- package/dist/{extensions.en-DRPFtVHT.js → extensions.en-fwqJr8P-.js} +1 -1
- package/dist/{extensions.en-DRPFtVHT.js.map → extensions.en-fwqJr8P-.js.map} +1 -1
- package/dist/externals/lit.js +1 -1
- package/dist/externals/third-party.js.map +1 -1
- package/dist/externals/webawesome.js +1 -1
- package/dist/{fastviews.de-BFxFslBz.js → fastviews.de-C-B48vwv.js} +1 -1
- package/dist/fastviews.de-C-B48vwv.js.map +1 -0
- package/dist/{fastviews.en-Cb4J_JXL.js → fastviews.en-BlAxYlHD.js} +1 -1
- package/dist/fastviews.en-BlAxYlHD.js.map +1 -0
- package/dist/{filebrowser.de-GEf6Eilh.js → filebrowser.de-LWsrI9xj.js} +1 -1
- package/dist/{filebrowser.de-GEf6Eilh.js.map → filebrowser.de-LWsrI9xj.js.map} +1 -1
- package/dist/{filebrowser.en-o0Ad5f7Z.js → filebrowser.en-C02vpzAs.js} +1 -1
- package/dist/{filebrowser.en-o0Ad5f7Z.js.map → filebrowser.en-C02vpzAs.js.map} +1 -1
- package/dist/{fs-access-DTXPsV1W.js → fs-access-Cjcg0_Me.js} +27 -25
- package/dist/{fs-access-DTXPsV1W.js.map → fs-access-Cjcg0_Me.js.map} +1 -1
- package/dist/fs-access-Dp9Fwsxk.js +2 -0
- package/dist/index.js +7 -7
- package/dist/layouts/standard-layout.d.ts +9 -1
- package/dist/layouts/standard-layout.d.ts.map +1 -1
- package/dist/{logger-DT0_NW3S.js → logger-CiT0Cc4g.js} +1 -1
- package/dist/{logger-DT0_NW3S.js.map → logger-CiT0Cc4g.js.map} +1 -1
- package/dist/{logterminal.de-DKp940Ox.js → logterminal.de-BP1FuxHH.js} +1 -1
- package/dist/{logterminal.de-DKp940Ox.js.map → logterminal.de-BP1FuxHH.js.map} +1 -1
- package/dist/{logterminal.en-Ci2nm0b2.js → logterminal.en-BeDRvTvb.js} +1 -1
- package/dist/{logterminal.en-Ci2nm0b2.js.map → logterminal.en-BeDRvTvb.js.map} +1 -1
- package/dist/{partname.de-v76uEl0F.js → partname.de-C0I4Wf2X.js} +1 -1
- package/dist/{partname.de-v76uEl0F.js.map → partname.de-C0I4Wf2X.js.map} +1 -1
- package/dist/{partname.en-By5aAawT.js → partname.en-CIT8z3cY.js} +1 -1
- package/dist/{partname.en-By5aAawT.js.map → partname.en-CIT8z3cY.js.map} +1 -1
- package/dist/parts/contextmenu.d.ts.map +1 -1
- package/dist/parts/index.js +1 -1
- package/dist/parts/part.d.ts +2 -0
- package/dist/parts/part.d.ts.map +1 -1
- package/dist/parts/resizable-grid.d.ts +10 -3
- package/dist/parts/resizable-grid.d.ts.map +1 -1
- package/dist/parts/tabs.d.ts +6 -0
- package/dist/parts/tabs.d.ts.map +1 -1
- package/dist/{parts-CRVxaDd-.js → parts-DQRktiiR.js} +1086 -611
- package/dist/parts-DQRktiiR.js.map +1 -0
- package/dist/{tasks.de-y2xPmQ1k.js → tasks.de-DRvUVugd.js} +1 -1
- package/dist/{tasks.de-y2xPmQ1k.js.map → tasks.de-DRvUVugd.js.map} +1 -1
- package/dist/{tasks.en-BTbFrxJj.js → tasks.en-dRDildBd.js} +1 -1
- package/dist/{tasks.en-BTbFrxJj.js.map → tasks.en-dRDildBd.js.map} +1 -1
- package/dist/vite-plugin-app-splash.js.map +1 -1
- package/dist/vite-plugin-local-aliases.js +1 -1
- package/dist/vite-plugin-local-aliases.js.map +1 -1
- package/dist/vite-plugin-resolve-deps.d.ts +6 -3
- package/dist/vite-plugin-resolve-deps.d.ts.map +1 -1
- package/dist/vite-plugin-resolve-deps.js +17 -15
- package/dist/vite-plugin-resolve-deps.js.map +1 -1
- package/dist/{webawesome-Y1_HnKa_.js → webawesome-C0Da7hPu.js} +19 -11
- package/dist/webawesome-C0Da7hPu.js.map +1 -0
- package/dist/{widget-BqQtioK1.js → widget-DUR6wxME.js} +6 -5
- package/dist/{widget-BqQtioK1.js.map → widget-DUR6wxME.js.map} +1 -1
- package/dist/widgets/index.js +1 -1
- package/dist/{widgets-C9V42Mqq.js → widgets-A9XMOA_j.js} +2 -2
- package/dist/{widgets-C9V42Mqq.js.map → widgets-A9XMOA_j.js.map} +1 -1
- package/package.json +1 -1
- package/src/api/services.ts +12 -0
- package/src/components/attribution.ts +2 -0
- package/src/components/command.ts +2 -8
- package/src/components/extensions.ts +20 -3
- package/src/components/language-selector.ts +0 -1
- package/src/components/layout-switcher.ts +39 -26
- package/src/components/npm-packages.ts +2 -0
- package/src/components/release-history.ts +29 -40
- package/src/components/tasks.ts +0 -1
- package/src/contributions/default-layout-contributions.ts +7 -43
- package/src/contributions/default-ui-contributions.ts +4 -4
- package/src/core/apploader.ts +7 -54
- package/src/core/contribution-targets.ts +1 -0
- package/src/core/dialogservice.ts +76 -19
- package/src/core/dropdown-item.ts +52 -17
- package/src/core/extensionregistry.ts +1 -1
- package/src/core/layout-panels.ts +121 -0
- package/src/dialogs/navigable-info-dialog.ts +5 -2
- package/src/dialogs/version-info-dialog.ts +163 -21
- package/src/icons/icons.txt +4 -2
- package/src/icons/layout-standard-bottom-panel.svg +4 -4
- package/src/icons/layout-standard-full.svg +4 -4
- package/src/icons/layout-standard-left-aux.svg +8 -0
- package/src/icons/layout-standard-left-sidebar.svg +5 -0
- package/src/icons/layout-standard-right-aux.svg +8 -0
- package/src/icons/layout-standard-right-sidebar.svg +5 -0
- package/src/layouts/standard-layout.ts +81 -5
- package/src/parts/contextmenu.ts +2 -1
- package/src/parts/part.ts +24 -0
- package/src/parts/resizable-grid.ts +125 -57
- package/src/parts/tabs.ts +103 -0
- package/src/vite-plugin-resolve-deps.ts +29 -25
- package/dist/api-Da9zQcfd.js.map +0 -1
- package/dist/fastviews.de-BFxFslBz.js.map +0 -1
- package/dist/fastviews.en-Cb4J_JXL.js.map +0 -1
- package/dist/fs-access-CzOh5ot8.js +0 -2
- package/dist/parts-CRVxaDd-.js.map +0 -1
- package/dist/webawesome-Y1_HnKa_.js.map +0 -1
- package/src/icons/layout-standard-bottom-sidebar.svg +0 -6
- package/src/icons/layout-standard.svg +0 -6
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { n as defaultLogger, o as rootContext, s as uiContext, t as createLogger } from "./logger-
|
|
2
|
-
import { T as toastInfo, _ as getContributionDisabled, a as TOPIC_COMMAND_REGISTERED, f as activeTasksSignal, g as contributionRegistry, h as TOPIC_CONTRIBUTEIONS_CHANGED, l as activeEditorSignal, n as watchSignal, o as commandRegistry, p as partDirtySignal, t as DocksWidget, u as activePartSignal, v as getContributionVisible, w as toastError, x as contributionTargetMappingRegistry, y as readReactiveBoolean } from "./widget-
|
|
3
|
-
import { n as subscribe, t as publish } from "./events-
|
|
4
|
-
import { a as File, i as Directory, l as TOPIC_WORKSPACE_CHANGED, m as persistenceService, o as FileContentType, p as workspaceService } from "./fs-access-
|
|
5
|
-
import "./webawesome-
|
|
1
|
+
import { n as defaultLogger, o as rootContext, s as uiContext, t as createLogger } from "./logger-CiT0Cc4g.js";
|
|
2
|
+
import { T as toastInfo, _ as getContributionDisabled, a as TOPIC_COMMAND_REGISTERED, f as activeTasksSignal, g as contributionRegistry, h as TOPIC_CONTRIBUTEIONS_CHANGED, l as activeEditorSignal, n as watchSignal, o as commandRegistry, p as partDirtySignal, t as DocksWidget, u as activePartSignal, v as getContributionVisible, w as toastError, x as contributionTargetMappingRegistry, y as readReactiveBoolean } from "./widget-DUR6wxME.js";
|
|
3
|
+
import { n as subscribe, t as publish } from "./events-BAE5R6TH.js";
|
|
4
|
+
import { a as File, i as Directory, l as TOPIC_WORKSPACE_CHANGED, m as persistenceService, o as FileContentType, p as workspaceService } from "./fs-access-Cjcg0_Me.js";
|
|
5
|
+
import "./webawesome-C0Da7hPu.js";
|
|
6
6
|
import { css, html, nothing, render } from "lit";
|
|
7
7
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
8
8
|
import DOMPurify from "dompurify";
|
|
9
9
|
import { marked } from "marked";
|
|
10
10
|
import { customElement, property, state } from "lit/decorators.js";
|
|
11
11
|
import _decorate from "@oxc-project/runtime/helpers/decorate";
|
|
12
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
12
13
|
import { styleMap } from "lit/directives/style-map.js";
|
|
13
14
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
14
15
|
import { when } from "lit/directives/when.js";
|
|
15
16
|
import { repeat } from "lit/directives/repeat.js";
|
|
16
|
-
import { ifDefined } from "lit/directives/if-defined.js";
|
|
17
17
|
//#region \0rolldown/runtime.js
|
|
18
18
|
var __defProp = Object.defineProperty;
|
|
19
19
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -45,6 +45,7 @@ var EDITOR_AREA_MAIN = "editor-area-main";
|
|
|
45
45
|
var SIDEBAR_MAIN = "sidebar-main";
|
|
46
46
|
var SIDEBAR_MAIN_BOTTOM = "sidebar-main-bottom";
|
|
47
47
|
var SIDEBAR_AUXILIARY = "sidebar-auxiliary";
|
|
48
|
+
var SIDEBAR_AUXILIARY_BOTTOM = "sidebar-auxiliary-bottom";
|
|
48
49
|
var PANEL_BOTTOM = "panel-bottom";
|
|
49
50
|
//#endregion
|
|
50
51
|
//#region src/core/constants.ts
|
|
@@ -56,6 +57,7 @@ var constants_exports = /* @__PURE__ */ __exportAll({
|
|
|
56
57
|
MouseButton: () => MouseButton,
|
|
57
58
|
PANEL_BOTTOM: () => PANEL_BOTTOM,
|
|
58
59
|
SIDEBAR_AUXILIARY: () => SIDEBAR_AUXILIARY,
|
|
60
|
+
SIDEBAR_AUXILIARY_BOTTOM: () => SIDEBAR_AUXILIARY_BOTTOM,
|
|
59
61
|
SIDEBAR_MAIN: () => SIDEBAR_MAIN,
|
|
60
62
|
SIDEBAR_MAIN_BOTTOM: () => SIDEBAR_MAIN_BOTTOM,
|
|
61
63
|
SIDEBAR_MAIN_TOOLBAR: () => SIDEBAR_MAIN_TOOLBAR,
|
|
@@ -271,7 +273,7 @@ var taskService = new TaskService();
|
|
|
271
273
|
rootContext.put("taskService", taskService);
|
|
272
274
|
//#endregion
|
|
273
275
|
//#region src/core/esmsh-service.ts
|
|
274
|
-
var logger$
|
|
276
|
+
var logger$4 = createLogger("EsmShService");
|
|
275
277
|
var esmShService = new class EsmShService {
|
|
276
278
|
static {
|
|
277
279
|
this.ESM_SH_BASE = "https://esm.sh";
|
|
@@ -416,7 +418,6 @@ var esmShService = new class EsmShService {
|
|
|
416
418
|
case "pr":
|
|
417
419
|
url += `/${EsmShService.PR_PREFIX}${source.owner}/${source.repo}`;
|
|
418
420
|
if (source.commit) url += `@${source.commit}`;
|
|
419
|
-
break;
|
|
420
421
|
}
|
|
421
422
|
const queryParams = [];
|
|
422
423
|
if (options?.deps) {
|
|
@@ -435,7 +436,7 @@ var esmShService = new class EsmShService {
|
|
|
435
436
|
if (this.isHttpUrl(source)) return source;
|
|
436
437
|
const parsed = this.parseSource(source);
|
|
437
438
|
if (!parsed) {
|
|
438
|
-
logger$
|
|
439
|
+
logger$4.warn(`Could not parse source identifier: ${source}`);
|
|
439
440
|
return source;
|
|
440
441
|
}
|
|
441
442
|
return this.buildEsmShUrl(parsed, options);
|
|
@@ -466,11 +467,13 @@ var esmShService = new class EsmShService {
|
|
|
466
467
|
let repo = pathParts[1].replace(/\.git$/, "");
|
|
467
468
|
let ref;
|
|
468
469
|
let filePath;
|
|
469
|
-
if (pathParts.length > 2)
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
470
|
+
if (pathParts.length > 2) {
|
|
471
|
+
if (pathParts[2] === "blob" || pathParts[2] === "tree") {
|
|
472
|
+
ref = pathParts[3] || "main";
|
|
473
|
+
if (pathParts[2] === "blob" && pathParts.length > 4) filePath = pathParts.slice(4).join("/");
|
|
474
|
+
} else if (pathParts[2] === "commit") ref = pathParts[3];
|
|
475
|
+
else filePath = pathParts.slice(2).join("/");
|
|
476
|
+
}
|
|
474
477
|
let ghUrl = `${EsmShService.GITHUB_PREFIX}${owner}/${repo}`;
|
|
475
478
|
if (ref) ghUrl += `@${ref}`;
|
|
476
479
|
if (filePath) ghUrl += `/${filePath}`;
|
|
@@ -672,10 +675,7 @@ var ExtensionRegistry = class {
|
|
|
672
675
|
async ensureExtensionRegistered(extensionId) {
|
|
673
676
|
if (this.extensions[extensionId]) return;
|
|
674
677
|
try {
|
|
675
|
-
await import(
|
|
676
|
-
/* @vite-ignore */
|
|
677
|
-
extensionId
|
|
678
|
-
);
|
|
678
|
+
await import(extensionId);
|
|
679
679
|
} catch (error) {
|
|
680
680
|
defaultLogger.debug(`Could not side-effect import extension package ${extensionId}: ${error}`);
|
|
681
681
|
}
|
|
@@ -1074,13 +1074,16 @@ var DocksDialogContent = class extends DocksElement {
|
|
|
1074
1074
|
dispose() {}
|
|
1075
1075
|
getResult() {}
|
|
1076
1076
|
renderMessage(message, markdown = false) {
|
|
1077
|
-
if (markdown)
|
|
1077
|
+
if (markdown) {
|
|
1078
|
+
const htmlContent = parseMarkdownHtml(message);
|
|
1079
|
+
return html`<div class="dialog-message" style="white-space: normal;">${unsafeHTML(htmlContent)}</div>`;
|
|
1080
|
+
}
|
|
1078
1081
|
return html`<div class="dialog-message" style="white-space: pre-line;">${message}</div>`;
|
|
1079
1082
|
}
|
|
1080
1083
|
};
|
|
1081
1084
|
//#endregion
|
|
1082
1085
|
//#region src/core/dialogservice.ts
|
|
1083
|
-
var logger$
|
|
1086
|
+
var logger$3 = createLogger("DialogService");
|
|
1084
1087
|
var DIALOG_CONTRIBUTION_TARGET = "dialogs";
|
|
1085
1088
|
var OK_BUTTON = {
|
|
1086
1089
|
id: "ok",
|
|
@@ -1106,6 +1109,20 @@ function getDialogContainer() {
|
|
|
1106
1109
|
}
|
|
1107
1110
|
return dialogContainer;
|
|
1108
1111
|
}
|
|
1112
|
+
function findWaDialog(root) {
|
|
1113
|
+
if (root instanceof Element && root.tagName.toLowerCase() === "wa-dialog") return root;
|
|
1114
|
+
const children = root instanceof Document || root instanceof DocumentFragment || root instanceof Element ? Array.from(root.children) : root instanceof ShadowRoot ? Array.from(root.children) : [];
|
|
1115
|
+
for (const child of children) {
|
|
1116
|
+
if (child instanceof Element && child.tagName.toLowerCase() === "wa-dialog") return child;
|
|
1117
|
+
if (child instanceof Element && child.shadowRoot) {
|
|
1118
|
+
const nested = findWaDialog(child.shadowRoot);
|
|
1119
|
+
if (nested) return nested;
|
|
1120
|
+
}
|
|
1121
|
+
const nested = findWaDialog(child);
|
|
1122
|
+
if (nested) return nested;
|
|
1123
|
+
}
|
|
1124
|
+
return null;
|
|
1125
|
+
}
|
|
1109
1126
|
var DialogService = class {
|
|
1110
1127
|
constructor() {
|
|
1111
1128
|
this.contributions = /* @__PURE__ */ new Map();
|
|
@@ -1126,15 +1143,15 @@ var DialogService = class {
|
|
|
1126
1143
|
this.contributions.clear();
|
|
1127
1144
|
for (const contribution of contributions) {
|
|
1128
1145
|
if (!contribution.id) {
|
|
1129
|
-
logger$
|
|
1146
|
+
logger$3.warn("Dialog contribution missing id, skipping");
|
|
1130
1147
|
continue;
|
|
1131
1148
|
}
|
|
1132
1149
|
if (!contribution.component) {
|
|
1133
|
-
logger$
|
|
1150
|
+
logger$3.warn(`Dialog contribution "${contribution.id}" has no component function, skipping`);
|
|
1134
1151
|
continue;
|
|
1135
1152
|
}
|
|
1136
|
-
if (!contribution.onButton) {
|
|
1137
|
-
logger$
|
|
1153
|
+
if (!contribution.onButton && !contribution.selfContained) {
|
|
1154
|
+
logger$3.warn(`Dialog contribution "${contribution.id}" has no onButton callback, skipping`);
|
|
1138
1155
|
continue;
|
|
1139
1156
|
}
|
|
1140
1157
|
this.contributions.set(contribution.id, contribution);
|
|
@@ -1143,50 +1160,68 @@ var DialogService = class {
|
|
|
1143
1160
|
async open(dialogId, state) {
|
|
1144
1161
|
const contribution = this.contributions.get(dialogId);
|
|
1145
1162
|
if (!contribution) {
|
|
1146
|
-
logger$
|
|
1163
|
+
logger$3.error(`Dialog "${dialogId}" not found`);
|
|
1147
1164
|
throw new Error(`Dialog "${dialogId}" not found`);
|
|
1148
1165
|
}
|
|
1149
1166
|
return new Promise((resolve) => {
|
|
1150
1167
|
const container = getDialogContainer();
|
|
1151
|
-
let
|
|
1168
|
+
let closed = false;
|
|
1152
1169
|
let dialogContentElement = null;
|
|
1153
1170
|
const cleanup = async () => {
|
|
1154
|
-
if (
|
|
1155
|
-
|
|
1171
|
+
if (closed) return;
|
|
1172
|
+
closed = true;
|
|
1156
1173
|
if (dialogContentElement) try {
|
|
1157
1174
|
await dialogContentElement.dispose();
|
|
1158
1175
|
} catch (error) {
|
|
1159
1176
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1160
|
-
logger$
|
|
1177
|
+
logger$3.error(`Error disposing dialog content for "${dialogId}": ${errorMessage}`);
|
|
1161
1178
|
}
|
|
1162
1179
|
try {
|
|
1163
1180
|
const result = dialogContentElement ? dialogContentElement.getResult() : void 0;
|
|
1164
|
-
await contribution.onButton("close", result, stateWithClose);
|
|
1181
|
+
if (contribution.onButton) await contribution.onButton("close", result, stateWithClose);
|
|
1165
1182
|
} catch (error) {
|
|
1166
1183
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1167
|
-
logger$
|
|
1184
|
+
logger$3.error(`Error executing close callback for dialog "${dialogId}": ${errorMessage}`);
|
|
1168
1185
|
}
|
|
1169
1186
|
render(html``, container);
|
|
1170
1187
|
resolve();
|
|
1171
1188
|
};
|
|
1189
|
+
const closeDialog = () => {
|
|
1190
|
+
if (closed) return;
|
|
1191
|
+
const dialog = findWaDialog(container);
|
|
1192
|
+
if (dialog && dialog.open !== false) {
|
|
1193
|
+
dialog.open = false;
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
cleanup();
|
|
1197
|
+
};
|
|
1198
|
+
const handleAfterHide = () => {
|
|
1199
|
+
cleanup();
|
|
1200
|
+
};
|
|
1172
1201
|
const handleButtonClick = async (buttonId) => {
|
|
1202
|
+
if (!contribution.onButton) return;
|
|
1173
1203
|
try {
|
|
1174
1204
|
const result = dialogContentElement ? dialogContentElement.getResult() : void 0;
|
|
1175
|
-
if (await contribution.onButton(buttonId, result, stateWithClose) !== false)
|
|
1205
|
+
if (await contribution.onButton(buttonId, result, stateWithClose) !== false) closeDialog();
|
|
1176
1206
|
} catch (error) {
|
|
1177
1207
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1178
|
-
logger$
|
|
1179
|
-
|
|
1208
|
+
logger$3.error(`Error executing button callback for dialog "${dialogId}": ${errorMessage}`);
|
|
1209
|
+
closeDialog();
|
|
1180
1210
|
}
|
|
1181
1211
|
};
|
|
1182
1212
|
const buttons = contribution.buttons && contribution.buttons.length > 0 ? contribution.buttons : [OK_BUTTON];
|
|
1183
|
-
if (state && typeof state === "object") state.close = cleanup;
|
|
1184
1213
|
const stateWithClose = {
|
|
1185
1214
|
...state,
|
|
1186
|
-
close:
|
|
1215
|
+
close: closeDialog,
|
|
1216
|
+
onAfterHide: handleAfterHide
|
|
1187
1217
|
};
|
|
1188
|
-
|
|
1189
|
-
|
|
1218
|
+
if (state && typeof state === "object") {
|
|
1219
|
+
state.close = closeDialog;
|
|
1220
|
+
state.onAfterHide = handleAfterHide;
|
|
1221
|
+
}
|
|
1222
|
+
const dialogLabel = state && typeof state === "object" && typeof state.label === "string" ? state.label : contribution.label || dialogId;
|
|
1223
|
+
const template = contribution.selfContained ? contribution.component(stateWithClose) : html`
|
|
1224
|
+
<wa-dialog label="${dialogLabel}" open @wa-after-hide=${handleAfterHide}>
|
|
1190
1225
|
<style>
|
|
1191
1226
|
.dialog-service-content {
|
|
1192
1227
|
display: flex;
|
|
@@ -1218,13 +1253,14 @@ var DialogService = class {
|
|
|
1218
1253
|
@dialog-cancel=${() => {
|
|
1219
1254
|
const cancelButton = buttons.find((b) => b.id === "cancel");
|
|
1220
1255
|
if (cancelButton) handleButtonClick(cancelButton.id);
|
|
1221
|
-
else
|
|
1256
|
+
else closeDialog();
|
|
1222
1257
|
}}>
|
|
1223
1258
|
${contribution.component(state)}
|
|
1224
1259
|
|
|
1225
1260
|
<div class="dialog-service-footer">
|
|
1226
1261
|
${buttons.map((button) => html`
|
|
1227
1262
|
<wa-button
|
|
1263
|
+
data-dialog-button="${button.id}"
|
|
1228
1264
|
variant="${button.variant || "default"}"
|
|
1229
1265
|
?disabled=${button.disabled}
|
|
1230
1266
|
@click=${() => handleButtonClick(button.id)}
|
|
@@ -1235,7 +1271,8 @@ var DialogService = class {
|
|
|
1235
1271
|
</div>
|
|
1236
1272
|
</div>
|
|
1237
1273
|
</wa-dialog>
|
|
1238
|
-
|
|
1274
|
+
`;
|
|
1275
|
+
render(template, container);
|
|
1239
1276
|
(async () => {
|
|
1240
1277
|
const allElements = Array.from(container.querySelectorAll("*"));
|
|
1241
1278
|
for (const element of allElements) if (element instanceof DocksDialogContent) {
|
|
@@ -1300,13 +1337,13 @@ workspaceService.registerContribution({
|
|
|
1300
1337
|
},
|
|
1301
1338
|
async connect(_input) {
|
|
1302
1339
|
const root = await getOPFSRoot();
|
|
1303
|
-
const FileSysDirHandleResource = (await import("./fs-access-
|
|
1340
|
+
const FileSysDirHandleResource = (await import("./fs-access-Dp9Fwsxk.js")).FileSysDirHandleResource;
|
|
1304
1341
|
return new OPFSRootDirectory(new FileSysDirHandleResource(root));
|
|
1305
1342
|
},
|
|
1306
1343
|
async restore(data) {
|
|
1307
1344
|
if (data && typeof data === "object" && data.opfs === true) {
|
|
1308
1345
|
const root = await getOPFSRoot();
|
|
1309
|
-
const FileSysDirHandleResource = (await import("./fs-access-
|
|
1346
|
+
const FileSysDirHandleResource = (await import("./fs-access-Dp9Fwsxk.js")).FileSysDirHandleResource;
|
|
1310
1347
|
return new OPFSRootDirectory(new FileSysDirHandleResource(root));
|
|
1311
1348
|
}
|
|
1312
1349
|
},
|
|
@@ -1426,7 +1463,8 @@ async function idbRenameTree(rootId, oldPath, newPath) {
|
|
|
1426
1463
|
}
|
|
1427
1464
|
const key = String(cursor.key);
|
|
1428
1465
|
if (key === oldPrefix || key.startsWith(oldPrefix + "/")) {
|
|
1429
|
-
const
|
|
1466
|
+
const suffix = key.slice(oldPrefix.length);
|
|
1467
|
+
const newKey = newPrefix + suffix;
|
|
1430
1468
|
const value = cursor.value;
|
|
1431
1469
|
operations.push(() => {
|
|
1432
1470
|
cursor.delete();
|
|
@@ -1465,9 +1503,10 @@ async function idbListChildrenOfDir(rootId, dirPath) {
|
|
|
1465
1503
|
}
|
|
1466
1504
|
const idx = rest.indexOf("/");
|
|
1467
1505
|
const childName = idx === -1 ? rest : rest.slice(0, idx);
|
|
1468
|
-
if (idx === -1)
|
|
1469
|
-
|
|
1470
|
-
|
|
1506
|
+
if (idx === -1) {
|
|
1507
|
+
if (entry.type === "dir") dirNames.add(childName);
|
|
1508
|
+
else fileEntries.set(childName, entry);
|
|
1509
|
+
} else dirNames.add(childName);
|
|
1471
1510
|
cursor.continue();
|
|
1472
1511
|
};
|
|
1473
1512
|
});
|
|
@@ -1747,7 +1786,7 @@ async function deleteIndexedDbWorkspaceData(directory) {
|
|
|
1747
1786
|
}
|
|
1748
1787
|
//#endregion
|
|
1749
1788
|
//#region src/core/marketplaceregistry.ts
|
|
1750
|
-
var logger$
|
|
1789
|
+
var logger$2 = createLogger("MarketplaceRegistry");
|
|
1751
1790
|
var TOPIC_MARKETPLACE_CHANGED = "events/marketplaceregistry/changed";
|
|
1752
1791
|
var KEY_CATALOG_URLS = "marketplace.catalogUrls";
|
|
1753
1792
|
var MarketplaceRegistry = class {
|
|
@@ -1756,7 +1795,7 @@ var MarketplaceRegistry = class {
|
|
|
1756
1795
|
this.loadingPromises = /* @__PURE__ */ new Map();
|
|
1757
1796
|
this.loadCatalogUrls().then(() => {
|
|
1758
1797
|
this.refreshCatalogs().catch((err) => {
|
|
1759
|
-
logger$
|
|
1798
|
+
logger$2.error(`Failed to refresh catalogs on init: ${err.message}`);
|
|
1760
1799
|
});
|
|
1761
1800
|
});
|
|
1762
1801
|
}
|
|
@@ -1765,7 +1804,7 @@ var MarketplaceRegistry = class {
|
|
|
1765
1804
|
const urls = await appSettings.get(KEY_CATALOG_URLS);
|
|
1766
1805
|
this.catalogUrls = Array.isArray(urls) ? urls : [];
|
|
1767
1806
|
} catch (error) {
|
|
1768
|
-
logger$
|
|
1807
|
+
logger$2.error(`Failed to load catalog URLs: ${error}`);
|
|
1769
1808
|
this.catalogUrls = [];
|
|
1770
1809
|
}
|
|
1771
1810
|
}
|
|
@@ -1779,28 +1818,28 @@ var MarketplaceRegistry = class {
|
|
|
1779
1818
|
async addCatalogUrl(url) {
|
|
1780
1819
|
if (!this.isValidUrl(url)) throw new Error(`Invalid catalog URL: ${url}`);
|
|
1781
1820
|
if (this.catalogUrls.includes(url)) {
|
|
1782
|
-
logger$
|
|
1821
|
+
logger$2.debug(`Catalog URL already exists: ${url}`);
|
|
1783
1822
|
return;
|
|
1784
1823
|
}
|
|
1785
1824
|
this.catalogUrls.push(url);
|
|
1786
1825
|
await this.saveCatalogUrls();
|
|
1787
|
-
logger$
|
|
1826
|
+
logger$2.debug(`Added catalog URL: ${url}`);
|
|
1788
1827
|
try {
|
|
1789
1828
|
await this.refreshCatalogs();
|
|
1790
1829
|
} catch (error) {
|
|
1791
|
-
logger$
|
|
1830
|
+
logger$2.warn(`Failed to refresh catalogs immediately after adding: ${error}`);
|
|
1792
1831
|
}
|
|
1793
1832
|
}
|
|
1794
1833
|
async addCatalogUrls(urls) {
|
|
1795
1834
|
let added = 0;
|
|
1796
1835
|
for (const url of urls) {
|
|
1797
1836
|
if (!this.isValidUrl(url)) {
|
|
1798
|
-
logger$
|
|
1837
|
+
logger$2.warn(`Skipping invalid catalog URL: ${url}`);
|
|
1799
1838
|
continue;
|
|
1800
1839
|
}
|
|
1801
1840
|
if (this.catalogUrls.includes(url)) continue;
|
|
1802
1841
|
this.catalogUrls.push(url);
|
|
1803
|
-
logger$
|
|
1842
|
+
logger$2.debug(`Added catalog URL: ${url}`);
|
|
1804
1843
|
added++;
|
|
1805
1844
|
}
|
|
1806
1845
|
if (added === 0) return;
|
|
@@ -1808,7 +1847,7 @@ var MarketplaceRegistry = class {
|
|
|
1808
1847
|
try {
|
|
1809
1848
|
await this.refreshCatalogs();
|
|
1810
1849
|
} catch (error) {
|
|
1811
|
-
logger$
|
|
1850
|
+
logger$2.warn(`Failed to refresh catalogs after adding URLs: ${error}`);
|
|
1812
1851
|
}
|
|
1813
1852
|
}
|
|
1814
1853
|
async removeCatalogUrl(url) {
|
|
@@ -1816,7 +1855,7 @@ var MarketplaceRegistry = class {
|
|
|
1816
1855
|
if (index === -1) return;
|
|
1817
1856
|
this.catalogUrls.splice(index, 1);
|
|
1818
1857
|
await this.saveCatalogUrls();
|
|
1819
|
-
logger$
|
|
1858
|
+
logger$2.info(`Removed catalog URL: ${url}`);
|
|
1820
1859
|
}
|
|
1821
1860
|
getCatalogUrls() {
|
|
1822
1861
|
return [...this.catalogUrls];
|
|
@@ -1847,7 +1886,7 @@ var MarketplaceRegistry = class {
|
|
|
1847
1886
|
extensions: data.extensions || []
|
|
1848
1887
|
};
|
|
1849
1888
|
} catch (error) {
|
|
1850
|
-
logger$
|
|
1889
|
+
logger$2.error(`Failed to fetch catalog from ${url}: ${error}`);
|
|
1851
1890
|
throw error;
|
|
1852
1891
|
} finally {
|
|
1853
1892
|
this.loadingPromises.delete(url);
|
|
@@ -1858,7 +1897,7 @@ var MarketplaceRegistry = class {
|
|
|
1858
1897
|
}
|
|
1859
1898
|
async refreshCatalogs() {
|
|
1860
1899
|
const promises = this.catalogUrls.map((url) => this.fetchCatalog(url).catch((error) => {
|
|
1861
|
-
logger$
|
|
1900
|
+
logger$2.warn(`Failed to refresh catalog ${url}: ${error.message}`);
|
|
1862
1901
|
return null;
|
|
1863
1902
|
}));
|
|
1864
1903
|
const catalogs = await Promise.allSettled(promises);
|
|
@@ -1878,8 +1917,8 @@ var MarketplaceRegistry = class {
|
|
|
1878
1917
|
});
|
|
1879
1918
|
}
|
|
1880
1919
|
});
|
|
1881
|
-
logger$
|
|
1882
|
-
if (registeredCount > 0) logger$
|
|
1920
|
+
logger$2.debug(`Refreshed ${this.catalogUrls.length} catalogs, ${registeredCount} extensions registered`);
|
|
1921
|
+
if (registeredCount > 0) logger$2.info(`Marketplace: ${registeredCount} new extension(s) available`);
|
|
1883
1922
|
publish(TOPIC_MARKETPLACE_CHANGED, { type: "refreshed" });
|
|
1884
1923
|
}
|
|
1885
1924
|
getMarketplaceExtension(extensionId) {
|
|
@@ -1908,16 +1947,10 @@ rootContext.put("marketplaceRegistry", marketplaceRegistry);
|
|
|
1908
1947
|
* - Application: App-specific code, gs-* components, contributions
|
|
1909
1948
|
* - App Loader: Bridge between framework and application
|
|
1910
1949
|
*/
|
|
1911
|
-
var logger = createLogger("AppLoader");
|
|
1950
|
+
var logger$1 = createLogger("AppLoader");
|
|
1912
1951
|
function getLayoutIdFromApp(app) {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
return typeof l === "object" ? l.id : l ?? "standard";
|
|
1916
|
-
}
|
|
1917
|
-
function propsToAttributes(props) {
|
|
1918
|
-
const out = {};
|
|
1919
|
-
for (const [k, v] of Object.entries(props)) out[k] = typeof v === "boolean" ? v ? "true" : "false" : v;
|
|
1920
|
-
return out;
|
|
1952
|
+
const layout = app?.layout ?? "standard";
|
|
1953
|
+
return typeof layout === "object" ? layout.id : layout;
|
|
1921
1954
|
}
|
|
1922
1955
|
/**
|
|
1923
1956
|
* Extracts error message from an error object.
|
|
@@ -1946,9 +1979,6 @@ var appLoaderService = new class AppLoaderService {
|
|
|
1946
1979
|
static {
|
|
1947
1980
|
this.PREFERRED_APP_KEY = "preferredAppName";
|
|
1948
1981
|
}
|
|
1949
|
-
static {
|
|
1950
|
-
this.PREFERRED_LAYOUT_KEY = "preferredLayoutId";
|
|
1951
|
-
}
|
|
1952
1982
|
/**
|
|
1953
1983
|
* Register an application with the framework.
|
|
1954
1984
|
* Optionally starts the apploader automatically after registration.
|
|
@@ -1967,7 +1997,8 @@ var appLoaderService = new class AppLoaderService {
|
|
|
1967
1997
|
}
|
|
1968
1998
|
app.name = app.name ?? "app";
|
|
1969
1999
|
app.version = app.version ?? "0.0.0";
|
|
1970
|
-
|
|
2000
|
+
app.layout = app.layout ?? "standard";
|
|
2001
|
+
if (this.apps.has(app.name)) logger$1.warn(`App '${app.name}' is already registered. Overwriting.`);
|
|
1971
2002
|
if (app.marketplaceCatalogUrls?.length) marketplaceRegistry.addCatalogUrls(app.marketplaceCatalogUrls).catch(() => {});
|
|
1972
2003
|
this.apps.set(app.name, app);
|
|
1973
2004
|
if (options?.defaultAppName) this.defaultAppName = options.defaultAppName;
|
|
@@ -1984,13 +2015,13 @@ var appLoaderService = new class AppLoaderService {
|
|
|
1984
2015
|
*/
|
|
1985
2016
|
async start() {
|
|
1986
2017
|
if (this.started) {
|
|
1987
|
-
logger.debug("AppLoader already started");
|
|
2018
|
+
logger$1.debug("AppLoader already started");
|
|
1988
2019
|
return;
|
|
1989
2020
|
}
|
|
1990
2021
|
this.started = true;
|
|
1991
2022
|
const appIdFromUrl = new URLSearchParams(window.location.search).get("appId");
|
|
1992
2023
|
const appIdFromPath = extractAppIdFromPath();
|
|
1993
|
-
if (appIdFromPath) logger.info(`Extracted app ID from current page path: ${appIdFromPath}`);
|
|
2024
|
+
if (appIdFromPath) logger$1.info(`Extracted app ID from current page path: ${appIdFromPath}`);
|
|
1994
2025
|
const appToLoad = await this.selectAppToLoad({
|
|
1995
2026
|
appIdFromUrl,
|
|
1996
2027
|
appIdFromPath
|
|
@@ -2018,10 +2049,10 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2018
2049
|
if (!app) throw new Error(`App '${appName}' not found. Make sure it's registered.`);
|
|
2019
2050
|
this.dispatchLoadProgress("Starting…");
|
|
2020
2051
|
if (this.currentApp) {
|
|
2021
|
-
logger.info(`Disposing current app: ${this.currentApp.name}`);
|
|
2052
|
+
logger$1.info(`Disposing current app: ${this.currentApp.name}`);
|
|
2022
2053
|
if (this.currentApp.dispose) await this.currentApp.dispose();
|
|
2023
2054
|
if (this.currentApp.extensions && this.currentApp.extensions.length > 0) {
|
|
2024
|
-
logger.info(`Disabling ${this.currentApp.extensions.length} extensions...`);
|
|
2055
|
+
logger$1.info(`Disabling ${this.currentApp.extensions.length} extensions...`);
|
|
2025
2056
|
this.currentApp.extensions.forEach((extId) => {
|
|
2026
2057
|
extensionRegistry.disable(extId);
|
|
2027
2058
|
});
|
|
@@ -2031,25 +2062,28 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2031
2062
|
if (app.remaps?.length) {
|
|
2032
2063
|
const remappedTargets = /* @__PURE__ */ new Set();
|
|
2033
2064
|
for (const r of app.remaps) for (const t of r.targets) remappedTargets.add(t);
|
|
2034
|
-
for (const target of remappedTargets)
|
|
2035
|
-
target
|
|
2036
|
-
|
|
2037
|
-
|
|
2065
|
+
for (const target of remappedTargets) {
|
|
2066
|
+
const contributions = contributionRegistry.getContributions(target);
|
|
2067
|
+
publish(TOPIC_CONTRIBUTEIONS_CHANGED, {
|
|
2068
|
+
target,
|
|
2069
|
+
contributions
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2038
2072
|
}
|
|
2039
2073
|
if (app.contributions) {
|
|
2040
|
-
logger.info("Registering app contributions...");
|
|
2074
|
+
logger$1.info("Registering app contributions...");
|
|
2041
2075
|
if (app.contributions.ui) {
|
|
2042
2076
|
app.contributions.ui.forEach((contribution) => {
|
|
2043
2077
|
const target = contribution.target;
|
|
2044
2078
|
if (target) contributionRegistry.registerContribution(target, contribution);
|
|
2045
2079
|
});
|
|
2046
|
-
logger.info(`Registered ${app.contributions.ui.length} UI contributions`);
|
|
2080
|
+
logger$1.info(`Registered ${app.contributions.ui.length} UI contributions`);
|
|
2047
2081
|
}
|
|
2048
2082
|
if (app.contributions.extensions) {
|
|
2049
2083
|
app.contributions.extensions.forEach((extension) => {
|
|
2050
2084
|
extensionRegistry.registerExtension(extension);
|
|
2051
2085
|
});
|
|
2052
|
-
logger.info(`Registered ${app.contributions.extensions.length} app extensions`);
|
|
2086
|
+
logger$1.info(`Registered ${app.contributions.extensions.length} app extensions`);
|
|
2053
2087
|
}
|
|
2054
2088
|
}
|
|
2055
2089
|
const extensionsSet = new Set(app.extensions || []);
|
|
@@ -2058,19 +2092,18 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2058
2092
|
if (app.extensions.length > 0) {
|
|
2059
2093
|
this.dispatchLoadProgress("Enabling extensions…");
|
|
2060
2094
|
await Promise.all(app.extensions.map((extId) => extensionRegistry.enableAsync(extId).catch((e) => {
|
|
2061
|
-
logger.error(`Failed to load extension ${extId}: ${getErrorMessage(e)}`);
|
|
2095
|
+
logger$1.error(`Failed to load extension ${extId}: ${getErrorMessage(e)}`);
|
|
2062
2096
|
})));
|
|
2063
2097
|
}
|
|
2064
2098
|
this.dispatchLoadProgress("Loading extensions…");
|
|
2065
2099
|
await extensionRegistry.loadEnabledExtensions();
|
|
2066
2100
|
if (app.initialize) {
|
|
2067
2101
|
this.dispatchLoadProgress("Initializing…");
|
|
2068
|
-
logger.info(`Initializing ${app.name}...`);
|
|
2102
|
+
logger$1.info(`Initializing ${app.name}...`);
|
|
2069
2103
|
await app.initialize();
|
|
2070
2104
|
}
|
|
2071
2105
|
this.currentApp = app;
|
|
2072
|
-
logger.info(`App ${app.name} loaded successfully`);
|
|
2073
|
-
this.preferredLayoutId = await this.getPreferredLayoutId();
|
|
2106
|
+
logger$1.info(`App ${app.name} loaded successfully`);
|
|
2074
2107
|
this.updateDocumentMetadata(app);
|
|
2075
2108
|
if (container) {
|
|
2076
2109
|
this.dispatchLoadProgress("Rendering layout…");
|
|
@@ -2103,19 +2136,17 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2103
2136
|
*/
|
|
2104
2137
|
renderApp(container) {
|
|
2105
2138
|
if (!this.currentApp) throw new Error("No app loaded. Call loadApp() first.");
|
|
2106
|
-
const layoutId =
|
|
2139
|
+
const layoutId = getLayoutIdFromApp(this.currentApp);
|
|
2107
2140
|
const layouts = contributionRegistry.getContributions(SYSTEM_LAYOUTS);
|
|
2108
2141
|
let layout = layouts.find((c) => c.id === layoutId);
|
|
2109
2142
|
if (!layout) {
|
|
2110
|
-
logger.warn(`Layout '${layoutId}' not found, falling back to 'standard'`);
|
|
2143
|
+
logger$1.warn(`Layout '${layoutId}' not found, falling back to 'standard'`);
|
|
2111
2144
|
layout = layouts.find((c) => c.id === "standard");
|
|
2112
2145
|
}
|
|
2113
2146
|
if (!layout) throw new Error(`No layout found for layoutId '${layoutId}' and no 'standard' layout registered.`);
|
|
2114
2147
|
const r = layout.component;
|
|
2115
2148
|
let effectiveAttributes = {};
|
|
2116
2149
|
if (r && typeof r === "object" && "tag" in r && r.attributes) effectiveAttributes = { ...r.attributes };
|
|
2117
|
-
const appLayout = this.currentApp?.layout;
|
|
2118
|
-
if (typeof appLayout === "object" && appLayout.id === layoutId && appLayout.props) Object.assign(effectiveAttributes, propsToAttributes(appLayout.props));
|
|
2119
2150
|
container.innerHTML = "";
|
|
2120
2151
|
if (typeof r === "string") {
|
|
2121
2152
|
const el = document.createElement(r);
|
|
@@ -2128,7 +2159,7 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2128
2159
|
} else if (typeof r === "function") render(r(), container);
|
|
2129
2160
|
else throw new Error(`Layout '${layout.id}' has invalid component.`);
|
|
2130
2161
|
if (layout.onShow) requestAnimationFrame(() => {
|
|
2131
|
-
Promise.resolve(layout.onShow()).catch((err) => logger.error(`Layout onShow failed for '${layout.id}': ${getErrorMessage(err)}`));
|
|
2162
|
+
Promise.resolve(layout.onShow()).catch((err) => logger$1.error(`Layout onShow failed for '${layout.id}': ${getErrorMessage(err)}`));
|
|
2132
2163
|
});
|
|
2133
2164
|
}
|
|
2134
2165
|
/**
|
|
@@ -2150,7 +2181,7 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2150
2181
|
try {
|
|
2151
2182
|
return await appSettings.get(AppLoaderService.PREFERRED_APP_KEY);
|
|
2152
2183
|
} catch (error) {
|
|
2153
|
-
logger.debug(`Failed to get preferred app ID from settings: ${getErrorMessage(error)}`);
|
|
2184
|
+
logger$1.debug(`Failed to get preferred app ID from settings: ${getErrorMessage(error)}`);
|
|
2154
2185
|
return;
|
|
2155
2186
|
}
|
|
2156
2187
|
}
|
|
@@ -2162,9 +2193,9 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2162
2193
|
try {
|
|
2163
2194
|
await appSettings.set(AppLoaderService.PREFERRED_APP_KEY, appId);
|
|
2164
2195
|
this.defaultAppName = appId;
|
|
2165
|
-
logger.info(`Set preferred app to: ${appId}`);
|
|
2196
|
+
logger$1.info(`Set preferred app to: ${appId}`);
|
|
2166
2197
|
} catch (error) {
|
|
2167
|
-
logger.error(`Failed to persist preferred app: ${getErrorMessage(error)}`);
|
|
2198
|
+
logger$1.error(`Failed to persist preferred app: ${getErrorMessage(error)}`);
|
|
2168
2199
|
throw error;
|
|
2169
2200
|
}
|
|
2170
2201
|
}
|
|
@@ -2172,28 +2203,7 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2172
2203
|
return contributionRegistry.getContributions(SYSTEM_LAYOUTS);
|
|
2173
2204
|
}
|
|
2174
2205
|
getCurrentLayoutId() {
|
|
2175
|
-
return
|
|
2176
|
-
}
|
|
2177
|
-
async getPreferredLayoutId() {
|
|
2178
|
-
try {
|
|
2179
|
-
return await appSettings.get(AppLoaderService.PREFERRED_LAYOUT_KEY);
|
|
2180
|
-
} catch (error) {
|
|
2181
|
-
logger.debug(`Failed to get preferred layout ID: ${getErrorMessage(error)}`);
|
|
2182
|
-
return;
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
async setPreferredLayoutId(layoutId) {
|
|
2186
|
-
if (!this.getRegisteredLayouts().some((l) => l.id === layoutId)) throw new Error(`Layout '${layoutId}' not found.`);
|
|
2187
|
-
try {
|
|
2188
|
-
await appSettings.set(AppLoaderService.PREFERRED_LAYOUT_KEY, layoutId);
|
|
2189
|
-
this.preferredLayoutId = layoutId;
|
|
2190
|
-
logger.info(`Set preferred layout to: ${layoutId}`);
|
|
2191
|
-
if (this.currentApp && this.container) this.renderApp(this.container);
|
|
2192
|
-
window.dispatchEvent(new CustomEvent("layout-changed", { detail: { layoutId } }));
|
|
2193
|
-
} catch (error) {
|
|
2194
|
-
logger.error(`Failed to persist preferred layout: ${getErrorMessage(error)}`);
|
|
2195
|
-
throw error;
|
|
2196
|
-
}
|
|
2206
|
+
return getLayoutIdFromApp(this.currentApp);
|
|
2197
2207
|
}
|
|
2198
2208
|
/**
|
|
2199
2209
|
* Select which app to load based on priority:
|
|
@@ -2208,26 +2218,26 @@ var appLoaderService = new class AppLoaderService {
|
|
|
2208
2218
|
if (appIdFromUrl) {
|
|
2209
2219
|
const name = this.findAppNameBySegment(appIdFromUrl) ?? appIdFromUrl;
|
|
2210
2220
|
if (this.apps.has(name)) {
|
|
2211
|
-
logger.info(`Loading app specified by URL parameter 'appId': ${name}`);
|
|
2221
|
+
logger$1.info(`Loading app specified by URL parameter 'appId': ${name}`);
|
|
2212
2222
|
return name;
|
|
2213
2223
|
}
|
|
2214
|
-
logger.warn(`App '${appIdFromUrl}' from URL parameter not found`);
|
|
2224
|
+
logger$1.warn(`App '${appIdFromUrl}' from URL parameter not found`);
|
|
2215
2225
|
}
|
|
2216
2226
|
if (appIdFromPath) {
|
|
2217
2227
|
const name = this.findAppNameBySegment(appIdFromPath);
|
|
2218
2228
|
if (name) {
|
|
2219
|
-
logger.info(`Loading app from URL path: ${appIdFromPath}`);
|
|
2229
|
+
logger$1.info(`Loading app from URL path: ${appIdFromPath}`);
|
|
2220
2230
|
return name;
|
|
2221
2231
|
}
|
|
2222
|
-
logger.debug(`App for path '${appIdFromPath}' not found, continuing search`);
|
|
2232
|
+
logger$1.debug(`App for path '${appIdFromPath}' not found, continuing search`);
|
|
2223
2233
|
}
|
|
2224
2234
|
const preferred = await this.getPreferredAppId();
|
|
2225
2235
|
if (preferred && this.apps.has(preferred)) {
|
|
2226
|
-
logger.info(`Loading preferred app from settings: ${preferred}`);
|
|
2236
|
+
logger$1.info(`Loading preferred app from settings: ${preferred}`);
|
|
2227
2237
|
return preferred;
|
|
2228
2238
|
}
|
|
2229
2239
|
if (this.defaultAppName && this.apps.has(this.defaultAppName)) return this.defaultAppName;
|
|
2230
|
-
if (this.defaultAppName) logger.warn(`Default app '${this.defaultAppName}' not found`);
|
|
2240
|
+
if (this.defaultAppName) logger$1.warn(`Default app '${this.defaultAppName}' not found`);
|
|
2231
2241
|
const registeredApps = this.getRegisteredApps();
|
|
2232
2242
|
if (registeredApps.length > 0) return registeredApps[0].name;
|
|
2233
2243
|
}
|
|
@@ -2642,7 +2652,9 @@ var DocksNavigableInfoDialogContent = class DocksNavigableInfoDialogContent exte
|
|
|
2642
2652
|
action.callback();
|
|
2643
2653
|
}
|
|
2644
2654
|
handleClose() {
|
|
2645
|
-
if (this.
|
|
2655
|
+
if (this.resolveCallback) this.resolveCallback();
|
|
2656
|
+
const dialog = this.closest("wa-dialog");
|
|
2657
|
+
if (dialog && dialog.open !== false) dialog.open = false;
|
|
2646
2658
|
}
|
|
2647
2659
|
static {
|
|
2648
2660
|
this.styles = [...DocksDialogContent.styles, css`
|
|
@@ -2873,7 +2885,8 @@ var DocksFilebrowserDialog = class DocksFilebrowserDialog extends DocksDialogCon
|
|
|
2873
2885
|
nodes.sort((a, b) => a.label.localeCompare(b.label));
|
|
2874
2886
|
this.rootNodes = nodes;
|
|
2875
2887
|
} catch (e) {
|
|
2876
|
-
|
|
2888
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2889
|
+
this.loadError = msg;
|
|
2877
2890
|
this.rootNodes = [];
|
|
2878
2891
|
} finally {
|
|
2879
2892
|
this.loading = false;
|
|
@@ -2983,77 +2996,633 @@ function filebrowserDialog(mode = "either") {
|
|
|
2983
2996
|
});
|
|
2984
2997
|
}
|
|
2985
2998
|
//#endregion
|
|
2986
|
-
//#region src/
|
|
2987
|
-
var
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
var
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
2999
|
+
//#region src/core/contribution-names.ts
|
|
3000
|
+
var VIEW_FILEBROWSER = "view.filebrowser";
|
|
3001
|
+
var VIEW_LOG_TERMINAL = "view.logTerminal";
|
|
3002
|
+
var TOOLBAR_INFO = "toolbar.info";
|
|
3003
|
+
var TOOLBAR_FAST_VIEWS = "toolbar.fastViews";
|
|
3004
|
+
var TOOLBAR_LANGUAGE_SELECTOR = "toolbar.languageSelector";
|
|
3005
|
+
/** Main toolbar (right): layout picker (`docks-layout-switcher`). */
|
|
3006
|
+
var TOOLBAR_LAYOUT_SWITCHER = "toolbar.layoutSwitcher";
|
|
3007
|
+
/** Main toolbar (right): dark/light theme toggle (`switch_theme`). */
|
|
3008
|
+
var TOOLBAR_THEME_SWITCHER = "toolbar.themeSwitcher";
|
|
3009
|
+
/** Main toolbar (right): document fullscreen toggle (`fullscreen`). */
|
|
3010
|
+
var TOOLBAR_FULLSCREEN = "toolbar.fullscreen";
|
|
3011
|
+
/** Bottom-center toolbar: focused part title / active part indicator (`docks-part-name`). */
|
|
3012
|
+
var TOOLBAR_ACTIVE_PART_NAME = "toolbar.activePartName";
|
|
3013
|
+
/** Bottom-center toolbar: background tasks / progress (`docks-tasks`). */
|
|
3014
|
+
var TOOLBAR_TASKS = "toolbar.tasks";
|
|
3015
|
+
/** Main sidebar header toolbar: open extensions (`open_extensions` command). */
|
|
3016
|
+
var SIDEBAR_TOOLBAR_EXTENSIONS = "sidebar.toolbar.extensions";
|
|
3017
|
+
/** Default file-type → icon mappings on `system.icons`. */
|
|
3018
|
+
var SYSTEM_DEFAULT_FILE_ICONS = "system.icons.default";
|
|
3019
|
+
var ABOUT_TAB_RELEASE = "about.tab.release";
|
|
3020
|
+
var ABOUT_TAB_PACKAGES = "about.tab.packages";
|
|
3021
|
+
var ABOUT_TAB_ATTRIBUTIONS = "about.tab.attributions";
|
|
3022
|
+
var ATTRIBUTION_ECLIPSE_DOCKS = "attribution.eclipse-docks";
|
|
3023
|
+
var CTXMENU_FILEBROWSER_RENAME = "contextmenu.filebrowser.rename";
|
|
3024
|
+
var CTXMENU_FILEBROWSER_DELETE = "contextmenu.filebrowser.delete";
|
|
3025
|
+
//#endregion
|
|
3026
|
+
//#region src/parts/container.ts
|
|
3027
|
+
var DocksContainer = class extends DocksElement {};
|
|
3028
|
+
//#endregion
|
|
3029
|
+
//#region src/parts/part.ts
|
|
3030
|
+
var DocksPart = class DocksPart extends DocksContainer {
|
|
3031
|
+
constructor(..._args) {
|
|
3032
|
+
super(..._args);
|
|
3033
|
+
this.scrollMode = "scroller";
|
|
3034
|
+
this.dirty = false;
|
|
3035
|
+
this.isEditor = false;
|
|
3036
|
+
this.embedded = false;
|
|
3037
|
+
this.onContentContextMenu = async (event) => {
|
|
3038
|
+
const contextMenu = this.renderRoot.querySelector("docks-contextmenu");
|
|
3039
|
+
if (!contextMenu) return;
|
|
3040
|
+
if (await contextMenu.show({
|
|
3041
|
+
x: event.clientX,
|
|
3042
|
+
y: event.clientY
|
|
3043
|
+
}, event)) event.preventDefault();
|
|
3044
|
+
};
|
|
3011
3045
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3046
|
+
getCommandStack() {
|
|
3047
|
+
return this.commandStack;
|
|
3048
|
+
}
|
|
3049
|
+
/**
|
|
3050
|
+
* Override this method to provide toolbar content for this part.
|
|
3051
|
+
* This is a lightweight alternative to registering toolbar contributions
|
|
3052
|
+
* for actions that are scoped to this part instance.
|
|
3053
|
+
*
|
|
3054
|
+
* IMPORTANT: Event handlers MUST use arrow functions to preserve the component's 'this' context.
|
|
3055
|
+
* The toolbar template is rendered in a different component (docks-toolbar), so direct method
|
|
3056
|
+
* references lose their binding.
|
|
3057
|
+
*
|
|
3058
|
+
* ✅ Correct:
|
|
3059
|
+
* @click=${() => this.myMethod()}
|
|
3060
|
+
* @click=${(e) => this.handleClick(e)}
|
|
3061
|
+
*
|
|
3062
|
+
* ❌ Wrong (this will be bound to the toolbar, not your component):
|
|
3063
|
+
* @click=${this.myMethod}
|
|
3064
|
+
*
|
|
3065
|
+
* Example:
|
|
3066
|
+
* ```typescript
|
|
3067
|
+
* protected renderToolbar() {
|
|
3068
|
+
* return html`
|
|
3069
|
+
* <wa-button @click=${() => this.save()} title="Save">
|
|
3070
|
+
* <wa-icon name="save"></wa-icon>
|
|
3071
|
+
* </wa-button>
|
|
3072
|
+
* `;
|
|
3073
|
+
* }
|
|
3074
|
+
* ```
|
|
3075
|
+
*
|
|
3076
|
+
* @returns TemplateResult with toolbar items, or nothing if no toolbar needed
|
|
3077
|
+
*/
|
|
3078
|
+
renderToolbar() {
|
|
3079
|
+
return nothing;
|
|
3080
|
+
}
|
|
3081
|
+
/**
|
|
3082
|
+
* Activates the tab that contains this part by walking up the DOM to the first
|
|
3083
|
+
* docks-tabs ancestor and activating the tab panel that contains this part.
|
|
3084
|
+
* Crosses Shadow DOM boundaries (e.g. wa-tab-group) via getRootNode().host.
|
|
3085
|
+
* No-op if this part is not inside a docks-tabs / wa-tab-panel.
|
|
3086
|
+
*/
|
|
3087
|
+
activateContainingTab() {
|
|
3088
|
+
let el = this;
|
|
3089
|
+
let panelName = null;
|
|
3090
|
+
let tabsEl = null;
|
|
3091
|
+
while (el) {
|
|
3092
|
+
const tag = el.tagName?.toLowerCase();
|
|
3093
|
+
if (tag === "wa-tab-panel") panelName = el.getAttribute("name");
|
|
3094
|
+
if (tag === "docks-tabs") {
|
|
3095
|
+
tabsEl = el;
|
|
3096
|
+
break;
|
|
3097
|
+
}
|
|
3098
|
+
const parent = el.parentElement;
|
|
3099
|
+
if (parent) el = parent;
|
|
3100
|
+
else {
|
|
3101
|
+
const root = el.getRootNode();
|
|
3102
|
+
el = root instanceof ShadowRoot ? root.host : null;
|
|
3103
|
+
}
|
|
3018
3104
|
}
|
|
3105
|
+
if (tabsEl && panelName != null && panelName !== "") tabsEl.activate(panelName);
|
|
3106
|
+
}
|
|
3107
|
+
/**
|
|
3108
|
+
* Override this method to provide context menu content for this part.
|
|
3109
|
+
* This is a lightweight alternative to registering context menu contributions
|
|
3110
|
+
* for actions that are scoped to this part instance.
|
|
3111
|
+
*
|
|
3112
|
+
* IMPORTANT: Event handlers MUST use arrow functions to preserve the component's 'this' context.
|
|
3113
|
+
* The context menu is rendered in a different component (contextmenu), so direct method
|
|
3114
|
+
* references lose their binding.
|
|
3115
|
+
*
|
|
3116
|
+
* ✅ Correct:
|
|
3117
|
+
* @click=${() => this.myMethod()}
|
|
3118
|
+
* @click=${(e) => this.handleClick(e)}
|
|
3119
|
+
*
|
|
3120
|
+
* ❌ Wrong (this will be bound to the context menu, not your component):
|
|
3121
|
+
* @click=${this.myMethod}
|
|
3122
|
+
*
|
|
3123
|
+
* Example:
|
|
3124
|
+
* ```typescript
|
|
3125
|
+
* protected renderContextMenu() {
|
|
3126
|
+
* return html`
|
|
3127
|
+
* <wa-dropdown-item @click=${() => this.open()}>
|
|
3128
|
+
* <wa-icon name="folder-open"></wa-icon>
|
|
3129
|
+
* Open
|
|
3130
|
+
* </wa-dropdown-item>
|
|
3131
|
+
* <wa-divider></wa-divider>
|
|
3132
|
+
* <wa-dropdown-item @click=${() => this.delete()}>
|
|
3133
|
+
* <wa-icon name="trash"></wa-icon>
|
|
3134
|
+
* Delete
|
|
3135
|
+
* </wa-dropdown-item>
|
|
3136
|
+
* `;
|
|
3137
|
+
* }
|
|
3138
|
+
* ```
|
|
3139
|
+
*
|
|
3140
|
+
* @returns TemplateResult with context menu items, or nothing if no context menu needed
|
|
3141
|
+
*/
|
|
3142
|
+
renderContextMenu() {
|
|
3143
|
+
return nothing;
|
|
3144
|
+
}
|
|
3145
|
+
renderContent() {
|
|
3146
|
+
return nothing;
|
|
3147
|
+
}
|
|
3148
|
+
/** Part-level toolbar contributions (`toolbar:${partId}`). */
|
|
3149
|
+
getToolbarTarget() {
|
|
3150
|
+
const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
|
|
3151
|
+
return contributionKey ? `toolbar:${contributionKey}` : void 0;
|
|
3152
|
+
}
|
|
3153
|
+
/** Part-level context-menu contributions (`contextmenu:${partId}`). */
|
|
3154
|
+
getContextMenuTarget() {
|
|
3155
|
+
const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
|
|
3156
|
+
return contributionKey ? `contextmenu:${contributionKey}` : void 0;
|
|
3157
|
+
}
|
|
3158
|
+
syncIsEditorCapability() {
|
|
3159
|
+
const next = this.save !== DocksPart.prototype.save;
|
|
3160
|
+
if (next === this.isEditor) return;
|
|
3161
|
+
this.isEditor = next;
|
|
3162
|
+
}
|
|
3163
|
+
maybeActivateForCoupledEditors() {
|
|
3164
|
+
const coupled = this.tabContribution?.coupledEditors;
|
|
3165
|
+
if (!coupled?.length) return;
|
|
3166
|
+
const active = activeEditorSignal.get();
|
|
3167
|
+
if (!(active instanceof DocksPart)) return;
|
|
3168
|
+
const editorId = active.tabContribution?.editorId;
|
|
3169
|
+
if (!editorId || !coupled.includes(editorId)) return;
|
|
3170
|
+
this.activateContainingTab();
|
|
3019
3171
|
}
|
|
3020
3172
|
render() {
|
|
3021
|
-
const
|
|
3173
|
+
const toolbarTarget = this.getToolbarTarget();
|
|
3174
|
+
const contextMenuTarget = this.getContextMenuTarget();
|
|
3175
|
+
const toolbarEnabled = this.tabContribution?.toolbar !== false;
|
|
3176
|
+
const contextMenuEnabled = this.tabContribution?.contextMenu !== false;
|
|
3177
|
+
const scrollMode = this.scrollMode;
|
|
3178
|
+
const scopeTokens = this.isEditor ? ["system.editors", ".system.editors"] : [];
|
|
3179
|
+
const content = this.renderContent();
|
|
3180
|
+
const contentNode = scrollMode === "scroller" ? html`
|
|
3181
|
+
<wa-scroller class="part-content-scroll" orientation="vertical">
|
|
3182
|
+
<div class="part-content-inner">${content}</div>
|
|
3183
|
+
</wa-scroller>
|
|
3184
|
+
` : html`<div class="part-content-inner">${content}</div>`;
|
|
3022
3185
|
return html`
|
|
3023
|
-
<div class="
|
|
3024
|
-
${
|
|
3025
|
-
|
|
3186
|
+
<div class="part-shell">
|
|
3187
|
+
${toolbarEnabled ? html`
|
|
3188
|
+
<docks-toolbar
|
|
3189
|
+
class="part-toolbar"
|
|
3190
|
+
id=${ifDefined(toolbarTarget)}
|
|
3191
|
+
.scopeTokens=${scopeTokens}
|
|
3192
|
+
.partToolbarRenderer=${() => this.renderToolbar()}>
|
|
3193
|
+
</docks-toolbar>
|
|
3194
|
+
` : nothing}
|
|
3195
|
+
<div class="part-content ${scrollMode === "native" ? "native-scroll" : ""}" @contextmenu=${contextMenuEnabled ? this.onContentContextMenu : void 0}>
|
|
3196
|
+
${contentNode}
|
|
3197
|
+
</div>
|
|
3198
|
+
${contextMenuEnabled ? html`
|
|
3199
|
+
<docks-contextmenu
|
|
3200
|
+
id=${ifDefined(contextMenuTarget)}
|
|
3201
|
+
.scopeTokens=${scopeTokens}
|
|
3202
|
+
.partContextMenuRenderer=${() => this.renderContextMenu()}>
|
|
3203
|
+
</docks-contextmenu>
|
|
3204
|
+
` : nothing}
|
|
3026
3205
|
</div>
|
|
3027
3206
|
`;
|
|
3028
3207
|
}
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
});
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3208
|
+
updated(_changedProperties) {
|
|
3209
|
+
super.updated(_changedProperties);
|
|
3210
|
+
this.syncIsEditorCapability();
|
|
3211
|
+
if (_changedProperties.has("tabContribution")) this.maybeActivateForCoupledEditors();
|
|
3212
|
+
if (_changedProperties.has("dirty")) {
|
|
3213
|
+
if (_changedProperties.get("dirty") !== void 0) this.dispatchEvent(new CustomEvent("dirty", {
|
|
3214
|
+
detail: this.dirty,
|
|
3215
|
+
bubbles: true
|
|
3216
|
+
}));
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
doClose() {}
|
|
3220
|
+
disconnectedCallback() {
|
|
3221
|
+
super.disconnectedCallback();
|
|
3222
|
+
}
|
|
3223
|
+
close() {
|
|
3224
|
+
this.doClose();
|
|
3225
|
+
}
|
|
3226
|
+
connectedCallback() {
|
|
3227
|
+
super.connectedCallback();
|
|
3228
|
+
this.syncIsEditorCapability();
|
|
3229
|
+
queueMicrotask(() => this.syncIsEditorCapability());
|
|
3230
|
+
this.watch(activeEditorSignal, () => this.maybeActivateForCoupledEditors());
|
|
3231
|
+
}
|
|
3232
|
+
save() {}
|
|
3233
|
+
isDirty() {
|
|
3234
|
+
return this.dirty;
|
|
3235
|
+
}
|
|
3236
|
+
markDirty(dirty) {
|
|
3237
|
+
this.dirty = dirty;
|
|
3238
|
+
partDirtySignal.set(null);
|
|
3239
|
+
partDirtySignal.set(this);
|
|
3240
|
+
activePartSignal.set(null);
|
|
3241
|
+
activePartSignal.set(this);
|
|
3242
|
+
}
|
|
3243
|
+
static {
|
|
3244
|
+
this.baseStyles = css`
|
|
3245
|
+
:host {
|
|
3246
|
+
display: block;
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
.part-shell {
|
|
3250
|
+
display: grid;
|
|
3251
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
3252
|
+
height: 100%;
|
|
3253
|
+
width: 100%;
|
|
3254
|
+
position: relative;
|
|
3255
|
+
overflow: hidden;
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
.part-content {
|
|
3259
|
+
min-height: 0;
|
|
3260
|
+
overflow: hidden;
|
|
3261
|
+
position: relative;
|
|
3262
|
+
}
|
|
3263
|
+
|
|
3264
|
+
.part-content.native-scroll {
|
|
3265
|
+
overflow: auto;
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
.part-content-scroll {
|
|
3269
|
+
width: 100%;
|
|
3270
|
+
height: 100%;
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3273
|
+
.part-content-inner {
|
|
3274
|
+
height: 100%;
|
|
3275
|
+
min-height: 100%;
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
:host([embedded]) {
|
|
3279
|
+
height: auto;
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
:host([embedded]) .part-shell {
|
|
3283
|
+
height: auto;
|
|
3284
|
+
overflow: visible;
|
|
3285
|
+
grid-template-rows: auto;
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
:host([embedded]) .part-content {
|
|
3289
|
+
overflow: visible;
|
|
3290
|
+
min-height: 0;
|
|
3291
|
+
}
|
|
3292
|
+
|
|
3293
|
+
:host([embedded]) .part-content-inner {
|
|
3294
|
+
height: auto;
|
|
3295
|
+
min-height: 0;
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3298
|
+
.part-toolbar {
|
|
3299
|
+
min-height: 0;
|
|
3300
|
+
}
|
|
3301
|
+
`;
|
|
3302
|
+
}
|
|
3303
|
+
static finalizeStyles(styles) {
|
|
3304
|
+
const own = super.finalizeStyles(styles);
|
|
3305
|
+
return [DocksPart.baseStyles, ...own];
|
|
3306
|
+
}
|
|
3307
|
+
};
|
|
3308
|
+
_decorate([property()], DocksPart.prototype, "dirty", void 0);
|
|
3309
|
+
_decorate([property({ attribute: false })], DocksPart.prototype, "tabContribution", void 0);
|
|
3310
|
+
_decorate([property({
|
|
3311
|
+
type: Boolean,
|
|
3312
|
+
attribute: false
|
|
3313
|
+
})], DocksPart.prototype, "isEditor", void 0);
|
|
3314
|
+
_decorate([property({
|
|
3315
|
+
type: Boolean,
|
|
3316
|
+
reflect: true
|
|
3317
|
+
})], DocksPart.prototype, "embedded", void 0);
|
|
3318
|
+
//#endregion
|
|
3319
|
+
//#region src/components/release-history.ts
|
|
3320
|
+
var logger = createLogger("ReleaseHistory");
|
|
3321
|
+
async function loadReleases(releaseHistory) {
|
|
3322
|
+
if (!releaseHistory) return [];
|
|
3323
|
+
if (typeof releaseHistory !== "function") return releaseHistory;
|
|
3324
|
+
try {
|
|
3325
|
+
return await releaseHistory();
|
|
3326
|
+
} catch (error) {
|
|
3327
|
+
logger.error(`Failed to load release history from app: ${error instanceof Error ? error.message : String(error)}`);
|
|
3328
|
+
return [];
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
function semverEqual(a, b) {
|
|
3332
|
+
return a.replace(/^v/i, "") === b.replace(/^v/i, "");
|
|
3333
|
+
}
|
|
3334
|
+
function isNewerThan(releaseTag, currentVersion) {
|
|
3335
|
+
const currentParts = currentVersion.replace(/^v/i, "").split(".").map(Number);
|
|
3336
|
+
const releaseParts = releaseTag.replace(/^v/i, "").split(".").map(Number);
|
|
3337
|
+
for (let i = 0; i < Math.max(currentParts.length, releaseParts.length); i++) {
|
|
3338
|
+
const current = currentParts[i] || 0;
|
|
3339
|
+
const releasePart = releaseParts[i] || 0;
|
|
3340
|
+
if (releasePart > current) return true;
|
|
3341
|
+
if (releasePart < current) return false;
|
|
3342
|
+
}
|
|
3343
|
+
return false;
|
|
3344
|
+
}
|
|
3345
|
+
var DocksReleaseHistory = class DocksReleaseHistory extends DocksPart {
|
|
3346
|
+
constructor(..._args) {
|
|
3347
|
+
super(..._args);
|
|
3348
|
+
this.scrollMode = "none";
|
|
3349
|
+
this.appVersion = "0.0.0";
|
|
3350
|
+
this.releases = [];
|
|
3351
|
+
this.currentReleaseIndex = 0;
|
|
3352
|
+
}
|
|
3353
|
+
static {
|
|
3354
|
+
this.styles = [css`
|
|
3355
|
+
.release-panel {
|
|
3356
|
+
display: flex;
|
|
3357
|
+
flex-direction: column;
|
|
3358
|
+
gap: 0.5rem;
|
|
3359
|
+
padding: 0.75rem;
|
|
3360
|
+
box-sizing: border-box;
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3363
|
+
.release-body {
|
|
3364
|
+
white-space: normal;
|
|
3365
|
+
}
|
|
3366
|
+
`];
|
|
3367
|
+
}
|
|
3368
|
+
doInitUI() {
|
|
3369
|
+
this.load();
|
|
3370
|
+
}
|
|
3371
|
+
async load() {
|
|
3372
|
+
const app = appLoaderService.getCurrentApp();
|
|
3373
|
+
this.appVersion = app?.version ?? "0.0.0";
|
|
3374
|
+
this.releases = await loadReleases(app?.releaseHistory);
|
|
3375
|
+
const currentIndex = this.releases.findIndex((release) => semverEqual(release.tag_name, this.appVersion));
|
|
3376
|
+
this.currentReleaseIndex = currentIndex >= 0 ? currentIndex : 0;
|
|
3377
|
+
this.notifyChanged();
|
|
3378
|
+
}
|
|
3379
|
+
getNavState() {
|
|
3380
|
+
return {
|
|
3381
|
+
hasMultiple: this.releases.length > 1,
|
|
3382
|
+
atOldest: this.currentReleaseIndex >= this.releases.length - 1,
|
|
3383
|
+
atNewest: this.currentReleaseIndex <= 0
|
|
3384
|
+
};
|
|
3385
|
+
}
|
|
3386
|
+
showOlder() {
|
|
3387
|
+
if (this.currentReleaseIndex < this.releases.length - 1) {
|
|
3388
|
+
this.currentReleaseIndex += 1;
|
|
3389
|
+
this.notifyChanged();
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
showNewer() {
|
|
3393
|
+
if (this.currentReleaseIndex > 0) {
|
|
3394
|
+
this.currentReleaseIndex -= 1;
|
|
3395
|
+
this.notifyChanged();
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
notifyChanged() {
|
|
3399
|
+
this.dispatchEvent(new CustomEvent("release-history-changed", {
|
|
3400
|
+
bubbles: true,
|
|
3401
|
+
composed: true
|
|
3402
|
+
}));
|
|
3403
|
+
}
|
|
3404
|
+
renderContent() {
|
|
3405
|
+
const release = this.releases[this.currentReleaseIndex];
|
|
3406
|
+
if (!release) return html`<div class="release-panel">No release history available.</div>`;
|
|
3407
|
+
const isCurrent = semverEqual(release.tag_name, this.appVersion);
|
|
3408
|
+
const showUpdateHint = !isCurrent && isNewerThan(release.tag_name, this.appVersion);
|
|
3409
|
+
const bodyHtml = release.body ? parseMarkdownHtml(release.body) : "";
|
|
3410
|
+
return html`
|
|
3411
|
+
<div class="release-panel">
|
|
3412
|
+
<p>
|
|
3413
|
+
<strong>Version:</strong> ${release.tag_name}${isCurrent ? " (Current)" : ""}
|
|
3414
|
+
</p>
|
|
3415
|
+
<p>
|
|
3416
|
+
<strong>Released:</strong>
|
|
3417
|
+
<wa-format-date
|
|
3418
|
+
.date=${release.published_at}
|
|
3419
|
+
month="short"
|
|
3420
|
+
day="numeric"
|
|
3421
|
+
year="numeric"
|
|
3422
|
+
></wa-format-date>
|
|
3423
|
+
</p>
|
|
3424
|
+
${showUpdateHint ? html`
|
|
3425
|
+
<wa-callout variant="warning">
|
|
3426
|
+
<wa-icon slot="icon" name="triangle-exclamation"></wa-icon>
|
|
3427
|
+
A newer release is available than the version you are running.
|
|
3428
|
+
Use <strong>Update Available</strong> in the toolbar when it appears.
|
|
3429
|
+
</wa-callout>
|
|
3430
|
+
` : ""}
|
|
3431
|
+
${bodyHtml ? html`<div class="release-body">${unsafeHTML(bodyHtml)}</div>` : ""}
|
|
3432
|
+
</div>
|
|
3433
|
+
`;
|
|
3434
|
+
}
|
|
3435
|
+
};
|
|
3436
|
+
_decorate([state()], DocksReleaseHistory.prototype, "appVersion", void 0);
|
|
3437
|
+
_decorate([state()], DocksReleaseHistory.prototype, "releases", void 0);
|
|
3438
|
+
_decorate([state()], DocksReleaseHistory.prototype, "currentReleaseIndex", void 0);
|
|
3439
|
+
DocksReleaseHistory = _decorate([customElement("docks-release-history")], DocksReleaseHistory);
|
|
3440
|
+
//#endregion
|
|
3441
|
+
//#region src/dialogs/version-info-dialog.ts
|
|
3442
|
+
var EMPTY_NAV = {
|
|
3443
|
+
hasMultiple: false,
|
|
3444
|
+
atOldest: true,
|
|
3445
|
+
atNewest: true
|
|
3446
|
+
};
|
|
3447
|
+
var DocksVersionInfoDialog = class DocksVersionInfoDialog extends DocksDialogContent {
|
|
3448
|
+
constructor(..._args) {
|
|
3449
|
+
super(..._args);
|
|
3450
|
+
this.label = "";
|
|
3451
|
+
this.activeTab = null;
|
|
3452
|
+
this.releaseNav = EMPTY_NAV;
|
|
3453
|
+
this.onReleaseHistoryChanged = () => {
|
|
3454
|
+
this.syncReleaseNav();
|
|
3455
|
+
};
|
|
3456
|
+
}
|
|
3457
|
+
static {
|
|
3458
|
+
this.styles = [...DocksDialogContent.styles, css`
|
|
3459
|
+
:host {
|
|
3460
|
+
display: block;
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
wa-dialog {
|
|
3464
|
+
--width: 600px;
|
|
3465
|
+
}
|
|
3466
|
+
|
|
3467
|
+
wa-dialog::part(body) {
|
|
3468
|
+
display: flex;
|
|
3469
|
+
flex-direction: column;
|
|
3470
|
+
min-height: 0;
|
|
3471
|
+
overflow: hidden;
|
|
3472
|
+
}
|
|
3473
|
+
|
|
3474
|
+
.dialog-body {
|
|
3475
|
+
display: flex;
|
|
3476
|
+
flex-direction: column;
|
|
3477
|
+
gap: 0.75rem;
|
|
3478
|
+
min-width: 32rem;
|
|
3479
|
+
height: min(70vh, 36rem);
|
|
3480
|
+
min-height: min(70vh, 36rem);
|
|
3481
|
+
overflow: hidden;
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
.dialog-body docks-tabs {
|
|
3485
|
+
flex: 1 1 auto;
|
|
3486
|
+
min-height: 0;
|
|
3487
|
+
overflow: hidden;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
.dialog-footer {
|
|
3491
|
+
display: flex;
|
|
3492
|
+
gap: 0.5rem;
|
|
3493
|
+
justify-content: flex-end;
|
|
3494
|
+
width: 100%;
|
|
3495
|
+
}
|
|
3496
|
+
`];
|
|
3497
|
+
}
|
|
3498
|
+
firstUpdated(changed) {
|
|
3499
|
+
super.firstUpdated(changed);
|
|
3500
|
+
this.addEventListener("release-history-changed", this.onReleaseHistoryChanged);
|
|
3501
|
+
this.updateComplete.then(() => {
|
|
3502
|
+
this.attachTabListener();
|
|
3503
|
+
this.syncActiveTab();
|
|
3504
|
+
this.syncReleaseNav();
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
disconnectedCallback() {
|
|
3508
|
+
this.removeEventListener("release-history-changed", this.onReleaseHistoryChanged);
|
|
3509
|
+
super.disconnectedCallback();
|
|
3510
|
+
}
|
|
3511
|
+
attachTabListener() {
|
|
3512
|
+
const tabGroup = this.getAboutTabs()?.shadowRoot?.querySelector("wa-tab-group");
|
|
3513
|
+
if (!tabGroup || tabGroup.hasAttribute("data-version-info-listener")) return;
|
|
3514
|
+
tabGroup.setAttribute("data-version-info-listener", "");
|
|
3515
|
+
tabGroup.addEventListener("wa-tab-show", (event) => {
|
|
3516
|
+
const name = event.detail?.name;
|
|
3517
|
+
if (name) this.activeTab = name;
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
3520
|
+
getAboutTabs() {
|
|
3521
|
+
return this.renderRoot.querySelector("docks-tabs");
|
|
3522
|
+
}
|
|
3523
|
+
getReleaseHistory() {
|
|
3524
|
+
const part = this.getAboutTabs()?.getTabPart(ABOUT_TAB_RELEASE);
|
|
3525
|
+
return part instanceof DocksReleaseHistory ? part : null;
|
|
3526
|
+
}
|
|
3527
|
+
syncActiveTab() {
|
|
3528
|
+
const tabGroup = this.getAboutTabs()?.shadowRoot?.querySelector("wa-tab-group");
|
|
3529
|
+
this.activeTab = tabGroup?.getAttribute("active") || tabGroup?.active || null;
|
|
3530
|
+
}
|
|
3531
|
+
syncReleaseNav() {
|
|
3532
|
+
this.releaseNav = this.getReleaseHistory()?.getNavState() ?? EMPTY_NAV;
|
|
3533
|
+
}
|
|
3534
|
+
handleClose() {
|
|
3535
|
+
const dialog = this.renderRoot.querySelector("wa-dialog");
|
|
3536
|
+
if (dialog && dialog.open !== false) {
|
|
3537
|
+
dialog.open = false;
|
|
3538
|
+
return;
|
|
3539
|
+
}
|
|
3540
|
+
this.close?.();
|
|
3541
|
+
}
|
|
3542
|
+
handleAfterHide() {
|
|
3543
|
+
this.onAfterHide?.();
|
|
3544
|
+
}
|
|
3545
|
+
showOlderRelease() {
|
|
3546
|
+
this.getReleaseHistory()?.showOlder();
|
|
3547
|
+
}
|
|
3548
|
+
showNewerRelease() {
|
|
3549
|
+
this.getReleaseHistory()?.showNewer();
|
|
3550
|
+
}
|
|
3551
|
+
render() {
|
|
3552
|
+
const app = appLoaderService.getCurrentApp();
|
|
3553
|
+
const showReleaseNav = this.activeTab === "about.tab.release" && this.releaseNav.hasMultiple;
|
|
3554
|
+
return html`
|
|
3555
|
+
<wa-dialog
|
|
3556
|
+
label=${this.label}
|
|
3557
|
+
open
|
|
3558
|
+
light-dismiss
|
|
3559
|
+
with-footer
|
|
3560
|
+
@wa-after-hide=${this.handleAfterHide}
|
|
3561
|
+
>
|
|
3562
|
+
<div class="dialog-body">
|
|
3563
|
+
${app?.description ? html`<small>${app.description}</small>` : ""}
|
|
3564
|
+
<docks-tabs id=${ABOUT_TABS} fill-height></docks-tabs>
|
|
3565
|
+
</div>
|
|
3566
|
+
<div slot="footer" class="dialog-footer">
|
|
3567
|
+
${showReleaseNav ? html`
|
|
3568
|
+
<wa-button
|
|
3569
|
+
variant="default"
|
|
3570
|
+
?disabled=${this.releaseNav.atOldest}
|
|
3571
|
+
@click=${this.showOlderRelease}
|
|
3572
|
+
>
|
|
3573
|
+
← Previous
|
|
3574
|
+
</wa-button>
|
|
3575
|
+
<wa-button
|
|
3576
|
+
variant="default"
|
|
3577
|
+
?disabled=${this.releaseNav.atNewest}
|
|
3578
|
+
@click=${this.showNewerRelease}
|
|
3579
|
+
>
|
|
3580
|
+
Next →
|
|
3581
|
+
</wa-button>
|
|
3582
|
+
` : nothing}
|
|
3583
|
+
<wa-button variant="primary" @click=${this.handleClose}>Close</wa-button>
|
|
3584
|
+
</div>
|
|
3585
|
+
</wa-dialog>
|
|
3586
|
+
`;
|
|
3587
|
+
}
|
|
3588
|
+
};
|
|
3589
|
+
_decorate([property({ type: String })], DocksVersionInfoDialog.prototype, "label", void 0);
|
|
3590
|
+
_decorate([property({ attribute: false })], DocksVersionInfoDialog.prototype, "close", void 0);
|
|
3591
|
+
_decorate([property({ attribute: false })], DocksVersionInfoDialog.prototype, "onAfterHide", void 0);
|
|
3592
|
+
_decorate([state()], DocksVersionInfoDialog.prototype, "activeTab", void 0);
|
|
3593
|
+
_decorate([state()], DocksVersionInfoDialog.prototype, "releaseNav", void 0);
|
|
3594
|
+
DocksVersionInfoDialog = _decorate([customElement("docks-version-info-dialog")], DocksVersionInfoDialog);
|
|
3595
|
+
contributionRegistry.registerContribution(DIALOG_CONTRIBUTION_TARGET, {
|
|
3596
|
+
id: "version-info",
|
|
3597
|
+
label: "About",
|
|
3598
|
+
selfContained: true,
|
|
3599
|
+
component: (state) => html`
|
|
3600
|
+
<docks-version-info-dialog
|
|
3601
|
+
.label=${state?.label ?? ""}
|
|
3602
|
+
.close=${state?.close}
|
|
3603
|
+
.onAfterHide=${state?.onAfterHide}
|
|
3604
|
+
></docks-version-info-dialog>
|
|
3605
|
+
`
|
|
3606
|
+
});
|
|
3607
|
+
function versionInfoDialog() {
|
|
3608
|
+
const app = appLoaderService.getCurrentApp();
|
|
3609
|
+
return dialogService.open("version-info", { label: `About ${app?.name ?? ""} - ${app?.version ?? "0.0.0"}` });
|
|
3610
|
+
}
|
|
3611
|
+
//#endregion
|
|
3612
|
+
//#region src/core/dropdown-menu-utils.ts
|
|
3613
|
+
function isOpenDropdown(element) {
|
|
3614
|
+
if (element.localName !== "wa-dropdown") return false;
|
|
3615
|
+
const dropdown = element;
|
|
3616
|
+
return dropdown.open === true || dropdown.hasAttribute("open");
|
|
3617
|
+
}
|
|
3618
|
+
function elementsFromEventPath(event) {
|
|
3619
|
+
const fromComposedPath = event.composedPath().filter((node) => node instanceof Element);
|
|
3620
|
+
if (fromComposedPath.length > 0) return fromComposedPath;
|
|
3621
|
+
if (!(event.target instanceof Element)) return [];
|
|
3622
|
+
const path = [];
|
|
3623
|
+
let current = event.target;
|
|
3624
|
+
while (current) {
|
|
3625
|
+
path.push(current);
|
|
3057
3626
|
const root = current.getRootNode();
|
|
3058
3627
|
if (root instanceof ShadowRoot) {
|
|
3059
3628
|
current = root.host;
|
|
@@ -3147,9 +3716,10 @@ var RESIZE_DEBOUNCE_MS = 150;
|
|
|
3147
3716
|
function renderButtonGroup(slotName, orientation, contributions, isToolbarItem, contributionCreator) {
|
|
3148
3717
|
const label = `Toolbar ${slotName ?? "default"}`;
|
|
3149
3718
|
const items = contributions.filter((c) => c.slot === slotName && isToolbarItem(c) && getContributionVisible(c));
|
|
3719
|
+
const slotHtml = slotName === "start" ? html`<slot name="start"></slot>` : slotName === "end" ? html`<slot name="end"></slot>` : html`<slot></slot>`;
|
|
3150
3720
|
return html`
|
|
3151
3721
|
<wa-button-group orientation=${orientation} label=${label}>
|
|
3152
|
-
${
|
|
3722
|
+
${slotHtml}
|
|
3153
3723
|
${items.map(contributionCreator)}
|
|
3154
3724
|
</wa-button-group>
|
|
3155
3725
|
`;
|
|
@@ -3358,21 +3928,36 @@ DocksToolbar = _decorate([customElement("docks-toolbar")], DocksToolbar);
|
|
|
3358
3928
|
* A part can expose both surfaces with the same part id but different prefixes, registering
|
|
3359
3929
|
* different contributions on each. Feature-scoped targets (e.g. `filebrowser.create`) may also
|
|
3360
3930
|
* be referenced explicitly from either surface when several controls share the same item set.
|
|
3931
|
+
*
|
|
3932
|
+
* Command-backed items rely on the parent {@link https://webawesome.com/docs/components/dropdown | wa-dropdown}
|
|
3933
|
+
* `wa-select` event (see {@link handleDropdownWaSelect}) so the popup closes cleanly before
|
|
3934
|
+
* native dialogs such as `showDirectoryPicker` open.
|
|
3361
3935
|
*/
|
|
3362
|
-
function
|
|
3363
|
-
const
|
|
3364
|
-
if (
|
|
3936
|
+
function parseDropdownItemParams(item) {
|
|
3937
|
+
const raw = item.getAttribute("data-params");
|
|
3938
|
+
if (!raw) return {};
|
|
3939
|
+
try {
|
|
3940
|
+
return JSON.parse(raw);
|
|
3941
|
+
} catch {
|
|
3942
|
+
return {};
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
function getDropdownItemCommand(item) {
|
|
3946
|
+
return item.getAttribute("data-cmd") || item.getAttribute("value") || void 0;
|
|
3947
|
+
}
|
|
3948
|
+
/** Handles `wa-select` from a parent `wa-dropdown` and runs the backing command. */
|
|
3949
|
+
function handleDropdownWaSelect(event) {
|
|
3950
|
+
const item = event.detail?.item;
|
|
3951
|
+
if (!item || item.disabled || item.hasAttribute("disabled")) return;
|
|
3952
|
+
const cmd = getDropdownItemCommand(item);
|
|
3953
|
+
if (!cmd) return;
|
|
3954
|
+
commandRegistry.execute(cmd, commandRegistry.createExecutionContext(parseDropdownItemParams(item)));
|
|
3365
3955
|
}
|
|
3366
|
-
function
|
|
3956
|
+
function onDropdownActionClick(options) {
|
|
3367
3957
|
return (event) => {
|
|
3368
3958
|
if (readReactiveBoolean(options.disabled, false)) return;
|
|
3369
3959
|
event.stopPropagation();
|
|
3370
|
-
|
|
3371
|
-
if (options.action) {
|
|
3372
|
-
options.action(event);
|
|
3373
|
-
return;
|
|
3374
|
-
}
|
|
3375
|
-
if (options.cmd) commandRegistry.execute(options.cmd, commandRegistry.createExecutionContext(options.params ?? {}));
|
|
3960
|
+
options.action?.(event);
|
|
3376
3961
|
};
|
|
3377
3962
|
}
|
|
3378
3963
|
function keybindingDetails(cmd) {
|
|
@@ -3384,12 +3969,16 @@ function keybindingDetails(cmd) {
|
|
|
3384
3969
|
/** Renders a native {@link https://webawesome.com/docs/components/dropdown-item | wa-dropdown-item}. */
|
|
3385
3970
|
function renderDropdownItem(options) {
|
|
3386
3971
|
const iconSpec = options.icon ?? "";
|
|
3972
|
+
const paramsJson = options.params && Object.keys(options.params).length > 0 ? JSON.stringify(options.params) : void 0;
|
|
3387
3973
|
return html`
|
|
3388
3974
|
<wa-dropdown-item
|
|
3389
3975
|
slot=${options.slot ?? nothing}
|
|
3390
3976
|
variant=${options.variant ?? "default"}
|
|
3977
|
+
value=${options.cmd ?? nothing}
|
|
3978
|
+
data-cmd=${options.cmd ?? nothing}
|
|
3979
|
+
data-params=${paramsJson ?? nothing}
|
|
3391
3980
|
?disabled=${readReactiveBoolean(options.disabled, false)}
|
|
3392
|
-
@click=${
|
|
3981
|
+
@click=${options.action ? onDropdownActionClick(options) : nothing}>
|
|
3393
3982
|
${iconSpec ? icon(iconSpec, {
|
|
3394
3983
|
label: options.title ?? options.label,
|
|
3395
3984
|
slot: "icon"
|
|
@@ -3422,7 +4011,8 @@ function renderDropdownContribution(contribution, options) {
|
|
|
3422
4011
|
}
|
|
3423
4012
|
/** Renders all visible contributions registered for a contribution target. */
|
|
3424
4013
|
function renderDropdownContributions(target, options) {
|
|
3425
|
-
|
|
4014
|
+
const items = contributionRegistry.getContributions(target).map((c) => renderDropdownContribution(c, options)).filter((item) => item !== nothing);
|
|
4015
|
+
return html`${items}`;
|
|
3426
4016
|
}
|
|
3427
4017
|
/** Renders a {@link wa-dropdown-item} with nested items from a contribution target in {@code slot="submenu"}. */
|
|
3428
4018
|
function renderDropdownSubmenu(options) {
|
|
@@ -3568,384 +4158,117 @@ var DocksContextMenu = class DocksContextMenu extends DocksElement {
|
|
|
3568
4158
|
return element;
|
|
3569
4159
|
}
|
|
3570
4160
|
getHostPart() {
|
|
3571
|
-
const root = this.getRootNode();
|
|
3572
|
-
if (root instanceof ShadowRoot && root.host instanceof HTMLElement) return root.host;
|
|
3573
|
-
return null;
|
|
3574
|
-
}
|
|
3575
|
-
/**
|
|
3576
|
-
* Triggers a click on the element under the cursor to update selection before showing context menu.
|
|
3577
|
-
*/
|
|
3578
|
-
triggerClickUnderCursor(mouseEvent) {
|
|
3579
|
-
const elementUnderCursor = this.getElementFromPoint(mouseEvent.clientX, mouseEvent.clientY);
|
|
3580
|
-
if (elementUnderCursor) {
|
|
3581
|
-
const clickEvent = new MouseEvent("click", {
|
|
3582
|
-
bubbles: true,
|
|
3583
|
-
cancelable: true,
|
|
3584
|
-
view: window,
|
|
3585
|
-
clientX: mouseEvent.clientX,
|
|
3586
|
-
clientY: mouseEvent.clientY,
|
|
3587
|
-
screenX: mouseEvent.screenX,
|
|
3588
|
-
screenY: mouseEvent.screenY,
|
|
3589
|
-
button: 0,
|
|
3590
|
-
buttons: 0,
|
|
3591
|
-
detail: 1,
|
|
3592
|
-
which: 1
|
|
3593
|
-
});
|
|
3594
|
-
elementUnderCursor.dispatchEvent(clickEvent);
|
|
3595
|
-
}
|
|
3596
|
-
}
|
|
3597
|
-
/** Opens the menu at `position`. Returns false when there is nothing to show (no thin empty panel). */
|
|
3598
|
-
async show(position, mouseEvent) {
|
|
3599
|
-
if (!this.hasMenuBody()) return false;
|
|
3600
|
-
if (mouseEvent) {
|
|
3601
|
-
this.triggerClickUnderCursor(mouseEvent);
|
|
3602
|
-
await this.getHostPart()?.updateComplete;
|
|
3603
|
-
}
|
|
3604
|
-
if (this.isOpen) {
|
|
3605
|
-
this.isOpen = false;
|
|
3606
|
-
await this.updateComplete;
|
|
3607
|
-
}
|
|
3608
|
-
this.menuPosition = position;
|
|
3609
|
-
this.isOpen = true;
|
|
3610
|
-
await this.updateComplete;
|
|
3611
|
-
this.syncVirtualPopupAnchor();
|
|
3612
|
-
document.addEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
|
|
3613
|
-
return true;
|
|
3614
|
-
}
|
|
3615
|
-
/** Points wa-dropdown's internal wa-popup at the pointer via a VirtualElement anchor. */
|
|
3616
|
-
syncVirtualPopupAnchor() {
|
|
3617
|
-
const popup = this.dropdownRef.value?.shadowRoot?.querySelector("wa-popup");
|
|
3618
|
-
if (!popup) return;
|
|
3619
|
-
popup.anchor = this.virtualAnchor;
|
|
3620
|
-
popup.reposition();
|
|
3621
|
-
}
|
|
3622
|
-
onClose() {
|
|
3623
|
-
if (!this.isOpen) return;
|
|
3624
|
-
this.isOpen = false;
|
|
3625
|
-
document.removeEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
|
|
3626
|
-
}
|
|
3627
|
-
updated(changedProperties) {
|
|
3628
|
-
super.updated(changedProperties);
|
|
3629
|
-
if (changedProperties.has("isOpen") && this.isOpen) this.syncVirtualPopupAnchor();
|
|
3630
|
-
}
|
|
3631
|
-
renderContribution(contribution) {
|
|
3632
|
-
return renderDropdownContribution(contribution);
|
|
3633
|
-
}
|
|
3634
|
-
render() {
|
|
3635
|
-
const partContent = this.partContextMenuRenderer ? this.partContextMenuRenderer() : nothing;
|
|
3636
|
-
return html`
|
|
3637
|
-
<wa-dropdown
|
|
3638
|
-
${ref(this.dropdownRef)}
|
|
3639
|
-
?open=${this.isOpen}
|
|
3640
|
-
@submenu-opening=${this.handleSubmenuOpening}
|
|
3641
|
-
@wa-after-hide=${this.onClose}>
|
|
3642
|
-
<span slot="trigger" hidden aria-hidden="true"></span>
|
|
3643
|
-
|
|
3644
|
-
${partContent}
|
|
3645
|
-
${this.contributions.map((c) => this.renderContribution(c))}
|
|
3646
|
-
</wa-dropdown>
|
|
3647
|
-
`;
|
|
3648
|
-
}
|
|
3649
|
-
static {
|
|
3650
|
-
this.styles = css`
|
|
3651
|
-
:host {
|
|
3652
|
-
position: fixed;
|
|
3653
|
-
top: 0;
|
|
3654
|
-
left: 0;
|
|
3655
|
-
width: 0;
|
|
3656
|
-
height: 0;
|
|
3657
|
-
pointer-events: none;
|
|
3658
|
-
z-index: 10000;
|
|
3659
|
-
}
|
|
3660
|
-
|
|
3661
|
-
wa-dropdown {
|
|
3662
|
-
pointer-events: none;
|
|
3663
|
-
min-width: 200px;
|
|
3664
|
-
}
|
|
3665
|
-
|
|
3666
|
-
wa-dropdown:state(open) {
|
|
3667
|
-
pointer-events: auto;
|
|
3668
|
-
}
|
|
3669
|
-
|
|
3670
|
-
wa-dropdown::part(menu) {
|
|
3671
|
-
min-width: 200px;
|
|
3672
|
-
}
|
|
3673
|
-
`;
|
|
3674
|
-
}
|
|
3675
|
-
};
|
|
3676
|
-
_decorate([property({ attribute: false })], DocksContextMenu.prototype, "scopeTokens", void 0);
|
|
3677
|
-
_decorate([property({ attribute: false })], DocksContextMenu.prototype, "partContextMenuRenderer", void 0);
|
|
3678
|
-
_decorate([state()], DocksContextMenu.prototype, "contributions", void 0);
|
|
3679
|
-
_decorate([state()], DocksContextMenu.prototype, "isOpen", void 0);
|
|
3680
|
-
DocksContextMenu = _decorate([customElement("docks-contextmenu")], DocksContextMenu);
|
|
3681
|
-
//#endregion
|
|
3682
|
-
//#region src/parts/container.ts
|
|
3683
|
-
var DocksContainer = class extends DocksElement {};
|
|
3684
|
-
//#endregion
|
|
3685
|
-
//#region src/parts/part.ts
|
|
3686
|
-
var DocksPart = class DocksPart extends DocksContainer {
|
|
3687
|
-
constructor(..._args) {
|
|
3688
|
-
super(..._args);
|
|
3689
|
-
this.scrollMode = "scroller";
|
|
3690
|
-
this.dirty = false;
|
|
3691
|
-
this.isEditor = false;
|
|
3692
|
-
this.onContentContextMenu = async (event) => {
|
|
3693
|
-
const contextMenu = this.renderRoot.querySelector("docks-contextmenu");
|
|
3694
|
-
if (!contextMenu) return;
|
|
3695
|
-
if (await contextMenu.show({
|
|
3696
|
-
x: event.clientX,
|
|
3697
|
-
y: event.clientY
|
|
3698
|
-
}, event)) event.preventDefault();
|
|
3699
|
-
};
|
|
3700
|
-
}
|
|
3701
|
-
getCommandStack() {
|
|
3702
|
-
return this.commandStack;
|
|
3703
|
-
}
|
|
3704
|
-
/**
|
|
3705
|
-
* Override this method to provide toolbar content for this part.
|
|
3706
|
-
* This is a lightweight alternative to registering toolbar contributions
|
|
3707
|
-
* for actions that are scoped to this part instance.
|
|
3708
|
-
*
|
|
3709
|
-
* IMPORTANT: Event handlers MUST use arrow functions to preserve the component's 'this' context.
|
|
3710
|
-
* The toolbar template is rendered in a different component (docks-toolbar), so direct method
|
|
3711
|
-
* references lose their binding.
|
|
3712
|
-
*
|
|
3713
|
-
* ✅ Correct:
|
|
3714
|
-
* @click=${() => this.myMethod()}
|
|
3715
|
-
* @click=${(e) => this.handleClick(e)}
|
|
3716
|
-
*
|
|
3717
|
-
* ❌ Wrong (this will be bound to the toolbar, not your component):
|
|
3718
|
-
* @click=${this.myMethod}
|
|
3719
|
-
*
|
|
3720
|
-
* Example:
|
|
3721
|
-
* ```typescript
|
|
3722
|
-
* protected renderToolbar() {
|
|
3723
|
-
* return html`
|
|
3724
|
-
* <wa-button @click=${() => this.save()} title="Save">
|
|
3725
|
-
* <wa-icon name="save"></wa-icon>
|
|
3726
|
-
* </wa-button>
|
|
3727
|
-
* `;
|
|
3728
|
-
* }
|
|
3729
|
-
* ```
|
|
3730
|
-
*
|
|
3731
|
-
* @returns TemplateResult with toolbar items, or nothing if no toolbar needed
|
|
3732
|
-
*/
|
|
3733
|
-
renderToolbar() {
|
|
3734
|
-
return nothing;
|
|
3735
|
-
}
|
|
3736
|
-
/**
|
|
3737
|
-
* Activates the tab that contains this part by walking up the DOM to the first
|
|
3738
|
-
* docks-tabs ancestor and activating the tab panel that contains this part.
|
|
3739
|
-
* Crosses Shadow DOM boundaries (e.g. wa-tab-group) via getRootNode().host.
|
|
3740
|
-
* No-op if this part is not inside a docks-tabs / wa-tab-panel.
|
|
3741
|
-
*/
|
|
3742
|
-
activateContainingTab() {
|
|
3743
|
-
let el = this;
|
|
3744
|
-
let panelName = null;
|
|
3745
|
-
let tabsEl = null;
|
|
3746
|
-
while (el) {
|
|
3747
|
-
const tag = el.tagName?.toLowerCase();
|
|
3748
|
-
if (tag === "wa-tab-panel") panelName = el.getAttribute("name");
|
|
3749
|
-
if (tag === "docks-tabs") {
|
|
3750
|
-
tabsEl = el;
|
|
3751
|
-
break;
|
|
3752
|
-
}
|
|
3753
|
-
const parent = el.parentElement;
|
|
3754
|
-
if (parent) el = parent;
|
|
3755
|
-
else {
|
|
3756
|
-
const root = el.getRootNode();
|
|
3757
|
-
el = root instanceof ShadowRoot ? root.host : null;
|
|
3758
|
-
}
|
|
3759
|
-
}
|
|
3760
|
-
if (tabsEl && panelName != null && panelName !== "") tabsEl.activate(panelName);
|
|
3761
|
-
}
|
|
3762
|
-
/**
|
|
3763
|
-
* Override this method to provide context menu content for this part.
|
|
3764
|
-
* This is a lightweight alternative to registering context menu contributions
|
|
3765
|
-
* for actions that are scoped to this part instance.
|
|
3766
|
-
*
|
|
3767
|
-
* IMPORTANT: Event handlers MUST use arrow functions to preserve the component's 'this' context.
|
|
3768
|
-
* The context menu is rendered in a different component (contextmenu), so direct method
|
|
3769
|
-
* references lose their binding.
|
|
3770
|
-
*
|
|
3771
|
-
* ✅ Correct:
|
|
3772
|
-
* @click=${() => this.myMethod()}
|
|
3773
|
-
* @click=${(e) => this.handleClick(e)}
|
|
3774
|
-
*
|
|
3775
|
-
* ❌ Wrong (this will be bound to the context menu, not your component):
|
|
3776
|
-
* @click=${this.myMethod}
|
|
3777
|
-
*
|
|
3778
|
-
* Example:
|
|
3779
|
-
* ```typescript
|
|
3780
|
-
* protected renderContextMenu() {
|
|
3781
|
-
* return html`
|
|
3782
|
-
* <wa-dropdown-item @click=${() => this.open()}>
|
|
3783
|
-
* <wa-icon name="folder-open"></wa-icon>
|
|
3784
|
-
* Open
|
|
3785
|
-
* </wa-dropdown-item>
|
|
3786
|
-
* <wa-divider></wa-divider>
|
|
3787
|
-
* <wa-dropdown-item @click=${() => this.delete()}>
|
|
3788
|
-
* <wa-icon name="trash"></wa-icon>
|
|
3789
|
-
* Delete
|
|
3790
|
-
* </wa-dropdown-item>
|
|
3791
|
-
* `;
|
|
3792
|
-
* }
|
|
3793
|
-
* ```
|
|
3794
|
-
*
|
|
3795
|
-
* @returns TemplateResult with context menu items, or nothing if no context menu needed
|
|
3796
|
-
*/
|
|
3797
|
-
renderContextMenu() {
|
|
3798
|
-
return nothing;
|
|
3799
|
-
}
|
|
3800
|
-
renderContent() {
|
|
3801
|
-
return nothing;
|
|
3802
|
-
}
|
|
3803
|
-
/** Part-level toolbar contributions (`toolbar:${partId}`). */
|
|
3804
|
-
getToolbarTarget() {
|
|
3805
|
-
const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
|
|
3806
|
-
return contributionKey ? `toolbar:${contributionKey}` : void 0;
|
|
3807
|
-
}
|
|
3808
|
-
/** Part-level context-menu contributions (`contextmenu:${partId}`). */
|
|
3809
|
-
getContextMenuTarget() {
|
|
3810
|
-
const contributionKey = this.tabContribution?.editorId ?? this.id ?? this.tabContribution?.name;
|
|
3811
|
-
return contributionKey ? `contextmenu:${contributionKey}` : void 0;
|
|
3812
|
-
}
|
|
3813
|
-
syncIsEditorCapability() {
|
|
3814
|
-
const next = this.save !== DocksPart.prototype.save;
|
|
3815
|
-
if (next === this.isEditor) return;
|
|
3816
|
-
this.isEditor = next;
|
|
3817
|
-
}
|
|
3818
|
-
maybeActivateForCoupledEditors() {
|
|
3819
|
-
const coupled = this.tabContribution?.coupledEditors;
|
|
3820
|
-
if (!coupled?.length) return;
|
|
3821
|
-
const active = activeEditorSignal.get();
|
|
3822
|
-
if (!(active instanceof DocksPart)) return;
|
|
3823
|
-
const editorId = active.tabContribution?.editorId;
|
|
3824
|
-
if (!editorId || !coupled.includes(editorId)) return;
|
|
3825
|
-
this.activateContainingTab();
|
|
3826
|
-
}
|
|
3827
|
-
render() {
|
|
3828
|
-
const toolbarTarget = this.getToolbarTarget();
|
|
3829
|
-
const contextMenuTarget = this.getContextMenuTarget();
|
|
3830
|
-
const toolbarEnabled = this.tabContribution?.toolbar !== false;
|
|
3831
|
-
const contextMenuEnabled = this.tabContribution?.contextMenu !== false;
|
|
3832
|
-
const scrollMode = this.scrollMode;
|
|
3833
|
-
const scopeTokens = this.isEditor ? ["system.editors", ".system.editors"] : [];
|
|
3834
|
-
const content = this.renderContent();
|
|
3835
|
-
const contentNode = scrollMode === "scroller" ? html`
|
|
3836
|
-
<wa-scroller class="part-content-scroll" orientation="vertical">
|
|
3837
|
-
<div class="part-content-inner">${content}</div>
|
|
3838
|
-
</wa-scroller>
|
|
3839
|
-
` : html`<div class="part-content-inner">${content}</div>`;
|
|
3840
|
-
return html`
|
|
3841
|
-
<div class="part-shell">
|
|
3842
|
-
${toolbarEnabled ? html`
|
|
3843
|
-
<docks-toolbar
|
|
3844
|
-
class="part-toolbar"
|
|
3845
|
-
id=${ifDefined(toolbarTarget)}
|
|
3846
|
-
.scopeTokens=${scopeTokens}
|
|
3847
|
-
.partToolbarRenderer=${() => this.renderToolbar()}>
|
|
3848
|
-
</docks-toolbar>
|
|
3849
|
-
` : nothing}
|
|
3850
|
-
<div class="part-content ${scrollMode === "native" ? "native-scroll" : ""}" @contextmenu=${contextMenuEnabled ? this.onContentContextMenu : void 0}>
|
|
3851
|
-
${contentNode}
|
|
3852
|
-
</div>
|
|
3853
|
-
${contextMenuEnabled ? html`
|
|
3854
|
-
<docks-contextmenu
|
|
3855
|
-
id=${ifDefined(contextMenuTarget)}
|
|
3856
|
-
.scopeTokens=${scopeTokens}
|
|
3857
|
-
.partContextMenuRenderer=${() => this.renderContextMenu()}>
|
|
3858
|
-
</docks-contextmenu>
|
|
3859
|
-
` : nothing}
|
|
3860
|
-
</div>
|
|
3861
|
-
`;
|
|
4161
|
+
const root = this.getRootNode();
|
|
4162
|
+
if (root instanceof ShadowRoot && root.host instanceof HTMLElement) return root.host;
|
|
4163
|
+
return null;
|
|
3862
4164
|
}
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
bubbles: true
|
|
3871
|
-
|
|
4165
|
+
/**
|
|
4166
|
+
* Triggers a click on the element under the cursor to update selection before showing context menu.
|
|
4167
|
+
*/
|
|
4168
|
+
triggerClickUnderCursor(mouseEvent) {
|
|
4169
|
+
const elementUnderCursor = this.getElementFromPoint(mouseEvent.clientX, mouseEvent.clientY);
|
|
4170
|
+
if (elementUnderCursor) {
|
|
4171
|
+
const clickEvent = new MouseEvent("click", {
|
|
4172
|
+
bubbles: true,
|
|
4173
|
+
cancelable: true,
|
|
4174
|
+
view: window,
|
|
4175
|
+
clientX: mouseEvent.clientX,
|
|
4176
|
+
clientY: mouseEvent.clientY,
|
|
4177
|
+
screenX: mouseEvent.screenX,
|
|
4178
|
+
screenY: mouseEvent.screenY,
|
|
4179
|
+
button: 0,
|
|
4180
|
+
buttons: 0,
|
|
4181
|
+
detail: 1,
|
|
4182
|
+
which: 1
|
|
4183
|
+
});
|
|
4184
|
+
elementUnderCursor.dispatchEvent(clickEvent);
|
|
3872
4185
|
}
|
|
3873
4186
|
}
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
4187
|
+
/** Opens the menu at `position`. Returns false when there is nothing to show (no thin empty panel). */
|
|
4188
|
+
async show(position, mouseEvent) {
|
|
4189
|
+
if (!this.hasMenuBody()) return false;
|
|
4190
|
+
if (mouseEvent) {
|
|
4191
|
+
this.triggerClickUnderCursor(mouseEvent);
|
|
4192
|
+
await this.getHostPart()?.updateComplete;
|
|
4193
|
+
}
|
|
4194
|
+
if (this.isOpen) {
|
|
4195
|
+
this.isOpen = false;
|
|
4196
|
+
await this.updateComplete;
|
|
4197
|
+
}
|
|
4198
|
+
this.menuPosition = position;
|
|
4199
|
+
this.isOpen = true;
|
|
4200
|
+
await this.updateComplete;
|
|
4201
|
+
this.syncVirtualPopupAnchor();
|
|
4202
|
+
document.addEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
|
|
4203
|
+
return true;
|
|
3877
4204
|
}
|
|
3878
|
-
|
|
3879
|
-
|
|
4205
|
+
/** Points wa-dropdown's internal wa-popup at the pointer via a VirtualElement anchor. */
|
|
4206
|
+
syncVirtualPopupAnchor() {
|
|
4207
|
+
const popup = this.dropdownRef.value?.shadowRoot?.querySelector("wa-popup");
|
|
4208
|
+
if (!popup) return;
|
|
4209
|
+
popup.anchor = this.virtualAnchor;
|
|
4210
|
+
popup.reposition();
|
|
3880
4211
|
}
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
this.
|
|
3884
|
-
|
|
3885
|
-
this.watch(activeEditorSignal, () => this.maybeActivateForCoupledEditors());
|
|
4212
|
+
onClose() {
|
|
4213
|
+
if (!this.isOpen) return;
|
|
4214
|
+
this.isOpen = false;
|
|
4215
|
+
document.removeEventListener("pointerdown", this.boundHandleDocumentPointerDown, { capture: true });
|
|
3886
4216
|
}
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4217
|
+
updated(changedProperties) {
|
|
4218
|
+
super.updated(changedProperties);
|
|
4219
|
+
if (changedProperties.has("isOpen") && this.isOpen) this.syncVirtualPopupAnchor();
|
|
3890
4220
|
}
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
4221
|
+
renderContribution(contribution) {
|
|
4222
|
+
return renderDropdownContribution(contribution);
|
|
4223
|
+
}
|
|
4224
|
+
render() {
|
|
4225
|
+
const partContent = this.partContextMenuRenderer ? this.partContextMenuRenderer() : nothing;
|
|
4226
|
+
return html`
|
|
4227
|
+
<wa-dropdown
|
|
4228
|
+
${ref(this.dropdownRef)}
|
|
4229
|
+
?open=${this.isOpen}
|
|
4230
|
+
@submenu-opening=${this.handleSubmenuOpening}
|
|
4231
|
+
@wa-select=${handleDropdownWaSelect}
|
|
4232
|
+
@wa-after-hide=${this.onClose}>
|
|
4233
|
+
<span slot="trigger" hidden aria-hidden="true"></span>
|
|
4234
|
+
|
|
4235
|
+
${partContent}
|
|
4236
|
+
${this.contributions.map((c) => this.renderContribution(c))}
|
|
4237
|
+
</wa-dropdown>
|
|
4238
|
+
`;
|
|
3897
4239
|
}
|
|
3898
4240
|
static {
|
|
3899
|
-
this.
|
|
4241
|
+
this.styles = css`
|
|
3900
4242
|
:host {
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
width: 100%;
|
|
3909
|
-
position: relative;
|
|
3910
|
-
overflow: hidden;
|
|
3911
|
-
}
|
|
3912
|
-
|
|
3913
|
-
.part-content {
|
|
3914
|
-
min-height: 0;
|
|
3915
|
-
overflow: hidden;
|
|
3916
|
-
position: relative;
|
|
3917
|
-
}
|
|
3918
|
-
|
|
3919
|
-
.part-content.native-scroll {
|
|
3920
|
-
overflow: auto;
|
|
4243
|
+
position: fixed;
|
|
4244
|
+
top: 0;
|
|
4245
|
+
left: 0;
|
|
4246
|
+
width: 0;
|
|
4247
|
+
height: 0;
|
|
4248
|
+
pointer-events: none;
|
|
4249
|
+
z-index: 10000;
|
|
3921
4250
|
}
|
|
3922
4251
|
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
4252
|
+
wa-dropdown {
|
|
4253
|
+
pointer-events: none;
|
|
4254
|
+
min-width: 200px;
|
|
3926
4255
|
}
|
|
3927
4256
|
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
min-height: 100%;
|
|
4257
|
+
wa-dropdown:state(open) {
|
|
4258
|
+
pointer-events: auto;
|
|
3931
4259
|
}
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
min-
|
|
4260
|
+
|
|
4261
|
+
wa-dropdown::part(menu) {
|
|
4262
|
+
min-width: 200px;
|
|
3935
4263
|
}
|
|
3936
4264
|
`;
|
|
3937
4265
|
}
|
|
3938
|
-
static finalizeStyles(styles) {
|
|
3939
|
-
const own = super.finalizeStyles(styles);
|
|
3940
|
-
return [DocksPart.baseStyles, ...own];
|
|
3941
|
-
}
|
|
3942
4266
|
};
|
|
3943
|
-
_decorate([property()],
|
|
3944
|
-
_decorate([property({ attribute: false })],
|
|
3945
|
-
_decorate([
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
})], DocksPart.prototype, "isEditor", void 0);
|
|
4267
|
+
_decorate([property({ attribute: false })], DocksContextMenu.prototype, "scopeTokens", void 0);
|
|
4268
|
+
_decorate([property({ attribute: false })], DocksContextMenu.prototype, "partContextMenuRenderer", void 0);
|
|
4269
|
+
_decorate([state()], DocksContextMenu.prototype, "contributions", void 0);
|
|
4270
|
+
_decorate([state()], DocksContextMenu.prototype, "isOpen", void 0);
|
|
4271
|
+
DocksContextMenu = _decorate([customElement("docks-contextmenu")], DocksContextMenu);
|
|
3949
4272
|
//#endregion
|
|
3950
4273
|
//#region src/parts/tabs.ts
|
|
3951
4274
|
var _DocksTabs;
|
|
@@ -3959,6 +4282,8 @@ var DocksTabs = class DocksTabs extends DocksContainer {
|
|
|
3959
4282
|
this.iconOnly = false;
|
|
3960
4283
|
this.withToolbar = false;
|
|
3961
4284
|
this.hideTabs = false;
|
|
4285
|
+
this.fitContent = false;
|
|
4286
|
+
this.fillHeight = false;
|
|
3962
4287
|
this.itemSize = "m";
|
|
3963
4288
|
this.contributions = [];
|
|
3964
4289
|
this.tabGroup = createRef();
|
|
@@ -4011,6 +4336,11 @@ var DocksTabs = class DocksTabs extends DocksContainer {
|
|
|
4011
4336
|
if (!this.tabGroup.value) return null;
|
|
4012
4337
|
return this.tabGroup.value.getAttribute("active");
|
|
4013
4338
|
}
|
|
4339
|
+
getTabPart(tabName) {
|
|
4340
|
+
const tabPanel = this.getTabPanel(tabName);
|
|
4341
|
+
if (!tabPanel) return null;
|
|
4342
|
+
return this.getPartFromPanel(tabPanel);
|
|
4343
|
+
}
|
|
4014
4344
|
open(contribution) {
|
|
4015
4345
|
if (this.contributions.find((c) => c.name === contribution.name)) {
|
|
4016
4346
|
this.activate(contribution.name);
|
|
@@ -4260,6 +4590,95 @@ var DocksTabs = class DocksTabs extends DocksContainer {
|
|
|
4260
4590
|
width: 100%;
|
|
4261
4591
|
}
|
|
4262
4592
|
|
|
4593
|
+
:host([fit-content]) {
|
|
4594
|
+
display: flex;
|
|
4595
|
+
flex-direction: column;
|
|
4596
|
+
height: auto;
|
|
4597
|
+
max-height: 100%;
|
|
4598
|
+
min-height: 0;
|
|
4599
|
+
}
|
|
4600
|
+
|
|
4601
|
+
:host([fit-content]) wa-tab-group {
|
|
4602
|
+
display: flex;
|
|
4603
|
+
flex-direction: column;
|
|
4604
|
+
flex: 1 1 auto;
|
|
4605
|
+
min-height: 0;
|
|
4606
|
+
height: auto;
|
|
4607
|
+
max-height: 100%;
|
|
4608
|
+
}
|
|
4609
|
+
|
|
4610
|
+
:host([fit-content]) wa-tab-group::part(base) {
|
|
4611
|
+
display: flex;
|
|
4612
|
+
flex-direction: column;
|
|
4613
|
+
flex: 1 1 auto;
|
|
4614
|
+
min-height: 0;
|
|
4615
|
+
max-height: 100%;
|
|
4616
|
+
height: auto;
|
|
4617
|
+
}
|
|
4618
|
+
|
|
4619
|
+
:host([fit-content]) wa-tab-group::part(body) {
|
|
4620
|
+
flex: 1 1 auto;
|
|
4621
|
+
min-height: 0;
|
|
4622
|
+
height: auto;
|
|
4623
|
+
overflow-x: hidden;
|
|
4624
|
+
overflow-y: auto;
|
|
4625
|
+
}
|
|
4626
|
+
|
|
4627
|
+
:host([fit-content]) wa-tab-panel[active] {
|
|
4628
|
+
display: block;
|
|
4629
|
+
height: auto;
|
|
4630
|
+
overflow: visible;
|
|
4631
|
+
}
|
|
4632
|
+
|
|
4633
|
+
:host([fit-content]) wa-tab-panel > * {
|
|
4634
|
+
height: auto;
|
|
4635
|
+
min-height: 0;
|
|
4636
|
+
}
|
|
4637
|
+
|
|
4638
|
+
:host([fill-height]) {
|
|
4639
|
+
display: flex;
|
|
4640
|
+
flex-direction: column;
|
|
4641
|
+
height: 100%;
|
|
4642
|
+
min-height: 0;
|
|
4643
|
+
max-height: 100%;
|
|
4644
|
+
}
|
|
4645
|
+
|
|
4646
|
+
:host([fill-height]) wa-tab-group {
|
|
4647
|
+
display: flex;
|
|
4648
|
+
flex-direction: column;
|
|
4649
|
+
flex: 1 1 auto;
|
|
4650
|
+
min-height: 0;
|
|
4651
|
+
height: 100%;
|
|
4652
|
+
max-height: 100%;
|
|
4653
|
+
}
|
|
4654
|
+
|
|
4655
|
+
:host([fill-height]) wa-tab-group::part(base) {
|
|
4656
|
+
display: flex;
|
|
4657
|
+
flex-direction: column;
|
|
4658
|
+
flex: 1 1 auto;
|
|
4659
|
+
min-height: 0;
|
|
4660
|
+
max-height: 100%;
|
|
4661
|
+
height: 100%;
|
|
4662
|
+
}
|
|
4663
|
+
|
|
4664
|
+
:host([fill-height]) wa-tab-group::part(body) {
|
|
4665
|
+
flex: 1 1 auto;
|
|
4666
|
+
min-height: 0;
|
|
4667
|
+
overflow-x: hidden;
|
|
4668
|
+
overflow-y: auto;
|
|
4669
|
+
}
|
|
4670
|
+
|
|
4671
|
+
:host([fill-height]) wa-tab-panel[active] {
|
|
4672
|
+
display: block;
|
|
4673
|
+
height: auto;
|
|
4674
|
+
overflow: visible;
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4677
|
+
:host([fill-height]) wa-tab-panel > * {
|
|
4678
|
+
height: auto;
|
|
4679
|
+
min-height: 0;
|
|
4680
|
+
}
|
|
4681
|
+
|
|
4263
4682
|
wa-tab-group {
|
|
4264
4683
|
height: 100%;
|
|
4265
4684
|
width: 100%;
|
|
@@ -4487,6 +4906,16 @@ _decorate([property({
|
|
|
4487
4906
|
reflect: true,
|
|
4488
4907
|
attribute: "hide-tabs"
|
|
4489
4908
|
})], DocksTabs.prototype, "hideTabs", void 0);
|
|
4909
|
+
_decorate([property({
|
|
4910
|
+
type: Boolean,
|
|
4911
|
+
reflect: true,
|
|
4912
|
+
attribute: "fit-content"
|
|
4913
|
+
})], DocksTabs.prototype, "fitContent", void 0);
|
|
4914
|
+
_decorate([property({
|
|
4915
|
+
type: Boolean,
|
|
4916
|
+
reflect: true,
|
|
4917
|
+
attribute: "fill-height"
|
|
4918
|
+
})], DocksTabs.prototype, "fillHeight", void 0);
|
|
4490
4919
|
_decorate([property({
|
|
4491
4920
|
reflect: true,
|
|
4492
4921
|
attribute: "item-size"
|
|
@@ -4526,9 +4955,9 @@ var DocksResizableGrid = class DocksResizableGrid extends DocksElement {
|
|
|
4526
4955
|
this.gridChildren = [];
|
|
4527
4956
|
this.resizing = null;
|
|
4528
4957
|
this.resizeOverlay = null;
|
|
4529
|
-
this.childrenLoaded = false;
|
|
4530
4958
|
this.childStylesApplied = false;
|
|
4531
|
-
this.
|
|
4959
|
+
this.refreshScheduled = false;
|
|
4960
|
+
this.layoutGeneration = 0;
|
|
4532
4961
|
this.handleResize = (e) => {
|
|
4533
4962
|
if (!this.resizing) return;
|
|
4534
4963
|
const delta = (this.orientation === "horizontal" ? e.clientX : e.clientY) - this.resizing.startPos;
|
|
@@ -4578,56 +5007,108 @@ var DocksResizableGrid = class DocksResizableGrid extends DocksElement {
|
|
|
4578
5007
|
return this;
|
|
4579
5008
|
}
|
|
4580
5009
|
doBeforeUI() {
|
|
4581
|
-
|
|
4582
|
-
this.
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
5010
|
+
this.mutationObserver = new MutationObserver(() => {
|
|
5011
|
+
this.scheduleRefreshGridLayout();
|
|
5012
|
+
});
|
|
5013
|
+
this.mutationObserver.observe(this, {
|
|
5014
|
+
childList: true,
|
|
5015
|
+
subtree: false
|
|
5016
|
+
});
|
|
5017
|
+
this.scheduleRefreshGridLayout();
|
|
5018
|
+
}
|
|
5019
|
+
scheduleRefreshGridLayout() {
|
|
5020
|
+
if (this.refreshScheduled) return;
|
|
5021
|
+
this.refreshScheduled = true;
|
|
5022
|
+
queueMicrotask(() => {
|
|
5023
|
+
this.refreshScheduled = false;
|
|
5024
|
+
this.refreshGridLayout();
|
|
5025
|
+
});
|
|
4591
5026
|
}
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
5027
|
+
getGridChildrenFromDom() {
|
|
5028
|
+
return Array.from(this.children).filter((child) => child.tagName !== "STYLE" && child.tagName !== "SCRIPT" && !child.classList.contains("resize-handle"));
|
|
5029
|
+
}
|
|
5030
|
+
static isNestedResizableGrid(child) {
|
|
5031
|
+
return child.tagName.toLowerCase() === "docks-resizable-grid";
|
|
5032
|
+
}
|
|
5033
|
+
applyChildLayoutStyles() {
|
|
5034
|
+
this.gridChildren.forEach((child, index) => {
|
|
5035
|
+
child.style.overflow = "hidden";
|
|
5036
|
+
child.style.height = "100%";
|
|
5037
|
+
child.style.width = "100%";
|
|
5038
|
+
child.style.gridColumn = this.orientation === "horizontal" ? `${index * 2 + 1}` : "1";
|
|
5039
|
+
child.style.gridRow = this.orientation === "vertical" ? `${index * 2 + 1}` : "1";
|
|
5040
|
+
if (!_DocksResizableGrid.isNestedResizableGrid(child)) {
|
|
5041
|
+
child.style.display = "flex";
|
|
5042
|
+
child.style.flexDirection = "column";
|
|
4608
5043
|
}
|
|
5044
|
+
});
|
|
5045
|
+
}
|
|
5046
|
+
resolveGridSizes(childCount) {
|
|
5047
|
+
const parsedSizes = this.sizes?.split(",").map((s) => s.trim()).filter(Boolean) ?? [];
|
|
5048
|
+
if (parsedSizes.length === childCount) return parsedSizes;
|
|
5049
|
+
const equalSize = `${100 / childCount}%`;
|
|
5050
|
+
return Array.from({ length: childCount }, () => equalSize);
|
|
5051
|
+
}
|
|
5052
|
+
resolvePersistedSizes(persisted, childCount) {
|
|
5053
|
+
if (!persisted || typeof persisted !== "object") return null;
|
|
5054
|
+
const record = persisted;
|
|
5055
|
+
const byCount = record.sizesByCount?.[String(childCount)];
|
|
5056
|
+
if (Array.isArray(byCount) && byCount.length === childCount && byCount.every((size) => typeof size === "string")) return byCount;
|
|
5057
|
+
if (Array.isArray(record.sizes) && record.sizes.length === childCount && record.sizes.every((size) => typeof size === "string")) return record.sizes;
|
|
5058
|
+
return null;
|
|
5059
|
+
}
|
|
5060
|
+
async refreshGridLayout() {
|
|
5061
|
+
const generation = ++this.layoutGeneration;
|
|
5062
|
+
const potentialChildren = this.getGridChildrenFromDom();
|
|
5063
|
+
if (potentialChildren.length === 0) {
|
|
5064
|
+
this.gridChildren = [];
|
|
5065
|
+
this.gridSizes = [];
|
|
5066
|
+
this.childStylesApplied = false;
|
|
5067
|
+
this.requestUpdate();
|
|
5068
|
+
return;
|
|
4609
5069
|
}
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
5070
|
+
const identityChanged = potentialChildren.length !== this.gridChildren.length || potentialChildren.some((child, index) => child !== this.gridChildren[index]);
|
|
5071
|
+
this.gridChildren = potentialChildren;
|
|
5072
|
+
const persisted = await this.getDialogSetting();
|
|
5073
|
+
if (generation !== this.layoutGeneration) return;
|
|
5074
|
+
const restoredSizes = this.resolvePersistedSizes(persisted, this.gridChildren.length);
|
|
5075
|
+
if (restoredSizes) {
|
|
5076
|
+
const sizesChanged = restoredSizes.join("|") !== this.gridSizes.join("|");
|
|
5077
|
+
this.gridSizes = restoredSizes;
|
|
5078
|
+
if (identityChanged || sizesChanged) this.childStylesApplied = false;
|
|
5079
|
+
this.requestUpdate();
|
|
5080
|
+
return;
|
|
4614
5081
|
}
|
|
5082
|
+
const nextSizes = this.resolveGridSizes(this.gridChildren.length);
|
|
5083
|
+
const sizesChanged = nextSizes.join("|") !== this.gridSizes.join("|");
|
|
5084
|
+
this.gridSizes = nextSizes;
|
|
5085
|
+
if (identityChanged || sizesChanged) this.childStylesApplied = false;
|
|
4615
5086
|
this.requestUpdate();
|
|
4616
5087
|
}
|
|
5088
|
+
doInitUI() {
|
|
5089
|
+
this.scheduleRefreshGridLayout();
|
|
5090
|
+
}
|
|
4617
5091
|
async saveSizes() {
|
|
4618
5092
|
if (this.gridSizes.length === 0) return;
|
|
5093
|
+
const persisted = await this.getDialogSetting();
|
|
5094
|
+
const existingByCount = persisted && typeof persisted === "object" ? persisted.sizesByCount ?? {} : {};
|
|
4619
5095
|
await this.setDialogSetting({
|
|
4620
5096
|
sizes: this.gridSizes,
|
|
5097
|
+
sizesByCount: {
|
|
5098
|
+
...existingByCount,
|
|
5099
|
+
[String(this.gridSizes.length)]: this.gridSizes
|
|
5100
|
+
},
|
|
4621
5101
|
orientation: this.orientation
|
|
4622
5102
|
});
|
|
4623
5103
|
}
|
|
4624
5104
|
updated(changedProperties) {
|
|
4625
5105
|
super.updated(changedProperties);
|
|
4626
|
-
if (changedProperties.has("
|
|
5106
|
+
if (changedProperties.has("sizes")) this.scheduleRefreshGridLayout();
|
|
5107
|
+
if (!this.childStylesApplied && this.gridChildren.length > 0) {
|
|
4627
5108
|
this.childStylesApplied = true;
|
|
4628
5109
|
/**
|
|
4629
5110
|
* Direct style manipulation is intentionally used here.
|
|
4630
|
-
*
|
|
5111
|
+
*
|
|
4631
5112
|
* Reasoning:
|
|
4632
5113
|
* - Grid positioning (gridColumn/gridRow) must be computed dynamically based on
|
|
4633
5114
|
* the number of children and orientation at runtime
|
|
@@ -4637,16 +5118,9 @@ var DocksResizableGrid = class DocksResizableGrid extends DocksElement {
|
|
|
4637
5118
|
* (e.g., child at index 0 → column 1, index 1 → column 3, etc.)
|
|
4638
5119
|
* - This is a layout container whose primary job is to programmatically position
|
|
4639
5120
|
* its children within a CSS grid system
|
|
5121
|
+
* - Nested resizable grids manage their own display mode and must not receive flex
|
|
4640
5122
|
*/
|
|
4641
|
-
this.
|
|
4642
|
-
child.style.overflow = "hidden";
|
|
4643
|
-
child.style.height = "100%";
|
|
4644
|
-
child.style.width = "100%";
|
|
4645
|
-
child.style.gridColumn = this.orientation === "horizontal" ? `${index * 2 + 1}` : "1";
|
|
4646
|
-
child.style.gridRow = this.orientation === "vertical" ? `${index * 2 + 1}` : "1";
|
|
4647
|
-
child.style.display = "flex";
|
|
4648
|
-
child.style.flexDirection = "column";
|
|
4649
|
-
});
|
|
5123
|
+
this.applyChildLayoutStyles();
|
|
4650
5124
|
}
|
|
4651
5125
|
}
|
|
4652
5126
|
startResize(e, handleIndex) {
|
|
@@ -4654,14 +5128,15 @@ var DocksResizableGrid = class DocksResizableGrid extends DocksElement {
|
|
|
4654
5128
|
if (handleIndex >= this.gridChildren.length - 1) return;
|
|
4655
5129
|
const startPos = this.orientation === "horizontal" ? e.clientX : e.clientY;
|
|
4656
5130
|
const containerSize = this.orientation === "horizontal" ? this.offsetWidth : this.offsetHeight;
|
|
5131
|
+
const startSizes = this.gridSizes.map((size) => {
|
|
5132
|
+
if (size.endsWith("%")) return parseFloat(size) / 100 * containerSize;
|
|
5133
|
+
else if (size.endsWith("px")) return parseFloat(size);
|
|
5134
|
+
else return parseFloat(size);
|
|
5135
|
+
});
|
|
4657
5136
|
this.resizing = {
|
|
4658
5137
|
handleIndex,
|
|
4659
5138
|
startPos,
|
|
4660
|
-
startSizes
|
|
4661
|
-
if (size.endsWith("%")) return parseFloat(size) / 100 * containerSize;
|
|
4662
|
-
else if (size.endsWith("px")) return parseFloat(size);
|
|
4663
|
-
else return parseFloat(size);
|
|
4664
|
-
})
|
|
5139
|
+
startSizes
|
|
4665
5140
|
};
|
|
4666
5141
|
this.resizeOverlay = document.createElement("div");
|
|
4667
5142
|
this.resizeOverlay.style.position = "fixed";
|
|
@@ -4765,6 +5240,6 @@ DocksResizableGrid = _DocksResizableGrid = _decorate([customElement("docks-resiz
|
|
|
4765
5240
|
//#region src/parts/index.ts
|
|
4766
5241
|
installOpenDropdownNativeContextMenuGuard();
|
|
4767
5242
|
//#endregion
|
|
4768
|
-
export {
|
|
5243
|
+
export { HIDE_DOT_RESOURCE as $, filebrowserDialog as A, dialogService as B, TOOLBAR_INFO as C, TOOLBAR_THEME_SWITCHER as D, TOOLBAR_TASKS as E, formDialogRequired as F, keyBindingManager as G, DocksElement as H, validateFormDialogFields as I, esmShService as J, TOPIC_EXTENSIONS_CHANGED as K, promptDialog as L, confirmDialog as M, infoDialog as N, VIEW_FILEBROWSER as O, formDialog as P, COMMAND_SAVE as Q, appLoaderService as R, TOOLBAR_FULLSCREEN as S, TOOLBAR_LAYOUT_SWITCHER as T, parseMarkdownHtml as U, DocksDialogContent as V, sanitizeHtml as W, TOPIC_SETTINGS_CHANGED as X, taskService as Y, appSettings as Z, CTXMENU_FILEBROWSER_RENAME as _, TOOLBAR_MAIN_CENTER as _t, renderDropdownItem as a, SIDEBAR_AUXILIARY as at, TOOLBAR_ACTIVE_PART_NAME as b, parseIconSpec as c, SIDEBAR_MAIN_BOTTOM as ct, DocksContainer as d, SYSTEM_LAYOUTS as dt, MouseButton as et, ABOUT_TAB_ATTRIBUTIONS as f, SYSTEM_VIEWS as ft, CTXMENU_FILEBROWSER_DELETE as g, TOOLBAR_MAIN as gt, ATTRIBUTION_ECLIPSE_DOCKS as h, TOOLBAR_BOTTOM_END as ht, renderDropdownContributions as i, PANEL_BOTTOM as it, navigableInfoDialog as j, VIEW_LOG_TERMINAL as k, versionInfoDialog as l, SIDEBAR_MAIN_TOOLBAR as lt, ABOUT_TAB_RELEASE as m, TOOLBAR_BOTTOM_CENTER as mt, renderCommandContribution as n, ABOUT_TABS as nt, renderDropdownSubmenu as o, SIDEBAR_AUXILIARY_BOTTOM as ot, ABOUT_TAB_PACKAGES as p, TOOLBAR_BOTTOM as pt, extensionRegistry as q, renderDropdownContribution as r, EDITOR_AREA_MAIN as rt, icon as s, SIDEBAR_MAIN as st, handleDropdownWaSelect as t, constants_exports as tt, DocksPart as u, SYSTEM_ATTRIBUTIONS as ut, SIDEBAR_TOOLBAR_EXTENSIONS as v, TOOLBAR_MAIN_RIGHT as vt, TOOLBAR_LANGUAGE_SELECTOR as w, TOOLBAR_FAST_VIEWS as x, SYSTEM_DEFAULT_FILE_ICONS as y, deleteIndexedDbWorkspaceData as z };
|
|
4769
5244
|
|
|
4770
|
-
//# sourceMappingURL=parts-
|
|
5245
|
+
//# sourceMappingURL=parts-DQRktiiR.js.map
|