@moraya/core 0.1.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 +344 -0
- package/LICENSE +85 -0
- package/README.md +82 -0
- package/dist/adapters/browser-media-resolver.d.ts +21 -0
- package/dist/adapters/browser-media-resolver.js +24 -0
- package/dist/adapters/browser-media-resolver.js.map +1 -0
- package/dist/commands.d.ts +35 -0
- package/dist/commands.js +976 -0
- package/dist/commands.js.map +1 -0
- package/dist/doc-cache.d.ts +29 -0
- package/dist/doc-cache.js +50 -0
- package/dist/doc-cache.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +4534 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +46 -0
- package/dist/markdown.js +1553 -0
- package/dist/markdown.js.map +1 -0
- package/dist/plugins/code-block-view.d.ts +52 -0
- package/dist/plugins/code-block-view.js +686 -0
- package/dist/plugins/code-block-view.js.map +1 -0
- package/dist/plugins/cursor-syntax.d.ts +27 -0
- package/dist/plugins/cursor-syntax.js +122 -0
- package/dist/plugins/cursor-syntax.js.map +1 -0
- package/dist/plugins/definition-list.d.ts +23 -0
- package/dist/plugins/definition-list.js +12 -0
- package/dist/plugins/definition-list.js.map +1 -0
- package/dist/plugins/editor-props-plugin.d.ts +36 -0
- package/dist/plugins/editor-props-plugin.js +1963 -0
- package/dist/plugins/editor-props-plugin.js.map +1 -0
- package/dist/plugins/emoji.d.ts +21 -0
- package/dist/plugins/emoji.js +42 -0
- package/dist/plugins/emoji.js.map +1 -0
- package/dist/plugins/enter-handler.d.ts +26 -0
- package/dist/plugins/enter-handler.js +193 -0
- package/dist/plugins/enter-handler.js.map +1 -0
- package/dist/plugins/highlight.d.ts +39 -0
- package/dist/plugins/highlight.js +283 -0
- package/dist/plugins/highlight.js.map +1 -0
- package/dist/plugins/inline-code-convert.d.ts +32 -0
- package/dist/plugins/inline-code-convert.js +173 -0
- package/dist/plugins/inline-code-convert.js.map +1 -0
- package/dist/plugins/link-text-plugin.d.ts +22 -0
- package/dist/plugins/link-text-plugin.js +194 -0
- package/dist/plugins/link-text-plugin.js.map +1 -0
- package/dist/plugins/mermaid-renderer.d.ts +24 -0
- package/dist/plugins/mermaid-renderer.js +80 -0
- package/dist/plugins/mermaid-renderer.js.map +1 -0
- package/dist/schema.d.ts +48 -0
- package/dist/schema.js +847 -0
- package/dist/schema.js.map +1 -0
- package/dist/setup.d.ts +104 -0
- package/dist/setup.js +4393 -0
- package/dist/setup.js.map +1 -0
- package/dist/types.d.ts +107 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +121 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@moraya/core` are documented here. SemVer.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-05-07
|
|
6
|
+
|
|
7
|
+
Initial public release on npmjs.com. Faithful 1:1 extraction of Moraya desktop's `src/lib/editor/` markdown editor core into a host-agnostic, dependency-injected ESM package, per the iteration spec at [`v0.60.0-pre-shared-markdown-core.md`](https://github.com/zouwei/moraya/blob/main/docs/iterations/v0.60.0-pre-shared-markdown-core.md).
|
|
8
|
+
|
|
9
|
+
### Package identity
|
|
10
|
+
|
|
11
|
+
- **Name**: `@moraya/core` (final name; renamed twice during pre-release: working name `@moraya/markdown-core` → interim `@zouwei/moraya-core` (GitHub Packages attempt) → final `@moraya/core` (npmjs.com public))
|
|
12
|
+
- **Repo**: https://github.com/zouwei/moraya-core (public)
|
|
13
|
+
- **Registry**: npmjs.com (https://registry.npmjs.org), `access: public` — anyone can `npm install @moraya/core` with no token
|
|
14
|
+
- **License**: PolyForm Internal Use 1.0.0
|
|
15
|
+
|
|
16
|
+
### Distribution rationale
|
|
17
|
+
|
|
18
|
+
The original spec §5.1 chose GitHub Packages (private) for cost reasons, but GitHub Packages requires authentication even for public packages — incompatible with Moraya's open-source distribution model. The pre-release `@zouwei/moraya-core@0.1.0` published to GitHub Packages on 2026-05-06 was unpublished; `@moraya/core@0.1.0` on npmjs.com supersedes it.
|
|
19
|
+
|
|
20
|
+
### Surface
|
|
21
|
+
|
|
22
|
+
- **Schema**: `createSchema(config)` factory + 23 nodes / 6 marks (faithful 1:1 from desktop)
|
|
23
|
+
- **Markdown**: `parseMarkdown` / `parseMarkdownAsync` (≥50KB threshold) / `serializeMarkdown` with cross-schema parser cache
|
|
24
|
+
- **Editor lifecycle**: `createEditor` / `createEditorPlugins` / `preloadEnhancementPlugins` (Tier 1 chunked dynamic import: highlight + emoji + code-block-view)
|
|
25
|
+
- **Plugins** (11 total): 8 base + 3 DI-coupled (highlight / editor-props / code-block-view); `review-decoration` excluded (stays in moraya for v0.30.0+ team-collab)
|
|
26
|
+
- **Doc cache**: `createDocCache(maxEntries?)` + `djb2Hash`
|
|
27
|
+
- **Commands** (14): bold/italic/strike/code/heading/blockquote/lists/code-block/table/HR/math-block/link/image
|
|
28
|
+
- **Adapters**: `BrowserMediaResolver` (Tauri / Electron / Capacitor adapters live in their consumer repos)
|
|
29
|
+
- **DI seams**: `MediaResolver` / `LinkOpener` / `RendererRegistry` / `Platform` (4 interfaces, §3.3)
|
|
30
|
+
|
|
31
|
+
### Engineering contract
|
|
32
|
+
|
|
33
|
+
- **Pure ESM** — `dist/` contains 0 Node API imports, 0 `require()`, 0 host-specific imports (verified by 4 §1.1.4 CI gates)
|
|
34
|
+
- **Bundle**: main entry **34 KB gzipped** (42% of 80 KB budget)
|
|
35
|
+
- **Tests**: 106 vitest cases across 4 spec files
|
|
36
|
+
- 72 roundtrip tests (55 fixture files + 17 schema-critical data traps)
|
|
37
|
+
- 23 API contract tests
|
|
38
|
+
- 6 plugin-order fingerprint snapshots
|
|
39
|
+
- 5 adapter unit tests
|
|
40
|
+
- **Behavior parity**: §1.2.2 layer 1 (fixture roundtrip) + layer 2 (plugin order snapshot) green; layer 3 (3-note byte-diff) deferred to consumer-side smoke test
|
|
41
|
+
|
|
42
|
+
### Tarball hygiene
|
|
43
|
+
|
|
44
|
+
`pnpm pack` produces a 58-entry tarball containing only:
|
|
45
|
+
- `package/LICENSE`, `package/package.json`, `package/CHANGELOG.md`, `package/README.md`
|
|
46
|
+
- `package/dist/**/*.{js,js.map,d.ts}`
|
|
47
|
+
|
|
48
|
+
No `*.svelte`, `src-tauri/`, `*.test.ts`, lockfile, or fixtures leak into the published artifact.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## [Unreleased / pre-release notes] — schema + markdown + plugins/setup + DI plugins migration batches (2026-05-05 — 2026-05-06)
|
|
53
|
+
|
|
54
|
+
### DI plugins batch (2026-05-06)
|
|
55
|
+
|
|
56
|
+
Final batch of plugin migration. All 11 ProseMirror plugins from Moraya desktop's `src/lib/editor/plugins/` (excluding `review-decoration.ts` which stays in moraya/) are now in core.
|
|
57
|
+
|
|
58
|
+
#### Added (3 DI-coupled plugins migrated faithfully)
|
|
59
|
+
|
|
60
|
+
**`plugins/highlight.ts`** — full faithful 1:1 migration replaces the prior no-op stub.
|
|
61
|
+
- Imports + registers 39 highlight.js languages (javascript / typescript / python / rust / go / c / cpp / java / ruby / php / swift / kotlin / yaml / json / bash / sql / xml / html / css / scss / dart / r / perl / scala / objectivec / dockerfile / ini / powershell / makefile / groovy / elixir / haskell / protobuf / graphql / latex / nginx / shell / markdown / diff / lua + svelte/jsx/tsx aliases + cs / py / sh / rb / kt / yml / md / pl / objc / ex / hs / proto / gql / tex / nginxconf / ps1)
|
|
62
|
+
- `flattenHljsTree(rootNode)` + `scopeToClasses` walk hljs v11 emitter tree
|
|
63
|
+
- Per-block cache keyed by `(language, code)` with FIFO eviction at 100 entries (Moraya CLAUDE.md "Performance Coding Standards" §6 contract)
|
|
64
|
+
- 300 ms debounced full re-highlight via metadata-only transaction
|
|
65
|
+
- File-switch (`tr.getMeta('file-switch')`) and full-delete (`tr.getMeta('full-delete')`) paths rebuild from scratch
|
|
66
|
+
- Short-circuit when `tr.mapping` doesn't touch any code_block (saves ~90% of keystroke debounces)
|
|
67
|
+
- Schema-agnostic (no `$lib/` imports); zero behavior drift from desktop
|
|
68
|
+
|
|
69
|
+
**`plugins/editor-props-plugin.ts`** — full faithful 1:1 migration with `Platform` + `LinkOpener` DI.
|
|
70
|
+
- `editorStore.getState().currentFilePath` → `platform.getCurrentFilePath()`
|
|
71
|
+
- `isMacOS` from `$lib/utils/platform` → `platform.isMacOS`
|
|
72
|
+
- `import('@tauri-apps/plugin-opener').{openPath,openUrl}` → `linkOpener.open(href)` (consumer's LinkOpener routes URL vs local-file)
|
|
73
|
+
- 5-plugin merge preserved: `clipboardTextParser` + `handlePaste` (markdown image / empty link / degenerate slice fallbacks) + `transformPastedHTML` (language- → data-language) + `handleDOMEvents.{click,mousedown,keydown,keyup}` (link-hover class / Cmd+click open / math_block click / fast AllSelection delete / WKWebView Backspace fix) + `handleClick` (click-below-content append paragraph) + `handleClickOn` (image → TextSelection) + `handleKeyDown` (ArrowRight ZWSP escape / fast AllSelection delete fallback) + `decorations` (caret-empty-para macOS) + `view` lifecycle (scroll-after-paste + WKWebView empty-doc focus recovery)
|
|
74
|
+
- `isLocalFilePath` / `resolveLocalPath` ported as pure helpers (resolve-against-currentFile uses `platform.getCurrentFilePath()`)
|
|
75
|
+
|
|
76
|
+
**`plugins/code-block-view.ts`** — full faithful 1:1 migration with `RendererRegistry` DI.
|
|
77
|
+
- `RENDERER_PLUGINS` / `loadRendererPlugin` / `rendererVersions` (moraya-internal) → `RendererRegistry` injected via `createCodeBlockNodeViewFactory({ rendererRegistry })`
|
|
78
|
+
- Renderer plugin language list + versions derived from `registry.versions` keys
|
|
79
|
+
- Mermaid still has built-in special-case path (`language === 'mermaid'`) using core's `plugins/mermaid-renderer.ts`
|
|
80
|
+
- `LanguageEntry` registry (POPULAR_LANGUAGES + BASE_OTHER_LANGUAGES + dynamic renderer-plugin entries) + `findLanguageLabel`
|
|
81
|
+
- Language picker with auto-detect via `hljs.highlightAuto` (relevance > 5 threshold), grouped Popular / All / Renderer Plugins, keyboard nav, outside-click + Escape dismiss, focus-stealing-prevention via append-to-`.editor-wrapper` (not into ProseMirror DOM)
|
|
82
|
+
- Mermaid render path: lazy `loadMermaidApi()` → serial render queue → debounce 150 ms → SVG injection or error fallback → theme-change re-render via MutationObserver on `data-theme`
|
|
83
|
+
- Renderer render path: `registry.load(lang).render(source, container)` with §3.3 error contract: `<div class="renderer-error" data-language data-error>` fallback DOM, `module.destroy?(container)` called on lang-change / NodeView destroy
|
|
84
|
+
- Copy button + toggle-edit/preview button + `stopEvent` / `ignoreMutation` / `update` / `selectNode` / `deselectNode` / `destroy` lifecycle 1:1 from moraya
|
|
85
|
+
- 580 lines → ~700 lines (faithful, no shortcuts; the §1.2.4 "no simplification" rule is honored)
|
|
86
|
+
|
|
87
|
+
#### Wired into setup.ts (this batch)
|
|
88
|
+
- `preloadEnhancementPlugins(schema, rendererRegistry?)` now loads **3 chunks** in parallel: highlight + emoji + **code-block-view** (was 2 in previous batch)
|
|
89
|
+
- Cache key extended from `Schema` → `{ schema, rendererRegistry }` so consumers with different registry produce different cached factories
|
|
90
|
+
- `createEditorPlugins` adds `createEditorPropsPlugin({ platform, linkOpener })` between `columnResizing` and `cursorSyntax`
|
|
91
|
+
- `createEditor` wires `nodeViews.code_block` from `tier1.codeBlockView`
|
|
92
|
+
- Default `LinkOpener` (`window.open(href, '_blank', 'noopener,noreferrer')`) added when consumer doesn't inject one
|
|
93
|
+
|
|
94
|
+
#### Plugin order snapshot updates (§1.2.2)
|
|
95
|
+
Snapshot diffs reflect intentional changes:
|
|
96
|
+
- New `moraya-editor-props$` plugin added between `tableColumnResizing$` and `moraya-cursor-syntax$` (rank 8 → 9 shift for downstream plugins)
|
|
97
|
+
- Highlight key renamed: `moraya-highlight$` (stub) → `moraya-syntax-highlight$` (faithful)
|
|
98
|
+
Snapshots regenerated and committed per §1.2.2 reviewer-approval workflow.
|
|
99
|
+
|
|
100
|
+
#### Verification (this batch)
|
|
101
|
+
- ✅ `pnpm typecheck` clean (strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes)
|
|
102
|
+
- ✅ `pnpm test`: **68/68 pass** (snapshots updated + all roundtrip / api-contract / data-trap / plugin-order tests still passing)
|
|
103
|
+
- ✅ `pnpm build`: ESM + .d.ts; `dist/index.js` gzipped = **33.9 KB** (41% of 80 KB budget)
|
|
104
|
+
- ✅ §1.1.4 purity gates green (`.js` only): 0 Node API / 0 `require()` / 0 `@tauri-apps`/`@capacitor`/`electron` imports in dist
|
|
105
|
+
- ✅ Tier 1 chunks: `highlight.js` 2.4 KB gzipped, `code-block-view.js` 6.1 KB gzipped (hljs + mermaid live in consumer's bundle as peer deps)
|
|
106
|
+
|
|
107
|
+
#### Plugin migration progress: 11/11 ✅
|
|
108
|
+
| Plugin | Status |
|
|
109
|
+
|---|---|
|
|
110
|
+
| keybindings | Stays in moraya (static data, not a PM plugin) |
|
|
111
|
+
| definition-list | ✅ migrated |
|
|
112
|
+
| emoji | ✅ migrated |
|
|
113
|
+
| cursor-syntax | ✅ migrated |
|
|
114
|
+
| enter-handler | ✅ migrated |
|
|
115
|
+
| inline-code-convert | ✅ migrated |
|
|
116
|
+
| link-text | ✅ migrated |
|
|
117
|
+
| mermaid-renderer | ✅ migrated |
|
|
118
|
+
| **highlight** | ✅ migrated (this batch) |
|
|
119
|
+
| **editor-props-plugin** | ✅ migrated (this batch) |
|
|
120
|
+
| **code-block-view** | ✅ migrated (this batch) |
|
|
121
|
+
| review-decoration | Stays in moraya (v0.30.0+ team-collab specific) |
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
### plugins + setup batch (2026-05-06)
|
|
126
|
+
|
|
127
|
+
#### Added (8 plugins migrated faithfully)
|
|
128
|
+
- **`plugins/definition-list.ts`** — `createDefListInputRule(schema)` factory (schema-parameterized)
|
|
129
|
+
- **`plugins/emoji.ts`** — `createEmojiPlugin()` converts `:shortcode:` → emoji via `node-emoji` peer dep
|
|
130
|
+
- **`plugins/cursor-syntax.ts`** — Typora-style source-syntax overlay (heading/blockquote prefix + paired mark delimiters for strong/em/code/strike_through)
|
|
131
|
+
- **`plugins/enter-handler.ts`** — unified Enter-key handler (table cell row navigation + Cmd+Enter add row + Shift+Enter hardbreak + plain Enter exits last row + code-fence detection + pipe-table detection with `parsePipeTableHeader`/`buildTableFromHeaders`)
|
|
132
|
+
- **`plugins/inline-code-convert.ts`** — backtick-pair collapse + ZWSP cursor target after trailing `code/strong/em/strike_through` marks + storedMarks management at code-ZWSP boundary
|
|
133
|
+
- **`plugins/link-text-plugin.ts`** — `[text](url)` literal-text decoration + cursor-leave collapse to link mark + cursor-enter expand-back-to-literal
|
|
134
|
+
- **`plugins/mermaid-renderer.ts`** — lazy-loaded mermaid render utility (serial render queue, theme-color resolution from CSS custom properties); `mermaid` declared as optional peer (`peerDependenciesMeta.mermaid.optional = true`)
|
|
135
|
+
|
|
136
|
+
All plugin code is **host-agnostic**: zero Tauri / store / DOM-singleton imports. Schema lookups go through `state.schema.nodes[name]` / `state.schema.marks[name]` so each plugin works against any consumer-injected schema produced by `createSchema(config)`.
|
|
137
|
+
|
|
138
|
+
#### Skipped (intentional — moved out of core scope)
|
|
139
|
+
- **`keybindings.ts`** is **NOT a ProseMirror plugin** — it's static `KeyBinding[]` data consumed only by Moraya's CommandPalette UI (file save / zoom / sidebar toggle / etc.). Heavily app-specific shortcut metadata; stays in moraya/. The v0.60.0-pre §3 file-tree listing this in `plugins/` was a documentation artifact.
|
|
140
|
+
|
|
141
|
+
#### Pending for next batch (3 DI-coupled plugins)
|
|
142
|
+
- `editor-props-plugin.ts` (580 lines, needs `Platform.getCurrentFilePath` + `isMacOS` + `LinkOpener.open` injection)
|
|
143
|
+
- `code-block-view.ts` (780 lines, needs full `RendererRegistry` integration + mermaid wiring)
|
|
144
|
+
- `highlight.ts` faithful hljs integration (current core stub is no-op; full migration requires per-block decoration cache from Moraya CLAUDE.md performance §6/§9 contract)
|
|
145
|
+
|
|
146
|
+
### setup.ts batch (2026-05-06)
|
|
147
|
+
|
|
148
|
+
Replaces the 6KB minimum-viable stub with a 21KB faithful migration of Moraya desktop's editor lifecycle (730 lines).
|
|
149
|
+
|
|
150
|
+
#### Added
|
|
151
|
+
- `preloadEnhancementPlugins(schema)` — schema-keyed Tier 1 lazy-load cache (highlight + emoji currently; code-block-view + KaTeX CSS in next batch)
|
|
152
|
+
- `createImageSelectionPlugin()` — blue-overlay decoration for selected image / `<img>` html_inline nodes
|
|
153
|
+
- **`buildInputRules(schema, tier1)`** — 12 input rules: code-fence, blockquote, bullet/ordered list, heading 1-6, hr, math block + inline, strong (`**` / `__`), em (`*` / `_`), inline code, strike_through (`~~`), task-list checkbox, link `[text](url)`, def-list (Tier 1)
|
|
154
|
+
- **`buildKeymap(schema)`** — full keymap from Moraya:
|
|
155
|
+
- `Mod-z/y/Shift-z` → `undo` / `redo` (top-level ESM imports, replaces 3 `require('prosemirror-history')` calls per §1.1.1 Pure ESM)
|
|
156
|
+
- `Mod-b/i/e/Shift-x` → strong / em / code / strike_through marks
|
|
157
|
+
- `Mod-Alt-0..6` → paragraph / heading levels
|
|
158
|
+
- `Mod-Alt-c` → code_block, `Mod-Shift-b` → blockquote
|
|
159
|
+
- `Tab` / `Shift-Tab` / `Mod-]` / `Mod-[` → list indent/outdent
|
|
160
|
+
- `Mod-a` → code-block-local select-all OR doc-wide AllSelection
|
|
161
|
+
- `Shift-Enter` → hardbreak with `isInline: false`
|
|
162
|
+
- `Backspace` → 5-case WebKit contenteditable bug fix (full-doc fast delete + NodeSelection-on-atom + cursor-end-before-atom + cursor-start-after-atom + end-of-paragraph-after-inline-atom + end-of-textblock surrogate-pair-aware delete)
|
|
163
|
+
- `Delete` → block-atom protection (NodeSelection move + textblock-end consume)
|
|
164
|
+
- **listShortcutsPlugin** — `Cmd+Alt+O/U/X` → ordered/bullet/task list using `event.code` (macOS Option-key safe, Moraya CLAUDE.md "Option键快捷键处理" feedback memory)
|
|
165
|
+
- **`createDirtyTrackPlugin`** + **`createLazyChangePlugin`** — O(1) text-content callback vs debounced markdown-serialization callback
|
|
166
|
+
- Full `createEditor(opts)` + `createEditorPlugins(opts, schema?)` — assembles 13 base plugins + Tier 1 lazy-loaded plugins in faithful order:
|
|
167
|
+
1. listShortcuts → 2. inputRules → 3. enter-handler → 4. buildKeymap → 5. baseKeymap →
|
|
168
|
+
6. history (skippable for v0.72 Yjs) → 7. dropCursor → 8. columnResizing →
|
|
169
|
+
9. cursorSyntax → 10. linkText → 11. inlineCodeConvert → 12. imageSelection →
|
|
170
|
+
13. dirty/lazy-change → 14. Tier 1 highlight + emoji
|
|
171
|
+
- `wrapInBulletList` / `wrapInOrderedList` / `wrapInTaskList` exported from `commands.ts` (schema-agnostic via `state.schema`)
|
|
172
|
+
|
|
173
|
+
#### Plugin order fingerprint (§1.2.2)
|
|
174
|
+
- New `__tests__/plugin-order.spec.ts`: 6 snapshot/assertion tests covering default Web config, desktop-style config, history disabled (Yjs path), table-resize disabled, onChange/onDocChanged callback variants. **Snapshot is committed** so any reorder/add/remove triggers explicit reviewer review.
|
|
175
|
+
|
|
176
|
+
#### New peer deps
|
|
177
|
+
- `mermaid@^11.0.0` (optional via `peerDependenciesMeta`)
|
|
178
|
+
- `node-emoji@^2.0.0`
|
|
179
|
+
- `prosemirror-commands@^1.7.0`
|
|
180
|
+
- `prosemirror-dropcursor@^1.8.0`
|
|
181
|
+
- `prosemirror-inputrules@^1.5.0`
|
|
182
|
+
- `prosemirror-keymap@^1.2.0`
|
|
183
|
+
- `prosemirror-schema-list@^1.5.0`
|
|
184
|
+
- `prosemirror-tables@^1.8.0`
|
|
185
|
+
|
|
186
|
+
#### Verification (this batch)
|
|
187
|
+
- ✅ `pnpm typecheck` clean (strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes)
|
|
188
|
+
- ✅ `pnpm test`: **68/68 pass** (was 62/62; +6 plugin-order fingerprint tests)
|
|
189
|
+
- ✅ `pnpm build`: ESM + .d.ts; `dist/index.js` gzipped = 22.7 KB (28% of 80 KB budget)
|
|
190
|
+
- ✅ §1.1.4 purity gates green: 0 Node API / 0 `require()` / 0 host imports in dist
|
|
191
|
+
- ✅ All `require()` calls in original Moraya `setup.ts:282/286/290/343` replaced with top-level ESM imports per §1.1.1
|
|
192
|
+
|
|
193
|
+
### markdown.ts batch (2026-05-06)
|
|
194
|
+
|
|
195
|
+
### markdown.ts batch (2026-05-06)
|
|
196
|
+
|
|
197
|
+
#### Added
|
|
198
|
+
- Faithful 1:1 migration of Moraya desktop `markdown.ts` (912 lines)
|
|
199
|
+
- Full token override `MorayaMarkdownParser` class:
|
|
200
|
+
- `tr_open` dispatches to `table_header_row` (inside `<thead>`) vs `table_row` —
|
|
201
|
+
fixes "thead content lost to auto-inserted empty header row" bug
|
|
202
|
+
- `th_open/close` + `td_open/close` wrap inline content in inner `paragraph`
|
|
203
|
+
so `content: 'paragraph+'` cells aren't dropped by `createAndFill`
|
|
204
|
+
- `link_open` detects empty-text links `[]()` / `[](url)` and inserts the raw
|
|
205
|
+
markdown syntax as literal text instead of an empty (=removed) mark
|
|
206
|
+
- `html_inline` handler:
|
|
207
|
+
- Combines single-line `<audio>` / `<video>` opening + closing into one
|
|
208
|
+
`html_inline` atom node so `toDOM` can render media players
|
|
209
|
+
- Pre-scanned paired tags (`htmlPaired` meta) become `html_mark` open/close
|
|
210
|
+
so paired raw HTML like `<font>...</font>` round-trips as styled marks
|
|
211
|
+
- Unpaired tags stay as `html_inline` atom nodes for byte-stable roundtrip
|
|
212
|
+
- `html_block` handler:
|
|
213
|
+
- Promotes standalone `<img>` / `<video>` / `<audio>` blocks to
|
|
214
|
+
`paragraph(html_inline)` so they render as media instead of code blocks
|
|
215
|
+
- Multiple `<img>` tags in one block are joined with inline hardbreaks
|
|
216
|
+
- `tagPairedHtmlInline` pre-processor: scans inline tokens and tags paired
|
|
217
|
+
HTML opening/closing tags with `meta.htmlPaired = true`
|
|
218
|
+
- `preserveBlankLines` post-processor: injects empty paragraph tokens for
|
|
219
|
+
consecutive blank lines so multi-Enter spacing roundtrips faithfully
|
|
220
|
+
- Math support via `markdown-it-texmath` (peer dep): `math_inline`,
|
|
221
|
+
`math_inline_double` (mapped to `math_inline`), and `math_block`
|
|
222
|
+
- Definition list support via `markdown-it-deflist` (peer dep)
|
|
223
|
+
- GFM table + strikethrough enabled (`md.enable(['table', 'strikethrough'])`)
|
|
224
|
+
- Task list checkbox detection in `list_item` getAttrs:
|
|
225
|
+
- `[x]` / `[ ]` parsed from inline content into `checked: boolean | null`
|
|
226
|
+
- Literal checkbox text stripped from the rendered text
|
|
227
|
+
- `image` getAttrs decodes URL-encoded backslashes (`%5C` → `\`) so Windows
|
|
228
|
+
local image paths roundtrip correctly
|
|
229
|
+
- `link` getAttrs decodes percent-encoded non-ASCII UTF-8 sequences (e.g.
|
|
230
|
+
Chinese / Japanese / Korean) while leaving ASCII encodings (`%20` etc.) intact
|
|
231
|
+
- Pre-parse normalizers:
|
|
232
|
+
- `normalizeMathBlocks`: ensures `$$..$$` is surrounded by blank lines so
|
|
233
|
+
texmath parses it as `math_block` (not `math_inline_double`)
|
|
234
|
+
- `normalizeSmartQuotes`: converts curly quotes in image/link title
|
|
235
|
+
delimiters to straight quotes
|
|
236
|
+
- Post-serialize cleanup:
|
|
237
|
+
- Un-escapes over-escaped link syntax (`\[\](url)` → `[](url)`)
|
|
238
|
+
- Strips zero-width spaces (``) used as cursor targets
|
|
239
|
+
|
|
240
|
+
#### Serializer
|
|
241
|
+
- 23 node serializers (incl. `table` with alignment-aware separator,
|
|
242
|
+
`renderTableRow` helper using output-buffer capture, `math_inline`,
|
|
243
|
+
`math_block`, `defList` / `defListTerm` / `defListDescription`,
|
|
244
|
+
`html_block`, `html_inline`, `hardbreak` always emitting `' \n'`)
|
|
245
|
+
- 6 mark serializers (incl. `html_mark` writing `mark.attrs.openTag` /
|
|
246
|
+
`closeTag`, autolink-aware `link.open`/`close`, mixable `strike_through`)
|
|
247
|
+
- `serialize(doc, { tightLists: true })`
|
|
248
|
+
|
|
249
|
+
#### New fixtures (8→17)
|
|
250
|
+
- `09-table-aligned.md` — pipe table with left/center/right alignment
|
|
251
|
+
- `10-table-no-header.md` — pipe table sanity check
|
|
252
|
+
- `11-math-inline.md` — `$..$` inline math (KaTeX peer dep)
|
|
253
|
+
- `12-math-block.md` — `$$..$$` block math (multi-equation)
|
|
254
|
+
- `13-raw-html.md` — `<font>` paired tag (html_mark) + `<sub>` + unpaired `<br>`
|
|
255
|
+
- `14-def-list.md` — definition list via markdown-it-deflist
|
|
256
|
+
- `15-task-list.md` — GFM task list with checkbox stripping
|
|
257
|
+
- `16-cn-punctuation.md` — full-width CJK punctuation + bold/italic/strike on CJK
|
|
258
|
+
- `17-strikethrough-nested.md` — strikethrough nested inside bold + with em inside
|
|
259
|
+
|
|
260
|
+
#### New explicit data-trap tests (§4.4)
|
|
261
|
+
- block math `$$..$$` does NOT degrade to inline `$..$` after roundtrip
|
|
262
|
+
- raw HTML `<font>` preserved verbatim (no markdown conversion)
|
|
263
|
+
- paired `<sub>` round-trips byte-stably as `html_mark`
|
|
264
|
+
- table first child IS `table_header_row` (the table parsing fix)
|
|
265
|
+
- table cells use paragraph-wrapped content (not bare text)
|
|
266
|
+
- task list checkbox attrs recovered + literal `[x]`/`[ ]` stripped
|
|
267
|
+
- definition list parses to `defList` / `defListTerm` / `defListDescription`
|
|
268
|
+
|
|
269
|
+
#### Verification (this batch)
|
|
270
|
+
- ✅ `pnpm typecheck` clean
|
|
271
|
+
- ✅ `pnpm test`: **62/62 pass** (was 46/46; +9 fixture roundtrips, +7 data-trap tests)
|
|
272
|
+
- ✅ `pnpm build`: ESM + .d.ts; `dist/index.js` gzipped = 12.8 KB (16% of 80 KB budget)
|
|
273
|
+
- ✅ §1.1.4 purity gates: 0 Node API / 0 `require()` / 0 `@tauri-apps`/`@capacitor`/`electron` in dist
|
|
274
|
+
- ✅ New peer deps declared (`markdown-it-deflist@^3`, `markdown-it-texmath@^1`)
|
|
275
|
+
with TS shim declarations in `src/shims.d.ts`
|
|
276
|
+
|
|
277
|
+
### Schema batch (2026-05-05)
|
|
278
|
+
|
|
279
|
+
> **Honest status**: previous "0.1.0" CHANGELOG overclaimed scope. The actual
|
|
280
|
+
> v0.60.0-pre §1.2 *faithful migration* is in progress and shipped per-batch
|
|
281
|
+
> rather than as a single drop. Below is the real state at each batch boundary.
|
|
282
|
+
> The package will not be tagged & published until all batches land + Moraya
|
|
283
|
+
> desktop bridge layer is wired up + behavior parity (§1.2.2) is verified.
|
|
284
|
+
|
|
285
|
+
### Schema batch (this batch)
|
|
286
|
+
|
|
287
|
+
#### Added
|
|
288
|
+
- ProseMirror schema 1:1 faithful migration from Moraya desktop `src/lib/editor/schema.ts`:
|
|
289
|
+
- **23 nodes**: doc, text, paragraph, heading, blockquote, code_block,
|
|
290
|
+
horizontal_rule, bullet_list, ordered_list, list_item, image, hardbreak,
|
|
291
|
+
html_block, html_inline, table, table_header_row, table_row,
|
|
292
|
+
table_header, table_cell, math_inline, math_block,
|
|
293
|
+
defList, defListTerm, defListDescription
|
|
294
|
+
- **6 marks**: html_mark, strong, em, code, link, strike_through
|
|
295
|
+
- All node attributes match Moraya exact 1:1 (no rename / no schema simplification)
|
|
296
|
+
- KaTeX rendering inside `math_inline` / `math_block` `toDOM` (peer dep; no DI needed)
|
|
297
|
+
- HTML helpers (`extractHtmlAttr`, `extractAllHtmlAttrs`, `htmlTagToStyle`,
|
|
298
|
+
`showBrokenImage`, `createMediaElement`) ported as pure DOM helpers
|
|
299
|
+
- Path detection helpers (`isAbsoluteFilePath`, `isRelativePath`,
|
|
300
|
+
`resolveRelativePath`) ported as pure string ops
|
|
301
|
+
- Tauri `read_file_binary` IPC + `plugin-http` calls in image / video / audio
|
|
302
|
+
loaders are replaced by consumer-injected `MediaResolver` methods
|
|
303
|
+
(`loadLocalImage` / `loadLocalMedia` / `loadRemoteMedia`)
|
|
304
|
+
- Module-level `documentBaseDir` state preserved with public
|
|
305
|
+
`setDocumentBaseDir(dir)` / `getDocumentBaseDir()` exports
|
|
306
|
+
(pure string state, not Tauri-coupled)
|
|
307
|
+
- KaTeX render-error fallback marks math node with
|
|
308
|
+
`class="math-error" data-math-type="inline|block"` per §4.4 contract
|
|
309
|
+
|
|
310
|
+
#### Changed
|
|
311
|
+
- `code_block.attrs.params` → `code_block.attrs.language` (matches Moraya naming)
|
|
312
|
+
- `hard_break` node → `hardbreak` (matches Moraya naming + `leafText()` returns `\n`)
|
|
313
|
+
- `strikethrough` mark → `strike_through` (matches Moraya naming)
|
|
314
|
+
- `bullet_list` / `ordered_list` no longer have `tight` attr (Moraya schema doesn't track tightness on the list node)
|
|
315
|
+
- `image` no longer has `width` attr (Moraya encodes width in `title="width=70%"`)
|
|
316
|
+
- `list_item` now carries `label` / `listType` / `spread` / `checked` attrs (task-list support)
|
|
317
|
+
- `code_block.attrs.language` defaults to `'text'` (was `''`); fence info `''` → `'text'`
|
|
318
|
+
- `defaultSchema` now built from the full faithful 23N+6M, not the prior 15-node stub
|
|
319
|
+
|
|
320
|
+
### Still pending (subsequent batches)
|
|
321
|
+
- 38 fixtures (currently 17): empty-replace / link-input-rule / large-async /
|
|
322
|
+
KaTeX error / frontmatter YAML/TOML/JSON / footnote / wikilink / hashtag /
|
|
323
|
+
Mermaid / blockquote-nested / autolink / hardbreak edge cases / 50KB real doc, etc.
|
|
324
|
+
- Moraya desktop bridge layer + `TauriMediaResolver` / `TauriLinkOpener` /
|
|
325
|
+
`MorayaRendererRegistry` injection + bridge schema.ts re-export shim
|
|
326
|
+
- Moraya desktop end-to-end smoke (`pnpm tauri dev`, save → disk byte diff vs v0.39.0 baseline)
|
|
327
|
+
- `@moraya/markdown-core@0.1.0` first publish to GitHub Packages (only after bridge + behavior parity)
|
|
328
|
+
- Behavior parity 3-layer verification (§1.2.2): plugin order fingerprint snapshot,
|
|
329
|
+
fixture roundtrip CI gate dual-run with Moraya desktop, hand-test 3 representative
|
|
330
|
+
notes save → disk byte diff
|
|
331
|
+
- Moraya desktop bridge layer + `TauriMediaResolver` / `MorayaRendererRegistry` injection
|
|
332
|
+
- `@moraya/markdown-core` first publish to GitHub Packages (only after all of above)
|
|
333
|
+
|
|
334
|
+
### Verification (this batch)
|
|
335
|
+
- ✅ `pnpm typecheck`: clean (`tsc --noEmit`, strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes)
|
|
336
|
+
- ✅ `pnpm test`: 46/46 pass (3 spec files: api-contract, roundtrip, adapter)
|
|
337
|
+
- ✅ `pnpm build`: ESM + .d.ts emit, dist/index.js gzipped = 9.1 KB (89% under 80 KB budget)
|
|
338
|
+
- ✅ §1.1.4 purity gates: 0 Node API imports, 0 `require()`, 0 `@tauri-apps`/`@capacitor`/`electron` in dist
|
|
339
|
+
|
|
340
|
+
### Notes
|
|
341
|
+
- Excludes `review-decoration.ts` (Moraya v0.30.0+ team-collab specific; stays in moraya/ desktop repo)
|
|
342
|
+
- Schema requires consumer-provided `MediaResolver` (no default singleton exported; see v0.60.0-pre §6.1.1)
|
|
343
|
+
- The internal `defaultSchema` (sentinel-tagged null resolver) is used only by
|
|
344
|
+
`parseMarkdown` / `serializeMarkdown` and is NOT exported via `index.ts`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
PolyForm Internal Use License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/internal-use/1.0.0>
|
|
4
|
+
|
|
5
|
+
Acceptance
|
|
6
|
+
|
|
7
|
+
In order to get any license under these terms, you must agree to them as both
|
|
8
|
+
strict obligations and conditions to all your licenses.
|
|
9
|
+
|
|
10
|
+
Copyright License
|
|
11
|
+
|
|
12
|
+
The licensor grants you a copyright license for the software to do everything
|
|
13
|
+
you might do with the software that would otherwise infringe the licensor's
|
|
14
|
+
copyright in it for any permitted purpose. However, you may only distribute
|
|
15
|
+
the software according to Distribution License and make changes or new works
|
|
16
|
+
based on the software according to Changes and New Works License.
|
|
17
|
+
|
|
18
|
+
Distribution License
|
|
19
|
+
|
|
20
|
+
The licensor grants you an additional copyright license to distribute copies of
|
|
21
|
+
the software. Your license to distribute covers distributing the software with
|
|
22
|
+
changes and new works permitted by Changes and New Works License.
|
|
23
|
+
|
|
24
|
+
Changes and New Works License
|
|
25
|
+
|
|
26
|
+
The licensor grants you an additional copyright license to make changes and new
|
|
27
|
+
works based on the software for any permitted purpose.
|
|
28
|
+
|
|
29
|
+
Patent License
|
|
30
|
+
|
|
31
|
+
The licensor grants you a patent license for the software that covers patent
|
|
32
|
+
claims the licensor can license, or becomes able to license, that you would
|
|
33
|
+
infringe by using the software.
|
|
34
|
+
|
|
35
|
+
Internal Use
|
|
36
|
+
|
|
37
|
+
Any use you make of the software must be for the internal business operations
|
|
38
|
+
of you or your company. You may not use the software, in whole or in part, for
|
|
39
|
+
the benefit of third parties or to publicly distribute applications or
|
|
40
|
+
services that incorporate the software.
|
|
41
|
+
|
|
42
|
+
Patent Defense
|
|
43
|
+
|
|
44
|
+
If you make any written claim that the software infringes or contributes to
|
|
45
|
+
infringement of any patent, your patent license for the software granted under
|
|
46
|
+
these terms ends immediately. If your company makes such a claim, your patent
|
|
47
|
+
license ends immediately for work on behalf of your company.
|
|
48
|
+
|
|
49
|
+
Violations
|
|
50
|
+
|
|
51
|
+
The first time you are notified in writing that you have violated any of these
|
|
52
|
+
terms, or done anything with the software not covered by your license, your
|
|
53
|
+
license ends immediately. If we make a written demand, you must, within 30
|
|
54
|
+
days, send written documentation that all violations have stopped and that you
|
|
55
|
+
have taken steps to prevent recurrence. If you do not, your rights end
|
|
56
|
+
immediately.
|
|
57
|
+
|
|
58
|
+
No Liability
|
|
59
|
+
|
|
60
|
+
***As far as the law allows, the software comes as is, without any warranty
|
|
61
|
+
or condition, and the licensor will not be liable to you for any damages
|
|
62
|
+
arising out of these terms or the use or nature of the software, under any
|
|
63
|
+
kind of legal claim.***
|
|
64
|
+
|
|
65
|
+
Definitions
|
|
66
|
+
|
|
67
|
+
The "licensor" is the entity offering these terms, and the "software" is the
|
|
68
|
+
software the licensor makes available under these terms.
|
|
69
|
+
|
|
70
|
+
"You" refers to the individual or entity agreeing to these terms.
|
|
71
|
+
|
|
72
|
+
"Your company" is any legal entity, sole proprietorship, or other kind of
|
|
73
|
+
organization that you work for, plus all organizations that have control over,
|
|
74
|
+
are under the control of, or are under common control with that organization.
|
|
75
|
+
|
|
76
|
+
"Control" means ownership of substantially all the assets of an entity, or the
|
|
77
|
+
power to direct its management and policies by vote, contract, or otherwise.
|
|
78
|
+
Control can be direct or indirect.
|
|
79
|
+
|
|
80
|
+
"Your licenses" are all the licenses granted to you for the software under
|
|
81
|
+
these terms.
|
|
82
|
+
|
|
83
|
+
"Use" means anything you do with the software requiring one of your licenses.
|
|
84
|
+
|
|
85
|
+
Copyright (c) 2026 Moraya Project. All rights reserved.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @moraya/core
|
|
2
|
+
|
|
3
|
+
Shared markdown editor core for **Moraya desktop** (Tauri + Svelte 5) and **Moraya Web** (SvelteKit SPA). Pure ESM, host-agnostic, dependency-injected.
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
- v0.1.0 (initial extraction from Moraya desktop `src/lib/editor/`)
|
|
8
|
+
- See `CHANGELOG.md`
|
|
9
|
+
|
|
10
|
+
## Design
|
|
11
|
+
|
|
12
|
+
Per [v0.60.0-pre-shared-markdown-core](https://github.com/zouwei/moraya/blob/main/docs/iterations/v0.60.0-pre-shared-markdown-core.md):
|
|
13
|
+
|
|
14
|
+
- **Pure ESM** — no CommonJS, no Node API, no host-specific imports
|
|
15
|
+
- **DOM Level 4** required (ContentEditable + ResizeObserver + IntersectionObserver)
|
|
16
|
+
- **Dependency-injected** — `MediaResolver` / `LinkOpener` / `RendererRegistry` / `Platform`
|
|
17
|
+
- **5 peer deps** — `prosemirror-*`, `markdown-it`, `katex`, `highlight.js`
|
|
18
|
+
- **Bundle budget** — main entry ≤ 80KB gzipped
|
|
19
|
+
|
|
20
|
+
## Public API
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import {
|
|
24
|
+
// schema
|
|
25
|
+
createSchema, type SchemaConfig,
|
|
26
|
+
// markdown
|
|
27
|
+
parseMarkdown, parseMarkdownAsync, serializeMarkdown,
|
|
28
|
+
// setup
|
|
29
|
+
createEditor, createEditorPlugins,
|
|
30
|
+
type EditorPluginOptions, type CreateEditorOptions, type MorayaEditorInstance,
|
|
31
|
+
// doc cache
|
|
32
|
+
createDocCache, type DocCache,
|
|
33
|
+
// commands
|
|
34
|
+
toggleBold, toggleItalic, toggleStrikethrough, toggleCode,
|
|
35
|
+
setHeading, toggleBlockquote, toggleOrderedList, toggleBulletList, toggleCodeBlock,
|
|
36
|
+
insertTable, insertHorizontalRule, insertMathBlock,
|
|
37
|
+
toggleLink, insertImage,
|
|
38
|
+
// types
|
|
39
|
+
type MediaResolver, type LinkOpener, type RendererRegistry, type RendererPluginModule, type Platform,
|
|
40
|
+
} from '@moraya/core'
|
|
41
|
+
|
|
42
|
+
import { BrowserMediaResolver } from '@moraya/core/adapters/browser-media-resolver'
|
|
43
|
+
import '@moraya/core/style'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Consumer examples
|
|
47
|
+
|
|
48
|
+
### Moraya desktop bridge (Svelte 5 + Tauri)
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createSchema } from '@moraya/core'
|
|
52
|
+
import { tauriMediaResolver } from './tauri-media-resolver'
|
|
53
|
+
import { morayaRendererRegistry } from './moraya-renderer-registry'
|
|
54
|
+
|
|
55
|
+
export const schema = createSchema({
|
|
56
|
+
mediaResolver: tauriMediaResolver,
|
|
57
|
+
rendererRegistry: morayaRendererRegistry,
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Moraya Web (SvelteKit SPA)
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { createSchema } from '@moraya/core'
|
|
65
|
+
import { BrowserMediaResolver } from '@moraya/core/adapters/browser-media-resolver'
|
|
66
|
+
|
|
67
|
+
export const schema = createSchema({
|
|
68
|
+
mediaResolver: new BrowserMediaResolver(),
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Build & test
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pnpm install
|
|
76
|
+
pnpm build
|
|
77
|
+
pnpm test
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
PolyForm Internal Use 1.0.0 (private; not for redistribution).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MediaResolver } from '../types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default browser-side {@link MediaResolver}.
|
|
5
|
+
*
|
|
6
|
+
* - Local file paths are not meaningful in a pure browser (no FS access);
|
|
7
|
+
* returns a 1×1 transparent PNG fallback URL with a warning.
|
|
8
|
+
* - Remote URLs are returned as-is (browser handles via native `img.src`).
|
|
9
|
+
*
|
|
10
|
+
* Per v0.60.0-pre §3.7: errors **resolve** with a fallback URL rather than
|
|
11
|
+
* reject, to prevent NodeView crashes on missing assets.
|
|
12
|
+
*/
|
|
13
|
+
declare class BrowserMediaResolver implements MediaResolver {
|
|
14
|
+
/** 1×1 transparent PNG used as fallback for missing local assets. */
|
|
15
|
+
static readonly FALLBACK_PNG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=";
|
|
16
|
+
loadLocalImage(_absolutePath: string): Promise<string>;
|
|
17
|
+
loadLocalMedia(_absolutePath: string): Promise<string>;
|
|
18
|
+
loadRemoteMedia(url: string): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { BrowserMediaResolver };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/adapters/browser-media-resolver.ts
|
|
2
|
+
var BrowserMediaResolver = class _BrowserMediaResolver {
|
|
3
|
+
/** 1×1 transparent PNG used as fallback for missing local assets. */
|
|
4
|
+
static FALLBACK_PNG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=";
|
|
5
|
+
async loadLocalImage(_absolutePath) {
|
|
6
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
7
|
+
console.warn("[BrowserMediaResolver] loadLocalImage called with local path; returning fallback PNG");
|
|
8
|
+
}
|
|
9
|
+
return _BrowserMediaResolver.FALLBACK_PNG;
|
|
10
|
+
}
|
|
11
|
+
async loadLocalMedia(_absolutePath) {
|
|
12
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
13
|
+
console.warn("[BrowserMediaResolver] loadLocalMedia called with local path; returning empty fallback");
|
|
14
|
+
}
|
|
15
|
+
return _BrowserMediaResolver.FALLBACK_PNG;
|
|
16
|
+
}
|
|
17
|
+
async loadRemoteMedia(url) {
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
BrowserMediaResolver
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=browser-media-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/browser-media-resolver.ts"],"sourcesContent":["import type { MediaResolver } from '../types'\n\n/**\n * Default browser-side {@link MediaResolver}.\n *\n * - Local file paths are not meaningful in a pure browser (no FS access);\n * returns a 1×1 transparent PNG fallback URL with a warning.\n * - Remote URLs are returned as-is (browser handles via native `img.src`).\n *\n * Per v0.60.0-pre §3.7: errors **resolve** with a fallback URL rather than\n * reject, to prevent NodeView crashes on missing assets.\n */\nexport class BrowserMediaResolver implements MediaResolver {\n /** 1×1 transparent PNG used as fallback for missing local assets. */\n static readonly FALLBACK_PNG =\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII='\n\n async loadLocalImage(_absolutePath: string): Promise<string> {\n // Pure browser cannot read local FS paths. Return fallback so the NodeView\n // renders something instead of breaking. Consumers wanting browser-side\n // upload (drag-drop) should pre-convert to data: URL or blob: URL first.\n if (typeof console !== 'undefined' && console.warn) {\n console.warn('[BrowserMediaResolver] loadLocalImage called with local path; returning fallback PNG')\n }\n return BrowserMediaResolver.FALLBACK_PNG\n }\n\n async loadLocalMedia(_absolutePath: string): Promise<string> {\n if (typeof console !== 'undefined' && console.warn) {\n console.warn('[BrowserMediaResolver] loadLocalMedia called with local path; returning empty fallback')\n }\n return BrowserMediaResolver.FALLBACK_PNG\n }\n\n async loadRemoteMedia(url: string): Promise<string> {\n // Trust the browser to fetch http(s)/data:/blob: URLs directly.\n return url\n }\n}\n"],"mappings":";AAYO,IAAM,uBAAN,MAAM,sBAA8C;AAAA;AAAA,EAEzD,OAAgB,eACd;AAAA,EAEF,MAAM,eAAe,eAAwC;AAI3D,QAAI,OAAO,YAAY,eAAe,QAAQ,MAAM;AAClD,cAAQ,KAAK,sFAAsF;AAAA,IACrG;AACA,WAAO,sBAAqB;AAAA,EAC9B;AAAA,EAEA,MAAM,eAAe,eAAwC;AAC3D,QAAI,OAAO,YAAY,eAAe,QAAQ,MAAM;AAClD,cAAQ,KAAK,wFAAwF;AAAA,IACvG;AACA,WAAO,sBAAqB;AAAA,EAC9B;AAAA,EAEA,MAAM,gBAAgB,KAA8B;AAElD,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Command } from 'prosemirror-state';
|
|
2
|
+
export { Command, EditorState, Transaction } from 'prosemirror-state';
|
|
3
|
+
export { Node } from 'prosemirror-model';
|
|
4
|
+
|
|
5
|
+
declare const toggleBold: Command;
|
|
6
|
+
declare const toggleItalic: Command;
|
|
7
|
+
declare const toggleStrikethrough: Command;
|
|
8
|
+
declare const toggleCode: Command;
|
|
9
|
+
declare function setHeading(level: 1 | 2 | 3 | 4 | 5 | 6): Command;
|
|
10
|
+
declare const toggleBlockquote: Command;
|
|
11
|
+
declare const toggleOrderedList: Command;
|
|
12
|
+
declare const toggleBulletList: Command;
|
|
13
|
+
declare const wrapInBulletList: Command;
|
|
14
|
+
declare const wrapInOrderedList: Command;
|
|
15
|
+
/**
|
|
16
|
+
* Wrap current block(s) in a bullet list with task-list items (checked: false).
|
|
17
|
+
* Two-step: first apply wrapInList against the bullet_list type, then
|
|
18
|
+
* post-process newly-created list_item nodes within the affected range to
|
|
19
|
+
* set `checked: false` so they render as task items.
|
|
20
|
+
*/
|
|
21
|
+
declare const wrapInTaskList: Command;
|
|
22
|
+
declare const toggleCodeBlock: Command;
|
|
23
|
+
declare const insertHorizontalRule: Command;
|
|
24
|
+
/**
|
|
25
|
+
* Insert a 3×3 placeholder table. Note: full table support requires
|
|
26
|
+
* prosemirror-tables setup at editor mount time; this command falls back
|
|
27
|
+
* to inserting a markdown-style code block snippet if tables aren't
|
|
28
|
+
* registered (true for this minimal v0.1.0 schema).
|
|
29
|
+
*/
|
|
30
|
+
declare const insertTable: Command;
|
|
31
|
+
declare const insertMathBlock: Command;
|
|
32
|
+
declare function toggleLink(href?: string): Command;
|
|
33
|
+
declare function insertImage(src: string, alt?: string): Command;
|
|
34
|
+
|
|
35
|
+
export { insertHorizontalRule, insertImage, insertMathBlock, insertTable, setHeading, toggleBlockquote, toggleBold, toggleBulletList, toggleCode, toggleCodeBlock, toggleItalic, toggleLink, toggleOrderedList, toggleStrikethrough, wrapInBulletList, wrapInOrderedList, wrapInTaskList };
|