@lvce-editor/api 8.35.0 → 8.37.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.
- package/dist/index.d.ts +1 -1
- package/dist/parts/CommandMap/CommandMap.d.ts +1 -0
- package/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.d.ts +1 -0
- package/dist/parts/ExtensionApiCommandMap/ExtensionApiCommandMap.js +2 -1
- package/dist/parts/ExtensionApiWorkerCommandMap/ExtensionApiWorkerCommandMap.d.ts +1 -0
- package/dist/parts/View/View.d.ts +9 -0
- package/dist/parts/ViewRegistry/ViewRegistry.d.ts +2 -1
- package/dist/parts/ViewRegistry/ViewRegistry.js +70 -8
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { executeSourceControlAcceptInput, executeSourceControlAdd, executeSource
|
|
|
12
12
|
export { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewRegistrySnapshot, renderViewInstance, registerView, resetViewRegistry, saveViewInstanceState, } from './parts/ViewRegistry/ViewRegistry.ts';
|
|
13
13
|
export { createOutputChannel, getOutputChannelRegistrySnapshot, resetOutputChannelRegistry } from './parts/OutputChannel/OutputChannel.ts';
|
|
14
14
|
export { getStatusBarItemProviderRegistrySnapshot, registerStatusBarItemProvider, resetStatusBarItemProviderRegistry, } from './parts/StatusBar/StatusBar.ts';
|
|
15
|
-
export type { RegisteredView, View, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, VirtualDomViewInstance, } from './parts/View/View.ts';
|
|
15
|
+
export type { RegisteredView, View, ViewAction, ViewContext, ViewEvent, ViewKind, MenuEntry, ViewRegistrySnapshot, ViewRenderResult, VirtualDomViewInstance, } from './parts/View/View.ts';
|
|
16
16
|
export { handleExtensionManagementMessagePort } from './parts/HandleExtensionManagementMessagePort/HandleExtensionManagementMessagePort.ts';
|
|
17
17
|
export type { Command } from './parts/Command/Command.ts';
|
|
18
18
|
export type { CommandCallback } from './parts/CommandCallback/CommandCallback.ts';
|
|
@@ -28,6 +28,7 @@ export declare const commandMap: {
|
|
|
28
28
|
'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
|
|
29
29
|
'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
|
|
30
30
|
'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
|
|
31
|
+
'ExtensionApi.getViewActions': (uid: number) => Promise<readonly import("../View/View.ts").ViewAction[]>;
|
|
31
32
|
'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
|
|
32
33
|
'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
|
|
33
34
|
'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
|
|
@@ -27,6 +27,7 @@ export declare const commandMap: {
|
|
|
27
27
|
'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
|
|
28
28
|
'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
|
|
29
29
|
'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
|
|
30
|
+
'ExtensionApi.getViewActions': (uid: number) => Promise<readonly import("../View/View.ts").ViewAction[]>;
|
|
30
31
|
'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
|
|
31
32
|
'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
|
|
32
33
|
'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
|
|
@@ -6,7 +6,7 @@ import { getStatusBarItems } from "../GetStatusBarItems/GetStatusBarItems.js";
|
|
|
6
6
|
import { executeHoverProvider, getHoverProviderRegistrySnapshot } from "../Hover/Hover.js";
|
|
7
7
|
import { getOutputChannelRegistrySnapshot } from "../OutputChannel/OutputChannel.js";
|
|
8
8
|
import { executeSourceControlAcceptInput, executeSourceControlAdd, executeSourceControlDiscard, executeSourceControlGenerateCommitMessage, executeSourceControlGetChangedFiles, executeSourceControlGetFeatures, executeSourceControlGetFileBefore, executeSourceControlGetFileDecorations, executeSourceControlGetGroups, executeSourceControlIsActive, getSourceControlProviderRegistrySnapshot, } from "../SourceControl/SourceControl.js";
|
|
9
|
-
import { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewMenuEntries, getViewRegistrySnapshot, renderViewInstance, saveViewInstanceState, } from "../ViewRegistry/ViewRegistry.js";
|
|
9
|
+
import { createViewInstance, dispatchViewEvent, disposeViewInstance, executeViewProvider, getViewActions, getViewMenuEntries, getViewRegistrySnapshot, renderViewInstance, saveViewInstanceState, } from "../ViewRegistry/ViewRegistry.js";
|
|
10
10
|
export const commandMap = {
|
|
11
11
|
'ExtensionApi.createViewInstance': createViewInstance,
|
|
12
12
|
'ExtensionApi.dispatchViewEvent': dispatchViewEvent,
|
|
@@ -36,6 +36,7 @@ export const commandMap = {
|
|
|
36
36
|
'ExtensionApi.getOutputChannelRegistrySnapshot': getOutputChannelRegistrySnapshot,
|
|
37
37
|
'ExtensionApi.getSourceControlProviderRegistrySnapshot': getSourceControlProviderRegistrySnapshot,
|
|
38
38
|
'ExtensionApi.getStatusBarItems': getStatusBarItems,
|
|
39
|
+
'ExtensionApi.getViewActions': getViewActions,
|
|
39
40
|
'ExtensionApi.getViewMenuEntries': getViewMenuEntries,
|
|
40
41
|
'ExtensionApi.getViewRegistrySnapshot': getViewRegistrySnapshot,
|
|
41
42
|
'ExtensionApi.renderViewInstance': renderViewInstance,
|
|
@@ -29,6 +29,7 @@ export declare const commandMap: {
|
|
|
29
29
|
'ExtensionApi.getOutputChannelRegistrySnapshot': () => import("../OutputChannelRegistrySnapshot/OutputChannelRegistrySnapshot.ts").OutputChannelRegistrySnapshot;
|
|
30
30
|
'ExtensionApi.getSourceControlProviderRegistrySnapshot': () => import("../SourceControlProviderRegistrySnapshot/SourceControlProviderRegistrySnapshot.ts").SourceControlProviderRegistrySnapshot;
|
|
31
31
|
'ExtensionApi.getStatusBarItems': () => readonly import("../StatusBarItem/StatusBarItem.ts").StatusBarItem[];
|
|
32
|
+
'ExtensionApi.getViewActions': (uid: number) => Promise<readonly import("../View/View.ts").ViewAction[]>;
|
|
32
33
|
'ExtensionApi.getViewMenuEntries': (uid: number, menuId: string) => Promise<readonly import("../View/View.ts").MenuEntry[]>;
|
|
33
34
|
'ExtensionApi.getViewRegistrySnapshot': () => import("../View/View.ts").ViewRegistrySnapshot;
|
|
34
35
|
'ExtensionApi.renderViewInstance': (uid: number) => Promise<import("../View/View.ts").ViewRenderResult>;
|
|
@@ -21,6 +21,11 @@ export interface MenuEntry {
|
|
|
21
21
|
readonly id: string;
|
|
22
22
|
readonly label: string;
|
|
23
23
|
}
|
|
24
|
+
export interface ViewAction {
|
|
25
|
+
readonly command: string;
|
|
26
|
+
readonly icon: string;
|
|
27
|
+
readonly title: string;
|
|
28
|
+
}
|
|
24
29
|
export interface DomEventListener {
|
|
25
30
|
readonly capture?: boolean;
|
|
26
31
|
readonly name: string | number;
|
|
@@ -35,6 +40,8 @@ export interface VirtualDomViewInstance {
|
|
|
35
40
|
readonly getMenuEntries?: (menuId: string) => readonly MenuEntry[] | Promise<readonly MenuEntry[]>;
|
|
36
41
|
readonly handleEvent?: (event: ViewEvent) => unknown;
|
|
37
42
|
readonly render: () => readonly VirtualDomNode[] | Promise<readonly VirtualDomNode[]>;
|
|
43
|
+
readonly renderActions?: () => readonly ViewAction[] | Promise<readonly ViewAction[]>;
|
|
44
|
+
readonly renderFocus?: (oldContext: Readonly<Record<string, boolean>>, newContext: Readonly<Record<string, boolean>>) => string | Promise<string>;
|
|
38
45
|
readonly saveState?: () => unknown;
|
|
39
46
|
}
|
|
40
47
|
export interface View {
|
|
@@ -61,9 +68,11 @@ export interface ViewRegistrySnapshot {
|
|
|
61
68
|
}
|
|
62
69
|
export interface ViewRenderResultDom {
|
|
63
70
|
readonly dom: readonly VirtualDomNode[];
|
|
71
|
+
readonly focusSelector?: string;
|
|
64
72
|
readonly type: 'setDom';
|
|
65
73
|
}
|
|
66
74
|
export interface ViewRenderResultPatches {
|
|
75
|
+
readonly focusSelector?: string;
|
|
67
76
|
readonly patches: readonly unknown[];
|
|
68
77
|
readonly type: 'setPatches';
|
|
69
78
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Disposable } from '../Disposable/Disposable.ts';
|
|
2
|
-
import type { MenuEntry, View, ViewContext, ViewEvent, ViewRegistrySnapshot, ViewRenderResult } from '../View/View.ts';
|
|
2
|
+
import type { MenuEntry, View, ViewAction, ViewContext, ViewEvent, ViewRegistrySnapshot, ViewRenderResult } from '../View/View.ts';
|
|
3
3
|
export declare const registerView: (view: View) => Disposable;
|
|
4
4
|
export declare const executeViewProvider: (id: string) => unknown;
|
|
5
5
|
export declare const createViewInstance: (viewId: string, uid: number, context?: ViewContext) => Promise<ViewRenderResult>;
|
|
@@ -8,5 +8,6 @@ export declare const renderViewInstance: (uid: number) => Promise<ViewRenderResu
|
|
|
8
8
|
export declare const disposeViewInstance: (uid: number) => Promise<void>;
|
|
9
9
|
export declare const saveViewInstanceState: (uid: number) => Promise<unknown>;
|
|
10
10
|
export declare const getViewMenuEntries: (uid: number, menuId: string) => Promise<readonly MenuEntry[]>;
|
|
11
|
+
export declare const getViewActions: (uid: number) => Promise<readonly ViewAction[]>;
|
|
11
12
|
export declare const getViewRegistrySnapshot: () => ViewRegistrySnapshot;
|
|
12
13
|
export declare const resetViewRegistry: () => void;
|
|
@@ -147,6 +147,26 @@ const normalizeMenuEntries = (entries) => {
|
|
|
147
147
|
}
|
|
148
148
|
return entries.map(normalizeMenuEntry);
|
|
149
149
|
};
|
|
150
|
+
const normalizeViewAction = (action, index) => {
|
|
151
|
+
if (!action || typeof action !== 'object' || Array.isArray(action)) {
|
|
152
|
+
throw new ExtensionApiError(`view action ${index} must be an object`);
|
|
153
|
+
}
|
|
154
|
+
const viewAction = action;
|
|
155
|
+
assertString(viewAction.title, `view action ${index} is missing title`);
|
|
156
|
+
assertString(viewAction.icon, `view action ${index} is missing icon`);
|
|
157
|
+
assertString(viewAction.command, `view action ${index} is missing command`);
|
|
158
|
+
return {
|
|
159
|
+
command: viewAction.command,
|
|
160
|
+
icon: viewAction.icon,
|
|
161
|
+
title: viewAction.title,
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
const normalizeViewActions = (actions) => {
|
|
165
|
+
if (!Array.isArray(actions)) {
|
|
166
|
+
throw new ExtensionApiError('view actions must be an array');
|
|
167
|
+
}
|
|
168
|
+
return actions.map(normalizeViewAction);
|
|
169
|
+
};
|
|
150
170
|
const renderPatches = async (uid, instance) => {
|
|
151
171
|
const oldDom = renderedDoms[uid] || [];
|
|
152
172
|
const newDom = await renderDom(instance);
|
|
@@ -182,14 +202,23 @@ const isSameContext = (oldContext, newContext) => {
|
|
|
182
202
|
}
|
|
183
203
|
return true;
|
|
184
204
|
};
|
|
205
|
+
const unchangedContext = {
|
|
206
|
+
changed: false,
|
|
207
|
+
newContext: {},
|
|
208
|
+
oldContext: {},
|
|
209
|
+
};
|
|
185
210
|
const maybeNotifyContextChanged = async (uid, viewId, instance) => {
|
|
186
211
|
if (typeof instance.getContext !== 'function') {
|
|
187
|
-
return;
|
|
212
|
+
return unchangedContext;
|
|
188
213
|
}
|
|
189
214
|
const oldContext = contexts[uid] || {};
|
|
190
215
|
const newContext = normalizeContext(instance.getContext());
|
|
191
216
|
if (isSameContext(oldContext, newContext)) {
|
|
192
|
-
return
|
|
217
|
+
return {
|
|
218
|
+
changed: false,
|
|
219
|
+
newContext,
|
|
220
|
+
oldContext,
|
|
221
|
+
};
|
|
193
222
|
}
|
|
194
223
|
if (Object.keys(newContext).length === 0) {
|
|
195
224
|
delete contexts[uid];
|
|
@@ -198,6 +227,31 @@ const maybeNotifyContextChanged = async (uid, viewId, instance) => {
|
|
|
198
227
|
contexts[uid] = newContext;
|
|
199
228
|
}
|
|
200
229
|
await ExtensionManagementWorker.invoke('Extensions.handleViewContextChange', uid, viewId, newContext);
|
|
230
|
+
return {
|
|
231
|
+
changed: true,
|
|
232
|
+
newContext,
|
|
233
|
+
oldContext,
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
const renderFocus = async (instance, contextChange) => {
|
|
237
|
+
if (!contextChange.changed || typeof instance.renderFocus !== 'function') {
|
|
238
|
+
return '';
|
|
239
|
+
}
|
|
240
|
+
const focusSelector = await instance.renderFocus(contextChange.oldContext, contextChange.newContext);
|
|
241
|
+
if (typeof focusSelector !== 'string') {
|
|
242
|
+
throw new ExtensionApiError('view renderFocus result must be a string');
|
|
243
|
+
}
|
|
244
|
+
return focusSelector;
|
|
245
|
+
};
|
|
246
|
+
const withFocusSelector = async (result, instance, contextChange) => {
|
|
247
|
+
const focusSelector = await renderFocus(instance, contextChange);
|
|
248
|
+
if (!focusSelector) {
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
...result,
|
|
253
|
+
focusSelector,
|
|
254
|
+
};
|
|
201
255
|
};
|
|
202
256
|
const maybeClearContext = async (uid, viewId) => {
|
|
203
257
|
if (!contexts[uid]) {
|
|
@@ -233,11 +287,12 @@ export const createViewInstance = async (viewId, uid, context) => {
|
|
|
233
287
|
contextViewIds[uid] = viewId;
|
|
234
288
|
const dom = await renderDom(instance);
|
|
235
289
|
renderedDoms[uid] = dom;
|
|
236
|
-
|
|
237
|
-
return {
|
|
290
|
+
const result = {
|
|
238
291
|
dom,
|
|
239
292
|
type: 'setDom',
|
|
240
293
|
};
|
|
294
|
+
const contextChange = await maybeNotifyContextChanged(uid, viewId, instance);
|
|
295
|
+
return withFocusSelector(result, instance, contextChange);
|
|
241
296
|
};
|
|
242
297
|
export const dispatchViewEvent = async (uid, event) => {
|
|
243
298
|
const instance = getVirtualDomInstance(uid);
|
|
@@ -245,14 +300,14 @@ export const dispatchViewEvent = async (uid, event) => {
|
|
|
245
300
|
await instance.handleEvent(event);
|
|
246
301
|
}
|
|
247
302
|
const result = await renderPatches(uid, instance);
|
|
248
|
-
await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
|
|
249
|
-
return result;
|
|
303
|
+
const contextChange = await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
|
|
304
|
+
return withFocusSelector(result, instance, contextChange);
|
|
250
305
|
};
|
|
251
306
|
export const renderViewInstance = async (uid) => {
|
|
252
307
|
const instance = getVirtualDomInstance(uid);
|
|
253
308
|
const result = await renderPatches(uid, instance);
|
|
254
|
-
await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
|
|
255
|
-
return result;
|
|
309
|
+
const contextChange = await maybeNotifyContextChanged(uid, contextViewIds[uid], instance);
|
|
310
|
+
return withFocusSelector(result, instance, contextChange);
|
|
256
311
|
};
|
|
257
312
|
export const disposeViewInstance = async (uid) => {
|
|
258
313
|
const instance = instances[uid];
|
|
@@ -279,6 +334,13 @@ export const getViewMenuEntries = async (uid, menuId) => {
|
|
|
279
334
|
}
|
|
280
335
|
return normalizeMenuEntries(await instance.getMenuEntries(menuId));
|
|
281
336
|
};
|
|
337
|
+
export const getViewActions = async (uid) => {
|
|
338
|
+
const instance = getVirtualDomInstance(uid);
|
|
339
|
+
if (typeof instance.renderActions !== 'function') {
|
|
340
|
+
return [];
|
|
341
|
+
}
|
|
342
|
+
return normalizeViewActions(await instance.renderActions());
|
|
343
|
+
};
|
|
282
344
|
export const getViewRegistrySnapshot = () => {
|
|
283
345
|
return {
|
|
284
346
|
views: Object.values(views).map(toRegisteredView),
|