@miragon/modeler-shell 0.0.0-stage → 0.2.0

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.
Files changed (147) hide show
  1. package/API.md +2869 -0
  2. package/LICENSE +21 -0
  3. package/README.md +566 -2
  4. package/THIRD_PARTY_NOTICES.md +52 -0
  5. package/dist/appearance-BBaM_4bD.d.ts +323 -0
  6. package/dist/appearance-D3FUcbu6.d.cts +53 -0
  7. package/dist/appearance-D3FUcbu6.d.ts +53 -0
  8. package/dist/appearance-XX3JC3pI.d.cts +323 -0
  9. package/dist/chunk-66HCSJNY.js +2792 -0
  10. package/dist/chunk-66HCSJNY.js.map +1 -0
  11. package/dist/chunk-KYDG5DMX.js +136 -0
  12. package/dist/chunk-KYDG5DMX.js.map +1 -0
  13. package/dist/chunk-N4QXFF3A.js +23 -0
  14. package/dist/chunk-N4QXFF3A.js.map +1 -0
  15. package/dist/chunk-OADW3GPA.js +785 -0
  16. package/dist/chunk-OADW3GPA.js.map +1 -0
  17. package/dist/core.cjs +873 -0
  18. package/dist/core.cjs.map +1 -0
  19. package/dist/core.d.cts +246 -0
  20. package/dist/core.d.ts +246 -0
  21. package/dist/core.js +131 -0
  22. package/dist/core.js.map +1 -0
  23. package/dist/diagram-js.cjs +1147 -0
  24. package/dist/diagram-js.cjs.map +1 -0
  25. package/dist/diagram-js.d.cts +170 -0
  26. package/dist/diagram-js.d.ts +170 -0
  27. package/dist/diagram-js.js +879 -0
  28. package/dist/diagram-js.js.map +1 -0
  29. package/dist/index.cjs +3632 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.cts +29 -0
  32. package/dist/index.d.ts +29 -0
  33. package/dist/index.js +143 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/protocol-DhYBakWL.d.cts +15 -0
  36. package/dist/protocol-IeW8bf4f.d.ts +15 -0
  37. package/dist/shell.css +1603 -0
  38. package/dist/testing-vscode-stub.cjs +332 -0
  39. package/dist/testing-vscode-stub.cjs.map +1 -0
  40. package/dist/testing-vscode-stub.d.cts +65 -0
  41. package/dist/testing-vscode-stub.d.ts +65 -0
  42. package/dist/testing-vscode-stub.js +154 -0
  43. package/dist/testing-vscode-stub.js.map +1 -0
  44. package/dist/testing.cjs +4663 -0
  45. package/dist/testing.cjs.map +1 -0
  46. package/dist/testing.d.cts +231 -0
  47. package/dist/testing.d.ts +231 -0
  48. package/dist/testing.js +4483 -0
  49. package/dist/testing.js.map +1 -0
  50. package/dist/toasts-Bp0REqdq.d.cts +142 -0
  51. package/dist/toasts-Bp0REqdq.d.ts +142 -0
  52. package/dist/types-CnRrINRs.d.cts +445 -0
  53. package/dist/types-PuDZczzy.d.ts +445 -0
  54. package/dist/vscode-extension.cjs +215 -0
  55. package/dist/vscode-extension.cjs.map +1 -0
  56. package/dist/vscode-extension.d.cts +103 -0
  57. package/dist/vscode-extension.d.ts +103 -0
  58. package/dist/vscode-extension.js +24 -0
  59. package/dist/vscode-extension.js.map +1 -0
  60. package/dist/vscode-webview.cjs +3561 -0
  61. package/dist/vscode-webview.cjs.map +1 -0
  62. package/dist/vscode-webview.d.cts +84 -0
  63. package/dist/vscode-webview.d.ts +84 -0
  64. package/dist/vscode-webview.js +259 -0
  65. package/dist/vscode-webview.js.map +1 -0
  66. package/package.json +145 -4
  67. package/src/core/appearance.ts +104 -0
  68. package/src/core/feedback/appearance.ts +141 -0
  69. package/src/core/feedback/problems.ts +23 -0
  70. package/src/core/feedback/toasts.ts +118 -0
  71. package/src/core/fit.ts +220 -0
  72. package/src/core/index.ts +127 -0
  73. package/src/core/keymap.ts +295 -0
  74. package/src/core/layout.ts +69 -0
  75. package/src/core/messages.ts +159 -0
  76. package/src/core/sizes.ts +85 -0
  77. package/src/core/types.ts +106 -0
  78. package/src/core/web-chrome/bottom-row.ts +37 -0
  79. package/src/core/web-chrome/drop.ts +78 -0
  80. package/src/core/web-chrome/top-row.ts +66 -0
  81. package/src/core/zoom.ts +74 -0
  82. package/src/core.ts +2 -0
  83. package/src/diagram-js/connect.ts +75 -0
  84. package/src/diagram-js/index.ts +16 -0
  85. package/src/diagram-js/module.ts +20 -0
  86. package/src/diagram-js/palette-skin.ts +267 -0
  87. package/src/diagram-js/palette.css +269 -0
  88. package/src/diagram-js/service.ts +243 -0
  89. package/src/diagram-js/types.ts +67 -0
  90. package/src/diagram-js/viewport.ts +583 -0
  91. package/src/diagram-js.ts +2 -0
  92. package/src/dom/buttons.css +124 -0
  93. package/src/dom/element.ts +51 -0
  94. package/src/dom/feedback/appearance.ts +184 -0
  95. package/src/dom/feedback/feedback.css +435 -0
  96. package/src/dom/feedback/problems-popover.ts +287 -0
  97. package/src/dom/feedback/toasts.ts +431 -0
  98. package/src/dom/hint.ts +51 -0
  99. package/src/dom/icons.ts +309 -0
  100. package/src/dom/index.ts +42 -0
  101. package/src/dom/inspector.ts +35 -0
  102. package/src/dom/keys.ts +67 -0
  103. package/src/dom/ledger.ts +87 -0
  104. package/src/dom/legend.ts +85 -0
  105. package/src/dom/menu.ts +404 -0
  106. package/src/dom/mount.ts +731 -0
  107. package/src/dom/problems.ts +73 -0
  108. package/src/dom/shell-dom.css +969 -0
  109. package/src/dom/status.ts +72 -0
  110. package/src/dom/tooltip.ts +237 -0
  111. package/src/dom/types.ts +459 -0
  112. package/src/dom/web/drop-zone.ts +181 -0
  113. package/src/dom/web/empty-state.ts +144 -0
  114. package/src/dom/web/legal.ts +75 -0
  115. package/src/dom/web/menu-groups.ts +69 -0
  116. package/src/dom/web/primary.ts +124 -0
  117. package/src/dom/web/web.css +386 -0
  118. package/src/dom/zoom-panel.ts +154 -0
  119. package/src/index.ts +3 -0
  120. package/src/shell.css +9 -0
  121. package/src/testing/case-tools.ts +164 -0
  122. package/src/testing/cases.ts +1077 -0
  123. package/src/testing/checks.ts +868 -0
  124. package/src/testing/facts.ts +641 -0
  125. package/src/testing/geometry.ts +652 -0
  126. package/src/testing/harness.ts +187 -0
  127. package/src/testing/index.ts +19 -0
  128. package/src/testing/page-tools.ts +457 -0
  129. package/src/testing/page.ts +27 -0
  130. package/src/testing/vscode-stub.ts +237 -0
  131. package/src/testing/web-cases.ts +913 -0
  132. package/src/testing/web-checks.ts +1049 -0
  133. package/src/testing/web-facts.ts +713 -0
  134. package/src/testing-vscode-stub.ts +2 -0
  135. package/src/testing.ts +2 -0
  136. package/src/vscode/extension/html.ts +107 -0
  137. package/src/vscode/extension/index.ts +8 -0
  138. package/src/vscode/extension/reveal.ts +9 -0
  139. package/src/vscode/extension/theme-bridge.ts +85 -0
  140. package/src/vscode/extension/types.ts +36 -0
  141. package/src/vscode/protocol.ts +31 -0
  142. package/src/vscode/webview/appearance.ts +141 -0
  143. package/src/vscode/webview/index.ts +8 -0
  144. package/src/vscode/webview/mount.ts +88 -0
  145. package/src/vscode/webview/state.ts +116 -0
  146. package/src/vscode-extension.ts +2 -0
  147. package/src/vscode-webview.ts +2 -0
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/testing-vscode-stub.ts
21
+ var testing_vscode_stub_exports = {};
22
+ __export(testing_vscode_stub_exports, {
23
+ STUB_SETTING_KEY: () => STUB_SETTING_KEY,
24
+ colorThemeKindOf: () => colorThemeKindOf,
25
+ installVsCodeWebviewStub: () => installVsCodeWebviewStub,
26
+ stubOptionsFromSearch: () => stubOptionsFromSearch
27
+ });
28
+ module.exports = __toCommonJS(testing_vscode_stub_exports);
29
+
30
+ // src/core/appearance.ts
31
+ function resolveAppearance(requested, themes) {
32
+ const [fallback] = themes;
33
+ if (fallback === void 0) {
34
+ throw new Error(
35
+ "@miragon/modeler-shell: resolveAppearance needs at least one theme the modeler can show"
36
+ );
37
+ }
38
+ const theme = themes.includes(requested.theme) ? requested.theme : fallback;
39
+ return withKontrast(theme, requested.kontrast);
40
+ }
41
+ function withKontrast(theme, kontrast) {
42
+ return kontrast === "hoch" ? { theme, kontrast } : { theme };
43
+ }
44
+ function appearanceFromColorThemeKind(kind) {
45
+ switch (kind) {
46
+ case 2:
47
+ return { theme: "dark" };
48
+ case 3:
49
+ return { theme: "dark", kontrast: "hoch" };
50
+ case 4:
51
+ return { theme: "light", kontrast: "hoch" };
52
+ default:
53
+ return { theme: "light" };
54
+ }
55
+ }
56
+ function requestedAppearance(kind, setting) {
57
+ const fromKind = appearanceFromColorThemeKind(kind);
58
+ const theme = setting === "light" || setting === "dark" ? setting : fromKind.theme;
59
+ return withKontrast(theme, fromKind.kontrast);
60
+ }
61
+ function appearanceAttributes(appearance) {
62
+ return appearance.kontrast === "hoch" ? { "data-cd-theme": appearance.theme, "data-cd-kontrast": "hoch" } : { "data-cd-theme": appearance.theme };
63
+ }
64
+
65
+ // src/vscode/extension/html.ts
66
+ var NONCE_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
67
+ var NONCE_LENGTH = 32;
68
+ var UNBIASED_BYTE_LIMIT = 256 - 256 % NONCE_ALPHABET.length;
69
+ var CSP_NONCE = /^[A-Za-z0-9+/_-]+={0,2}$/;
70
+ var DEFAULT_BODY = '<div id="app"></div>';
71
+ function createNonce() {
72
+ let nonce = "";
73
+ while (nonce.length < NONCE_LENGTH) {
74
+ for (const byte of crypto.getRandomValues(new Uint8Array(NONCE_LENGTH))) {
75
+ if (byte < UNBIASED_BYTE_LIMIT && nonce.length < NONCE_LENGTH) {
76
+ nonce += NONCE_ALPHABET.charAt(byte % NONCE_ALPHABET.length);
77
+ }
78
+ }
79
+ }
80
+ return nonce;
81
+ }
82
+ function escapeHtml(value) {
83
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
84
+ }
85
+ function attribute(name, value) {
86
+ return `${name}="${escapeHtml(value)}"`;
87
+ }
88
+ function contentSecurityPolicy(cspSource, nonce, inlineStyles) {
89
+ return [
90
+ "default-src 'none'",
91
+ `img-src ${cspSource} data: blob:`,
92
+ inlineStyles ? `style-src ${cspSource} 'unsafe-inline'` : `style-src ${cspSource}`,
93
+ `font-src ${cspSource} data:`,
94
+ `script-src 'nonce-${nonce}'`
95
+ ].join("; ");
96
+ }
97
+ function renderWebviewHtml(options) {
98
+ const nonce = options.nonce ?? createNonce();
99
+ if (!CSP_NONCE.test(nonce)) {
100
+ throw new Error(`@miragon/modeler-shell: renderWebviewHtml got an invalid nonce "${nonce}"`);
101
+ }
102
+ const appearance = appearanceAttributes(options.appearance);
103
+ const kontrast = appearance["data-cd-kontrast"];
104
+ const htmlAttributes = [
105
+ attribute("lang", options.lang),
106
+ attribute("class", "cd-shell-document"),
107
+ attribute("data-cd-theme", appearance["data-cd-theme"]),
108
+ ...kontrast ? [attribute("data-cd-kontrast", kontrast)] : []
109
+ ].join(" ");
110
+ const stylesheets = (options.styleUris ?? []).map(
111
+ (uri) => `
112
+ <link ${attribute("rel", "stylesheet")} ${attribute("href", uri)} />`
113
+ );
114
+ return `<!doctype html>
115
+ <html ${htmlAttributes}>
116
+ <head>
117
+ <meta charset="UTF-8" />
118
+ <meta http-equiv="Content-Security-Policy" ${attribute("content", contentSecurityPolicy(options.cspSource, nonce, options.inlineStyles !== false))} />
119
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />${stylesheets.join("")}
120
+ <title>${escapeHtml(options.title)}</title>
121
+ </head>
122
+ <body>
123
+ ${options.body ?? DEFAULT_BODY}
124
+ <script ${attribute("nonce", nonce)} ${attribute("src", options.scriptUri)}></script>
125
+ </body>
126
+ </html>
127
+ `;
128
+ }
129
+
130
+ // src/vscode/protocol.ts
131
+ var APPEARANCE_MESSAGE_TYPE = "modelerShell.appearance";
132
+ function appearanceMessage(appearance) {
133
+ return {
134
+ type: APPEARANCE_MESSAGE_TYPE,
135
+ appearance: appearance.kontrast ? { theme: appearance.theme, kontrast: appearance.kontrast } : { theme: appearance.theme }
136
+ };
137
+ }
138
+
139
+ // src/vscode/extension/theme-bridge.ts
140
+ function isColorThemeSetting(value) {
141
+ return value === "automatic" || value === "light" || value === "dark";
142
+ }
143
+ function readColorThemeSetting(vscode, settingKey) {
144
+ const separator = settingKey.lastIndexOf(".");
145
+ const value = separator < 0 ? vscode.workspace.getConfiguration().get(settingKey) : vscode.workspace.getConfiguration(settingKey.slice(0, separator)).get(settingKey.slice(separator + 1));
146
+ return isColorThemeSetting(value) ? value : void 0;
147
+ }
148
+ function currentAppearance(vscode, options) {
149
+ const setting = options.settingKey ? readColorThemeSetting(vscode, options.settingKey) : void 0;
150
+ return resolveAppearance(requestedAppearance(vscode.window.activeColorTheme.kind, setting), options.themes);
151
+ }
152
+ function connectThemeBridge(vscode, panel, options) {
153
+ if (options.themes.length === 0) {
154
+ throw new Error("@miragon/modeler-shell: connectThemeBridge needs at least one theme");
155
+ }
156
+ const { settingKey } = options;
157
+ const post = () => {
158
+ void panel.webview.postMessage(appearanceMessage(currentAppearance(vscode, options)));
159
+ };
160
+ let wasVisible = panel.visible;
161
+ const subscriptions = [
162
+ vscode.window.onDidChangeActiveColorTheme(post),
163
+ panel.onDidChangeViewState(({ webviewPanel }) => {
164
+ const becameVisible = webviewPanel.visible && !wasVisible;
165
+ wasVisible = webviewPanel.visible;
166
+ if (becameVisible) post();
167
+ })
168
+ ];
169
+ if (settingKey) {
170
+ subscriptions.push(
171
+ vscode.workspace.onDidChangeConfiguration((event) => {
172
+ if (event.affectsConfiguration(settingKey)) post();
173
+ })
174
+ );
175
+ }
176
+ let disposed = false;
177
+ const dispose = () => {
178
+ if (disposed) return;
179
+ disposed = true;
180
+ for (const subscription of subscriptions.splice(0)) subscription.dispose();
181
+ };
182
+ subscriptions.push(panel.onDidDispose(dispose));
183
+ return { dispose };
184
+ }
185
+
186
+ // src/testing/vscode-stub.ts
187
+ var BODY_CLASSES = {
188
+ 1: ["vscode-light"],
189
+ 2: ["vscode-dark"],
190
+ 3: ["vscode-high-contrast"],
191
+ 4: ["vscode-high-contrast-light", "vscode-high-contrast"]
192
+ };
193
+ var ALL_BODY_CLASSES = Object.values(BODY_CLASSES).flat();
194
+ var REDUCE_MOTION_BODY_CLASS = "vscode-reduce-motion";
195
+ var VSCODE_DEFAULT_STYLES = `@layer vscode-default {
196
+ body { margin: 0; padding: 0 20px; color: currentColor; font-family: serif; font-size: 17px; }
197
+ kbd { box-shadow: inset 0 -1px 0 currentColor; vertical-align: middle; padding: 1px 3px; border-radius: 3px; font-family: serif; }
198
+ code { font-family: serif; padding: 1px 3px; border-radius: 4px; }
199
+ a:focus, input:focus, select:focus, textarea:focus { outline: 1px solid -webkit-focus-ring-color; outline-offset: -1px; }
200
+ }`;
201
+ var STUB_SETTING_KEY = "miragon.modeler.colorTheme";
202
+ function colorThemeKindOf(appearance) {
203
+ if (appearance.kontrast) return appearance.theme === "dark" ? 3 : 4;
204
+ return appearance.theme === "dark" ? 2 : 1;
205
+ }
206
+ function stubOptionsFromSearch(search) {
207
+ const params = new URLSearchParams(search);
208
+ const theme = params.get("theme") === "dark" ? "dark" : "light";
209
+ const setting = params.get("colorTheme");
210
+ return {
211
+ requested: params.get("kontrast") === "hoch" ? { theme, kontrast: "hoch" } : { theme },
212
+ colorTheme: setting === "automatic" || setting === "light" || setting === "dark" ? setting : void 0,
213
+ reduceMotion: params.has("reduceMotion")
214
+ };
215
+ }
216
+ function installVsCodeWebviewStub(options) {
217
+ const settingKey = options.settingKey ?? STUB_SETTING_KEY;
218
+ const scope = window;
219
+ let kind = colorThemeKindOf(options.requested);
220
+ let setting = options.colorTheme;
221
+ const themeListeners = /* @__PURE__ */ new Set();
222
+ const configurationListeners = /* @__PURE__ */ new Set();
223
+ const vscode = {
224
+ window: {
225
+ get activeColorTheme() {
226
+ return { kind };
227
+ },
228
+ onDidChangeActiveColorTheme(listener) {
229
+ themeListeners.add(listener);
230
+ return { dispose: () => themeListeners.delete(listener) };
231
+ }
232
+ },
233
+ workspace: {
234
+ getConfiguration: (section) => ({
235
+ get: (key) => (section ? `${section}.${key}` : key) === settingKey ? setting : void 0
236
+ }),
237
+ onDidChangeConfiguration(listener) {
238
+ configurationListeners.add(listener);
239
+ return { dispose: () => configurationListeners.delete(listener) };
240
+ }
241
+ }
242
+ };
243
+ const none = { dispose: () => void 0 };
244
+ let posted = 0;
245
+ let delivered = 0;
246
+ window.addEventListener("message", () => delivered++);
247
+ const panel = {
248
+ webview: {
249
+ postMessage(message) {
250
+ posted++;
251
+ window.postMessage(message, "*");
252
+ }
253
+ },
254
+ visible: true,
255
+ onDidChangeViewState: () => none,
256
+ onDidDispose: () => none
257
+ };
258
+ const bridgeOptions = { themes: options.themes, settingKey };
259
+ const defaults = document.createElement("style");
260
+ defaults.id = "_defaultStyles";
261
+ defaults.textContent = VSCODE_DEFAULT_STYLES;
262
+ document.head.prepend(defaults);
263
+ const html = new DOMParser().parseFromString(
264
+ renderWebviewHtml({
265
+ cspSource: window.location.origin,
266
+ scriptUri: "webview.js",
267
+ title: document.title,
268
+ lang: options.lang ?? "en",
269
+ appearance: currentAppearance(vscode, bridgeOptions)
270
+ }),
271
+ "text/html"
272
+ ).documentElement;
273
+ for (const name of html.getAttributeNames()) {
274
+ if (name === "class") document.documentElement.classList.add(...html.classList);
275
+ else document.documentElement.setAttribute(name, html.getAttribute(name) ?? "");
276
+ }
277
+ const setBodyClasses = (next) => {
278
+ document.body.classList.remove(...ALL_BODY_CLASSES);
279
+ document.body.classList.add(...BODY_CLASSES[next]);
280
+ };
281
+ setBodyClasses(kind);
282
+ document.body.classList.toggle(REDUCE_MOTION_BODY_CLASS, options.reduceMotion === true);
283
+ connectThemeBridge(vscode, panel, bridgeOptions);
284
+ let state = options.state;
285
+ const sent = [];
286
+ let acquired = false;
287
+ scope.acquireVsCodeApi = () => {
288
+ if (acquired) throw new Error("An instance of the VS Code API has already been acquired");
289
+ acquired = true;
290
+ return {
291
+ getState: () => state,
292
+ setState(next) {
293
+ state = next;
294
+ },
295
+ postMessage(message) {
296
+ sent.push(message);
297
+ }
298
+ };
299
+ };
300
+ const stub = {
301
+ get kind() {
302
+ return kind;
303
+ },
304
+ setColorThemeKind(next) {
305
+ kind = next;
306
+ setBodyClasses(next);
307
+ for (const listener of [...themeListeners]) listener({ kind: next });
308
+ },
309
+ setColorTheme(next) {
310
+ setting = next;
311
+ for (const listener of [...configurationListeners]) {
312
+ listener({ affectsConfiguration: (section) => settingKey.startsWith(section) });
313
+ }
314
+ },
315
+ setReduceMotion(reduceMotion) {
316
+ document.body.classList.toggle(REDUCE_MOTION_BODY_CLASS, reduceMotion);
317
+ },
318
+ pendingMessages: () => posted - delivered,
319
+ posted: sent,
320
+ state: () => state
321
+ };
322
+ scope.__modelerShellVsCodeStub = stub;
323
+ return stub;
324
+ }
325
+ // Annotate the CommonJS export names for ESM import in node:
326
+ 0 && (module.exports = {
327
+ STUB_SETTING_KEY,
328
+ colorThemeKindOf,
329
+ installVsCodeWebviewStub,
330
+ stubOptionsFromSearch
331
+ });
332
+ //# sourceMappingURL=testing-vscode-stub.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing-vscode-stub.ts","../src/core/appearance.ts","../src/vscode/extension/html.ts","../src/vscode/protocol.ts","../src/vscode/extension/theme-bridge.ts","../src/testing/vscode-stub.ts"],"sourcesContent":["// \"@miragon/modeler-shell/testing/vscode-stub\": a stand-in for VS Code around a webview test page.\nexport * from \"./testing/vscode-stub.js\";\n","/** The modes a Miragon modeler can show (guide §13.3). */\nexport type Theme = \"light\" | \"dark\";\n\n/** High contrast; written as `data-cd-kontrast=\"hoch\"` on the same element as `data-cd-theme`. */\nexport type Kontrast = \"hoch\";\n\nexport interface Appearance {\n theme: Theme;\n kontrast?: Kontrast | undefined;\n}\n\n/**\n * The one appearance decision of guide §13.5: a theme the modeler cannot show is never shown\n * (`themes[0]` wins, so `[\"light\"]` stays light whatever the host requests); `kontrast` always\n * passes through. Throws when `themes` is empty.\n */\nexport function resolveAppearance(requested: Appearance, themes: readonly Theme[]): Appearance {\n const [fallback] = themes;\n if (fallback === undefined) {\n throw new Error(\n \"@miragon/modeler-shell: resolveAppearance needs at least one theme the modeler can show\",\n );\n }\n const theme = themes.includes(requested.theme) ? requested.theme : fallback;\n return withKontrast(theme, requested.kontrast);\n}\n\n// Appearances arrive through postMessage and settings, so only the one known value passes.\nfunction withKontrast(theme: Theme, kontrast: unknown): Appearance {\n return kontrast === \"hoch\" ? { theme, kontrast } : { theme };\n}\n\n/**\n * The appearance VS Code requests for `vscode.window.activeColorTheme.kind`:\n * 1 Light → light, 2 Dark → dark, 3 HighContrast → dark + hoch, 4 HighContrastLight → light + hoch;\n * any other value → light.\n */\nexport function appearanceFromColorThemeKind(kind: number): Appearance {\n switch (kind) {\n case 2:\n return { theme: \"dark\" };\n case 3:\n return { theme: \"dark\", kontrast: \"hoch\" };\n case 4:\n return { theme: \"light\", kontrast: \"hoch\" };\n default:\n return { theme: \"light\" };\n }\n}\n\n/** The values of the setting `miragon.<modeler>.colorTheme` (it ships once a modeler can show dark). */\nexport type ColorThemeSetting = \"automatic\" | \"light\" | \"dark\";\n\n/**\n * The requested appearance in an IDE host: the setting's theme unless it is `automatic` (or\n * missing), the contrast always from the color theme kind.\n */\nexport function requestedAppearance(kind: number, setting?: ColorThemeSetting | undefined): Appearance {\n const fromKind = appearanceFromColorThemeKind(kind);\n const theme = setting === \"light\" || setting === \"dark\" ? setting : fromKind.theme;\n return withKontrast(theme, fromKind.kontrast);\n}\n\n/**\n * The fallback signal inside a VS Code webview: the body classes `vscode-high-contrast-light`\n * (checked first, VS Code adds `vscode-high-contrast` to it as well), `vscode-high-contrast`,\n * `vscode-dark`, `vscode-light`. `undefined` when none is set. Never use them for styling.\n */\nexport function appearanceFromBodyClasses(classes: Iterable<string>): Appearance | undefined {\n const present = new Set(classes);\n if (present.has(\"vscode-high-contrast-light\")) return { theme: \"light\", kontrast: \"hoch\" };\n if (present.has(\"vscode-high-contrast\")) return { theme: \"dark\", kontrast: \"hoch\" };\n if (present.has(\"vscode-dark\")) return { theme: \"dark\" };\n if (present.has(\"vscode-light\")) return { theme: \"light\" };\n return undefined;\n}\n\n/**\n * VS Code's `workbench.reduceMotion` as the webview sees it: the body class `vscode-reduce-motion`\n * (the webview host page sets it). Never use it for styling; the shell mirrors it as\n * `REDUCED_MOTION_CLASS` on `<html>`.\n */\nexport function reducedMotionFromBodyClasses(classes: Iterable<string>): boolean {\n return new Set(classes).has(\"vscode-reduce-motion\");\n}\n\n/**\n * On `<html>` while the host asks for reduced motion although the OS does not (VS Code's\n * `workbench.reduceMotion`): the shell's animations stop as under `prefers-reduced-motion`, and an\n * explicit fit jumps.\n */\nexport const REDUCED_MOTION_CLASS = \"cd-shell-reduce-motion\";\n\nexport interface AppearanceAttributes {\n \"data-cd-theme\": Theme;\n \"data-cd-kontrast\"?: Kontrast;\n}\n\n/** The attributes for `<html>` (own document) or the modeler container (foreign page). */\nexport function appearanceAttributes(appearance: Appearance): AppearanceAttributes {\n return appearance.kontrast === \"hoch\"\n ? { \"data-cd-theme\": appearance.theme, \"data-cd-kontrast\": \"hoch\" }\n : { \"data-cd-theme\": appearance.theme };\n}\n","import { appearanceAttributes, type Appearance } from \"../../core/index.js\";\n\nexport interface WebviewHtmlOptions {\n /** `webview.cspSource` */\n cspSource: string;\n /** The bundle, `webview.asWebviewUri(…).toString()`. */\n scriptUri: string;\n /** Stylesheets in load order (token CSS first, see API.md). */\n styleUris?: readonly string[] | undefined;\n /** `<title>` */\n title: string;\n /** The tool's UI language for `<html lang>`; English modelers pass `\"en\"`. */\n lang: string;\n /** Resolved appearance (`currentAppearance`), written before the first paint. */\n appearance: Appearance;\n /** Markup inside `<body>` before the script; default `<div id=\"app\"></div>`. */\n body?: string | undefined;\n /** Script nonce; default `createNonce()`. */\n nonce?: string | undefined;\n /**\n * Allow inline styles (`style-src … 'unsafe-inline'`), default `true`: renderers write `style`\n * attributes into markup (palette entries, SVG strings). The shell and diagram-js themselves\n * only style through the CSSOM and run without it; pass `false` once the renderer does too.\n */\n inlineStyles?: boolean | undefined;\n}\n\nconst NONCE_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst NONCE_LENGTH = 32;\n/** Bytes at or above this limit are rejected, so every character is equally likely. */\nconst UNBIASED_BYTE_LIMIT = 256 - (256 % NONCE_ALPHABET.length);\n/** The `base64-value` of a CSP `nonce-source`. */\nconst CSP_NONCE = /^[A-Za-z0-9+/_-]+={0,2}$/;\n\nconst DEFAULT_BODY = '<div id=\"app\"></div>';\n\n/** 32 characters `[A-Za-z0-9]` from `crypto.getRandomValues`. */\nexport function createNonce(): string {\n let nonce = \"\";\n while (nonce.length < NONCE_LENGTH) {\n for (const byte of crypto.getRandomValues(new Uint8Array(NONCE_LENGTH))) {\n if (byte < UNBIASED_BYTE_LIMIT && nonce.length < NONCE_LENGTH) {\n nonce += NONCE_ALPHABET.charAt(byte % NONCE_ALPHABET.length);\n }\n }\n }\n return nonce;\n}\n\nfunction escapeHtml(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n}\n\nfunction attribute(name: string, value: string): string {\n return `${name}=\"${escapeHtml(value)}\"`;\n}\n\nfunction contentSecurityPolicy(cspSource: string, nonce: string, inlineStyles: boolean): string {\n return [\n \"default-src 'none'\",\n `img-src ${cspSource} data: blob:`,\n inlineStyles ? `style-src ${cspSource} 'unsafe-inline'` : `style-src ${cspSource}`,\n `font-src ${cspSource} data:`,\n `script-src 'nonce-${nonce}'`,\n ].join(\"; \");\n}\n\n/**\n * The webview document: `<html lang class=\"cd-shell-document\" data-cd-theme [data-cd-kontrast]>`,\n * the CSP (`default-src 'none'`, `img-src <cspSource> data: blob:`, `style-src <cspSource>` plus\n * `'unsafe-inline'` unless `inlineStyles: false`, `font-src <cspSource> data:`,\n * `script-src 'nonce-…'`), the stylesheets, `body` and the nonce'd script. Attribute values and the\n * title are escaped; `body` is markup and is not. Throws for a `nonce` that is not a CSP base64\n * value.\n */\nexport function renderWebviewHtml(options: WebviewHtmlOptions): string {\n const nonce = options.nonce ?? createNonce();\n if (!CSP_NONCE.test(nonce)) {\n throw new Error(`@miragon/modeler-shell: renderWebviewHtml got an invalid nonce \"${nonce}\"`);\n }\n const appearance = appearanceAttributes(options.appearance);\n const kontrast = appearance[\"data-cd-kontrast\"];\n const htmlAttributes = [\n attribute(\"lang\", options.lang),\n attribute(\"class\", \"cd-shell-document\"),\n attribute(\"data-cd-theme\", appearance[\"data-cd-theme\"]),\n ...(kontrast ? [attribute(\"data-cd-kontrast\", kontrast)] : []),\n ].join(\" \");\n const stylesheets = (options.styleUris ?? []).map(\n (uri) => `\\n <link ${attribute(\"rel\", \"stylesheet\")} ${attribute(\"href\", uri)} />`,\n );\n\n return `<!doctype html>\n<html ${htmlAttributes}>\n <head>\n <meta charset=\"UTF-8\" />\n <meta http-equiv=\"Content-Security-Policy\" ${attribute(\"content\", contentSecurityPolicy(options.cspSource, nonce, options.inlineStyles !== false))} />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />${stylesheets.join(\"\")}\n <title>${escapeHtml(options.title)}</title>\n </head>\n <body>\n ${options.body ?? DEFAULT_BODY}\n <script ${attribute(\"nonce\", nonce)} ${attribute(\"src\", options.scriptUri)}></script>\n </body>\n</html>\n`;\n}\n","import type { Appearance } from \"../core/index.js\";\n\n/** The one message the theme bridge posts to the webview. */\nexport const APPEARANCE_MESSAGE_TYPE = \"modelerShell.appearance\";\n\nexport interface AppearanceMessage {\n type: typeof APPEARANCE_MESSAGE_TYPE;\n /** Already resolved against the modeler's themes. */\n appearance: Appearance;\n}\n\n/** A plain, JSON-safe message (no `kontrast: undefined` key). */\nexport function appearanceMessage(appearance: Appearance): AppearanceMessage {\n return {\n type: APPEARANCE_MESSAGE_TYPE,\n appearance: appearance.kontrast\n ? { theme: appearance.theme, kontrast: appearance.kontrast }\n : { theme: appearance.theme },\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Type guard for `MessageEvent.data` in the webview. */\nexport function isAppearanceMessage(value: unknown): value is AppearanceMessage {\n if (!isRecord(value) || value.type !== APPEARANCE_MESSAGE_TYPE || !isRecord(value.appearance)) return false;\n const { theme, kontrast } = value.appearance;\n return (theme === \"light\" || theme === \"dark\") && (kontrast === undefined || kontrast === \"hoch\");\n}\n","import {\n requestedAppearance,\n resolveAppearance,\n type Appearance,\n type ColorThemeSetting,\n type Theme,\n} from \"../../core/index.js\";\nimport { appearanceMessage } from \"../protocol.js\";\nimport type { DisposableLike, VsCodeLike, WebviewPanelLike } from \"./types.js\";\n\nexport interface ThemeBridgeOptions {\n /** The modes the modeler can show, a static value of the modeler package (`[\"light\"]` today). */\n themes: readonly Theme[];\n /** Full key of `miragon.<modeler>.colorTheme`; omit until the modeler can show dark. */\n settingKey?: string | undefined;\n}\n\nfunction isColorThemeSetting(value: unknown): value is ColorThemeSetting {\n return value === \"automatic\" || value === \"light\" || value === \"dark\";\n}\n\nfunction readColorThemeSetting(vscode: VsCodeLike, settingKey: string): ColorThemeSetting | undefined {\n const separator = settingKey.lastIndexOf(\".\");\n const value =\n separator < 0\n ? vscode.workspace.getConfiguration().get<unknown>(settingKey)\n : vscode.workspace\n .getConfiguration(settingKey.slice(0, separator))\n .get<unknown>(settingKey.slice(separator + 1));\n return isColorThemeSetting(value) ? value : undefined;\n}\n\n/**\n * The resolved appearance right now: color theme kind (and setting) through `resolveAppearance`.\n * A setting value outside `automatic | light | dark` counts as `automatic`.\n */\nexport function currentAppearance(vscode: VsCodeLike, options: ThemeBridgeOptions): Appearance {\n const setting = options.settingKey ? readColorThemeSetting(vscode, options.settingKey) : undefined;\n return resolveAppearance(requestedAppearance(vscode.window.activeColorTheme.kind, setting), options.themes);\n}\n\n/**\n * Posts an `AppearanceMessage` to the panel's webview on `onDidChangeActiveColorTheme`, on a change\n * of `settingKey` and whenever the panel becomes visible again (hidden retained webviews may miss\n * messages). Disposes itself with the panel. Throws when `themes` is empty.\n */\nexport function connectThemeBridge(\n vscode: VsCodeLike,\n panel: WebviewPanelLike,\n options: ThemeBridgeOptions,\n): DisposableLike {\n if (options.themes.length === 0) {\n throw new Error(\"@miragon/modeler-shell: connectThemeBridge needs at least one theme\");\n }\n const { settingKey } = options;\n const post = (): void => {\n void panel.webview.postMessage(appearanceMessage(currentAppearance(vscode, options)));\n };\n\n let wasVisible = panel.visible;\n const subscriptions: DisposableLike[] = [\n vscode.window.onDidChangeActiveColorTheme(post),\n panel.onDidChangeViewState(({ webviewPanel }) => {\n const becameVisible = webviewPanel.visible && !wasVisible;\n wasVisible = webviewPanel.visible;\n if (becameVisible) post();\n }),\n ];\n if (settingKey) {\n subscriptions.push(\n vscode.workspace.onDidChangeConfiguration((event) => {\n if (event.affectsConfiguration(settingKey)) post();\n }),\n );\n }\n\n let disposed = false;\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n for (const subscription of subscriptions.splice(0)) subscription.dispose();\n };\n subscriptions.push(panel.onDidDispose(dispose));\n return { dispose };\n}\n","import type { Appearance, ColorThemeSetting, Theme } from \"../core/index.js\";\nimport {\n connectThemeBridge,\n currentAppearance,\n renderWebviewHtml,\n type ColorThemeLike,\n type DisposableLike,\n type VsCodeLike,\n type WebviewPanelLike,\n} from \"../vscode/extension/index.js\";\n\n/*\n * Runs in the page, in front of a modeler's webview bundle: a stand-in for the VS Code around it,\n * so a modeler's e2e suite runs the conformance kit for the `ide` host without VS Code.\n */\n\n/** `vscode.ColorThemeKind`: 1 Light, 2 Dark, 3 High Contrast, 4 High Contrast Light. */\nexport type ColorThemeKind = 1 | 2 | 3 | 4;\n\n/** The body classes VS Code's webview host page sets per color theme (High Contrast Light keeps both). */\nconst BODY_CLASSES: Readonly<Record<ColorThemeKind, readonly string[]>> = {\n 1: [\"vscode-light\"],\n 2: [\"vscode-dark\"],\n 3: [\"vscode-high-contrast\"],\n 4: [\"vscode-high-contrast-light\", \"vscode-high-contrast\"],\n};\nconst ALL_BODY_CLASSES = Object.values(BODY_CLASSES).flat();\nconst REDUCE_MOTION_BODY_CLASS = \"vscode-reduce-motion\";\n\n/**\n * The rules of VS Code's default webview stylesheet the shell's own-document reset must beat\n * (implementation notes, \"VS Code: host hygiene\"), with deliberately foreign values so a leak shows.\n */\nconst VSCODE_DEFAULT_STYLES = `@layer vscode-default {\n body { margin: 0; padding: 0 20px; color: currentColor; font-family: serif; font-size: 17px; }\n kbd { box-shadow: inset 0 -1px 0 currentColor; vertical-align: middle; padding: 1px 3px; border-radius: 3px; font-family: serif; }\n code { font-family: serif; padding: 1px 3px; border-radius: 4px; }\n a:focus, input:focus, select:focus, textarea:focus { outline: 1px solid -webkit-focus-ring-color; outline-offset: -1px; }\n}`;\n\n/** The default setting key the stub answers when `colorTheme` is given without one. */\nexport const STUB_SETTING_KEY = \"miragon.modeler.colorTheme\";\n\n/** The VS Code color theme that requests `appearance` (guide §13.3). */\nexport function colorThemeKindOf(appearance: Appearance): ColorThemeKind {\n if (appearance.kontrast) return appearance.theme === \"dark\" ? 3 : 4;\n return appearance.theme === \"dark\" ? 2 : 1;\n}\n\nexport interface VsCodeWebviewStubOptions {\n /** What VS Code requests: its color theme, as the appearance the kit asks for. */\n requested: Appearance;\n /** The modes the modeler declares (what its extension passes to the theme bridge). */\n themes: readonly Theme[];\n /** `<html lang>`; default `\"en\"`. */\n lang?: string | undefined;\n /** The value of the modeler's `colorTheme` setting (from its dark-mode release on). */\n colorTheme?: ColorThemeSetting | undefined;\n /** The full setting key the stub answers and the bridge listens to; default `STUB_SETTING_KEY`. */\n settingKey?: string | undefined;\n /** VS Code's `workbench.reduceMotion` (the body class `vscode-reduce-motion`). */\n reduceMotion?: boolean | undefined;\n /** What `getState()` of the stubbed `acquireVsCodeApi()` returns at first. */\n state?: unknown;\n}\n\n/** The stubbed `acquireVsCodeApi()`. */\nexport interface StubbedVsCodeApi {\n getState(): unknown;\n setState(state: unknown): void;\n postMessage(message: unknown): void;\n}\n\nexport interface VsCodeWebviewStub {\n readonly kind: ColorThemeKind;\n /** What VS Code does on a color theme change: body classes first, then the extension's bridge posts. */\n setColorThemeKind(kind: ColorThemeKind): void;\n /** Changes the `colorTheme` setting, as the user does in the settings editor. */\n setColorTheme(setting: ColorThemeSetting | undefined): void;\n setReduceMotion(reduceMotion: boolean): void;\n /** Messages the bridge posted that have not reached the window yet. */\n pendingMessages(): number;\n /** What the webview posted with `acquireVsCodeApi().postMessage`. */\n readonly posted: readonly unknown[];\n /** The webview state as the last `setState` left it. */\n state(): unknown;\n}\n\n/** The page globals the stub sets. */\nexport type StubWindow = Window & {\n /** The stub of `installVsCodeWebviewStub`, for a Playwright suite to drive. */\n __modelerShellVsCodeStub?: VsCodeWebviewStub;\n acquireVsCodeApi?: () => StubbedVsCodeApi;\n};\n\n/**\n * The stub's options from a query string (`theme`, `kontrast=hoch`, `colorTheme`, `reduceMotion`),\n * the counterpart of `vsCodeStubSearch` of `@miragon/modeler-shell/testing`.\n */\nexport function stubOptionsFromSearch(\n search: string,\n): Pick<VsCodeWebviewStubOptions, \"requested\" | \"colorTheme\" | \"reduceMotion\"> {\n const params = new URLSearchParams(search);\n const theme: Theme = params.get(\"theme\") === \"dark\" ? \"dark\" : \"light\";\n const setting = params.get(\"colorTheme\");\n return {\n requested: params.get(\"kontrast\") === \"hoch\" ? { theme, kontrast: \"hoch\" } : { theme },\n colorTheme: setting === \"automatic\" || setting === \"light\" || setting === \"dark\" ? setting : undefined,\n reduceMotion: params.has(\"reduceMotion\"),\n };\n}\n\n/**\n * Stands in for VS Code around the page: its default stylesheet in `@layer vscode-default`, `<html>`\n * with the attributes `renderWebviewHtml` writes before the first paint, `<body>` with the host\n * page's theme (and reduce-motion) classes, `acquireVsCodeApi()`, and the real `connectThemeBridge`\n * running against a fake `vscode` namespace whose panel posts to this window. Call it before the\n * modeler's webview code runs; also exposed as `window.__modelerShellVsCodeStub`.\n */\nexport function installVsCodeWebviewStub(options: VsCodeWebviewStubOptions): VsCodeWebviewStub {\n const settingKey = options.settingKey ?? STUB_SETTING_KEY;\n const scope = window as StubWindow;\n let kind = colorThemeKindOf(options.requested);\n let setting = options.colorTheme;\n const themeListeners = new Set<(theme: ColorThemeLike) => unknown>();\n const configurationListeners = new Set<\n (event: { affectsConfiguration(section: string): boolean }) => unknown\n >();\n const vscode: VsCodeLike = {\n window: {\n get activeColorTheme() {\n return { kind };\n },\n onDidChangeActiveColorTheme(listener) {\n themeListeners.add(listener);\n return { dispose: () => themeListeners.delete(listener) };\n },\n },\n workspace: {\n getConfiguration: (section?: string) => ({\n get: <T>(key: string): T | undefined =>\n (section ? `${section}.${key}` : key) === settingKey ? (setting as T | undefined) : undefined,\n }),\n onDidChangeConfiguration(listener) {\n configurationListeners.add(listener);\n return { dispose: () => configurationListeners.delete(listener) };\n },\n },\n };\n const none: DisposableLike = { dispose: () => undefined };\n let posted = 0;\n let delivered = 0;\n // Registered before the modeler's listeners, so it counts a message before the shell applies it.\n window.addEventListener(\"message\", () => delivered++);\n const panel: WebviewPanelLike = {\n webview: {\n postMessage(message) {\n posted++;\n window.postMessage(message, \"*\");\n },\n },\n visible: true,\n onDidChangeViewState: () => none,\n onDidDispose: () => none,\n };\n const bridgeOptions = { themes: options.themes, settingKey };\n\n const defaults = document.createElement(\"style\");\n defaults.id = \"_defaultStyles\";\n defaults.textContent = VSCODE_DEFAULT_STYLES;\n document.head.prepend(defaults);\n\n const html = new DOMParser().parseFromString(\n renderWebviewHtml({\n cspSource: window.location.origin,\n scriptUri: \"webview.js\",\n title: document.title,\n lang: options.lang ?? \"en\",\n appearance: currentAppearance(vscode, bridgeOptions),\n }),\n \"text/html\",\n ).documentElement;\n for (const name of html.getAttributeNames()) {\n if (name === \"class\") document.documentElement.classList.add(...html.classList);\n else document.documentElement.setAttribute(name, html.getAttribute(name) ?? \"\");\n }\n\n const setBodyClasses = (next: ColorThemeKind): void => {\n document.body.classList.remove(...ALL_BODY_CLASSES);\n document.body.classList.add(...BODY_CLASSES[next]);\n };\n setBodyClasses(kind);\n document.body.classList.toggle(REDUCE_MOTION_BODY_CLASS, options.reduceMotion === true);\n connectThemeBridge(vscode, panel, bridgeOptions);\n\n let state = options.state;\n const sent: unknown[] = [];\n let acquired = false;\n scope.acquireVsCodeApi = () => {\n if (acquired) throw new Error(\"An instance of the VS Code API has already been acquired\");\n acquired = true;\n return {\n getState: () => state,\n setState(next) {\n state = next;\n },\n postMessage(message) {\n sent.push(message);\n },\n };\n };\n\n const stub: VsCodeWebviewStub = {\n get kind() {\n return kind;\n },\n setColorThemeKind(next) {\n kind = next;\n setBodyClasses(next);\n for (const listener of [...themeListeners]) listener({ kind: next });\n },\n setColorTheme(next) {\n setting = next;\n for (const listener of [...configurationListeners]) {\n listener({ affectsConfiguration: (section) => settingKey.startsWith(section) });\n }\n },\n setReduceMotion(reduceMotion) {\n document.body.classList.toggle(REDUCE_MOTION_BODY_CLASS, reduceMotion);\n },\n pendingMessages: () => posted - delivered,\n posted: sent,\n state: () => state,\n };\n scope.__modelerShellVsCodeStub = stub;\n return stub;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,65 @@
1
+ import { C as ColorThemeSetting, A as Appearance, T as Theme } from './appearance-D3FUcbu6.cjs';
2
+
3
+ /** `vscode.ColorThemeKind`: 1 Light, 2 Dark, 3 High Contrast, 4 High Contrast Light. */
4
+ type ColorThemeKind = 1 | 2 | 3 | 4;
5
+ /** The default setting key the stub answers when `colorTheme` is given without one. */
6
+ declare const STUB_SETTING_KEY = "miragon.modeler.colorTheme";
7
+ /** The VS Code color theme that requests `appearance` (guide §13.3). */
8
+ declare function colorThemeKindOf(appearance: Appearance): ColorThemeKind;
9
+ interface VsCodeWebviewStubOptions {
10
+ /** What VS Code requests: its color theme, as the appearance the kit asks for. */
11
+ requested: Appearance;
12
+ /** The modes the modeler declares (what its extension passes to the theme bridge). */
13
+ themes: readonly Theme[];
14
+ /** `<html lang>`; default `"en"`. */
15
+ lang?: string | undefined;
16
+ /** The value of the modeler's `colorTheme` setting (from its dark-mode release on). */
17
+ colorTheme?: ColorThemeSetting | undefined;
18
+ /** The full setting key the stub answers and the bridge listens to; default `STUB_SETTING_KEY`. */
19
+ settingKey?: string | undefined;
20
+ /** VS Code's `workbench.reduceMotion` (the body class `vscode-reduce-motion`). */
21
+ reduceMotion?: boolean | undefined;
22
+ /** What `getState()` of the stubbed `acquireVsCodeApi()` returns at first. */
23
+ state?: unknown;
24
+ }
25
+ /** The stubbed `acquireVsCodeApi()`. */
26
+ interface StubbedVsCodeApi {
27
+ getState(): unknown;
28
+ setState(state: unknown): void;
29
+ postMessage(message: unknown): void;
30
+ }
31
+ interface VsCodeWebviewStub {
32
+ readonly kind: ColorThemeKind;
33
+ /** What VS Code does on a color theme change: body classes first, then the extension's bridge posts. */
34
+ setColorThemeKind(kind: ColorThemeKind): void;
35
+ /** Changes the `colorTheme` setting, as the user does in the settings editor. */
36
+ setColorTheme(setting: ColorThemeSetting | undefined): void;
37
+ setReduceMotion(reduceMotion: boolean): void;
38
+ /** Messages the bridge posted that have not reached the window yet. */
39
+ pendingMessages(): number;
40
+ /** What the webview posted with `acquireVsCodeApi().postMessage`. */
41
+ readonly posted: readonly unknown[];
42
+ /** The webview state as the last `setState` left it. */
43
+ state(): unknown;
44
+ }
45
+ /** The page globals the stub sets. */
46
+ type StubWindow = Window & {
47
+ /** The stub of `installVsCodeWebviewStub`, for a Playwright suite to drive. */
48
+ __modelerShellVsCodeStub?: VsCodeWebviewStub;
49
+ acquireVsCodeApi?: () => StubbedVsCodeApi;
50
+ };
51
+ /**
52
+ * The stub's options from a query string (`theme`, `kontrast=hoch`, `colorTheme`, `reduceMotion`),
53
+ * the counterpart of `vsCodeStubSearch` of `@miragon/modeler-shell/testing`.
54
+ */
55
+ declare function stubOptionsFromSearch(search: string): Pick<VsCodeWebviewStubOptions, "requested" | "colorTheme" | "reduceMotion">;
56
+ /**
57
+ * Stands in for VS Code around the page: its default stylesheet in `@layer vscode-default`, `<html>`
58
+ * with the attributes `renderWebviewHtml` writes before the first paint, `<body>` with the host
59
+ * page's theme (and reduce-motion) classes, `acquireVsCodeApi()`, and the real `connectThemeBridge`
60
+ * running against a fake `vscode` namespace whose panel posts to this window. Call it before the
61
+ * modeler's webview code runs; also exposed as `window.__modelerShellVsCodeStub`.
62
+ */
63
+ declare function installVsCodeWebviewStub(options: VsCodeWebviewStubOptions): VsCodeWebviewStub;
64
+
65
+ export { type ColorThemeKind, STUB_SETTING_KEY, type StubWindow, type StubbedVsCodeApi, type VsCodeWebviewStub, type VsCodeWebviewStubOptions, colorThemeKindOf, installVsCodeWebviewStub, stubOptionsFromSearch };
@@ -0,0 +1,65 @@
1
+ import { C as ColorThemeSetting, A as Appearance, T as Theme } from './appearance-D3FUcbu6.js';
2
+
3
+ /** `vscode.ColorThemeKind`: 1 Light, 2 Dark, 3 High Contrast, 4 High Contrast Light. */
4
+ type ColorThemeKind = 1 | 2 | 3 | 4;
5
+ /** The default setting key the stub answers when `colorTheme` is given without one. */
6
+ declare const STUB_SETTING_KEY = "miragon.modeler.colorTheme";
7
+ /** The VS Code color theme that requests `appearance` (guide §13.3). */
8
+ declare function colorThemeKindOf(appearance: Appearance): ColorThemeKind;
9
+ interface VsCodeWebviewStubOptions {
10
+ /** What VS Code requests: its color theme, as the appearance the kit asks for. */
11
+ requested: Appearance;
12
+ /** The modes the modeler declares (what its extension passes to the theme bridge). */
13
+ themes: readonly Theme[];
14
+ /** `<html lang>`; default `"en"`. */
15
+ lang?: string | undefined;
16
+ /** The value of the modeler's `colorTheme` setting (from its dark-mode release on). */
17
+ colorTheme?: ColorThemeSetting | undefined;
18
+ /** The full setting key the stub answers and the bridge listens to; default `STUB_SETTING_KEY`. */
19
+ settingKey?: string | undefined;
20
+ /** VS Code's `workbench.reduceMotion` (the body class `vscode-reduce-motion`). */
21
+ reduceMotion?: boolean | undefined;
22
+ /** What `getState()` of the stubbed `acquireVsCodeApi()` returns at first. */
23
+ state?: unknown;
24
+ }
25
+ /** The stubbed `acquireVsCodeApi()`. */
26
+ interface StubbedVsCodeApi {
27
+ getState(): unknown;
28
+ setState(state: unknown): void;
29
+ postMessage(message: unknown): void;
30
+ }
31
+ interface VsCodeWebviewStub {
32
+ readonly kind: ColorThemeKind;
33
+ /** What VS Code does on a color theme change: body classes first, then the extension's bridge posts. */
34
+ setColorThemeKind(kind: ColorThemeKind): void;
35
+ /** Changes the `colorTheme` setting, as the user does in the settings editor. */
36
+ setColorTheme(setting: ColorThemeSetting | undefined): void;
37
+ setReduceMotion(reduceMotion: boolean): void;
38
+ /** Messages the bridge posted that have not reached the window yet. */
39
+ pendingMessages(): number;
40
+ /** What the webview posted with `acquireVsCodeApi().postMessage`. */
41
+ readonly posted: readonly unknown[];
42
+ /** The webview state as the last `setState` left it. */
43
+ state(): unknown;
44
+ }
45
+ /** The page globals the stub sets. */
46
+ type StubWindow = Window & {
47
+ /** The stub of `installVsCodeWebviewStub`, for a Playwright suite to drive. */
48
+ __modelerShellVsCodeStub?: VsCodeWebviewStub;
49
+ acquireVsCodeApi?: () => StubbedVsCodeApi;
50
+ };
51
+ /**
52
+ * The stub's options from a query string (`theme`, `kontrast=hoch`, `colorTheme`, `reduceMotion`),
53
+ * the counterpart of `vsCodeStubSearch` of `@miragon/modeler-shell/testing`.
54
+ */
55
+ declare function stubOptionsFromSearch(search: string): Pick<VsCodeWebviewStubOptions, "requested" | "colorTheme" | "reduceMotion">;
56
+ /**
57
+ * Stands in for VS Code around the page: its default stylesheet in `@layer vscode-default`, `<html>`
58
+ * with the attributes `renderWebviewHtml` writes before the first paint, `<body>` with the host
59
+ * page's theme (and reduce-motion) classes, `acquireVsCodeApi()`, and the real `connectThemeBridge`
60
+ * running against a fake `vscode` namespace whose panel posts to this window. Call it before the
61
+ * modeler's webview code runs; also exposed as `window.__modelerShellVsCodeStub`.
62
+ */
63
+ declare function installVsCodeWebviewStub(options: VsCodeWebviewStubOptions): VsCodeWebviewStub;
64
+
65
+ export { type ColorThemeKind, STUB_SETTING_KEY, type StubWindow, type StubbedVsCodeApi, type VsCodeWebviewStub, type VsCodeWebviewStubOptions, colorThemeKindOf, installVsCodeWebviewStub, stubOptionsFromSearch };