Skip to content

Commit 3c9db8a

Browse files
committed
readme, license and release info
1 parent 405de06 commit 3c9db8a

8 files changed

Lines changed: 163 additions & 92 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 David Walker
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Blazer Markdown Editor
2+
A lightweight ProseMirror-based Markdown editor for Blazor (including MudBlazor) with slash commands, table editing, and JSInterop-friendly APIs.
3+
4+
## Contents
5+
- **[Features](#features)**
6+
- **[Preview](#preview)**
7+
- [Desktop](#desktop)
8+
- [Mobile](#mobile)
9+
- **[Install](#install)**
10+
- [Install Method 1](#install-method-1)
11+
- **[Third-Party](#third-party)**
12+
13+
Additional docs:
14+
- [JSInterop Packaging](docs/jsinterop-packaging.md)
15+
- [How to Use](docs/how-to-use.md)
16+
17+
## Features
18+
* Markdown-first authoring with ProseMirror document model and serializer
19+
* Blazor-focused JSInterop API: `create`, `setMarkdown`, `getMarkdown`, `focus`, `destroy`
20+
* Productive editing features: slash menu, table controls, link toolbar, and keyboard shortcuts
21+
22+
## Preview
23+
### Desktop
24+
Use `samples/index.html` to preview editor behavior in desktop browsers.
25+
26+
### Mobile
27+
Use device emulation (or a real device) with `samples/index.html` to validate responsive behavior and touch interactions.
28+
29+
## Install
30+
### Install Method 1
31+
1. Install dependencies:
32+
- `npm ci`
33+
2. Build distributable assets:
34+
- `npm run build`
35+
3. Include generated assets from `wwwroot` in your Blazor app:
36+
- `blazer-markdown-editor.css`
37+
- `blazer-markdown-editor.js`
38+
- `blazer-markdown-editor.min.js`
39+
4. Call the global API via JSInterop:
40+
- `window.blazerMarkdownEditor.create(...)`
41+
- `window.blazerMarkdownEditor.setMarkdown(...)`
42+
- `window.blazerMarkdownEditor.getMarkdown(...)`
43+
- `window.blazerMarkdownEditor.focus(...)`
44+
- `window.blazerMarkdownEditor.destroy(...)`
45+
46+
Versioning uses a calendar schema: `YYYY.MINOR.PATCH` (current: `2026.2.1`).
47+
48+
## Third-Party
49+
* markdown-it 14.1.0
50+
* prosemirror-commands 1.6.2
51+
* prosemirror-dropcursor 1.8.1
52+
* prosemirror-gapcursor 1.3.2
53+
* prosemirror-history 1.4.1
54+
* prosemirror-inputrules 1.4.0
55+
* prosemirror-keymap 1.2.2
56+
* prosemirror-markdown 1.13.2
57+
* prosemirror-model 1.24.1
58+
* prosemirror-schema-list 1.5.1
59+
* prosemirror-state 1.4.3
60+
* prosemirror-tables 1.8.3
61+
* prosemirror-view 1.38.1

docs/how-to-use.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# How to Use Blazer Markdown Editor
2+
3+
## Build
4+
```bash
5+
npm ci
6+
npm run build
7+
```
8+
9+
## Include in Blazor / MudBlazor
10+
Add built assets to your host page or static web assets pipeline:
11+
12+
```html
13+
<link rel="stylesheet" href="_content/<YourPackageOrProject>/blazer-markdown-editor.css" />
14+
<script src="_content/<YourPackageOrProject>/blazer-markdown-editor.js"></script>
15+
```
16+
17+
## JSInterop API
18+
Use the global object:
19+
20+
- `window.blazerMarkdownEditor.create(target, { markdown })``editorId`
21+
- `window.blazerMarkdownEditor.setMarkdown(editorId, markdown)`
22+
- `window.blazerMarkdownEditor.getMarkdown(editorId)`
23+
- `window.blazerMarkdownEditor.focus(editorId)`
24+
- `window.blazerMarkdownEditor.destroy(editorId)`
25+
26+
## Typical lifecycle (Blazor)
27+
1. On first render, call `create` with the target element.
28+
2. Push external value changes with `setMarkdown`.
29+
3. Pull current editor state with `getMarkdown` when saving.
30+
4. Dispose with `destroy` in component cleanup.
31+
32+
## Notes
33+
- Keep `wwwroot` outputs as release artifacts (`js`, `min.js`, `css`).
34+
- Keep dependency versions pinned for deterministic behavior.
35+
- Use the packaging guidance in [jsinterop-packaging.md](jsinterop-packaging.md).

docs/jsinterop-packaging.md

Lines changed: 31 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,55 @@
1-
# ProseMirror Markdown Editor: production packaging for MudBlazor JSInterop
2-
3-
This prototype is a strong start. For production in a Blazor/MudBlazor app, the safest path is to **ship this as a small JavaScript package** (or static asset bundle) with explicit pinned dependencies, instead of loading many modules directly from CDN import maps.
4-
5-
## Recommended packaging approach
6-
7-
1. Create a small frontend package (for example `@your-org/blazer-markdown-editor`).
8-
2. Move editor setup code into a module that exports a tiny API:
9-
- `createEditor(element, options)`
10-
- `setMarkdown(instance, markdown)`
11-
- `getMarkdown(instance)`
12-
- `destroy(instance)`
13-
3. Bundle with `esbuild`, `vite`, or `rollup` into one or two static files.
14-
4. Copy the built artifacts into `wwwroot` and call through JSInterop.
15-
5. Keep ProseMirror package versions pinned and update intentionally.
16-
17-
## Minimal dependency set used by this prototype
18-
19-
From current code paths, the direct runtime dependencies are:
20-
21-
- `prosemirror-model`
22-
- `prosemirror-transform`
23-
- `prosemirror-state`
24-
- `prosemirror-view`
25-
- `prosemirror-keymap`
26-
- `prosemirror-history`
27-
- `prosemirror-commands`
28-
- `prosemirror-schema-list`
29-
- `prosemirror-inputrules`
30-
- `prosemirror-dropcursor`
31-
- `prosemirror-gapcursor`
32-
- `prosemirror-markdown`
33-
- `prosemirror-tables`
34-
- `markdown-it`
35-
36-
`prosemirror-example-setup` and `prosemirror-menu` are not required.
37-
38-
## Gaps / holes to evaluate before production
39-
40-
- **Sanitization / trust boundary**
41-
- If Markdown can come from untrusted users, sanitize rendered HTML on display paths.
42-
- Keep `html: false` for markdown-it when parsing input in the editor.
43-
- **Persistence model**
44-
- Decide if your source of truth is Markdown only, PM JSON only, or dual-format.
45-
- If dual-format, define reconciliation rules and tests.
46-
- **Schema migrations**
47-
- If schema changes later, old stored content may need migration logic.
48-
- **Plugin ordering contracts**
49-
- Current setup depends on plugin order (slash menu priority, keymaps).
50-
- Lock this in tests to prevent regressions.
51-
- **Keyboard behavior consistency**
52-
- Verify Windows/macOS/Linux keybindings in Blazor host pages.
53-
- **Table markdown round-trip**
54-
- Ensure table alignment and edge cases survive parse -> edit -> serialize cycles.
55-
- **Clipboard behavior**
56-
- Paste detection is heuristic; test mixed-content clipboard payloads.
57-
- **Error reporting**
58-
- Add JS-level hooks for errors/events so .NET can log and react.
59-
- **Styling isolation**
60-
- Consider scoping editor styles to avoid collisions with MudBlazor theme styles.
61-
62-
## Suggested JSInterop contract
63-
64-
A minimal contract that stays stable:
65-
66-
- `window.blazerMarkdownEditor.create(element, options)` => returns `editorId`
67-
- `window.blazerMarkdownEditor.setMarkdown(editorId, markdown)`
68-
- `window.blazerMarkdownEditor.getMarkdown(editorId)` => `string`
69-
- `window.blazerMarkdownEditor.onChange(editorId, dotNetRef, methodName)`
70-
- `window.blazerMarkdownEditor.destroy(editorId)`
71-
72-
This keeps lifecycle ownership clear and avoids leaking ProseMirror internals into C#.
1+
# Blazer Markdown Editor: JSInterop Packaging
732

74-
## Why the prototype import map was adjusted
3+
This repo is optimized for Blazor/MudBlazor usage by shipping static assets from `wwwroot`.
754

76-
For local prototyping, import maps are fine and this prototype keeps explicit pinned CDN imports for compatibility. In production, prefer your own package lock + local bundling over CDN-resolved dependency trees.
5+
## Packaging model
776

78-
## What this repo now ships
7+
1. Author source in `src/`.
8+
2. Build distributables with `npm run build`.
9+
3. Ship only `wwwroot` artifacts in releases:
10+
- `wwwroot/blazer-markdown-editor.js`
11+
- `wwwroot/blazer-markdown-editor.min.js`
12+
- `wwwroot/blazer-markdown-editor.css`
7913

80-
This repo now includes lockfile + local bundling support:
81-
82-
- `package.json` + `package-lock.json` for pinned JS dependencies
83-
- `src/blazer-markdown-editor.js` as the package entry
84-
- `scripts/build.mjs` build script
85-
- distributable assets in `wwwroot/` (JS generated by build):
86-
- `wwwroot/blazer-markdown-editor.js`
87-
- `wwwroot/blazer-markdown-editor.css`
88-
89-
### Build
14+
## Build
9015

9116
```bash
9217
npm ci
9318
npm run build
9419
```
9520

96-
### MudBlazor/Blazor usage
21+
Build output includes license headers automatically.
22+
23+
## Versioning
9724

98-
Include the generated static assets:
25+
This project uses calendar versioning:
26+
27+
- Format: `YYYY.MINOR.PATCH`
28+
- Current: `2026.2.1`
29+
30+
## Blazor / MudBlazor consumption
31+
32+
Include static assets:
9933

10034
```html
10135
<link rel="stylesheet" href="_content/<YourPackageOrProject>/blazer-markdown-editor.css" />
10236
<script src="_content/<YourPackageOrProject>/blazer-markdown-editor.js"></script>
10337
```
10438

105-
Then use JSInterop against:
39+
JSInterop API:
10640

10741
- `window.blazerMarkdownEditor.create(target, { markdown })`
10842
- `window.blazerMarkdownEditor.setMarkdown(editorId, markdown)`
10943
- `window.blazerMarkdownEditor.getMarkdown(editorId)`
11044
- `window.blazerMarkdownEditor.focus(editorId)`
11145
- `window.blazerMarkdownEditor.destroy(editorId)`
11246

113-
If this repo is consumed as a dependency in your MudBlazor solution, point your static-web-assets path to the `wwwroot` output and call `npm ci && npm run build` in your package/CI step.
47+
## Release process (artifact-only)
48+
49+
Create a GitHub release with only the `wwwroot` files for that version.
50+
51+
Suggested release assets:
52+
53+
- `wwwroot/blazer-markdown-editor.js`
54+
- `wwwroot/blazer-markdown-editor.min.js`
55+
- `wwwroot/blazer-markdown-editor.css`

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "blazer-markdown-editor",
3-
"version": "0.1.0",
3+
"version": "2026.2.1",
44
"private": true,
55
"type": "module",
66
"scripts": {

scripts/build.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { copyFileSync, mkdirSync } from "node:fs";
1+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
2+
3+
const licenseHeader = `// Copyright (c) 2026 David Walker\n// Licensed under the MIT License.\n\n`;
24

35
mkdirSync("wwwroot", { recursive: true });
4-
copyFileSync("src/blazer-markdown-editor.css", "wwwroot/blazer-markdown-editor.css");
6+
const cssContent = readFileSync("src/blazer-markdown-editor.css", "utf8");
7+
writeFileSync("wwwroot/blazer-markdown-editor.css", `${licenseHeader}${cssContent}`);
58

69
let build;
710
try {
@@ -17,6 +20,9 @@ const shared = {
1720
bundle: true,
1821
format: "iife",
1922
target: ["es2020"],
23+
banner: {
24+
js: licenseHeader,
25+
},
2026
};
2127

2228
await Promise.all([

wwwroot/blazer-markdown-editor.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) 2026 David Walker
2+
// Licensed under the MIT License.
3+
14
.ProseMirror {
25
background: #fff;
36
border: 1px solid #d0d0d0;

wwwroot/blazer-markdown-editor.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) 2026 David Walker
2+
// Licensed under the MIT License.
3+
14
(() => {
25
var __defProp = Object.defineProperty;
36
var __export = (target, all) => {

0 commit comments

Comments
 (0)