weml-monaco 0.5.2 → 0.7.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/CHANGELOG.md +56 -3
- package/README.md +161 -47
- package/dist/index.cjs +25587 -24926
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +204 -11
- package/dist/index.d.ts +204 -11
- package/dist/index.global.js +142 -132
- package/dist/index.mjs +25591 -24930
- package/dist/index.mjs.map +1 -1
- package/dist/panel.cjs +1314 -0
- package/dist/panel.cjs.map +1 -0
- package/dist/panel.css +261 -0
- package/dist/panel.d.mts +106 -0
- package/dist/panel.d.ts +106 -0
- package/dist/panel.mjs +1291 -0
- package/dist/panel.mjs.map +1 -0
- package/dist/preview.cjs +324 -0
- package/dist/preview.cjs.map +1 -0
- package/dist/preview.d.mts +63 -0
- package/dist/preview.d.ts +63 -0
- package/dist/preview.mjs +301 -0
- package/dist/preview.mjs.map +1 -0
- package/dist/weml.worker.d.mts +2 -0
- package/dist/weml.worker.mjs +25164 -0
- package/dist/weml.worker.mjs.map +1 -0
- package/dist/worker.cjs +8596 -0
- package/dist/worker.cjs.map +1 -0
- package/dist/worker.d.mts +21 -0
- package/dist/worker.d.ts +21 -0
- package/dist/worker.mjs +8597 -0
- package/dist/worker.mjs.map +1 -0
- package/package.json +57 -12
package/dist/index.d.mts
CHANGED
|
@@ -24,10 +24,11 @@ interface WemlActionOptions {
|
|
|
24
24
|
}
|
|
25
25
|
/** Wraps the current selection in `<tag [type=...]>…</tag>` (toolbar dropdown / hotkeys). */
|
|
26
26
|
declare function wrapSelection(editor: monaco.editor.ICodeEditor, tag: string, type?: string): void;
|
|
27
|
-
/** Inserts a snippet by its
|
|
27
|
+
/** Inserts a snippet by its id (`snippetBodyFor`: a composite label, the anchor, or a tag). */
|
|
28
28
|
declare function insertSnippetById(editor: monaco.editor.ICodeEditor, id: string): void;
|
|
29
29
|
/** Renumbers every `<div>` id in document order to a sequential 1..n. */
|
|
30
30
|
declare function renumberDivIds(editor: monaco.editor.ICodeEditor, options?: WemlActionOptions): void;
|
|
31
|
+
|
|
31
32
|
/**
|
|
32
33
|
* Cycles the whole document between the standard HTML formatting (even steps) and
|
|
33
34
|
* the canonical WEML normalizer (odd steps). The step counter advances on every
|
|
@@ -41,8 +42,8 @@ declare function cycleFormat(editor: monaco.editor.ICodeEditor, options?: WemlAc
|
|
|
41
42
|
* (Ctrl+B / Ctrl+I / Ctrl+U). Returns an `IDisposable` that removes them.
|
|
42
43
|
*
|
|
43
44
|
* `editor.addAction` is per-editor (Monaco has no global command registry akin
|
|
44
|
-
* to the VS Code extension host), so call this for every WEML editor
|
|
45
|
-
*
|
|
45
|
+
* to the VS Code extension host), so call this for every WEML editor (the deprecated
|
|
46
|
+
* `createWemlToolbar` calls it for you; the WEML panel does not).
|
|
46
47
|
*/
|
|
47
48
|
declare function registerWemlEditorActions(m: typeof monaco, editor: monaco.editor.IStandaloneCodeEditor, options?: WemlActionOptions): monaco.IDisposable;
|
|
48
49
|
|
|
@@ -69,9 +70,23 @@ interface WemlToolbar extends monaco.IDisposable {
|
|
|
69
70
|
*
|
|
70
71
|
* Returns the root element plus a `dispose()` that removes the toolbar and its
|
|
71
72
|
* actions.
|
|
73
|
+
*
|
|
74
|
+
* @deprecated Use the WEML panel (`createWemlPanel` from `weml-monaco/panel`, with
|
|
75
|
+
* `createMonacoPanelHost`): the same Tools and Search Suggestions as the VS Code
|
|
76
|
+
* extension. For the hotkeys alone, call `registerWemlEditorActions`.
|
|
72
77
|
*/
|
|
73
78
|
declare function createWemlToolbar(m: typeof monaco, editor: monaco.editor.IStandaloneCodeEditor, options?: WemlToolbarOptions): WemlToolbar;
|
|
74
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Builds a `<tag ...>SELECTION</tag>` snippet body for wrapping `selection`.
|
|
82
|
+
* - `type` (e.g. for `w-format`) fills `type="..."` directly.
|
|
83
|
+
* - `a` gets only `href="$1"` (it lists both href and id as required, but a
|
|
84
|
+
* wrapped selection is a link).
|
|
85
|
+
* - otherwise the tag's required attributes become `name="$1"` placeholders.
|
|
86
|
+
* An empty selection leaves a tab stop where the content goes.
|
|
87
|
+
*/
|
|
88
|
+
declare function buildWrapSnippet(tag: string, type: string | undefined, selection: string): string;
|
|
89
|
+
|
|
75
90
|
interface IdEdit {
|
|
76
91
|
/** Replacement range in the source text (start === end means a pure insertion). */
|
|
77
92
|
start: number;
|
|
@@ -85,15 +100,193 @@ interface IdEdit {
|
|
|
85
100
|
*/
|
|
86
101
|
declare function planDivIdRenumber(text: string): IdEdit[];
|
|
87
102
|
|
|
103
|
+
interface WrapOption {
|
|
104
|
+
/** Encoded option value, e.g. "w-format:italic" or "w-lang". */
|
|
105
|
+
value: string;
|
|
106
|
+
label: string;
|
|
107
|
+
tag: string;
|
|
108
|
+
/** The `type` of `w-format`; absent for the other inlines. */
|
|
109
|
+
type?: string;
|
|
110
|
+
}
|
|
111
|
+
/** The documentation's sections the tool picker groups its items by, in order. */
|
|
112
|
+
declare const TOOL_GROUPS: readonly ["Containers", "Blocks", "Inlines"];
|
|
113
|
+
type ToolGroup = (typeof TOOL_GROUPS)[number];
|
|
114
|
+
/** What a tool item does: wrap the selection, or insert a snippet at the cursor. */
|
|
115
|
+
type ToolAction = {
|
|
116
|
+
kind: 'wrap';
|
|
117
|
+
option: WrapOption;
|
|
118
|
+
} | {
|
|
119
|
+
kind: 'insert';
|
|
120
|
+
snippetId: string;
|
|
121
|
+
};
|
|
122
|
+
interface ToolItem {
|
|
123
|
+
/** Unique: the wrap option's value, or the snippet's tag. */
|
|
124
|
+
value: string;
|
|
125
|
+
/** What the picker shows and searches: the tag (`w-format.bold` for a format). */
|
|
126
|
+
label: string;
|
|
127
|
+
group: ToolGroup;
|
|
128
|
+
action: ToolAction;
|
|
129
|
+
/**
|
|
130
|
+
* A new section of `<body>` (a `<div id>` with its container): only for a whole document, not
|
|
131
|
+
* for an editor of one paragraph, whose model is a single `<div>` already.
|
|
132
|
+
*/
|
|
133
|
+
documentOnly?: boolean;
|
|
134
|
+
}
|
|
135
|
+
/** What is edited: a whole WEML document, or one paragraph (the content of one `<div>`). */
|
|
136
|
+
type ToolMode = 'file' | 'paragraph';
|
|
88
137
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* - `a` gets only `href="$1"` (it lists both href and id as required, but a
|
|
92
|
-
* wrapped selection is a link).
|
|
93
|
-
* - otherwise the tag's required attributes become `name="$1"` placeholders.
|
|
94
|
-
* An empty selection leaves a tab stop where the content goes.
|
|
138
|
+
* One list of everything the Tools offer — the snippets to insert, then the inlines to wrap the
|
|
139
|
+
* selection in — grouped as the WEML documentation is (containers, blocks, inlines).
|
|
95
140
|
*/
|
|
96
|
-
declare
|
|
141
|
+
declare const TOOL_ITEMS: ToolItem[];
|
|
142
|
+
/** The tool items for what is edited: a paragraph has no sections to add. */
|
|
143
|
+
declare function toolItemsFor(mode?: ToolMode): ToolItem[];
|
|
144
|
+
/** A tool item that matches a query, with the matched ranges of its label (`[start, end)`). */
|
|
145
|
+
interface ToolMatch {
|
|
146
|
+
item: ToolItem;
|
|
147
|
+
matches: [number, number][];
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The items whose label contains `query` (case-insensitive; an empty query matches all), in
|
|
151
|
+
* `TOOL_ITEMS` order, with the match to highlight.
|
|
152
|
+
*/
|
|
153
|
+
declare function filterToolItems(query: string, items?: readonly ToolItem[]): ToolMatch[];
|
|
154
|
+
|
|
155
|
+
/** The panel's remembered state (collapsed panes, pane sizes, per-pane values). */
|
|
156
|
+
interface WemlPanelStorage {
|
|
157
|
+
get(): unknown;
|
|
158
|
+
set(value: unknown): void;
|
|
159
|
+
}
|
|
160
|
+
/** The Tools pane's actions. */
|
|
161
|
+
interface WemlPanelTools {
|
|
162
|
+
/** Wraps the selection in the option's tag (a `WRAP_OPTIONS` entry). */
|
|
163
|
+
wrap(option: WrapOption): void;
|
|
164
|
+
/** Inserts a snippet by its id (weml-language-core's `snippetBodyFor`: a tag, a composite, the anchor). */
|
|
165
|
+
insertSnippet(id: string): void;
|
|
166
|
+
/** Renumbers every `<div>` id to 1…n. */
|
|
167
|
+
renumber(): void;
|
|
168
|
+
}
|
|
169
|
+
/** Whether search can run, and as whom. */
|
|
170
|
+
type WemlSearchState =
|
|
171
|
+
/** Something is missing on the host's side; `message` says what. */
|
|
172
|
+
{
|
|
173
|
+
kind: 'not-configured';
|
|
174
|
+
message: string;
|
|
175
|
+
canOpenSettings?: boolean;
|
|
176
|
+
} | {
|
|
177
|
+
kind: 'signed-out';
|
|
178
|
+
defaultLanguage?: string;
|
|
179
|
+
} | {
|
|
180
|
+
kind: 'signed-in';
|
|
181
|
+
account?: string;
|
|
182
|
+
defaultLanguage?: string;
|
|
183
|
+
};
|
|
184
|
+
/** A search suggestion as the panel shows it. */
|
|
185
|
+
interface WemlSearchResult {
|
|
186
|
+
paraId: string;
|
|
187
|
+
bookCode: string;
|
|
188
|
+
title: string;
|
|
189
|
+
/** The `egw://` link for a paragraph, or null. */
|
|
190
|
+
link: string | null;
|
|
191
|
+
}
|
|
192
|
+
/** The Search Suggestions pane's backend. */
|
|
193
|
+
interface WemlPanelSearch {
|
|
194
|
+
getState(): WemlSearchState | Promise<WemlSearchState>;
|
|
195
|
+
/** Calls `listener` whenever the state may have changed; returns the unsubscribe. */
|
|
196
|
+
onDidChangeState(listener: () => void): () => void;
|
|
197
|
+
/**
|
|
198
|
+
* Searches. The host cancels a previous request itself; the panel ignores answers that arrive
|
|
199
|
+
* after a newer search started. Rejects with an Error whose message the panel shows.
|
|
200
|
+
*/
|
|
201
|
+
search(query: string, lang: string): Promise<WemlSearchResult[]>;
|
|
202
|
+
/** Starts the sign-in; a rejection's message is shown under the Sign in button. */
|
|
203
|
+
signIn(): void | Promise<void>;
|
|
204
|
+
/** Shown as a link next to a "not configured" message when the state allows it. */
|
|
205
|
+
openSettings?(): void;
|
|
206
|
+
copy(text: string): void;
|
|
207
|
+
/** Inserts the link of the result at `index` (of the last answer) in place of the selection. */
|
|
208
|
+
insertLink(index: number): void;
|
|
209
|
+
}
|
|
210
|
+
interface WemlPanelHost {
|
|
211
|
+
tools: WemlPanelTools;
|
|
212
|
+
/** Without it the panel has no Search Suggestions pane. */
|
|
213
|
+
search?: WemlPanelSearch;
|
|
214
|
+
/** Without it nothing is remembered (in memory for this panel only). */
|
|
215
|
+
storage?: WemlPanelStorage;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** The EGW search as a web host provides it: where the API is, and how to get the user's token. */
|
|
219
|
+
interface MonacoPanelSearchOptions {
|
|
220
|
+
/** Base URL of the EGW API (`<apiUrl>/search/suggestions`). */
|
|
221
|
+
apiUrl: string;
|
|
222
|
+
/** The signed-in user's access token, or undefined when signed out. */
|
|
223
|
+
getAccessToken(): string | undefined | Promise<string | undefined>;
|
|
224
|
+
/** Starts the host application's sign-in; a rejection's message is shown in the pane. */
|
|
225
|
+
signIn?(): void | Promise<void>;
|
|
226
|
+
/** Notifies the panel when the user signs in or out; returns the unsubscribe. */
|
|
227
|
+
onDidChangeSession?(listener: () => void): () => void;
|
|
228
|
+
/** The account's display name, if the host wants it shown (it is not shown while signed in). */
|
|
229
|
+
account?(): string | undefined;
|
|
230
|
+
/** The search language until the user picks one. Default: `en`. */
|
|
231
|
+
defaultLanguage?: string;
|
|
232
|
+
}
|
|
233
|
+
interface MonacoPanelHostOptions extends WemlActionOptions {
|
|
234
|
+
/**
|
|
235
|
+
* The EGW search. Omitted: the Search Suggestions pane says the search is not configured;
|
|
236
|
+
* `false`: no Search Suggestions pane at all.
|
|
237
|
+
*/
|
|
238
|
+
search?: MonacoPanelSearchOptions | false;
|
|
239
|
+
/** What the "not configured" message says when `search` is omitted. */
|
|
240
|
+
notConfiguredMessage?: string;
|
|
241
|
+
/**
|
|
242
|
+
* Where the panel remembers its layout. Default: `localStorage` under `weml-panel`;
|
|
243
|
+
* `false`: nothing is remembered.
|
|
244
|
+
*/
|
|
245
|
+
storage?: WemlPanelStorage | false;
|
|
246
|
+
/** Copies text for the Copy buttons. Default: `navigator.clipboard.writeText`. */
|
|
247
|
+
copy?(text: string): void;
|
|
248
|
+
}
|
|
249
|
+
/** A WemlPanelHost for a Monaco editor on a web page. */
|
|
250
|
+
declare function createMonacoPanelHost(editor: monaco.editor.ICodeEditor, options?: MonacoPanelHostOptions): WemlPanelHost;
|
|
251
|
+
|
|
252
|
+
interface EgwWebAuthOptions {
|
|
253
|
+
/** OIDC authority (issuer); `/.well-known/openid-configuration` is read from it. */
|
|
254
|
+
authority: string;
|
|
255
|
+
clientId: string;
|
|
256
|
+
/** Space-separated scopes (`openid offline_access search …`). */
|
|
257
|
+
scopes: string;
|
|
258
|
+
/**
|
|
259
|
+
* Where the server sends the popup back to, on this page's origin; the client must allow it.
|
|
260
|
+
* Default: `<origin>/auth-callback`. Any page will do — it is read from here, not run — so a
|
|
261
|
+
* blank one is best.
|
|
262
|
+
*/
|
|
263
|
+
redirectUri?: string;
|
|
264
|
+
/** Optional login page the authorize request goes through: `loginPageUrl?next=<authorize path>`. */
|
|
265
|
+
loginPageUrl?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Where the session is kept. `session` (default): this tab, until it closes; `local`: every tab,
|
|
268
|
+
* across restarts; `false`: memory only, until the page reloads.
|
|
269
|
+
*/
|
|
270
|
+
storage?: 'session' | 'local' | false;
|
|
271
|
+
}
|
|
272
|
+
interface EgwWebAuth {
|
|
273
|
+
/** The access token, refreshed when it is about to expire; undefined when signed out. */
|
|
274
|
+
getAccessToken(): Promise<string | undefined>;
|
|
275
|
+
/**
|
|
276
|
+
* Opens the sign-in popup — call it from a click, or the browser blocks the popup. Resolves once
|
|
277
|
+
* signed in; rejects with a message to show (popup blocked, closed, refused by the server).
|
|
278
|
+
*/
|
|
279
|
+
signIn(): Promise<void>;
|
|
280
|
+
signOut(): void;
|
|
281
|
+
/** Calls `listener` on sign-in, sign-out and refresh (in other tabs too, with `local`). */
|
|
282
|
+
onDidChangeSession(listener: () => void): () => void;
|
|
283
|
+
/** The signed-in account's name, or undefined. */
|
|
284
|
+
account(): string | undefined;
|
|
285
|
+
/** Closes a pending popup and stops listening. */
|
|
286
|
+
dispose(): void;
|
|
287
|
+
}
|
|
288
|
+
/** The EGW sign-in for a web page: see `EgwWebAuthOptions`. */
|
|
289
|
+
declare function createEgwWebAuth(options: EgwWebAuthOptions): EgwWebAuth;
|
|
97
290
|
|
|
98
291
|
interface RegisterWemlOptions {
|
|
99
292
|
/** File extensions to associate with the language (default: [".weml"]). */
|
|
@@ -105,4 +298,4 @@ interface RegisterWemlOptions {
|
|
|
105
298
|
}
|
|
106
299
|
declare function registerWeml(m: typeof monaco, options?: RegisterWemlOptions): monaco.IDisposable;
|
|
107
300
|
|
|
108
|
-
export { type IdEdit, type RegisterWemlOptions, WEML_LANGUAGE_ID, type WemlActionOptions, type WemlNormalizationFailure, type WemlToolbar, type WemlToolbarOptions, buildWrapSnippet, canonicalFormattingFailureMessage, createWemlToolbar, cycleFormat, formatWemlText, insertSnippetById, isWemlNormalizationFailure, isWemlStructureValidationFailure, planDivIdRenumber, registerWeml, registerWemlEditorActions, renumberDivIds, validateWemlModel, wrapSelection };
|
|
301
|
+
export { type EgwWebAuth, type EgwWebAuthOptions, type IdEdit, type MonacoPanelHostOptions, type MonacoPanelSearchOptions, type RegisterWemlOptions, TOOL_GROUPS, TOOL_ITEMS, type ToolAction, type ToolGroup, type ToolItem, type ToolMatch, type ToolMode, WEML_LANGUAGE_ID, type WemlActionOptions, type WemlNormalizationFailure, type WemlToolbar, type WemlToolbarOptions, type WrapOption, buildWrapSnippet, canonicalFormattingFailureMessage, createEgwWebAuth, createMonacoPanelHost, createWemlToolbar, cycleFormat, filterToolItems, formatWemlText, insertSnippetById, isWemlNormalizationFailure, isWemlStructureValidationFailure, planDivIdRenumber, registerWeml, registerWemlEditorActions, renumberDivIds, toolItemsFor, validateWemlModel, wrapSelection };
|
package/dist/index.d.ts
CHANGED
|
@@ -24,10 +24,11 @@ interface WemlActionOptions {
|
|
|
24
24
|
}
|
|
25
25
|
/** Wraps the current selection in `<tag [type=...]>…</tag>` (toolbar dropdown / hotkeys). */
|
|
26
26
|
declare function wrapSelection(editor: monaco.editor.ICodeEditor, tag: string, type?: string): void;
|
|
27
|
-
/** Inserts a snippet by its
|
|
27
|
+
/** Inserts a snippet by its id (`snippetBodyFor`: a composite label, the anchor, or a tag). */
|
|
28
28
|
declare function insertSnippetById(editor: monaco.editor.ICodeEditor, id: string): void;
|
|
29
29
|
/** Renumbers every `<div>` id in document order to a sequential 1..n. */
|
|
30
30
|
declare function renumberDivIds(editor: monaco.editor.ICodeEditor, options?: WemlActionOptions): void;
|
|
31
|
+
|
|
31
32
|
/**
|
|
32
33
|
* Cycles the whole document between the standard HTML formatting (even steps) and
|
|
33
34
|
* the canonical WEML normalizer (odd steps). The step counter advances on every
|
|
@@ -41,8 +42,8 @@ declare function cycleFormat(editor: monaco.editor.ICodeEditor, options?: WemlAc
|
|
|
41
42
|
* (Ctrl+B / Ctrl+I / Ctrl+U). Returns an `IDisposable` that removes them.
|
|
42
43
|
*
|
|
43
44
|
* `editor.addAction` is per-editor (Monaco has no global command registry akin
|
|
44
|
-
* to the VS Code extension host), so call this for every WEML editor
|
|
45
|
-
*
|
|
45
|
+
* to the VS Code extension host), so call this for every WEML editor (the deprecated
|
|
46
|
+
* `createWemlToolbar` calls it for you; the WEML panel does not).
|
|
46
47
|
*/
|
|
47
48
|
declare function registerWemlEditorActions(m: typeof monaco, editor: monaco.editor.IStandaloneCodeEditor, options?: WemlActionOptions): monaco.IDisposable;
|
|
48
49
|
|
|
@@ -69,9 +70,23 @@ interface WemlToolbar extends monaco.IDisposable {
|
|
|
69
70
|
*
|
|
70
71
|
* Returns the root element plus a `dispose()` that removes the toolbar and its
|
|
71
72
|
* actions.
|
|
73
|
+
*
|
|
74
|
+
* @deprecated Use the WEML panel (`createWemlPanel` from `weml-monaco/panel`, with
|
|
75
|
+
* `createMonacoPanelHost`): the same Tools and Search Suggestions as the VS Code
|
|
76
|
+
* extension. For the hotkeys alone, call `registerWemlEditorActions`.
|
|
72
77
|
*/
|
|
73
78
|
declare function createWemlToolbar(m: typeof monaco, editor: monaco.editor.IStandaloneCodeEditor, options?: WemlToolbarOptions): WemlToolbar;
|
|
74
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Builds a `<tag ...>SELECTION</tag>` snippet body for wrapping `selection`.
|
|
82
|
+
* - `type` (e.g. for `w-format`) fills `type="..."` directly.
|
|
83
|
+
* - `a` gets only `href="$1"` (it lists both href and id as required, but a
|
|
84
|
+
* wrapped selection is a link).
|
|
85
|
+
* - otherwise the tag's required attributes become `name="$1"` placeholders.
|
|
86
|
+
* An empty selection leaves a tab stop where the content goes.
|
|
87
|
+
*/
|
|
88
|
+
declare function buildWrapSnippet(tag: string, type: string | undefined, selection: string): string;
|
|
89
|
+
|
|
75
90
|
interface IdEdit {
|
|
76
91
|
/** Replacement range in the source text (start === end means a pure insertion). */
|
|
77
92
|
start: number;
|
|
@@ -85,15 +100,193 @@ interface IdEdit {
|
|
|
85
100
|
*/
|
|
86
101
|
declare function planDivIdRenumber(text: string): IdEdit[];
|
|
87
102
|
|
|
103
|
+
interface WrapOption {
|
|
104
|
+
/** Encoded option value, e.g. "w-format:italic" or "w-lang". */
|
|
105
|
+
value: string;
|
|
106
|
+
label: string;
|
|
107
|
+
tag: string;
|
|
108
|
+
/** The `type` of `w-format`; absent for the other inlines. */
|
|
109
|
+
type?: string;
|
|
110
|
+
}
|
|
111
|
+
/** The documentation's sections the tool picker groups its items by, in order. */
|
|
112
|
+
declare const TOOL_GROUPS: readonly ["Containers", "Blocks", "Inlines"];
|
|
113
|
+
type ToolGroup = (typeof TOOL_GROUPS)[number];
|
|
114
|
+
/** What a tool item does: wrap the selection, or insert a snippet at the cursor. */
|
|
115
|
+
type ToolAction = {
|
|
116
|
+
kind: 'wrap';
|
|
117
|
+
option: WrapOption;
|
|
118
|
+
} | {
|
|
119
|
+
kind: 'insert';
|
|
120
|
+
snippetId: string;
|
|
121
|
+
};
|
|
122
|
+
interface ToolItem {
|
|
123
|
+
/** Unique: the wrap option's value, or the snippet's tag. */
|
|
124
|
+
value: string;
|
|
125
|
+
/** What the picker shows and searches: the tag (`w-format.bold` for a format). */
|
|
126
|
+
label: string;
|
|
127
|
+
group: ToolGroup;
|
|
128
|
+
action: ToolAction;
|
|
129
|
+
/**
|
|
130
|
+
* A new section of `<body>` (a `<div id>` with its container): only for a whole document, not
|
|
131
|
+
* for an editor of one paragraph, whose model is a single `<div>` already.
|
|
132
|
+
*/
|
|
133
|
+
documentOnly?: boolean;
|
|
134
|
+
}
|
|
135
|
+
/** What is edited: a whole WEML document, or one paragraph (the content of one `<div>`). */
|
|
136
|
+
type ToolMode = 'file' | 'paragraph';
|
|
88
137
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* - `a` gets only `href="$1"` (it lists both href and id as required, but a
|
|
92
|
-
* wrapped selection is a link).
|
|
93
|
-
* - otherwise the tag's required attributes become `name="$1"` placeholders.
|
|
94
|
-
* An empty selection leaves a tab stop where the content goes.
|
|
138
|
+
* One list of everything the Tools offer — the snippets to insert, then the inlines to wrap the
|
|
139
|
+
* selection in — grouped as the WEML documentation is (containers, blocks, inlines).
|
|
95
140
|
*/
|
|
96
|
-
declare
|
|
141
|
+
declare const TOOL_ITEMS: ToolItem[];
|
|
142
|
+
/** The tool items for what is edited: a paragraph has no sections to add. */
|
|
143
|
+
declare function toolItemsFor(mode?: ToolMode): ToolItem[];
|
|
144
|
+
/** A tool item that matches a query, with the matched ranges of its label (`[start, end)`). */
|
|
145
|
+
interface ToolMatch {
|
|
146
|
+
item: ToolItem;
|
|
147
|
+
matches: [number, number][];
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The items whose label contains `query` (case-insensitive; an empty query matches all), in
|
|
151
|
+
* `TOOL_ITEMS` order, with the match to highlight.
|
|
152
|
+
*/
|
|
153
|
+
declare function filterToolItems(query: string, items?: readonly ToolItem[]): ToolMatch[];
|
|
154
|
+
|
|
155
|
+
/** The panel's remembered state (collapsed panes, pane sizes, per-pane values). */
|
|
156
|
+
interface WemlPanelStorage {
|
|
157
|
+
get(): unknown;
|
|
158
|
+
set(value: unknown): void;
|
|
159
|
+
}
|
|
160
|
+
/** The Tools pane's actions. */
|
|
161
|
+
interface WemlPanelTools {
|
|
162
|
+
/** Wraps the selection in the option's tag (a `WRAP_OPTIONS` entry). */
|
|
163
|
+
wrap(option: WrapOption): void;
|
|
164
|
+
/** Inserts a snippet by its id (weml-language-core's `snippetBodyFor`: a tag, a composite, the anchor). */
|
|
165
|
+
insertSnippet(id: string): void;
|
|
166
|
+
/** Renumbers every `<div>` id to 1…n. */
|
|
167
|
+
renumber(): void;
|
|
168
|
+
}
|
|
169
|
+
/** Whether search can run, and as whom. */
|
|
170
|
+
type WemlSearchState =
|
|
171
|
+
/** Something is missing on the host's side; `message` says what. */
|
|
172
|
+
{
|
|
173
|
+
kind: 'not-configured';
|
|
174
|
+
message: string;
|
|
175
|
+
canOpenSettings?: boolean;
|
|
176
|
+
} | {
|
|
177
|
+
kind: 'signed-out';
|
|
178
|
+
defaultLanguage?: string;
|
|
179
|
+
} | {
|
|
180
|
+
kind: 'signed-in';
|
|
181
|
+
account?: string;
|
|
182
|
+
defaultLanguage?: string;
|
|
183
|
+
};
|
|
184
|
+
/** A search suggestion as the panel shows it. */
|
|
185
|
+
interface WemlSearchResult {
|
|
186
|
+
paraId: string;
|
|
187
|
+
bookCode: string;
|
|
188
|
+
title: string;
|
|
189
|
+
/** The `egw://` link for a paragraph, or null. */
|
|
190
|
+
link: string | null;
|
|
191
|
+
}
|
|
192
|
+
/** The Search Suggestions pane's backend. */
|
|
193
|
+
interface WemlPanelSearch {
|
|
194
|
+
getState(): WemlSearchState | Promise<WemlSearchState>;
|
|
195
|
+
/** Calls `listener` whenever the state may have changed; returns the unsubscribe. */
|
|
196
|
+
onDidChangeState(listener: () => void): () => void;
|
|
197
|
+
/**
|
|
198
|
+
* Searches. The host cancels a previous request itself; the panel ignores answers that arrive
|
|
199
|
+
* after a newer search started. Rejects with an Error whose message the panel shows.
|
|
200
|
+
*/
|
|
201
|
+
search(query: string, lang: string): Promise<WemlSearchResult[]>;
|
|
202
|
+
/** Starts the sign-in; a rejection's message is shown under the Sign in button. */
|
|
203
|
+
signIn(): void | Promise<void>;
|
|
204
|
+
/** Shown as a link next to a "not configured" message when the state allows it. */
|
|
205
|
+
openSettings?(): void;
|
|
206
|
+
copy(text: string): void;
|
|
207
|
+
/** Inserts the link of the result at `index` (of the last answer) in place of the selection. */
|
|
208
|
+
insertLink(index: number): void;
|
|
209
|
+
}
|
|
210
|
+
interface WemlPanelHost {
|
|
211
|
+
tools: WemlPanelTools;
|
|
212
|
+
/** Without it the panel has no Search Suggestions pane. */
|
|
213
|
+
search?: WemlPanelSearch;
|
|
214
|
+
/** Without it nothing is remembered (in memory for this panel only). */
|
|
215
|
+
storage?: WemlPanelStorage;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** The EGW search as a web host provides it: where the API is, and how to get the user's token. */
|
|
219
|
+
interface MonacoPanelSearchOptions {
|
|
220
|
+
/** Base URL of the EGW API (`<apiUrl>/search/suggestions`). */
|
|
221
|
+
apiUrl: string;
|
|
222
|
+
/** The signed-in user's access token, or undefined when signed out. */
|
|
223
|
+
getAccessToken(): string | undefined | Promise<string | undefined>;
|
|
224
|
+
/** Starts the host application's sign-in; a rejection's message is shown in the pane. */
|
|
225
|
+
signIn?(): void | Promise<void>;
|
|
226
|
+
/** Notifies the panel when the user signs in or out; returns the unsubscribe. */
|
|
227
|
+
onDidChangeSession?(listener: () => void): () => void;
|
|
228
|
+
/** The account's display name, if the host wants it shown (it is not shown while signed in). */
|
|
229
|
+
account?(): string | undefined;
|
|
230
|
+
/** The search language until the user picks one. Default: `en`. */
|
|
231
|
+
defaultLanguage?: string;
|
|
232
|
+
}
|
|
233
|
+
interface MonacoPanelHostOptions extends WemlActionOptions {
|
|
234
|
+
/**
|
|
235
|
+
* The EGW search. Omitted: the Search Suggestions pane says the search is not configured;
|
|
236
|
+
* `false`: no Search Suggestions pane at all.
|
|
237
|
+
*/
|
|
238
|
+
search?: MonacoPanelSearchOptions | false;
|
|
239
|
+
/** What the "not configured" message says when `search` is omitted. */
|
|
240
|
+
notConfiguredMessage?: string;
|
|
241
|
+
/**
|
|
242
|
+
* Where the panel remembers its layout. Default: `localStorage` under `weml-panel`;
|
|
243
|
+
* `false`: nothing is remembered.
|
|
244
|
+
*/
|
|
245
|
+
storage?: WemlPanelStorage | false;
|
|
246
|
+
/** Copies text for the Copy buttons. Default: `navigator.clipboard.writeText`. */
|
|
247
|
+
copy?(text: string): void;
|
|
248
|
+
}
|
|
249
|
+
/** A WemlPanelHost for a Monaco editor on a web page. */
|
|
250
|
+
declare function createMonacoPanelHost(editor: monaco.editor.ICodeEditor, options?: MonacoPanelHostOptions): WemlPanelHost;
|
|
251
|
+
|
|
252
|
+
interface EgwWebAuthOptions {
|
|
253
|
+
/** OIDC authority (issuer); `/.well-known/openid-configuration` is read from it. */
|
|
254
|
+
authority: string;
|
|
255
|
+
clientId: string;
|
|
256
|
+
/** Space-separated scopes (`openid offline_access search …`). */
|
|
257
|
+
scopes: string;
|
|
258
|
+
/**
|
|
259
|
+
* Where the server sends the popup back to, on this page's origin; the client must allow it.
|
|
260
|
+
* Default: `<origin>/auth-callback`. Any page will do — it is read from here, not run — so a
|
|
261
|
+
* blank one is best.
|
|
262
|
+
*/
|
|
263
|
+
redirectUri?: string;
|
|
264
|
+
/** Optional login page the authorize request goes through: `loginPageUrl?next=<authorize path>`. */
|
|
265
|
+
loginPageUrl?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Where the session is kept. `session` (default): this tab, until it closes; `local`: every tab,
|
|
268
|
+
* across restarts; `false`: memory only, until the page reloads.
|
|
269
|
+
*/
|
|
270
|
+
storage?: 'session' | 'local' | false;
|
|
271
|
+
}
|
|
272
|
+
interface EgwWebAuth {
|
|
273
|
+
/** The access token, refreshed when it is about to expire; undefined when signed out. */
|
|
274
|
+
getAccessToken(): Promise<string | undefined>;
|
|
275
|
+
/**
|
|
276
|
+
* Opens the sign-in popup — call it from a click, or the browser blocks the popup. Resolves once
|
|
277
|
+
* signed in; rejects with a message to show (popup blocked, closed, refused by the server).
|
|
278
|
+
*/
|
|
279
|
+
signIn(): Promise<void>;
|
|
280
|
+
signOut(): void;
|
|
281
|
+
/** Calls `listener` on sign-in, sign-out and refresh (in other tabs too, with `local`). */
|
|
282
|
+
onDidChangeSession(listener: () => void): () => void;
|
|
283
|
+
/** The signed-in account's name, or undefined. */
|
|
284
|
+
account(): string | undefined;
|
|
285
|
+
/** Closes a pending popup and stops listening. */
|
|
286
|
+
dispose(): void;
|
|
287
|
+
}
|
|
288
|
+
/** The EGW sign-in for a web page: see `EgwWebAuthOptions`. */
|
|
289
|
+
declare function createEgwWebAuth(options: EgwWebAuthOptions): EgwWebAuth;
|
|
97
290
|
|
|
98
291
|
interface RegisterWemlOptions {
|
|
99
292
|
/** File extensions to associate with the language (default: [".weml"]). */
|
|
@@ -105,4 +298,4 @@ interface RegisterWemlOptions {
|
|
|
105
298
|
}
|
|
106
299
|
declare function registerWeml(m: typeof monaco, options?: RegisterWemlOptions): monaco.IDisposable;
|
|
107
300
|
|
|
108
|
-
export { type IdEdit, type RegisterWemlOptions, WEML_LANGUAGE_ID, type WemlActionOptions, type WemlNormalizationFailure, type WemlToolbar, type WemlToolbarOptions, buildWrapSnippet, canonicalFormattingFailureMessage, createWemlToolbar, cycleFormat, formatWemlText, insertSnippetById, isWemlNormalizationFailure, isWemlStructureValidationFailure, planDivIdRenumber, registerWeml, registerWemlEditorActions, renumberDivIds, validateWemlModel, wrapSelection };
|
|
301
|
+
export { type EgwWebAuth, type EgwWebAuthOptions, type IdEdit, type MonacoPanelHostOptions, type MonacoPanelSearchOptions, type RegisterWemlOptions, TOOL_GROUPS, TOOL_ITEMS, type ToolAction, type ToolGroup, type ToolItem, type ToolMatch, type ToolMode, WEML_LANGUAGE_ID, type WemlActionOptions, type WemlNormalizationFailure, type WemlToolbar, type WemlToolbarOptions, type WrapOption, buildWrapSnippet, canonicalFormattingFailureMessage, createEgwWebAuth, createMonacoPanelHost, createWemlToolbar, cycleFormat, filterToolItems, formatWemlText, insertSnippetById, isWemlNormalizationFailure, isWemlStructureValidationFailure, planDivIdRenumber, registerWeml, registerWemlEditorActions, renumberDivIds, toolItemsFor, validateWemlModel, wrapSelection };
|