dsh-cait 1.0.3 → 1.0.4
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 +367 -352
- package/LICENSE +201 -201
- package/README.ja.md +4 -3
- package/README.md +424 -423
- package/README.zh-CN.md +391 -390
- package/client/components.js +2377 -2377
- package/client/helpers.js +103 -103
- package/client/locales.js +730 -730
- package/client/rpc.js +93 -93
- package/client/styles.js +258 -258
- package/client.js +3556 -3556
- package/icon.svg +8 -8
- package/index.js +45 -45
- package/lib/api.js +223 -223
- package/lib/docx.js +389 -389
- package/lib/errors.js +8 -8
- package/lib/formats.js +917 -917
- package/lib/glossary.js +178 -178
- package/lib/import-export.js +605 -605
- package/lib/libraries.js +183 -183
- package/lib/markdown.js +28 -28
- package/lib/mt.js +152 -152
- package/lib/persistence.js +321 -321
- package/lib/pptx.js +89 -89
- package/lib/segmenter.js +84 -84
- package/lib/similarity.js +113 -113
- package/lib/store-utils.js +339 -339
- package/lib/store.js +734 -734
- package/lib/tm.js +160 -160
- package/lib/tmx.js +85 -85
- package/lib/tools.js +472 -472
- package/lib/xlsx.js +218 -218
- package/lib/xml.js +31 -31
- package/locale/en.json +11 -11
- package/locale/zh.json +11 -11
- package/package.json +83 -83
- package/scripts/build-client.mjs +13 -13
package/client/helpers.js
CHANGED
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
const API = '/cait/api/rpc'
|
|
2
|
-
const SYNC_POLL_MS = 2000
|
|
3
|
-
|
|
4
|
-
// Only the last mounted library must stay checked. An unmounted library is
|
|
5
|
-
// always selectable, even when that is currently the only mounted one.
|
|
6
|
-
function isMountToggleDisabled({ mounted, mountedCount, busy = false } = {}) {
|
|
7
|
-
return Boolean(busy) || (Boolean(mounted) && Number(mountedCount) <= 1)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function computeNextMountIds(currentIds, id, checked) {
|
|
11
|
-
const current = Array.isArray(currentIds) ? currentIds : []
|
|
12
|
-
if (!checked && current.length <= 1) return null
|
|
13
|
-
return checked
|
|
14
|
-
? [...new Set([...current, id])]
|
|
15
|
-
: current.filter((item) => item !== id)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// A dirty draft wins over a remote snapshot; the banner asks the user to
|
|
19
|
-
// save/refresh instead of silently replacing their text.
|
|
20
|
-
function shouldAdoptRemote({ currentRevision, nextRevision, dirty = false } = {}) {
|
|
21
|
-
return !dirty && Number(nextRevision) !== Number(currentRevision)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const LANGUAGES = [
|
|
25
|
-
['en', 'English'],
|
|
26
|
-
['zh-CN', '简体中文'],
|
|
27
|
-
['zh-TW', '繁體中文'],
|
|
28
|
-
['ja', '日本語'],
|
|
29
|
-
['ko', '한국어'],
|
|
30
|
-
['fr', 'Français'],
|
|
31
|
-
['de', 'Deutsch'],
|
|
32
|
-
['es', 'Español'],
|
|
33
|
-
['pt', 'Português'],
|
|
34
|
-
['ru', 'Русский'],
|
|
35
|
-
['ar', 'العربية'],
|
|
36
|
-
['it', 'Italiano'],
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
// --- UI scaling ---------------------------------------------------------
|
|
40
|
-
// styles.js is authored in fixed CSS pixels, which makes the workbench look
|
|
41
|
-
// undersized next to the rest of DSH once the window is maximized. Every
|
|
42
|
-
// length is therefore rewritten as `calc(<n>px * var(--cait-u))` and
|
|
43
|
-
// --cait-u (a unitless multiplier) tracks the size of the panel.
|
|
44
|
-
const CAIT_UNIT_VAR = '--cait-u'
|
|
45
|
-
// The designed density is calibrated for roughly 1100×680 CSS pixels of
|
|
46
|
-
// DSH panel area. Fullscreen/maximized windows on 1440p and 4K displays
|
|
47
|
-
// were still capped at 1.4× with the old 1320×800 base, which left the
|
|
48
|
-
// 13px body type visibly smaller than the surrounding DSH UI. Keep the
|
|
49
|
-
// height term so short windows do not overflow, but let large panels grow
|
|
50
|
-
// to 1.8× before the cap applies.
|
|
51
|
-
const CAIT_UI_BASE = { width: 1100, height: 680 }
|
|
52
|
-
const CAIT_UI_MIN_UNIT = 1
|
|
53
|
-
const CAIT_UI_MAX_UNIT = 1.8
|
|
54
|
-
|
|
55
|
-
// Grow with the panel but never shrink below the designed size; the height
|
|
56
|
-
// term keeps short/wide windows from becoming oversized and scroll-heavy.
|
|
57
|
-
function computeCaitUnit({ width, height } = {}) {
|
|
58
|
-
const w = Number(width)
|
|
59
|
-
const h = Number(height)
|
|
60
|
-
if (!(w > 0) || !(h > 0)) return CAIT_UI_MIN_UNIT
|
|
61
|
-
const fit = Math.min(w / CAIT_UI_BASE.width, h / CAIT_UI_BASE.height)
|
|
62
|
-
const unit = Math.min(CAIT_UI_MAX_UNIT, Math.max(CAIT_UI_MIN_UNIT, fit))
|
|
63
|
-
return Math.round(unit * 1000) / 1000
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const CSS_PX_RE = /(-?(?:\d+\.?\d*|\.\d+))px/g
|
|
67
|
-
|
|
68
|
-
function scaleCssChunk(chunk, unitVar) {
|
|
69
|
-
return chunk.replace(CSS_PX_RE, (whole, value) => {
|
|
70
|
-
// Hairlines stay exactly 1px so borders keep rendering crisply.
|
|
71
|
-
if (Math.abs(Number(value)) <= 1) return whole
|
|
72
|
-
return `calc(${value}px * var(${unitVar}, 1))`
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Scale declaration values only. Media/supports/container preludes are
|
|
77
|
-
// copied verbatim: var() is not allowed in a media condition and those
|
|
78
|
-
// breakpoints must keep matching viewport pixels.
|
|
79
|
-
function scaleCssLengths(css, unitVar = CAIT_UNIT_VAR) {
|
|
80
|
-
const source = String(css ?? '')
|
|
81
|
-
let output = ''
|
|
82
|
-
let index = 0
|
|
83
|
-
while (index < source.length) {
|
|
84
|
-
const at = source.indexOf('@', index)
|
|
85
|
-
if (at === -1) {
|
|
86
|
-
output += scaleCssChunk(source.slice(index), unitVar)
|
|
87
|
-
break
|
|
88
|
-
}
|
|
89
|
-
output += scaleCssChunk(source.slice(index, at), unitVar)
|
|
90
|
-
let cursor = at
|
|
91
|
-
let depth = 0
|
|
92
|
-
while (cursor < source.length) {
|
|
93
|
-
const ch = source[cursor]
|
|
94
|
-
if (ch === '(') depth += 1
|
|
95
|
-
else if (ch === ')') depth = Math.max(0, depth - 1)
|
|
96
|
-
else if (depth === 0 && (ch === '{' || ch === ';')) break
|
|
97
|
-
cursor += 1
|
|
98
|
-
}
|
|
99
|
-
output += source.slice(at, cursor + 1)
|
|
100
|
-
index = cursor + 1
|
|
101
|
-
}
|
|
102
|
-
return output
|
|
103
|
-
}
|
|
1
|
+
const API = '/cait/api/rpc'
|
|
2
|
+
const SYNC_POLL_MS = 2000
|
|
3
|
+
|
|
4
|
+
// Only the last mounted library must stay checked. An unmounted library is
|
|
5
|
+
// always selectable, even when that is currently the only mounted one.
|
|
6
|
+
function isMountToggleDisabled({ mounted, mountedCount, busy = false } = {}) {
|
|
7
|
+
return Boolean(busy) || (Boolean(mounted) && Number(mountedCount) <= 1)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function computeNextMountIds(currentIds, id, checked) {
|
|
11
|
+
const current = Array.isArray(currentIds) ? currentIds : []
|
|
12
|
+
if (!checked && current.length <= 1) return null
|
|
13
|
+
return checked
|
|
14
|
+
? [...new Set([...current, id])]
|
|
15
|
+
: current.filter((item) => item !== id)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// A dirty draft wins over a remote snapshot; the banner asks the user to
|
|
19
|
+
// save/refresh instead of silently replacing their text.
|
|
20
|
+
function shouldAdoptRemote({ currentRevision, nextRevision, dirty = false } = {}) {
|
|
21
|
+
return !dirty && Number(nextRevision) !== Number(currentRevision)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const LANGUAGES = [
|
|
25
|
+
['en', 'English'],
|
|
26
|
+
['zh-CN', '简体中文'],
|
|
27
|
+
['zh-TW', '繁體中文'],
|
|
28
|
+
['ja', '日本語'],
|
|
29
|
+
['ko', '한국어'],
|
|
30
|
+
['fr', 'Français'],
|
|
31
|
+
['de', 'Deutsch'],
|
|
32
|
+
['es', 'Español'],
|
|
33
|
+
['pt', 'Português'],
|
|
34
|
+
['ru', 'Русский'],
|
|
35
|
+
['ar', 'العربية'],
|
|
36
|
+
['it', 'Italiano'],
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
// --- UI scaling ---------------------------------------------------------
|
|
40
|
+
// styles.js is authored in fixed CSS pixels, which makes the workbench look
|
|
41
|
+
// undersized next to the rest of DSH once the window is maximized. Every
|
|
42
|
+
// length is therefore rewritten as `calc(<n>px * var(--cait-u))` and
|
|
43
|
+
// --cait-u (a unitless multiplier) tracks the size of the panel.
|
|
44
|
+
const CAIT_UNIT_VAR = '--cait-u'
|
|
45
|
+
// The designed density is calibrated for roughly 1100×680 CSS pixels of
|
|
46
|
+
// DSH panel area. Fullscreen/maximized windows on 1440p and 4K displays
|
|
47
|
+
// were still capped at 1.4× with the old 1320×800 base, which left the
|
|
48
|
+
// 13px body type visibly smaller than the surrounding DSH UI. Keep the
|
|
49
|
+
// height term so short windows do not overflow, but let large panels grow
|
|
50
|
+
// to 1.8× before the cap applies.
|
|
51
|
+
const CAIT_UI_BASE = { width: 1100, height: 680 }
|
|
52
|
+
const CAIT_UI_MIN_UNIT = 1
|
|
53
|
+
const CAIT_UI_MAX_UNIT = 1.8
|
|
54
|
+
|
|
55
|
+
// Grow with the panel but never shrink below the designed size; the height
|
|
56
|
+
// term keeps short/wide windows from becoming oversized and scroll-heavy.
|
|
57
|
+
function computeCaitUnit({ width, height } = {}) {
|
|
58
|
+
const w = Number(width)
|
|
59
|
+
const h = Number(height)
|
|
60
|
+
if (!(w > 0) || !(h > 0)) return CAIT_UI_MIN_UNIT
|
|
61
|
+
const fit = Math.min(w / CAIT_UI_BASE.width, h / CAIT_UI_BASE.height)
|
|
62
|
+
const unit = Math.min(CAIT_UI_MAX_UNIT, Math.max(CAIT_UI_MIN_UNIT, fit))
|
|
63
|
+
return Math.round(unit * 1000) / 1000
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const CSS_PX_RE = /(-?(?:\d+\.?\d*|\.\d+))px/g
|
|
67
|
+
|
|
68
|
+
function scaleCssChunk(chunk, unitVar) {
|
|
69
|
+
return chunk.replace(CSS_PX_RE, (whole, value) => {
|
|
70
|
+
// Hairlines stay exactly 1px so borders keep rendering crisply.
|
|
71
|
+
if (Math.abs(Number(value)) <= 1) return whole
|
|
72
|
+
return `calc(${value}px * var(${unitVar}, 1))`
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Scale declaration values only. Media/supports/container preludes are
|
|
77
|
+
// copied verbatim: var() is not allowed in a media condition and those
|
|
78
|
+
// breakpoints must keep matching viewport pixels.
|
|
79
|
+
function scaleCssLengths(css, unitVar = CAIT_UNIT_VAR) {
|
|
80
|
+
const source = String(css ?? '')
|
|
81
|
+
let output = ''
|
|
82
|
+
let index = 0
|
|
83
|
+
while (index < source.length) {
|
|
84
|
+
const at = source.indexOf('@', index)
|
|
85
|
+
if (at === -1) {
|
|
86
|
+
output += scaleCssChunk(source.slice(index), unitVar)
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
output += scaleCssChunk(source.slice(index, at), unitVar)
|
|
90
|
+
let cursor = at
|
|
91
|
+
let depth = 0
|
|
92
|
+
while (cursor < source.length) {
|
|
93
|
+
const ch = source[cursor]
|
|
94
|
+
if (ch === '(') depth += 1
|
|
95
|
+
else if (ch === ')') depth = Math.max(0, depth - 1)
|
|
96
|
+
else if (depth === 0 && (ch === '{' || ch === ';')) break
|
|
97
|
+
cursor += 1
|
|
98
|
+
}
|
|
99
|
+
output += source.slice(at, cursor + 1)
|
|
100
|
+
index = cursor + 1
|
|
101
|
+
}
|
|
102
|
+
return output
|
|
103
|
+
}
|