dsh-fonttune 0.2.5 → 0.2.7
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.en.md +89 -95
- package/CHANGELOG.md +89 -95
- package/README.en.md +11 -7
- package/README.md +11 -7
- package/cordis.patch.yml +12 -2
- package/lib/client.js +346 -86
- package/lib/shared.cjs +273 -84
- package/package.json +5 -5
package/CHANGELOG.en.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to **dsh-fonttune** are documented here. Chinese version: [CHANGELOG.md](CHANGELOG.md).
|
|
4
4
|
|
|
5
|
+
## [0.2.7] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **DSH 0.1.7-rc.2 support**: it is a patch update of 0.1.7-rc.1 with the same settings service and configuration-card seats, so no code had to change; each item was verified in an isolated environment (host start, stylesheet applied, card expanded, a change written through), and the compatibility table lists 0.1.7-rc.2.
|
|
9
|
+
|
|
10
|
+
## [0.2.6] - 2026-09-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Dragging the UI stuttered**: dragging the sidebar width, the conversation-list width and similar handles dropped frames (the injected stylesheet matched the whole page against every rule on each style recalculation). Each axis now matches only the elements it needs: dragging is smooth again, and the typography and the code axis look unchanged.
|
|
14
|
+
- **Opening "Font tune" on the Plugins page did not show the settings right away**: on 0.1.7 the page treats opening the entry as the expansion gesture, while the card carried a collapsible header of its own and asked for a second click. It now opens expanded, and the chevron still collapses it by hand.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **DSH 0.1.7-rc.1 support**: it is the 0.1.7 interface on the rc channel, sharing the settings service and the configuration-card seats with 0.1.7-alpha.x, so no code had to change; each item was verified in an isolated environment (host start, stylesheet applied, card open and close, a change written through).
|
|
18
|
+
- **The declared compatibility floor is now 0.1.5-rc.3**: 0.1.5-rc.1 and 0.1.5-rc.2 are no longer claimed (`engines.dsh` tightened to match), and the README compatibility table follows.
|
|
19
|
+
- **The loader row id matches the settings namespace** (`fonttune` → `dsh-fonttune`): from DSH 0.1.7 on, settings are addressed by entry id, and a name that differs from the namespace the plugin registers leaves the saved families and weights in the imported file, unread (which shows up as "the plugin does nothing"). With the matching id the package can also be installed through the profile's `dsh.profile.bundles`.
|
|
20
|
+
|
|
5
21
|
## [0.2.5] - 2026-09-23
|
|
6
22
|
|
|
7
23
|
### Fixed
|
|
@@ -23,154 +39,132 @@ All notable changes to **dsh-fonttune** are documented here. Chinese version: [C
|
|
|
23
39
|
## [0.2.3] - 2026-09-22
|
|
24
40
|
|
|
25
41
|
### Fixed
|
|
26
|
-
- **A refused settings write
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
-
|
|
30
|
-
- **The per-theme "code font inside the dialog" rule missed its theme prefix** (dormant: per-theme is off today). `pushScopedCodeFamily` emitted its scoped rule without `body[data-ds-dark-theme]`, so with per-theme on the dark set would re-assert the **light** code family inside a dark dialog. It is prefixed like every other rule now, and a case asserts that every per-theme rule starts with the theme attribute.
|
|
31
|
-
- **`test/split-verify.mjs` was measuring a retired axis**: it still wrote `sizeOffset` (the interface size axis retired in 0.2.0) and expected the conversation chain to follow, so it rightly went red on a real machine. It now writes `sizeOffsetDialog` + `sizeOffsetCode`, computes its ratios from the measured baseline (the conversation offset rides DSH's own size, the code axis scales over the 16px reference — the two expectations differ), and adds a live check that the retired interface size axis moves nothing.
|
|
42
|
+
- **A refused settings write no longer looks like a successful one**: when the host rejects a save, the preset row says "The setting was not saved: <reason>" instead of silently snapping the control back to the stored value.
|
|
43
|
+
- **Export hands over the whole thing even without a clipboard**: the clipboard is tried first; on an origin that has none (the remote HTTP entry) the legacy copy path is used; only when both fail does the full JSON land in a fully selected read-only box, one copy shortcut away.
|
|
44
|
+
- **The font picker**: the four curated groups (monospace / CJK / Latin / generic) no longer vanish once local enumeration succeeds, so a curated family this machine does not have can still be found by name; a family is listed once; a refused font permission is no longer remembered forever — reopening the panel retries after twenty seconds.
|
|
45
|
+
- Every per-theme rule now carries its theme prefix (per-theme is not open yet; a latent bug fixed ahead of time).
|
|
32
46
|
|
|
33
47
|
### Changed
|
|
34
|
-
- **A smaller stylesheet
|
|
35
|
-
- **The retired size and line-height axes left the value surface**: `sizeOffset` and `lineHeight` (the interface's size and line height, which have emitted nothing since 0.2.0) stay in the schema and the document — old configurations still parse and `normalizeConfig` still carries them — but they are no longer part of a preset snapshot and no longer decide whether the dark set is a second set, so a light/dark pair that differs only there emits one stylesheet instead of two. "Reset every axis" **still clears them**, so a value nothing shows cannot hide in a document forever.
|
|
36
|
-
- **Dead code removed**: 31 dictionary keys nobody renders (both locales — the retired interface size/line-height copy, the per-theme editor, the old preset button row, the fixed preview label), one dead CSS rule (`.dfp-presetForm`) and seven dead exports (`MARKER`, `isShorthandToken`, `bodyTokenNames`, `uiLineTokenNames`, `deltaTokenNames`, `codeTokenNames`, `uiShorthandTokens`, `scaleFontShorthand`). `VALUE_FIELDS` / `RETIRED_FIELDS` / `DURABLE_FIELDS` now name the three ideas — value axes, stored-but-unrendered, every durable field — separately.
|
|
37
|
-
- **One entry point for the browser checks**: `npm run verify:browser` (`test/browser-verify.mjs`) runs the read-only `browser-probe` / `ui-walk` / `style-verify` by default, adds the four scripts that write the settings namespace under `--writers` (each snapshots the user layer and restores it before exiting), takes `--only a,b` for a subset, and prints a per-script time and exit-code summary. Two walk scripts were rewritten for the 0.2.x card: `slider-walk` expands the section it needs first (the card opens fully collapsed) and asserts "a drag writes nothing, a release writes, each axis lands on its own field"; `split-walk` writes a three-entry stack and asserts the simple-mode slots and remainder note, that a mode round-trip leaves the stack alone, and that picking a Western family in the real panel replaces exactly that slot. **A missing control is now a failure** — the old scripts printed "not found" and exited zero, which is a false green.
|
|
48
|
+
- **A smaller stylesheet and a cheaper background**: collapsing the exclusion lists took one real configuration's stylesheet from 2735 to 2440 bytes, and the size axis now compares three cheap signals before touching any stylesheet at all.
|
|
38
49
|
- Compatibility table gained 0.2.3.
|
|
39
50
|
|
|
40
|
-
### Tests
|
|
41
|
-
- `test/run.mjs` (86 checks): the picker's grouping rules (curated groups always present, no family twice, the local cap and sanitizing, the refusal-retry contract) and the polling gate with a counting stub (negative control included).
|
|
42
|
-
- `test/render-card.mjs` (21 checks): a second render after a state change keeping the hook order, both shapes of a refused write being reported, the export fallback handing over the whole JSON selected, reset clearing the retired axes, and a retired axis not being a value axis.
|
|
43
|
-
- Live (managed instance + headless Edge): WEIGHT OK (17 checks), SPLIT OK (9), SLIDER OK (9), SPLIT WALK OK (14), browser-probe and ui-walk green.
|
|
44
51
|
|
|
45
52
|
## [0.2.2] - 2026-09-16
|
|
46
53
|
|
|
47
54
|
### Fixed
|
|
48
|
-
- **
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
- **The release workflow never ran the tests**: `npm pack` does **not** trigger `prepublishOnly` (only `npm publish` does), so the tag-triggered release had always packed an untested artifact. It now installs and runs `npm run verify` before packing — deliberately **without** building first, because `test/artifacts.mjs` is exactly the check that the committed `lib/` is what the current `src/` produces, and a build step would mask that — and asserts that the tag equals the `package.json` version.
|
|
52
|
-
- **The CHANGELOG extraction matched version prefixes**: the release body used `index(line, "## " pat)`, so `0.2.1` also matched a `0.2.10` heading. It now matches `## <version> ` exactly and **fails the job** when the version has no section (it used to fall back to generated notes silently).
|
|
53
|
-
- **Two common CJK family names were not recognised**: `MS PGothic` and `MS PMincho` were treated as non-CJK (while `MS Gothic` and `MS Mincho` were fine), which feeds the simple mode's CJK slot. Fixed to `ms ?p?(?:gothic|mincho)`, the safe direction for a name heuristic.
|
|
54
|
-
- **`shiftTokens` guards zero**: a zero offset used to emit a real `calc((14px) + 0px)` declaration that disagrees with `isDormant` and `sameValueSet`. Unreachable today (the call sites guard), but a trap for the next caller.
|
|
55
|
-
- **`build.mjs --watch` watched files instead of the directory**: after an editor renamed a source, the process kept waiting on a dead inode and never rebuilt. It now watches `src/` and filters by name, and logs each successful rebuild.
|
|
55
|
+
- **In simple mode the CJK slot could not be picked or cleared**: choosing a family there, or clearing that chip, threw and lost the change (the western slot was fine); all three family sections now write their CJK slot properly.
|
|
56
|
+
- **`MS PGothic` / `MS PMincho` are recognised as CJK**: they used to be treated as western, which feeds simple mode's CJK slot.
|
|
57
|
+
- **A guard for unwired controls**: the offline checks now fire every control's callback (sliders, segmented controls, the family picker, the preset select, text inputs, every button), so a handler that was never connected fails immediately.
|
|
56
58
|
|
|
57
59
|
### Changed
|
|
58
|
-
- **
|
|
59
|
-
-
|
|
60
|
+
- **A release can no longer ship an untested package**: the tag-triggered build runs the full check before packing, and asserts that the packed artifact matches the sources and that the tag matches the version.
|
|
61
|
+
- Documentation: editing a source file requires a build first (the browser loads the built artifact), and the market entry only *states* its compatibility — there is no pre-install preflight.
|
|
62
|
+
|
|
60
63
|
|
|
61
64
|
## [0.2.1] - 2026-09-16
|
|
62
65
|
|
|
63
66
|
### Fixed
|
|
64
|
-
- **"
|
|
65
|
-
- **
|
|
66
|
-
- **The interface weight is back, and it
|
|
67
|
-
- **
|
|
68
|
-
-
|
|
69
|
-
|
|
67
|
+
- **After switching "interface follows conversation" off, the interface weight did not fall back and reset did nothing**: two copies of the injected stylesheet lived in the page, and the served one is only rebuilt on the next page load, so any change that *removed* a rule never took effect. There is only one copy now, and both switching the follow off and resetting apply immediately.
|
|
68
|
+
- **Going from following to not following no longer snaps the interface back to its own old value**: the value the interface was showing is stored as its own the moment the switch goes off, so nothing moves visually and the slider stays where it was; a conversation axis that was never set keeps DSH's own value.
|
|
69
|
+
- **The interface weight is back, and it really cannot touch the conversation**: the whole conversation body and code subtree is excluded from the interface weight rule — every interface text element moves, not a single conversation element does.
|
|
70
|
+
- **The conversation section no longer claims to "follow the interface" when unset** (the following has always been one-way: the interface follows the conversation).
|
|
71
|
+
- The previews inside the card are no longer dragged along by the interface weight: conversation, code and interface previews each match the real surface.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- **The follow switch now covers font and weight together**: while it is on the interface uses the conversation's family and weight (its own two controls are hidden); with it off the interface uses its own, and neither side affects the other.
|
|
75
|
+
|
|
70
76
|
|
|
71
77
|
## [0.2.0] - 2026-09-16
|
|
72
78
|
|
|
73
79
|
### Added
|
|
74
|
-
- **Three
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
- **Code ligatures**:
|
|
78
|
-
- **Refuse synthetic
|
|
79
|
-
- **
|
|
80
|
-
- **
|
|
81
|
-
- **Card information architecture**: top to bottom the open card becomes an edit-mode row, a **preset bar** and three **accordion sections** — **conversation → interface → code** (the conversation leads because it owns every axis) — all collapsed by default, each title row carrying a summary with the chevron pinned to the far right, at most one open at a time; "refuse synthetic styles" is one or two switches, so it **no longer earns an accordion** and sits flat below the three sections. Expanding a section ends with that section's own **inline preview box** (rendering just that part; a floating variant was tried first and reverted after real-machine feedback). **Row format lines up with dsh-quick-toc**: every setting is a field row with 14px vertical padding (was 16px), every on/off control is the joined "one box split in two" segmented control (28px tall, was a 22px pill switch), and the control sits in the same row as its label, right-aligned (`.dfp-inline`, the same shape as quick-toc's `.dqt-pinline`) — so the two cards' rows and controls align.
|
|
82
|
-
- **The interface size / line-height / weight axes are RETIRED (measured)**: DSH exposes **no interface size hook** — the settings sheet, both sidebars and the workspace size their text with literals in upstream CSS (22 literals in settings-plugins, 18 in workspace, 6 in sidebar, **0** uses of the interface ladder tokens), and the ladder tokens (`--dsw-font-xs-13`, `--dsw-font-s-14`, …) are consumed only by 6 conversation-area packages (tool / trajectory / attachment / chat / conversation / cordis). The only official size hook is the conversation one. Scaling the ladder from these fields could not reach the settings sheet or the sidebars, while it reached the **conversation** through `--dsh-content-font-size` — the root cause of "I change the interface and the conversation moves". Weight is worse: it can only be expressed as a `body, body *` rule, which cannot avoid reaching the conversation either (narrowing it off the markdown subtree would also strip the theme's own heading weights). So **size, line height and weight belong to the conversation alone**, and the interface keeps the one axis that measurably works: its font (a page-wide `body` rule plus the theme variable). The `sizeOffset` / `lineHeight` / `weight` fields stay in the schema (old documents and presets keep parsing) but inject nothing at all.
|
|
83
|
-
- **Per-theme values ship out of this release**: light and dark share one value set — the top-bar per-theme switch and the light/dark editor are removed (the dark fields stay in the host schema but dormant, and rendering ignores them), to be re-evaluated in a later release.
|
|
84
|
-
|
|
85
|
-
### Fixed (real-machine walkthrough)
|
|
86
|
-
- **Preset messages no longer linger, and no longer move the layout**: a note like "Presets copied to the clipboard." used to sit in the card forever and, as a fresh line, push the sections below it down. It now **shares one row** with "With a preset selected, every change saves into it automatically": the message fades in on the **right** of that row and **fades out by itself after 2.6 s** (a 0.24 s opacity transition, then the text is cleared). The row is **always mounted** and exactly one line tall, and the message is clamped with `nowrap + ellipsis` — so appearing and disappearing never changes the row height and nothing below ever moves. Two identical actions in a row still work (each message carries an incrementing id, and the auto-hide timer restarts), and an over-long message (the clipboard-unavailable fallback, say) stays readable on hover through its `title`.
|
|
87
|
-
- **"I change the interface and the conversation moves"**: the interface size axis scaled the conversation's official content-size chain (`--dsh-content-font-size` / the secondary size) alongside the interface ladder, and every markdown size derives from that chain — so an interface edit really was a conversation edit. The interface axis is now explicitly barred from it (`bodyTokenNames` excludes `--dsh-content-font-*`), and the interface size axis itself is retired for the reason above.
|
|
88
|
-
- **The conversation size offset used to move headings but not paragraphs**: the old implementation only rewrote the delta tokens and literal sizes, while paragraphs take their size from `var(--dsh-content-font-size,14px)` — and `var()` inside a custom property resolves where the property is **declared**, so a deeper scoped override cannot reach it. The new implementation declares `--dsh-content-font-size` as "official value + offset" at the source, so paragraphs, headings and line heights all follow.
|
|
89
|
-
- **Dark overrides used to be shadowed by the light values**: the per-theme resolver merged the dark map over an **already-expanded** value set, so as soon as the follow rule changed direction the borrowed values could overwrite the dark ones. The dark overrides are now merged over the raw values and expanded afterwards, so a dark font can no longer be clobbered by a light value.
|
|
90
|
-
- **Weight readouts read 400**: an unset weight used to print "unset" while the slider sat at 400 and the hint said 400 keeps DSH's own — three statements that disagreed. An unset weight now reads **400** (conversation and code weights both).
|
|
91
|
-
- **The % vanished while dragging the line-height slider**: the pending readout had no unit and only gained one on release — the pending readout now keeps the `%` too (the size / code-height `px` prefixes already did).
|
|
92
|
-
- **The conversation section showed English "variable names"**: the dialog axis label keys (`dialog.*`, `size/line/weight.dialogLabel`…) were missing from the bilingual dictionaries, so `translate` fell back to the key names — both dictionaries are complete now.
|
|
93
|
-
- **The first control sat too far from the section title**: field rows carry 16px top padding on top of the section body — the first field of a section body is tightened to 10px.
|
|
94
|
-
- **The chevron left the far right edge when expanded**: with the summary gone nothing pushed it there — an expanded section renders a flexible spacer instead, so the arrow stays pinned in both states.
|
|
80
|
+
- **Three separate sets of typography**: **conversation** (body, tables, headings — family, size, line height and weight), **interface** (family only, following the conversation by default) and **code** (its own set, with ligatures and feature switches).
|
|
81
|
+
- **Conversation size**: −3 to +6 px on top of DSH's own conversation size, moving paragraphs, headings and line height together.
|
|
82
|
+
- **Conversation line height**: 100%–160%; the code line height is a separate additive offset.
|
|
83
|
+
- **Code ligatures**: default / on / off, plus a sanitized `font-feature-settings` field in advanced mode.
|
|
84
|
+
- **Refuse synthetic italics and bolds**: one switch in simple mode, two independent ones in advanced mode.
|
|
85
|
+
- **Presets**: a dropdown in the card with five defaults, applied on pick; once one is selected every edit is saved into it; rename, import and export sit beside it (import merges by name, at most 20, synced across browsers).
|
|
86
|
+
- **A rebuilt card**: edit mode, a preset bar, then collapsible conversation / interface / code sections that start collapsed, one open at a time, each ending in its own preview; row heights and controls match dsh-quick-toc.
|
|
95
87
|
|
|
96
88
|
### Changed
|
|
97
|
-
- **
|
|
98
|
-
-
|
|
89
|
+
- **The interface's size, line height and weight axes retired**: DSH has no interface-size interface (the settings page and sidebars use hard-coded sizes upstream), so those axes could not reach the interface and only disturbed the conversation. Size, line height and weight now belong to the conversation alone; the interface keeps the family, which does work. The old fields stay in the schema and keep parsing.
|
|
90
|
+
- Font families are delivered through the official theme layer, so a theme switch applies immediately.
|
|
91
|
+
- Light and dark share one set of values in this release; per-theme values are deferred.
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
- **"Changing the interface changed the conversation"**: the interface size axis used to scale the conversation's size chain too; it is isolated now.
|
|
95
|
+
- **The conversation size offset only moved headings, not paragraphs**: the offset is added once at the source, so paragraphs, headings and line height all follow.
|
|
96
|
+
- **In the dark theme a dark value could be overridden by a light one.**
|
|
97
|
+
- **The weight readout said "not set" while the slider sat at 400**: the readout is 400 now.
|
|
98
|
+
- **The `%` disappeared while dragging the line-height slider**: the pending readout carries its unit too.
|
|
99
|
+
- **The conversation section showed English variable names as labels**: both dictionaries are complete.
|
|
100
|
+
- The first field of an expanded section sat too far from the heading, and the expanded chevron was not pinned to the right.
|
|
101
|
+
|
|
99
102
|
|
|
100
103
|
## [0.1.6] - 2026-09-15
|
|
101
104
|
|
|
102
105
|
### Fixed
|
|
103
|
-
- **The
|
|
106
|
+
- **The card's expand chevron did not match the host's**: it was a text character — thinner than the host's arrows and off-centre when rotated. It is now the host's own inline chevron, rotating around its own centre.
|
|
107
|
+
|
|
104
108
|
|
|
105
109
|
## [0.1.5] - 2026-09-15
|
|
106
110
|
|
|
107
111
|
### Added
|
|
108
|
-
- **Code
|
|
112
|
+
- **Code weight**: weight split into independent "body weight" and "code weight" sliders (300–600 each, 400 meaning unchanged), so changing the body no longer drags the code along.
|
|
109
113
|
|
|
110
114
|
### Changed
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
|
|
115
|
+
- The weight slider moved into the family group it belongs to, with separate labels for the two.
|
|
116
|
+
- An unset code weight now writes DSH's own value back explicitly, so code does not follow the body weight after upgrading.
|
|
117
|
+
|
|
114
118
|
|
|
115
119
|
## [0.1.4] - 2026-09-15
|
|
116
120
|
|
|
117
121
|
### Added
|
|
118
|
-
- **Code
|
|
122
|
+
- **Code size**: size split into independent "body size" and "code size" sliders (−3 to +6 px each, 0 meaning unchanged), so changing the body no longer drags the code along.
|
|
119
123
|
|
|
120
124
|
### Changed
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
- **Compatibility table** now lists 0.1.4 as the latest version.
|
|
125
|
+
- The size slider moved under the family it belongs to, with separate labels; after upgrading the body behaves as before and code returns to DSH's own value.
|
|
126
|
+
|
|
124
127
|
|
|
125
128
|
## [0.1.3] - 2026-09-14
|
|
126
129
|
|
|
127
130
|
### Changed
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
|
|
131
|
+
- The switch row's label became "edit mode", and its two options went back to a joined segmented control with one divider between them.
|
|
132
|
+
- The card description now mentions the western/CJK split.
|
|
133
|
+
- The README dropped three implementation notes ("written on release", "no font flash on the first frame", "bilingual") — behaviour unchanged.
|
|
134
|
+
|
|
132
135
|
|
|
133
136
|
## [0.1.2] - 2026-09-14
|
|
134
137
|
|
|
135
138
|
### Changed
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
|
|
139
|
+
- The README was rewritten as features / install / usage / compatibility / development; design trade-offs and development pitfalls left it (both languages).
|
|
140
|
+
- The compatibility statement is narrower: only the latest patch of the 0.1.5 line is listed — older patches in the same major are compatible per semantic versioning and are no longer enumerated.
|
|
141
|
+
- The npm description was trimmed (published metadata cannot be edited, so this takes effect from 0.1.2), and the English card title became "Font tune", matching the package name.
|
|
142
|
+
|
|
140
143
|
|
|
141
144
|
## [0.1.1] - 2026-09-14
|
|
142
145
|
|
|
143
146
|
### Added
|
|
144
|
-
-
|
|
145
|
-
-
|
|
147
|
+
- An English changelog, `CHANGELOG.en.md`, shipped with the package.
|
|
148
|
+
- Pushing a `v*` tag now packs and creates/updates a Release automatically, including a version-less `dsh-fonttune.tgz` for the market entry to link to; the release body is the Chinese section for that version with the English one folded inside.
|
|
146
149
|
|
|
147
|
-
### Changed
|
|
148
|
-
- The stale offline-check count in the README and changelog was corrected (35 → 42). The running code is identical to 0.1.0.
|
|
149
150
|
|
|
150
151
|
## [0.1.0] - 2026-09-14
|
|
151
152
|
|
|
152
|
-
|
|
153
|
+
The first release: a two-half plugin. The browser half owns the settings card and the style injection; the host half registers the settings namespace and serves the saved declarations with the index, so the first frame already uses them.
|
|
153
154
|
|
|
154
155
|
### Added
|
|
155
|
-
- **
|
|
156
|
-
- **
|
|
157
|
-
- **
|
|
158
|
-
- **
|
|
159
|
-
- **
|
|
160
|
-
- **
|
|
161
|
-
- **
|
|
162
|
-
- **Global font weight** (300 ~ 600, any integer): applied through `body, body *`; 400 and "unset" both mean "leave DSH's own weight alone".
|
|
163
|
-
- **Commit-on-release sliders**: dragging the size-offset or weight slider only updates a local value and its readout — the write happens once on `pointerup` / `touchend` (window capture-level listeners) or on blur/keyup, so dragging never recomputes the size tokens and rewrites the settings document per step. **The local value also stays on screen until the host confirms it**: clearing it immediately would show the old committed number for one frame ("bounces back, then settles"); a repeated `pointerup` is guarded by an "already awaiting confirmation" flag so the same value is never written twice.
|
|
164
|
-
- **No first-paint font flash**: the host half listens on `webserver/index-inject` and injects the same declarations, so the first paint is already correct.
|
|
165
|
-
- **Bilingual copy** (Chinese/English) with a Chinese fallback; `queryLocalFonts` unavailability or refusal falls back to the built-in list silently.
|
|
166
|
-
- **Family-name sanitizing**: names are filtered through an allowlist and then quoted as a whole (letters/digits/space/`.` `,` `_` `-` only); the host schema adds a `^[^{};<>\\]*$` pattern and a length cap. A hand-crafted CSS injection cannot close a declaration or start a rule.
|
|
156
|
+
- **The plugin configuration card**: in Settings → Plugins → Plugin configuration, reading and writing DSH's own settings document.
|
|
157
|
+
- **Two font stacks**, one for the body and one for code, each a fallback list that may be empty (= leave DSH's fonts alone).
|
|
158
|
+
- **A font picker**: the built-in monospace / CJK / Latin / generic groups, the machine's installed families on Chromium, a "use <name>" entry for anything not listed, and every row rendered in its own family.
|
|
159
|
+
- **Western/CJK split (simple mode)**: the stack becomes a western slot and a CJK slot while every other entry and the order stay untouched; advanced mode is the full chip editor with drag reordering and a live preview.
|
|
160
|
+
- **A global size offset** (−3 to +6 px, stacking with DSH's own size slider) and **a global weight** (300–600, 400 meaning unchanged).
|
|
161
|
+
- **Sliders write on release**: nothing is written while dragging, and the readout holds until the host confirms.
|
|
162
|
+
- **Bilingual copy**; family names are sanitized so they cannot close a declaration or open a rule.
|
|
167
163
|
|
|
168
164
|
### Fixed
|
|
169
|
-
- **The card crashed on first render** (a release blocker):
|
|
170
|
-
- **Three
|
|
171
|
-
- **
|
|
172
|
-
- **
|
|
173
|
-
- **
|
|
174
|
-
|
|
175
|
-
- **The size-token regex missed `--dsh-content-font-size`** (the name has no `-font-` segment) and its `-secondary` variants.
|
|
176
|
-
- **Timers now go through `globalThis`** instead of assuming `window` carries them.
|
|
165
|
+
- **The card crashed on its first render** (a release blocker): the subscribe method was passed bare, losing `this`, so the card never appeared on the plugin configuration page.
|
|
166
|
+
- **Three problems in the size offset**: the body itself was not scaled, a refresh multiplied the plugin's own declarations as if they were the baseline, and derived sizes were scaled twice.
|
|
167
|
+
- **The family did not reach the conversation area or the sidebars** (those areas declare the font variable themselves).
|
|
168
|
+
- **The weight was snapped to the nearest hundred**: any integer now applies as chosen.
|
|
169
|
+
- **Family sanitizing was too permissive.**
|
|
170
|
+
|