dsh-cait 1.0.4 → 1.1.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 +202 -0
- package/README.ja.md +147 -25
- package/README.md +176 -27
- package/README.zh-CN.md +137 -26
- package/client/components.js +2047 -340
- package/client/entry.js +13 -0
- package/client/helpers.js +110 -7
- package/client/locales.js +435 -6
- package/client/rpc.js +1 -1
- package/client/styles.js +137 -3
- package/client.js +2742 -356
- package/index.js +3 -0
- package/lib/aligner.js +411 -0
- package/lib/api.js +31 -0
- package/lib/context.js +71 -0
- package/lib/docx.js +12 -9
- package/lib/epub.js +355 -0
- package/lib/formats.js +88 -33
- package/lib/glossary.js +4 -4
- package/lib/html.js +271 -0
- package/lib/import-export.js +208 -95
- package/lib/libraries.js +55 -0
- package/lib/library-export.js +75 -0
- package/lib/library-view.js +215 -0
- package/lib/mt.js +17 -7
- package/lib/persistence.js +92 -7
- package/lib/pre-translate.js +263 -0
- package/lib/preprocess.js +65 -0
- package/lib/propagate.js +133 -0
- package/lib/qa.js +167 -0
- package/lib/store-utils.js +48 -6
- package/lib/store.js +143 -12
- package/lib/term-extract.js +190 -0
- package/lib/terms.js +102 -0
- package/lib/tm.js +123 -11
- package/lib/tmx.js +47 -2
- package/lib/tools.js +472 -0
- package/package.json +2 -2
package/client/entry.js
CHANGED
|
@@ -14,6 +14,19 @@
|
|
|
14
14
|
scaleCssLengths,
|
|
15
15
|
caitUiBase: CAIT_UI_BASE,
|
|
16
16
|
caitUiMaxUnit: CAIT_UI_MAX_UNIT,
|
|
17
|
+
caitUiDamping: CAIT_UI_DAMPING,
|
|
18
|
+
caitThemeAttr: CAIT_THEME_ATTR,
|
|
19
|
+
detectThemeKind,
|
|
20
|
+
normalizePageSize,
|
|
21
|
+
readPageSize,
|
|
22
|
+
writePageSize,
|
|
23
|
+
pageCount,
|
|
24
|
+
clampPage,
|
|
25
|
+
pageBounds,
|
|
26
|
+
segmentNumberToIndex,
|
|
27
|
+
pageSizeOptions: PAGE_SIZE_OPTIONS,
|
|
28
|
+
pageSizeDefault: PAGE_SIZE_DEFAULT,
|
|
29
|
+
pageSizeStorageKey: PAGE_SIZE_STORAGE_KEY,
|
|
17
30
|
cssScaled: CSS_SCALED,
|
|
18
31
|
syncPollMs: SYNC_POLL_MS,
|
|
19
32
|
makeTranslator,
|
package/client/helpers.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
const API = '/cait/api/rpc'
|
|
2
2
|
const SYNC_POLL_MS = 2000
|
|
3
|
+
// One pre-translation block is 8 segments: roughly 12 s with a warm route,
|
|
4
|
+
// short enough that one cancellation click never waits long.
|
|
5
|
+
const PRETRANSLATE_BLOCK_SIZE = 8
|
|
3
6
|
|
|
4
7
|
// Only the last mounted library must stay checked. An unmounted library is
|
|
5
8
|
// always selectable, even when that is currently the only mounted one.
|
|
@@ -43,14 +46,16 @@
|
|
|
43
46
|
// --cait-u (a unitless multiplier) tracks the size of the panel.
|
|
44
47
|
const CAIT_UNIT_VAR = '--cait-u'
|
|
45
48
|
// The designed density is calibrated for roughly 1100×680 CSS pixels of
|
|
46
|
-
// DSH panel area.
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
// to 1.8× before the cap applies.
|
|
49
|
+
// DSH panel area. Growing linearly from there made a maximized window reach
|
|
50
|
+
// 1.8×, which is visibly larger than the surrounding DSH chrome and eats the
|
|
51
|
+
// horizontal budget the three-column review view needs. Growth is therefore
|
|
52
|
+
// damped and capped well below the old ceiling.
|
|
51
53
|
const CAIT_UI_BASE = { width: 1100, height: 680 }
|
|
52
54
|
const CAIT_UI_MIN_UNIT = 1
|
|
53
|
-
const CAIT_UI_MAX_UNIT = 1.
|
|
55
|
+
const CAIT_UI_MAX_UNIT = 1.45
|
|
56
|
+
// 0.6 keeps small and mid panels close to the old density while flattening
|
|
57
|
+
// the large end: 1920×1080 lands at 1.353, 2560 and 4K stop at 1.45.
|
|
58
|
+
const CAIT_UI_DAMPING = 0.6
|
|
54
59
|
|
|
55
60
|
// Grow with the panel but never shrink below the designed size; the height
|
|
56
61
|
// term keeps short/wide windows from becoming oversized and scroll-heavy.
|
|
@@ -59,7 +64,8 @@
|
|
|
59
64
|
const h = Number(height)
|
|
60
65
|
if (!(w > 0) || !(h > 0)) return CAIT_UI_MIN_UNIT
|
|
61
66
|
const fit = Math.min(w / CAIT_UI_BASE.width, h / CAIT_UI_BASE.height)
|
|
62
|
-
const
|
|
67
|
+
const grown = 1 + (fit - 1) * CAIT_UI_DAMPING
|
|
68
|
+
const unit = Math.min(CAIT_UI_MAX_UNIT, Math.max(CAIT_UI_MIN_UNIT, grown))
|
|
63
69
|
return Math.round(unit * 1000) / 1000
|
|
64
70
|
}
|
|
65
71
|
|
|
@@ -101,3 +107,100 @@
|
|
|
101
107
|
}
|
|
102
108
|
return output
|
|
103
109
|
}
|
|
110
|
+
|
|
111
|
+
// --- theme --------------------------------------------------------------
|
|
112
|
+
// DSH marks the dark theme on <body>; the tokens handle every authored
|
|
113
|
+
// colour, but native widgets (select popups, checkboxes, scrollbars, caret)
|
|
114
|
+
// follow `color-scheme`, which tokens cannot reach. Mirror the host's theme
|
|
115
|
+
// onto our own root attribute and let CSS set the scheme from it.
|
|
116
|
+
const CAIT_THEME_ATTR = 'data-cait-theme'
|
|
117
|
+
|
|
118
|
+
function detectThemeKind(doc) {
|
|
119
|
+
const root = doc?.documentElement
|
|
120
|
+
const body = doc?.body
|
|
121
|
+
if (body?.hasAttribute?.('data-ds-dark-theme')) return 'dark'
|
|
122
|
+
const explicit = root?.getAttribute?.('data-theme') || body?.getAttribute?.('data-theme')
|
|
123
|
+
if (explicit === 'dark') return 'dark'
|
|
124
|
+
return 'light'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// --- paging -------------------------------------------------------------
|
|
128
|
+
// Both the segment rail and the library page page through server-side
|
|
129
|
+
// windows, so the arithmetic lives here: one place to clamp, one place to
|
|
130
|
+
// validate a typed segment number, one place to remember the page size.
|
|
131
|
+
const PAGE_SIZE_OPTIONS = [20, 50, 100, 200]
|
|
132
|
+
const PAGE_SIZE_DEFAULT = 50
|
|
133
|
+
const PAGE_SIZE_STORAGE_KEY = 'cait:pageSize'
|
|
134
|
+
|
|
135
|
+
function normalizePageSize(value) {
|
|
136
|
+
// A missing setting arrives as null (localStorage) or undefined, and
|
|
137
|
+
// Number(null) is 0, which would snap to the smallest page instead of the
|
|
138
|
+
// documented default.
|
|
139
|
+
if (value === null || value === undefined || value === '') return PAGE_SIZE_DEFAULT
|
|
140
|
+
const size = Number(value)
|
|
141
|
+
if (!Number.isFinite(size)) return PAGE_SIZE_DEFAULT
|
|
142
|
+
let best = PAGE_SIZE_OPTIONS[0]
|
|
143
|
+
let bestGap = Infinity
|
|
144
|
+
for (const option of PAGE_SIZE_OPTIONS) {
|
|
145
|
+
const gap = Math.abs(option - size)
|
|
146
|
+
if (gap < bestGap) {
|
|
147
|
+
best = option
|
|
148
|
+
bestGap = gap
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return best
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function readPageSize(storage) {
|
|
155
|
+
try {
|
|
156
|
+
return normalizePageSize(storage?.getItem?.(PAGE_SIZE_STORAGE_KEY))
|
|
157
|
+
} catch {
|
|
158
|
+
return PAGE_SIZE_DEFAULT
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function writePageSize(storage, value) {
|
|
163
|
+
const size = normalizePageSize(value)
|
|
164
|
+
try {
|
|
165
|
+
storage?.setItem?.(PAGE_SIZE_STORAGE_KEY, String(size))
|
|
166
|
+
} catch {
|
|
167
|
+
// A blocked storage must not break paging; the in-memory value wins.
|
|
168
|
+
}
|
|
169
|
+
return size
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function pageCount(total, pageSize) {
|
|
173
|
+
const size = normalizePageSize(pageSize)
|
|
174
|
+
const count = Number(total)
|
|
175
|
+
if (!Number.isFinite(count) || count <= 0) return 1
|
|
176
|
+
return Math.max(1, Math.ceil(count / size))
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function clampPage(page, total, pageSize) {
|
|
180
|
+
const last = pageCount(total, pageSize)
|
|
181
|
+
const wanted = Number(page)
|
|
182
|
+
if (!Number.isFinite(wanted)) return 1
|
|
183
|
+
return Math.min(last, Math.max(1, Math.trunc(wanted)))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Returns 1-based inclusive bounds plus the row count, so callers can print
|
|
187
|
+
// "x–y of n" without repeating the arithmetic.
|
|
188
|
+
function pageBounds(page, total, pageSize) {
|
|
189
|
+
const size = normalizePageSize(pageSize)
|
|
190
|
+
const count = Math.max(0, Number(total) || 0)
|
|
191
|
+
const current = clampPage(page, count, size)
|
|
192
|
+
const start = count === 0 ? 0 : (current - 1) * size + 1
|
|
193
|
+
const end = Math.min(count, current * size)
|
|
194
|
+
return { page: current, pageSize: size, start, end, total: count, pages: pageCount(count, size) }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// A translator types "42" meaning segment 42, so the input is 1-based; the
|
|
198
|
+
// return value is the 0-based index the store uses.
|
|
199
|
+
function segmentNumberToIndex(value, total) {
|
|
200
|
+
const text = String(value ?? '').trim()
|
|
201
|
+
if (!/^\d+$/.test(text)) return null
|
|
202
|
+
const number = Number(text)
|
|
203
|
+
const count = Number(total)
|
|
204
|
+
if (!Number.isFinite(count) || number < 1 || number > count) return null
|
|
205
|
+
return number - 1
|
|
206
|
+
}
|