weml-monaco 0.6.0 → 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 +46 -3
- package/README.md +119 -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.mjs +24672 -24456
- package/dist/weml.worker.mjs.map +1 -1
- package/dist/worker.cjs +110 -118
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.mjs +110 -118
- package/dist/worker.mjs.map +1 -1
- package/package.json +43 -12
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,52 @@ All notable changes to the **Monaco** contribution (`weml-monaco`) are documente
|
|
|
4
4
|
here. The format is based on [Keep a Changelog](https://keepachangelog.com/), and
|
|
5
5
|
this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
-
This package
|
|
8
|
-
track the port catching up with
|
|
9
|
-
|
|
7
|
+
This package shares the language logic of the VS Code extension (`weml-support`): older
|
|
8
|
+
entries below track the port catching up with its provider changes; since the shared language
|
|
9
|
+
features, both take the same code.
|
|
10
|
+
|
|
11
|
+
## [0.7.0] — 2026-10-08
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- The WEML panel, `weml-monaco/panel` (+ `weml-monaco/panel.css`): the Tools and Search
|
|
15
|
+
Suggestions of the WEML Tools VS Code extension as a framework-free DOM component
|
|
16
|
+
(`createWemlPanel`), the same look and behaviour, theme from Monaco's `--vscode-*` variables.
|
|
17
|
+
- `createMonacoPanelHost(editor, options)`: the panel's host for a Monaco editor — tools on the
|
|
18
|
+
editor, EGW search with the host application's access token, layout in `localStorage`.
|
|
19
|
+
- `createEgwWebAuth(options)`: the EGW sign-in for a web page without one of its own — OIDC
|
|
20
|
+
code flow + PKCE in a popup, tokens in `sessionStorage` (or `localStorage`), refreshed; spread
|
|
21
|
+
into `createMonacoPanelHost`'s `search`. The panel shows why a sign-in failed under its button
|
|
22
|
+
(`signIn` may return a promise).
|
|
23
|
+
- The WEML preview, `weml-monaco/preview` (`createWemlPreview`): a live preview of the editor's
|
|
24
|
+
document rendered with weml-stylesheet — now an optional peer dependency (`^4.0.0`), needed
|
|
25
|
+
only by this entry.
|
|
26
|
+
- The preview's scroll sync with the editor, both ways (`scrollSync` option, `setScrollSync`),
|
|
27
|
+
sharing its line mapping with the VS Code preview; a `transform` may return
|
|
28
|
+
`{ markup, firstLine }`; double-click on a block goes to its line (`doubleClickToEditor`).
|
|
29
|
+
It looks like the open file next to it: the editor's background, text and scrollbars (10px,
|
|
30
|
+
the theme's slider) through `monaco-component` on the pane (`monacoTheme: false` to leave it
|
|
31
|
+
off), not the page's background and the browser's scrollbars.
|
|
32
|
+
- `TOOL_ITEMS` / `TOOL_GROUPS` / `filterToolItems` / `toolItemsFor(mode)`: everything the Tools
|
|
33
|
+
offer as one list, grouped Containers / Blocks / Inlines, for a host that builds its own picker.
|
|
34
|
+
- Completion in `<body>` offers a new section with any container — *div + w-para*,
|
|
35
|
+
*div + w-toc* and *div + w-page* join *div + w-heading* and *div + w-para-group*.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- The WEML panel's Tools: the wrap `<select>` and the Insert buttons are one searchable tag picker
|
|
39
|
+
drawn as VS Code's quick pick (Enter or a click chooses, the button in the field wraps or
|
|
40
|
+
inserts; the choice is remembered). It offers every tag of the docs' containers, blocks and
|
|
41
|
+
inlines — new: `w-para-group`, `w-toc`, a new `div` section (with `w-para`, `w-heading`,
|
|
42
|
+
`w-para-group`, `w-toc`, or a `w-page` page break), `w-text-block`, `hr`, `w-page`, `br`,
|
|
43
|
+
the `a id` anchor, and `w-sent` to wrap in. Inputs and buttons are 26px, as in VS Code,
|
|
44
|
+
whatever the host page's line height; the panes' borders show under Monaco themes too.
|
|
45
|
+
- `createWemlPanel`'s `renumber` option is `mode: 'file' | 'paragraph'`: a paragraph has no
|
|
46
|
+
Renumber and no `div` sections to insert (`toolItemsFor(mode)`).
|
|
47
|
+
- Diagnostics, hover, completion and the outline come from the language logic shared with the
|
|
48
|
+
VS Code extension instead of a copy of it — the same problems, tooltips and suggestions in
|
|
49
|
+
both editors; no change in behaviour or API.
|
|
50
|
+
|
|
51
|
+
### Deprecated
|
|
52
|
+
- `createWemlToolbar`: use the WEML panel (and `registerWemlEditorActions` for the hotkeys alone).
|
|
10
53
|
|
|
11
54
|
## [0.6.0] — 2026-10-06
|
|
12
55
|
|
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@ extension. It provides, for models with language id `weml`:
|
|
|
23
23
|
HTML ↔ canonical format cycle.
|
|
24
24
|
|
|
25
25
|
This package does **not** modify the original VS Code extension — it is a
|
|
26
|
-
standalone re-implementation living entirely
|
|
26
|
+
standalone re-implementation living entirely in this package (`packages/weml-monaco` of the
|
|
27
|
+
monorepo).
|
|
27
28
|
|
|
28
29
|
## Install & build
|
|
29
30
|
|
|
@@ -31,9 +32,9 @@ standalone re-implementation living entirely under `monaco-editor/`.
|
|
|
31
32
|
npm install weml-monaco
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
The package has no runtime dependencies (`node-html-parser
|
|
35
|
-
`vscode-html-languageservice` are bundled in) and
|
|
36
|
-
dependency you already have.
|
|
35
|
+
The package has no runtime dependencies (`node-html-parser`,
|
|
36
|
+
`vscode-html-languageservice` and the shared normalizer are bundled in) and
|
|
37
|
+
`monaco-editor` is a peer dependency you already have.
|
|
37
38
|
|
|
38
39
|
| entry point | file | for |
|
|
39
40
|
| ---------------------- | ----------------------- | -------------------------------------- |
|
|
@@ -44,8 +45,8 @@ dependency you already have.
|
|
|
44
45
|
Working on the package itself:
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
npm ci # at the repository root (npm workspaces)
|
|
49
|
+
cd packages/weml-monaco
|
|
49
50
|
npm run build # tsup → dist/ (ESM + CJS + IIFE + declarations)
|
|
50
51
|
npm run typecheck # tsc --noEmit
|
|
51
52
|
npm test # build + Node smoke test
|
|
@@ -141,31 +142,104 @@ hovers, outline and markers are the same; only where they are computed changes.
|
|
|
141
142
|
terminated on `dispose()`). The global `<script>` build (`index.global.js`) has
|
|
142
143
|
no worker variant.
|
|
143
144
|
|
|
144
|
-
##
|
|
145
|
+
## The WEML panel
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
The side panel of the WEML Tools VS Code extension — **Tools** (wrap the
|
|
148
|
+
selection, insert snippets, renumber `<div>` ids) and **Search Suggestions**
|
|
149
|
+
(EGW search with ParaId / BookCode and `egw://` links to copy or insert) — as a
|
|
150
|
+
framework-free DOM component: the same panel, look and behaviour as in VS Code
|
|
151
|
+
(the extension's webview bundles this very code). It follows Monaco's theme
|
|
152
|
+
through the `--vscode-*` variables Monaco defines on `.monaco-component`.
|
|
149
153
|
|
|
150
154
|
```ts
|
|
151
|
-
import { registerWeml,
|
|
155
|
+
import { createMonacoPanelHost, registerWeml, registerWemlEditorActions } from 'weml-monaco';
|
|
156
|
+
import { createWemlPanel } from 'weml-monaco/panel';
|
|
152
157
|
|
|
153
158
|
registerWeml(monaco);
|
|
154
159
|
const editor = monaco.editor.create(container, { model });
|
|
160
|
+
registerWemlEditorActions(monaco, editor); // the hotkeys (below)
|
|
161
|
+
|
|
162
|
+
const panel = createWemlPanel(
|
|
163
|
+
createMonacoPanelHost(editor, {
|
|
164
|
+
search: {
|
|
165
|
+
apiUrl: 'https://…', // the EGW API
|
|
166
|
+
getAccessToken: () => auth.token, // your app's sign-in — the only part you supply
|
|
167
|
+
signIn: () => auth.login(),
|
|
168
|
+
onDidChangeSession: (listener) => auth.subscribe(listener),
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
{ container: document.getElementById('weml-panel') },
|
|
172
|
+
);
|
|
173
|
+
// panel.dispose() removes it.
|
|
174
|
+
```
|
|
155
175
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
- `createWemlPanel` (`weml-monaco/panel`, light: UI only) takes any
|
|
177
|
+
`WemlPanelHost` — tools, an optional search backend, optional storage.
|
|
178
|
+
`createMonacoPanelHost` (main entry) is that host for a Monaco editor: the
|
|
179
|
+
tools edit the editor, the search sends your token as a bearer (nothing is
|
|
180
|
+
sent while signed out), and the layout is remembered in `localStorage`
|
|
181
|
+
(`storage: false` to opt out). Without `search` the pane says the search is
|
|
182
|
+
not configured; `search: false` leaves the pane out.
|
|
183
|
+
- An app without a sign-in of its own takes `createEgwWebAuth` — the EGW
|
|
184
|
+
sign-in (OIDC code flow + PKCE) in a popup, tokens in `sessionStorage`,
|
|
185
|
+
refreshed before they expire:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { createEgwWebAuth } from 'weml-monaco';
|
|
189
|
+
|
|
190
|
+
const auth = createEgwWebAuth({ authority, clientId, scopes: 'openid offline_access search' });
|
|
191
|
+
createMonacoPanelHost(editor, { search: { apiUrl, ...auth } });
|
|
192
|
+
auth.signOut(); // from the app's own account menu
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The popup comes back to `<origin>/auth-callback` (`redirectUri` to change it),
|
|
196
|
+
which the client must allow; a blank page there is enough. `storage: 'local'`
|
|
197
|
+
shares the session between tabs. A failed sign-in (popup blocked or closed,
|
|
198
|
+
refused) shows its message under the Sign in button.
|
|
199
|
+
- The stylesheet is injected into the page by default; it is also published as
|
|
200
|
+
`weml-monaco/panel.css` (`injectStyles: false` to link it yourself).
|
|
201
|
+
- `mode: 'paragraph'` for an editor of one paragraph (the content of one `<div>`): no Renumber
|
|
202
|
+
div ids, and no `div + …` sections among the tags to insert. Default: `'file'`.
|
|
203
|
+
|
|
204
|
+
## The WEML preview
|
|
205
|
+
|
|
206
|
+
A live preview of the editor's document, rendered with
|
|
207
|
+
[`weml-stylesheet`](../weml-stylesheet) — an **optional peer dependency**:
|
|
208
|
+
install it (and load its CSS) to use this entry; nothing else needs it.
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { createWemlPreview } from 'weml-monaco/preview';
|
|
212
|
+
import 'weml-stylesheet/css/weml.scoped.css';
|
|
162
213
|
|
|
163
|
-
|
|
164
|
-
|
|
214
|
+
const preview = createWemlPreview(editor, {
|
|
215
|
+
container: document.getElementById('weml-preview'),
|
|
216
|
+
theme: 'dark', // data-weml-theme; omit to follow prefers-color-scheme
|
|
217
|
+
});
|
|
218
|
+
preview.setTheme('light');
|
|
219
|
+
preview.dispose();
|
|
165
220
|
```
|
|
166
221
|
|
|
167
|
-
|
|
168
|
-
|
|
222
|
+
It renders at once, then after a pause in typing (`delay`, 300 ms), and at once
|
|
223
|
+
again when the editor gets another model; an unchanged text is not rendered
|
|
224
|
+
twice (a whole book is not cheap). A whole document keeps its `dir` / `lang`
|
|
225
|
+
(right-to-left books render right to left). Blank text shows `emptyText`;
|
|
226
|
+
`transform(text)` picks what to render (e.g. without a wrapper your editor adds).
|
|
227
|
+
|
|
228
|
+
**Scroll sync**, both ways, as in the VS Code preview (and with the same code,
|
|
229
|
+
weml-language-core's): the rendered blocks carry their source line, so the
|
|
230
|
+
preview follows the editor's top line and the editor follows the preview. Turn
|
|
231
|
+
it off, or one way only, with `scrollSync` — `true` (default), `false`, or
|
|
232
|
+
`{ previewWithEditor, editorWithPreview }` — and later with
|
|
233
|
+
`preview.setScrollSync(...)`; there is no button of its own, the host decides.
|
|
234
|
+
A `transform` that drops lines from the top returns `{ markup, firstLine }` (the
|
|
235
|
+
model line its markup starts on) so the lines still match. A double-click on a
|
|
236
|
+
block puts the editor's cursor on its line (`doubleClickToEditor: false` to
|
|
237
|
+
turn it off).
|
|
238
|
+
|
|
239
|
+
## Editor commands
|
|
240
|
+
|
|
241
|
+
`registerWemlEditorActions(monaco, editor, options)` registers the editor
|
|
242
|
+
actions (keybindings and the command palette):
|
|
169
243
|
|
|
170
244
|
| action / command | keybinding | effect |
|
|
171
245
|
| ------------------------- | ------------- | -------------------------------------------------- |
|
|
@@ -175,38 +249,36 @@ panel too, via keybindings and the command palette):
|
|
|
175
249
|
| `weml.cycleFormat` | `Alt+Shift+F` | cycle document: HTML ↔ canonical WEML formatting |
|
|
176
250
|
| `weml.renumberDivIds` | — | renumber every `<div>` id to a sequential 1…n |
|
|
177
251
|
|
|
178
|
-
|
|
179
|
-
`
|
|
180
|
-
|
|
181
|
-
|
|
252
|
+
The underlying operations (`wrapSelection`, `insertSnippetById`,
|
|
253
|
+
`renumberDivIds`, `cycleFormat`) and the pure helpers (`planDivIdRenumber`,
|
|
254
|
+
`buildWrapSnippet`) are exported too. Snippet insertion uses Monaco's
|
|
255
|
+
`snippetController2`, so `$1`/`$2` tab stops behave like `editor.insertSnippet`
|
|
256
|
+
in VS Code.
|
|
182
257
|
|
|
183
|
-
|
|
184
|
-
behave like `editor.insertSnippet` in VS Code.
|
|
258
|
+
### `createWemlToolbar` (deprecated)
|
|
185
259
|
|
|
186
|
-
|
|
260
|
+
The earlier flat DOM toolbar (`createWemlToolbar(monaco, editor, { container,
|
|
261
|
+
onStatus })`) still works and still registers the editor actions, but it is
|
|
262
|
+
deprecated in favour of the WEML panel and gets no new features.
|
|
187
263
|
|
|
188
|
-
|
|
189
|
-
npm run demo # builds dist/ and copies the IIFE bundle → demo/weml-monaco.js
|
|
190
|
-
# then open demo/index.html in a browser
|
|
191
|
-
```
|
|
264
|
+
## Trying it out
|
|
192
265
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
266
|
+
The monorepo's dev app, [`weml-storybook`](../weml-storybook)
|
|
267
|
+
(`npm start -w weml-storybook` from the repository root), runs this package from
|
|
268
|
+
its sources in a full editor: completions (Ctrl+Space), hover, "Format
|
|
269
|
+
Document", the outline, diagnostics and the toolbar.
|
|
197
270
|
|
|
198
271
|
## How it relates to the VS Code extension
|
|
199
272
|
|
|
200
|
-
The
|
|
273
|
+
The language logic is shared with the VS Code extensions, not copied — two workspace packages,
|
|
274
|
+
bundled into every build (neither is a runtime dependency):
|
|
201
275
|
|
|
202
|
-
|
|
|
276
|
+
| shared (workspace package) | adapted for Monaco |
|
|
203
277
|
| ------------------------------------ | ---------------------------------------- |
|
|
204
|
-
| `
|
|
205
|
-
| `
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
runs in the browser
|
|
211
|
-
APIs for `monaco.languages.*` and converting between Monaco's 1-based
|
|
212
|
-
line/column positions and the language service's 0-based LSP positions.
|
|
278
|
+
| `weml-language-core`: schema, structure rules, snippets, entities, markdown text, the language features (diagnostics, hover, completion, outline), tool model, wrap / renumber | `schema/docs.ts` (plain `IMarkdownString`) |
|
|
279
|
+
| `weml-normalizer`: the canonical normalizer | `wemlDocument.ts` (parse cache, offsets ↔ Monaco positions), `providers/*` (the features' data → Monaco provider types), `index.ts` (registration + diagnostics) |
|
|
280
|
+
|
|
281
|
+
The diagnostics, tooltips, suggestions and outline are computed once, in the shared package, as
|
|
282
|
+
plain data with offsets — the VS Code extension and this package only map them to their editor's
|
|
283
|
+
types, so both editors report the same problems and offer the same items. Parsing uses
|
|
284
|
+
`vscode-html-languageservice` (editor-agnostic, runs in the browser and in the worker).
|