jsmdcui 0.5.0 → 0.6.3
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 +168 -0
- package/README.md +214 -23
- package/image-processor.md +360 -0
- package/image-processor.zh-TW.md +360 -0
- package/package.json +1 -1
- package/runmd.mjs +77 -3
- package/runtime/help/help.md +214 -23
- package/select.md +61 -0
- package/single-exe/packAssets.sh +1 -1
- package/src/cui/id-collision.mjs +151 -0
- package/src/cui/rpc.mjs +71 -1
- package/src/cui/task-checkbox.mjs +16 -0
- package/src/index.js +87 -10
- package/src/plugins/js-bridge.js +116 -1
- package/tests/demo.test.js +110 -1
- package/tests/id-collision.test.js +146 -0
- package/tests/wui.test.js +30 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,174 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-visible changes to jsmdcui are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.6.3] - 2026-07-18
|
|
6
|
+
|
|
7
|
+
This update enforces unique heading IDs at the Markdown source level and
|
|
8
|
+
clarifies the portable fenced-block identity contract shared by the TUI and
|
|
9
|
+
WUI.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Treat duplicate Markdown headings that generate the same base ID as a
|
|
14
|
+
source-level collision. Later headings no longer pass `--check` merely
|
|
15
|
+
because Bun would silently assign generated suffixes such as `-1` or `-2`
|
|
16
|
+
that the Markdown author cannot see.
|
|
17
|
+
- Document that a selectable fenced-block declaration requires a tag and uses
|
|
18
|
+
the `tag#id.class` identity form. The officially supported portable control
|
|
19
|
+
tags are currently limited to `text` and `textarea` so the same Markdown
|
|
20
|
+
behaves consistently in both the TUI and WUI.
|
|
21
|
+
- Clarify that selector queries may omit the tag or classes after a valid
|
|
22
|
+
declaration.
|
|
23
|
+
- Expand checker and TUI selector regression coverage across tag/no-tag and
|
|
24
|
+
class/no-class combinations, heading-to-heading, heading-to-block, and
|
|
25
|
+
block-to-block ID collisions.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Fix duplicate source headings incorrectly passing the checker after Bun
|
|
30
|
+
automatically changed the generated ID of later headings.
|
|
31
|
+
|
|
32
|
+
## [0.6.2] - 2026-07-18
|
|
33
|
+
|
|
34
|
+
This update makes Markdown ID-collision checks match the full TUI `$()` block
|
|
35
|
+
selector and gives check results clearer final status banners.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Extend `--check FILE.md` from `text` and `textarea` controls to every
|
|
40
|
+
explicitly named fenced block accepted by the TUI `$()` selector, including
|
|
41
|
+
identities such as `hello#myid` and `json#config`.
|
|
42
|
+
- Report separate heading and fenced-block declaration counts, and describe
|
|
43
|
+
arbitrary block tags and their source lines in collision details.
|
|
44
|
+
- Replace the previous success label with a large green `PASSED` banner and
|
|
45
|
+
add a matching large red `FAILED` banner at the bottom of failed reports.
|
|
46
|
+
Both true-color foregrounds are generated with
|
|
47
|
+
`Bun.color(..., "ansi-16m")`, with standard ANSI fallbacks.
|
|
48
|
+
- Update the README and bundled help to clarify that generated heading IDs
|
|
49
|
+
share the selector namespace with all explicitly named fenced blocks, not
|
|
50
|
+
only editable text controls.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- Fix `--check` overlooking collisions between a heading and a non-text
|
|
55
|
+
fenced block even though TUI `$().val()` could select both declarations.
|
|
56
|
+
- Add regression coverage for arbitrary fenced-block IDs and the colored
|
|
57
|
+
`PASSED` and `FAILED` terminal statuses.
|
|
58
|
+
|
|
59
|
+
## [0.6.1] - 2026-07-18
|
|
60
|
+
|
|
61
|
+
This update adds Markdown UI ID-collision diagnostics and bundles a practical
|
|
62
|
+
Bun.Image processor demo in English and Traditional Chinese.
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- Add `--check FILE.md` to inspect Markdown heading and text-control IDs
|
|
67
|
+
without opening a UI or writing generated companion files. The report uses
|
|
68
|
+
`Bun.markdown.ansi()` headings and nested lists, identifies every collision
|
|
69
|
+
by ID, source type, line number, and original declaration, and exits with
|
|
70
|
+
status `0` for unique IDs, `1` for collisions, or `2` for usage and read
|
|
71
|
+
errors.
|
|
72
|
+
- Add `image-processor.md` and `image-processor.zh-TW.md`, runnable Bun.Image
|
|
73
|
+
tools for the TUI and WUI. They support image metadata inspection, resizing,
|
|
74
|
+
fit and resampling filters, enlargement prevention, EXIF auto-orientation,
|
|
75
|
+
rotation, vertical and horizontal mirroring, brightness and saturation
|
|
76
|
+
adjustment, and JPEG or PNG output options.
|
|
77
|
+
- Add detailed image-processing status fields. Successful writes show the
|
|
78
|
+
output path, dimensions, byte count, and all selected option values; failed
|
|
79
|
+
metadata reads and writes show the available error details and stack.
|
|
80
|
+
- Add `--demo-imgtool` and `--demo-imgtool-zh`. Each command preserves an
|
|
81
|
+
existing local processor Markdown file or writes its bundled language
|
|
82
|
+
version when missing, then opens it in the TUI.
|
|
83
|
+
- Bundle both image processor Markdown files in the single-executable asset
|
|
84
|
+
archive and add regression coverage for ID checks and both demo languages.
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- Consolidate bundled demo Markdown loading behind one
|
|
89
|
+
`bundledMarkdownSource(filename)` implementation shared by `testapp.md`,
|
|
90
|
+
`select.md`, and both image processor variants.
|
|
91
|
+
- Document that heading selector values include the complete visible label.
|
|
92
|
+
Selection parsers should use deliberate substring, prefix, or token checks
|
|
93
|
+
when labels contain explanatory text instead of assuming exact identifiers.
|
|
94
|
+
- Document that generated heading IDs and explicitly named controls share the
|
|
95
|
+
same selector namespace and that every selectable ID should be unique.
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
|
|
99
|
+
- Prevent explanatory text in image processor task-list labels from breaking
|
|
100
|
+
yes/no, fit, filter, and output-format selection parsing.
|
|
101
|
+
- Fix the English image processor status update silently targeting a heading
|
|
102
|
+
after `## Write Status` generated the same `#write-status` ID as its text
|
|
103
|
+
control.
|
|
104
|
+
- Catch image metadata and processing failures at both frontend and backend
|
|
105
|
+
boundaries so errors are displayed in the appropriate status field.
|
|
106
|
+
|
|
107
|
+
## [0.6.0] - 2026-07-18
|
|
108
|
+
|
|
109
|
+
This update turns Markdown headings and task lists into cross-environment form
|
|
110
|
+
controls, improves the safety and consistency of the bundled demo workflow,
|
|
111
|
+
and adds a way to export the bundled README as a runnable Markdown app.
|
|
112
|
+
|
|
113
|
+
### Added
|
|
114
|
+
|
|
115
|
+
- Add `--export-readme` to write or overwrite `./README.md` with the bundled
|
|
116
|
+
README source and exit.
|
|
117
|
+
- Add terminal task-checkbox activation. Activating a protected mdcui row at
|
|
118
|
+
or after its `☐` or `☒` toggles that checkbox and still allows the remaining
|
|
119
|
+
default cell callback to run. JavaScript links continue to take priority.
|
|
120
|
+
- Add hierarchical `<section>` wrappers to generated WUI HTML. Every h1-h6
|
|
121
|
+
opens a section; an equal or higher-level heading closes the applicable open
|
|
122
|
+
sections, while lower-level headings create nested sections. Content before
|
|
123
|
+
the first heading remains outside the generated sections.
|
|
124
|
+
- Add heading lookup to the TUI `$` API using the IDs generated by
|
|
125
|
+
`Bun.markdown.html(..., { headings: { ids: true } })`.
|
|
126
|
+
- Add `$('#heading-id').html()` in TUI to return a heading's inner HTML, and
|
|
127
|
+
`$('#heading-id').line()` to return its current 1-based terminal row or `0`
|
|
128
|
+
when it cannot be found. Line lookup follows text-block row additions,
|
|
129
|
+
removals, and multiline `.val(value)` replacements.
|
|
130
|
+
- Add `.html()` getters to WUI `$` selections. Any successfully selected DOM
|
|
131
|
+
element returns its `innerHTML`; missing or invalid selections return an
|
|
132
|
+
empty string.
|
|
133
|
+
- Add heading-based task-list values in both interfaces. `.val()` reads the
|
|
134
|
+
first task-list group directly following the selected heading, stops at the
|
|
135
|
+
next heading, and ignores nested task items. IDs beginning with `select`
|
|
136
|
+
return the first checked value or `null`; other IDs return all checked values
|
|
137
|
+
as an array or `[]`.
|
|
138
|
+
- Add `select.md`, a runnable multilevel heading and task-list example with
|
|
139
|
+
links that display single-select and multiple-select values through
|
|
140
|
+
`alert()`.
|
|
141
|
+
- Bundle `select.md` in packaged assets and add `--demo-select`. The command
|
|
142
|
+
preserves an existing `./select.md`, writes the bundled copy when missing,
|
|
143
|
+
opens it in the TUI, and generates its five companion files.
|
|
144
|
+
|
|
145
|
+
### Changed
|
|
146
|
+
|
|
147
|
+
- Make `--demo` preserve an existing `./testapp.md`. The bundled source is now
|
|
148
|
+
written only when the file is missing, then opened in the terminal UI.
|
|
149
|
+
- Make `--wui` without a file follow the same source-file rule: use an existing
|
|
150
|
+
`./testapp.md`, or write the bundled demo there when missing, before creating
|
|
151
|
+
the generated companion files.
|
|
152
|
+
- Wrap generated WUI task-checkbox text in `<label>` so clicking the associated
|
|
153
|
+
text toggles the checkbox. Direct text and immediately following paragraph
|
|
154
|
+
elements are included; unrelated tags and nested lists remain outside.
|
|
155
|
+
- Extend the 0.5 `$().val()` contract: text and textarea controls retain their
|
|
156
|
+
string getter/setter behavior, while heading selections now return scalar,
|
|
157
|
+
array, or `null` task-list values according to the heading ID.
|
|
158
|
+
- Add a demo screenshot and expand the README and built-in help with clearer
|
|
159
|
+
TUI/WUI startup, demo preservation, and README export instructions.
|
|
160
|
+
|
|
161
|
+
### Fixed
|
|
162
|
+
|
|
163
|
+
- Ensure WUI fallback to the bundled `testapp.md` materializes the Markdown
|
|
164
|
+
source in the current working directory instead of generating only its
|
|
165
|
+
companion files.
|
|
166
|
+
- Protect comments and `script`, `style`, `pre`, `code`, `textarea`, and
|
|
167
|
+
`template` regions while wrapping WUI headings, preventing heading-like HTML
|
|
168
|
+
strings inside those regions from changing the section hierarchy.
|
|
169
|
+
- Keep TUI heading lookup independent of ANSI heading text and duplicate
|
|
170
|
+
labels by mapping Bun-generated heading order and level to Bun's current
|
|
171
|
+
h1-h6 ANSI signatures.
|
|
172
|
+
|
|
5
173
|
## [0.5.0] - 2026-07-16
|
|
6
174
|
|
|
7
175
|
This update adds cross-environment form-like text blocks and a small
|
package/README.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# Demo App
|
|
4
|
+
## My app
|
|
5
|
+
|
|
6
|
+
- [Say hello](javascript:sayHello())
|
|
7
|
+
- [Get server time](javascript:showServerTime())
|
|
8
|
+
- [Update text box](javascript:updateText())
|
|
9
|
+
- [Show selected](javascript:alert(JSON.stringify($('#my-app').val())))
|
|
10
|
+
- [x] task1
|
|
11
|
+
- [x] task2
|
|
12
|
+
- [ ] unselected task
|
|
13
|
+
|
|
14
|
+
```text#myid.myclass
|
|
15
|
+
Editable in both TUI and WUI
|
|
16
|
+
```
|
|
17
|
+
|
|
1
18
|
# Introduction
|
|
2
19
|
- jsmdcui stands for:
|
|
3
20
|
- JavaScript Markdown Cross-environment User Interface
|
|
@@ -10,6 +27,12 @@
|
|
|
10
27
|
- Original projects:
|
|
11
28
|
- https://github.com/jjtseng93/bunmicro
|
|
12
29
|
- https://github.com/micro-editor/micro
|
|
30
|
+
- .
|
|
31
|
+
- This README is itself a runnable app.
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npx jsmdcui@latest README.md
|
|
35
|
+
```
|
|
13
36
|
|
|
14
37
|
## Quick start
|
|
15
38
|
|
|
@@ -24,28 +47,52 @@ On other platforms, follow the [official Bun installation guide](https://bun.com
|
|
|
24
47
|
Choose either of these two ways to run jsmdcui.
|
|
25
48
|
|
|
26
49
|
> **Important:** Opening or rendering a local `.md` file writes or overwrites
|
|
27
|
-
>
|
|
28
|
-
>
|
|
50
|
+
> 5 generated files beside it. Starting `--wui` without a file writes the
|
|
51
|
+
> 5 files generated from `testapp.md` in the current directory. The source
|
|
29
52
|
> Markdown is not changed, but you should run the demo in a directory where
|
|
30
53
|
> overwriting generated files is safe.
|
|
31
54
|
|
|
32
55
|
### Route 1: Run with npx
|
|
33
56
|
|
|
34
|
-
This route requires both `npx` and `bun` on your `PATH`; no source checkout is
|
|
35
|
-
required.
|
|
57
|
+
- This route requires both `npx` and `bun` on your `PATH`; no source checkout is
|
|
58
|
+
required.
|
|
59
|
+
|
|
60
|
+
#### Open the normal terminal editor
|
|
36
61
|
|
|
37
62
|
```sh
|
|
38
63
|
npx jsmdcui
|
|
39
64
|
```
|
|
40
65
|
|
|
41
|
-
|
|
66
|
+
#### Start `testapp.md` as the TUI/WUI demo
|
|
67
|
+
- If `testapp.md` is missing, the bundled copy is written to the current working directory
|
|
68
|
+
- If `testapp.md` already exists, it will be used and won't be overwritten.
|
|
42
69
|
|
|
43
70
|
```sh
|
|
71
|
+
# TUI(Terminal User Interface) Demo
|
|
72
|
+
npx jsmdcui --demo
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
# Heading and task-list selector demo
|
|
77
|
+
npx jsmdcui --demo-select
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
# Bun.Image processor demo
|
|
82
|
+
npx jsmdcui --demo-imgtool
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
# Traditional Chinese Bun.Image processor demo
|
|
87
|
+
npx jsmdcui --demo-imgtool-zh
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
# WUI(Web User Interface) Demo
|
|
44
92
|
npx jsmdcui --wui
|
|
45
93
|
```
|
|
46
94
|
|
|
47
|
-
|
|
48
|
-
instead of the bundled demo. To open your own Markdown UI, pass its path:
|
|
95
|
+
#### Open your own Markdown CUI App
|
|
49
96
|
|
|
50
97
|
```sh
|
|
51
98
|
npx jsmdcui app.md
|
|
@@ -60,30 +107,37 @@ cd jsmdcui
|
|
|
60
107
|
bun src/index.js testapp.md
|
|
61
108
|
```
|
|
62
109
|
|
|
63
|
-
The last command opens the included demo in the terminal
|
|
64
|
-
|
|
65
|
-
|
|
110
|
+
- The last command opens the included demo in the terminal
|
|
111
|
+
- Use arrow keys to move around
|
|
112
|
+
- `Enter`, `Space`, or mouse click to activate an item, and `Ctrl-Q` to quit.
|
|
113
|
+
- To open the same demo in a browser instead:
|
|
66
114
|
|
|
67
115
|
```sh
|
|
68
116
|
bun src/index.js --wui testapp.md
|
|
69
117
|
```
|
|
70
118
|
|
|
71
|
-
After starting `--wui`, open the last printed `http://...` URL in a browser.
|
|
72
|
-
Keep the command running while using the
|
|
73
|
-
|
|
119
|
+
- After starting `--wui`, open the last printed `http://...` URL in a browser.
|
|
120
|
+
- Keep the command running while using the CUI App, and press `Ctrl-C` in that terminal to stop the server.
|
|
121
|
+
|
|
122
|
+
### Usage table
|
|
74
123
|
|
|
75
|
-
The command table below uses the cloned-source form.
|
|
76
|
-
`bun src/index.js` with `npx jsmdcui
|
|
124
|
+
- The command table below uses the cloned-source form.
|
|
125
|
+
- If you use npx, replace `bun src/index.js` with `npx jsmdcui`
|
|
77
126
|
|
|
78
127
|
| Command | Result |
|
|
79
128
|
| --- | --- |
|
|
80
129
|
| `bun src/index.js app.md` | Render `app.md` as a read-only terminal UI and write five generated files beside it. |
|
|
130
|
+
| `bun src/index.js --check app.md` | Check heading and fenced-block IDs for collisions, print line-by-line details, and exit. |
|
|
81
131
|
| `bun src/index.js --edit app.md` | Open `app.md` as editable UTF-8 source, overriding automatic Markdown UI detection. |
|
|
82
132
|
| `bun src/index.js --cat app.md` | Render the terminal version to stdout, write five generated files beside it, and exit. |
|
|
83
133
|
| `bun src/index.js --testapp.md` | Write the bundled `testapp.md` source to stdout and exit. |
|
|
84
|
-
| `bun src/index.js --
|
|
134
|
+
| `bun src/index.js --export-readme` | Write or overwrite `./README.md` with the bundled README source and exit. |
|
|
135
|
+
| `bun src/index.js --demo` | Use local `testapp.md` when present, otherwise write the bundled demo; open it in the terminal UI and write five generated files beside it. |
|
|
136
|
+
| `bun src/index.js --demo-select` | Use local `select.md` when present, otherwise write the bundled selector demo; open it in the terminal UI and write five generated files beside it. |
|
|
137
|
+
| `bun src/index.js --demo-imgtool` | Use local `image-processor.md` when present, otherwise write the bundled Bun.Image processor; open it in the terminal UI and write five generated files beside it. |
|
|
138
|
+
| `bun src/index.js --demo-imgtool-zh` | Use local `image-processor.zh-TW.md` when present, otherwise write the bundled Traditional Chinese Bun.Image processor; open it in the terminal UI and write five generated files beside it. |
|
|
85
139
|
| `bun src/index.js --allow-url URL.md` | Download HTTP(S) Markdown to the current directory, write 5 generated files, and allow its embedded code to run. Only use trusted URLs. |
|
|
86
|
-
| `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise
|
|
140
|
+
| `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise write the bundled demo; write five generated files in the current directory, then print and serve a random URL. |
|
|
87
141
|
| `bun src/index.js --wui app.md` | Write five generated files beside `app.md`, then print and serve a random URL. |
|
|
88
142
|
| `PORT=8080 bun src/index.js --wui app.md` | Start the browser UI on another port. |
|
|
89
143
|
| `bun src/index.js` | Open the normal terminal editor with an empty buffer. |
|
|
@@ -96,11 +150,15 @@ options.
|
|
|
96
150
|
Create `app.md`:
|
|
97
151
|
|
|
98
152
|
````md
|
|
99
|
-
|
|
153
|
+
## My app
|
|
100
154
|
|
|
101
155
|
- [Say hello](javascript:sayHello())
|
|
102
156
|
- [Get server time](javascript:showServerTime())
|
|
103
157
|
- [Update text box](javascript:updateText())
|
|
158
|
+
- [Show selected](javascript:alert(JSON.stringify($('#my-app').val())))
|
|
159
|
+
- [x] task1
|
|
160
|
+
- [x] task2
|
|
161
|
+
- [ ] unselected task
|
|
104
162
|
|
|
105
163
|
```text#myid.myclass
|
|
106
164
|
Editable in both TUI and WUI
|
|
@@ -136,6 +194,11 @@ bun src/index.js app.md
|
|
|
136
194
|
bun src/index.js --wui app.md
|
|
137
195
|
```
|
|
138
196
|
|
|
197
|
+
- The resulting App UI is shown at the beginning of this README.md
|
|
198
|
+
- Run this demo app directly by:
|
|
199
|
+
* bun src/index.js README.md
|
|
200
|
+
* If you didn't clone the repo, use --export-readme to write README.md to the current folder
|
|
201
|
+
|
|
139
202
|
### Text blocks
|
|
140
203
|
|
|
141
204
|
Both `text` and `textarea` fenced blocks define editable text fields:
|
|
@@ -146,6 +209,20 @@ Initial value
|
|
|
146
209
|
```
|
|
147
210
|
````
|
|
148
211
|
|
|
212
|
+
A fenced-block declaration must include a tag. Its supported identity syntax is
|
|
213
|
+
`tag`, optionally followed by `#id` and one or more `.class` names, for
|
|
214
|
+
example `text#message.note` or `textarea#notes.readonly`. Tags, IDs, and class
|
|
215
|
+
names must begin with an ASCII letter or underscore; their remaining
|
|
216
|
+
characters may also include digits, `_`, `-`, and `:`. Declarations such as
|
|
217
|
+
`#message` and `#message.note` have no tag and are therefore not recognized as
|
|
218
|
+
selectable fenced blocks.
|
|
219
|
+
|
|
220
|
+
The currently supported fenced-block tags are only `text` and `textarea` so
|
|
221
|
+
the same control works consistently in both the TUI and WUI. Selector queries
|
|
222
|
+
may omit the tag or classes after a valid declaration, so all of
|
|
223
|
+
`$('text#message.note')`, `$('text#message')`, `$('#message.note')`, and
|
|
224
|
+
`$('#message')` can select the example above.
|
|
225
|
+
|
|
149
226
|
The same Markdown works in both interfaces. In the browser WUI it becomes a
|
|
150
227
|
native `<textarea>` with the declared ID and classes. Long text wraps
|
|
151
228
|
automatically, and the field height is recalculated when the user types, the
|
|
@@ -158,6 +235,99 @@ blocked. Activate the lower-left frame corner to add a row. Activate the
|
|
|
158
235
|
upper-left frame corner to remove the trailing row only when it is empty;
|
|
159
236
|
non-empty content is never removed.
|
|
160
237
|
|
|
238
|
+
### Heading task lists and selector API
|
|
239
|
+
|
|
240
|
+
Headings can act as form-group selectors. jsmdcui uses the IDs generated by
|
|
241
|
+
`Bun.markdown.html(..., { headings: { ids: true } })`; for example,
|
|
242
|
+
`## Select Color` becomes `#select-color`. A heading selection reads the first
|
|
243
|
+
task list directly following that heading and stops at the next heading. Nested
|
|
244
|
+
task items are not included in the outer list's value.
|
|
245
|
+
|
|
246
|
+
Heading IDs share the same selector namespace as all explicitly named fenced
|
|
247
|
+
blocks, not only `text` and `textarea`, so avoid name collisions between them.
|
|
248
|
+
For example, `## Write Status` generates `#write-status` and must not be used
|
|
249
|
+
together with a block such as `text#write-status` or
|
|
250
|
+
`textarea#write-status`.
|
|
251
|
+
Otherwise, `$('#write-status')` may select the heading instead of the block and
|
|
252
|
+
updates can appear to do nothing. Rename either declaration so every
|
|
253
|
+
selectable ID is unique.
|
|
254
|
+
|
|
255
|
+
Duplicate source headings are also treated as collisions when they generate
|
|
256
|
+
the same base ID. Although Bun would automatically rename later headings with
|
|
257
|
+
suffixes such as `-1` and `-2`, those implicit selector names are not visible
|
|
258
|
+
in the Markdown source and should not be relied on. Give each heading a name
|
|
259
|
+
that produces a unique ID before rendering.
|
|
260
|
+
|
|
261
|
+
Run `bun src/index.js --check app.md` (or `jsmdcui --check app.md`) to
|
|
262
|
+
check these IDs without opening either UI or writing generated files. The
|
|
263
|
+
command prints each collision with its source type, line number, and original
|
|
264
|
+
declaration, then exits immediately. Its exit status is `0` when all IDs are
|
|
265
|
+
unique, `1` when collisions are found, and `2` for invalid arguments or read
|
|
266
|
+
errors.
|
|
267
|
+
|
|
268
|
+
If the heading ID begins with `select`, `.val()` behaves like a single select:
|
|
269
|
+
it returns the first checked item or `null`. Other heading IDs behave like a
|
|
270
|
+
multiple select and return all checked items as an array, or `[]` when none are
|
|
271
|
+
checked.
|
|
272
|
+
|
|
273
|
+
Heading values contain the complete visible label, including any explanatory
|
|
274
|
+
text. When interpreting a selection, prefer `value.includes(...)` (or another
|
|
275
|
+
deliberate prefix/token parser) unless labels are guaranteed to be exact,
|
|
276
|
+
stable identifiers. For example, `yes(flip vertically)` should not be tested
|
|
277
|
+
with `value === "yes"`.
|
|
278
|
+
|
|
279
|
+
````md
|
|
280
|
+
## Select Color
|
|
281
|
+
|
|
282
|
+
- [ ] Red
|
|
283
|
+
- [x] Green
|
|
284
|
+
- [ ] Blue
|
|
285
|
+
|
|
286
|
+
## Features
|
|
287
|
+
|
|
288
|
+
- [x] Search
|
|
289
|
+
- [ ] Notifications
|
|
290
|
+
- [x] Offline mode
|
|
291
|
+
|
|
292
|
+
```js front
|
|
293
|
+
export function showValues() {
|
|
294
|
+
alert(JSON.stringify({
|
|
295
|
+
color: $('#select-color').val(),
|
|
296
|
+
features: $('#features').val(),
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
````
|
|
301
|
+
|
|
302
|
+
The same getter works in TUI and WUI:
|
|
303
|
+
|
|
304
|
+
```js
|
|
305
|
+
$('#select-color').val() // "Green"
|
|
306
|
+
$('#features').val() // ["Search", "Offline mode"]
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
The bundled `select.md` is a multilevel runnable example. Use `--demo-select`
|
|
310
|
+
to write it into the current directory when missing and open it in the TUI, or
|
|
311
|
+
open it explicitly in either interface:
|
|
312
|
+
|
|
313
|
+
```sh
|
|
314
|
+
bun src/index.js --demo-select
|
|
315
|
+
bun src/index.js select.md
|
|
316
|
+
bun src/index.js --wui select.md
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The available selector methods are:
|
|
320
|
+
|
|
321
|
+
| Method | TUI | WUI |
|
|
322
|
+
| --- | --- | --- |
|
|
323
|
+
| `.val()` | Read text blocks or heading task-list values. | Read textareas/controls or heading task-list values. |
|
|
324
|
+
| `.val(value)` | Replace text-block contents and resize multiline values. | Set textarea/control values and resize textareas. |
|
|
325
|
+
| `.html()` | Return a selected heading's inner HTML. | Return any successfully selected DOM element's `innerHTML`. |
|
|
326
|
+
| `.line()` | Return a heading's current 1-based TUI row, or `0` if missing. | Not available. |
|
|
327
|
+
|
|
328
|
+
TUI heading rows are recalculated after text-block rows are added, removed, or
|
|
329
|
+
replaced with multiline `.val(value)` content.
|
|
330
|
+
|
|
161
331
|
The three UI building blocks are:
|
|
162
332
|
|
|
163
333
|
- Regular Markdown provides headings, text, lists, task checkboxes, code, and
|
|
@@ -213,8 +383,8 @@ selection, search, and copy remain available.
|
|
|
213
383
|
| Input | Result |
|
|
214
384
|
| --- | --- |
|
|
215
385
|
| Arrow keys, `Home`, `End`, `PageUp`, `PageDown` | Move through the rendered UI. |
|
|
216
|
-
| `Enter` or `Space` | Activate the cell under the cursor. Put the cursor on a `javascript:` link to run it. |
|
|
217
|
-
| Left click | Move to and activate the clicked cell. A `javascript:` link runs immediately. |
|
|
386
|
+
| `Enter` or `Space` | Activate the cell under the cursor. Put the cursor on a `javascript:` link to run it, or on or to the right of `☐` or `☒` to toggle that task. |
|
|
387
|
+
| Left click | Move to and activate the clicked cell. A `javascript:` link runs immediately; clicking on or to the right of `☐` or `☒` toggles that task. |
|
|
218
388
|
| Mouse wheel | Scroll three rows at a time. |
|
|
219
389
|
| `Shift` + arrow keys | Select rendered text. |
|
|
220
390
|
| `Ctrl-C` | Copy the selection, or the current line when nothing is selected. |
|
|
@@ -232,9 +402,10 @@ normal links in the browser.
|
|
|
232
402
|
|
|
233
403
|
The WUI uses normal browser mouse and keyboard behavior. Clicking a
|
|
234
404
|
`javascript:` link calls its front-end function, regular links navigate
|
|
235
|
-
normally, and task checkboxes can be toggled
|
|
236
|
-
use the browser's built-in
|
|
237
|
-
|
|
405
|
+
normally, and task checkboxes can be toggled by clicking either the checkbox or
|
|
406
|
+
its associated text. `alert`, `confirm`, and `prompt` use the browser's built-in
|
|
407
|
+
dialogs. Checkbox changes exist only in the current page: refreshing does not
|
|
408
|
+
preserve them and does not update the Markdown file.
|
|
238
409
|
|
|
239
410
|
The WUI uses port `3000` by default and accepts connections through the
|
|
240
411
|
machine's available network interfaces. The printed `localhost` URL is for the
|
|
@@ -260,6 +431,26 @@ app.md-server.js
|
|
|
260
431
|
They are regenerated from `app.md`, so edit the Markdown source rather than the
|
|
261
432
|
generated files. The source directory must be writable.
|
|
262
433
|
|
|
434
|
+
### Generated heading sections
|
|
435
|
+
|
|
436
|
+
WUI output wraps each h1-h6 and its content in a hierarchical `<section>`.
|
|
437
|
+
Lower-level headings create nested sections; the next equal or higher-level
|
|
438
|
+
heading closes the applicable sections. Content before the first heading stays
|
|
439
|
+
outside all generated sections.
|
|
440
|
+
|
|
441
|
+
```html
|
|
442
|
+
<section>
|
|
443
|
+
<h1 id="chapter">Chapter</h1>
|
|
444
|
+
<section>
|
|
445
|
+
<h2 id="topic">Topic</h2>
|
|
446
|
+
</section>
|
|
447
|
+
</section>
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
This structure provides stable boundaries for CSS, DOM queries, and heading
|
|
451
|
+
task-list values. Heading-like text inside comments, scripts, styles, code,
|
|
452
|
+
textareas, and templates is protected and does not create sections.
|
|
453
|
+
|
|
263
454
|
## Security
|
|
264
455
|
|
|
265
456
|
A Markdown UI is an executable application, not a passive document. Starting a
|