wolfy-reader 0.1.0
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/LICENSE +21 -0
- package/README.md +277 -0
- package/dist/core/book.d.ts +75 -0
- package/dist/core/book.d.ts.map +1 -0
- package/dist/core/book.js +2 -0
- package/dist/core/book.js.map +1 -0
- package/dist/core/errors.d.ts +17 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +29 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/format.d.ts +13 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +2 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/graphemes.d.ts +36 -0
- package/dist/core/graphemes.d.ts.map +1 -0
- package/dist/core/graphemes.js +62 -0
- package/dist/core/graphemes.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lookup.d.ts +10 -0
- package/dist/core/lookup.d.ts.map +1 -0
- package/dist/core/lookup.js +16 -0
- package/dist/core/lookup.js.map +1 -0
- package/dist/core/open.d.ts +12 -0
- package/dist/core/open.d.ts.map +1 -0
- package/dist/core/open.js +23 -0
- package/dist/core/open.js.map +1 -0
- package/dist/core/position.d.ts +121 -0
- package/dist/core/position.d.ts.map +1 -0
- package/dist/core/position.js +327 -0
- package/dist/core/position.js.map +1 -0
- package/dist/core/reading-text.d.ts +77 -0
- package/dist/core/reading-text.d.ts.map +1 -0
- package/dist/core/reading-text.js +144 -0
- package/dist/core/reading-text.js.map +1 -0
- package/dist/core/source.d.ts +17 -0
- package/dist/core/source.d.ts.map +1 -0
- package/dist/core/source.js +39 -0
- package/dist/core/source.js.map +1 -0
- package/dist/core/storage.d.ts +7 -0
- package/dist/core/storage.d.ts.map +1 -0
- package/dist/core/storage.js +2 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/text.d.ts +18 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +32 -0
- package/dist/core/text.js.map +1 -0
- package/dist/formats/epub/href.d.ts +14 -0
- package/dist/formats/epub/href.d.ts.map +1 -0
- package/dist/formats/epub/href.js +52 -0
- package/dist/formats/epub/href.js.map +1 -0
- package/dist/formats/epub/index.d.ts +3 -0
- package/dist/formats/epub/index.d.ts.map +1 -0
- package/dist/formats/epub/index.js +223 -0
- package/dist/formats/epub/index.js.map +1 -0
- package/dist/formats/epub/opf.d.ts +27 -0
- package/dist/formats/epub/opf.d.ts.map +1 -0
- package/dist/formats/epub/opf.js +110 -0
- package/dist/formats/epub/opf.js.map +1 -0
- package/dist/formats/epub/toc.d.ts +6 -0
- package/dist/formats/epub/toc.d.ts.map +1 -0
- package/dist/formats/epub/toc.js +88 -0
- package/dist/formats/epub/toc.js.map +1 -0
- package/dist/formats/fb2/index.d.ts +13 -0
- package/dist/formats/fb2/index.d.ts.map +1 -0
- package/dist/formats/fb2/index.js +317 -0
- package/dist/formats/fb2/index.js.map +1 -0
- package/dist/formats/index.d.ts +4 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/index.js +4 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/formats/text/index.d.ts +11 -0
- package/dist/formats/text/index.d.ts.map +1 -0
- package/dist/formats/text/index.js +201 -0
- package/dist/formats/text/index.js.map +1 -0
- package/dist/formats/xml.d.ts +33 -0
- package/dist/formats/xml.d.ts.map +1 -0
- package/dist/formats/xml.js +321 -0
- package/dist/formats/xml.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/chunk.d.ts +51 -0
- package/dist/layout/chunk.d.ts.map +1 -0
- package/dist/layout/chunk.js +131 -0
- package/dist/layout/chunk.js.map +1 -0
- package/dist/layout/index.d.ts +238 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +476 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/reader/index.d.ts +231 -0
- package/dist/reader/index.d.ts.map +1 -0
- package/dist/reader/index.js +958 -0
- package/dist/reader/index.js.map +1 -0
- package/dist/reader/input.d.ts +69 -0
- package/dist/reader/input.d.ts.map +1 -0
- package/dist/reader/input.js +75 -0
- package/dist/reader/input.js.map +1 -0
- package/dist/search/extract.d.ts +51 -0
- package/dist/search/extract.d.ts.map +1 -0
- package/dist/search/extract.js +401 -0
- package/dist/search/extract.js.map +1 -0
- package/dist/search/index.d.ts +11 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +11 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/matcher.d.ts +56 -0
- package/dist/search/matcher.d.ts.map +1 -0
- package/dist/search/matcher.js +128 -0
- package/dist/search/matcher.js.map +1 -0
- package/dist/search/normalize.d.ts +48 -0
- package/dist/search/normalize.d.ts.map +1 -0
- package/dist/search/normalize.js +103 -0
- package/dist/search/normalize.js.map +1 -0
- package/dist/view/allowlist.d.ts +59 -0
- package/dist/view/allowlist.d.ts.map +1 -0
- package/dist/view/allowlist.js +198 -0
- package/dist/view/allowlist.js.map +1 -0
- package/dist/view/appearance.d.ts +137 -0
- package/dist/view/appearance.d.ts.map +1 -0
- package/dist/view/appearance.js +274 -0
- package/dist/view/appearance.js.map +1 -0
- package/dist/view/css.d.ts +24 -0
- package/dist/view/css.d.ts.map +1 -0
- package/dist/view/css.js +153 -0
- package/dist/view/css.js.map +1 -0
- package/dist/view/frame.d.ts +54 -0
- package/dist/view/frame.d.ts.map +1 -0
- package/dist/view/frame.js +980 -0
- package/dist/view/frame.js.map +1 -0
- package/dist/view/host.d.ts +160 -0
- package/dist/view/host.d.ts.map +1 -0
- package/dist/view/host.js +385 -0
- package/dist/view/host.js.map +1 -0
- package/dist/view/index.d.ts +12 -0
- package/dist/view/index.d.ts.map +1 -0
- package/dist/view/index.js +7 -0
- package/dist/view/index.js.map +1 -0
- package/dist/view/protocol.d.ts +220 -0
- package/dist/view/protocol.d.ts.map +1 -0
- package/dist/view/protocol.js +246 -0
- package/dist/view/protocol.js.map +1 -0
- package/dist/view/reference.d.ts +18 -0
- package/dist/view/reference.d.ts.map +1 -0
- package/dist/view/reference.js +25 -0
- package/dist/view/reference.js.map +1 -0
- package/dist/view/resources.d.ts +51 -0
- package/dist/view/resources.d.ts.map +1 -0
- package/dist/view/resources.js +242 -0
- package/dist/view/resources.js.map +1 -0
- package/dist/view/sanitize.d.ts +32 -0
- package/dist/view/sanitize.d.ts.map +1 -0
- package/dist/view/sanitize.js +226 -0
- package/dist/view/sanitize.js.map +1 -0
- package/dist/zip/central.d.ts +12 -0
- package/dist/zip/central.d.ts.map +1 -0
- package/dist/zip/central.js +72 -0
- package/dist/zip/central.js.map +1 -0
- package/dist/zip/crc32.d.ts +3 -0
- package/dist/zip/crc32.d.ts.map +1 -0
- package/dist/zip/crc32.js +28 -0
- package/dist/zip/crc32.js.map +1 -0
- package/dist/zip/eocd.d.ts +9 -0
- package/dist/zip/eocd.d.ts.map +1 -0
- package/dist/zip/eocd.js +84 -0
- package/dist/zip/eocd.js.map +1 -0
- package/dist/zip/errors.d.ts +19 -0
- package/dist/zip/errors.d.ts.map +1 -0
- package/dist/zip/errors.js +37 -0
- package/dist/zip/errors.js.map +1 -0
- package/dist/zip/index.d.ts +18 -0
- package/dist/zip/index.d.ts.map +1 -0
- package/dist/zip/index.js +78 -0
- package/dist/zip/index.js.map +1 -0
- package/dist/zip/inflate.d.ts +2 -0
- package/dist/zip/inflate.d.ts.map +1 -0
- package/dist/zip/inflate.js +43 -0
- package/dist/zip/inflate.js.map +1 -0
- package/dist/zip/source.d.ts +15 -0
- package/dist/zip/source.d.ts.map +1 -0
- package/dist/zip/source.js +34 -0
- package/dist/zip/source.js.map +1 -0
- package/package.json +75 -0
- package/src/core/book.ts +80 -0
- package/src/core/errors.ts +31 -0
- package/src/core/format.ts +14 -0
- package/src/core/graphemes.ts +73 -0
- package/src/core/index.ts +27 -0
- package/src/core/lookup.ts +16 -0
- package/src/core/open.ts +31 -0
- package/src/core/position.ts +485 -0
- package/src/core/reading-text.ts +200 -0
- package/src/core/source.ts +61 -0
- package/src/core/storage.ts +6 -0
- package/src/core/text.ts +35 -0
- package/src/formats/epub/href.ts +54 -0
- package/src/formats/epub/index.ts +235 -0
- package/src/formats/epub/opf.ts +143 -0
- package/src/formats/epub/toc.ts +120 -0
- package/src/formats/fb2/index.ts +348 -0
- package/src/formats/index.ts +3 -0
- package/src/formats/text/index.ts +208 -0
- package/src/formats/xml.ts +326 -0
- package/src/index.ts +26 -0
- package/src/layout/chunk.ts +169 -0
- package/src/layout/index.ts +573 -0
- package/src/reader/index.ts +1206 -0
- package/src/reader/input.ts +122 -0
- package/src/search/extract.ts +403 -0
- package/src/search/index.ts +10 -0
- package/src/search/matcher.ts +187 -0
- package/src/search/normalize.ts +122 -0
- package/src/view/allowlist.ts +273 -0
- package/src/view/appearance.ts +380 -0
- package/src/view/css.ts +172 -0
- package/src/view/frame.ts +1018 -0
- package/src/view/host.ts +527 -0
- package/src/view/index.ts +24 -0
- package/src/view/protocol.ts +412 -0
- package/src/view/reference.ts +30 -0
- package/src/view/resources.ts +265 -0
- package/src/view/sanitize.ts +266 -0
- package/src/zip/central.ts +85 -0
- package/src/zip/crc32.ts +30 -0
- package/src/zip/eocd.ts +97 -0
- package/src/zip/errors.ts +41 -0
- package/src/zip/index.ts +114 -0
- package/src/zip/inflate.ts +41 -0
- package/src/zip/source.ts +51 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The appearance system's theme half: the `--wr-*` CSS custom-property contract,
|
|
3
|
+
* the built-in themes, and the frame stylesheet that delivers them so publisher
|
|
4
|
+
* CSS can restyle its own content but can never reach the theme variables.
|
|
5
|
+
*
|
|
6
|
+
* This module is pure and DOM-free. It maps an {@link Appearance} to a variable
|
|
7
|
+
* set and emits the `<style>` the frame injects at document-assembly time — no
|
|
8
|
+
* `document`, no `window`, no protocol traffic. The frame-injection seam lives in
|
|
9
|
+
* `frame.ts`; the reader facade owns the live appearance state.
|
|
10
|
+
*
|
|
11
|
+
* The typography half (font family, size, line height, alignment, hyphenation,
|
|
12
|
+
* columns) adds more `--wr-*` names to the same namespace and rides the same
|
|
13
|
+
* cascade. The reflowing knobs (font, size, line height, columns) change chunk
|
|
14
|
+
* geometry, so the reader re-lays out and restores the reading position for them
|
|
15
|
+
* rather than repainting in place the way a colour change does.
|
|
16
|
+
*/
|
|
17
|
+
import { CONTENT_ROOT_ID } from './frame.js';
|
|
18
|
+
/**
|
|
19
|
+
* The built-in themes. Each is a full {@link ThemeVariables} set so a forced
|
|
20
|
+
* theme is self-contained — it needs no media query to be complete.
|
|
21
|
+
*/
|
|
22
|
+
export const THEMES = {
|
|
23
|
+
light: {
|
|
24
|
+
'--wr-background': '#ffffff',
|
|
25
|
+
'--wr-color': '#1a1a1a',
|
|
26
|
+
'--wr-link-color': '#1a5fb4',
|
|
27
|
+
'--wr-selection-background': '#b4d5fe',
|
|
28
|
+
'--wr-selection-color': '#1a1a1a',
|
|
29
|
+
},
|
|
30
|
+
dark: {
|
|
31
|
+
'--wr-background': '#121212',
|
|
32
|
+
'--wr-color': '#e6e6e6',
|
|
33
|
+
'--wr-link-color': '#8ab4f8',
|
|
34
|
+
'--wr-selection-background': '#2f5fb0',
|
|
35
|
+
'--wr-selection-color': '#ffffff',
|
|
36
|
+
},
|
|
37
|
+
sepia: {
|
|
38
|
+
'--wr-background': '#f4ecd8',
|
|
39
|
+
'--wr-color': '#5b4636',
|
|
40
|
+
'--wr-link-color': '#8a5a1a',
|
|
41
|
+
'--wr-selection-background': '#e0cfa8',
|
|
42
|
+
'--wr-selection-color': '#5b4636',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/** The default theme when the host does not force one and the OS is in light mode. */
|
|
46
|
+
const DEFAULT_LIGHT = { ...THEMES.light };
|
|
47
|
+
/** The default theme when the host does not force one and the OS is in dark mode. */
|
|
48
|
+
const DEFAULT_DARK = { ...THEMES.dark };
|
|
49
|
+
/** The cascade layer the theme reset lives in, so publisher rules outrank it. */
|
|
50
|
+
const THEME_LAYER = 'wolfy-reader-theme';
|
|
51
|
+
/** Normalize a custom-property key to its `--`-prefixed form. */
|
|
52
|
+
function normalizeVarName(name) {
|
|
53
|
+
return name.startsWith('--') ? name : `--${name}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Merge two partial `Appearance`s. `update` wins field-by-field; `customProperties`
|
|
57
|
+
* shallow-merges (an update's keys override the base's, and only the base's other
|
|
58
|
+
* keys survive). Passing `theme: undefined` in `update` does not clear the base
|
|
59
|
+
* theme — omit the key to keep it, since `exactOptionalPropertyTypes` distinguishes
|
|
60
|
+
* absent from `undefined`.
|
|
61
|
+
*/
|
|
62
|
+
export function mergeAppearance(base, update) {
|
|
63
|
+
const merged = {};
|
|
64
|
+
const theme = 'theme' in update ? update.theme : base.theme;
|
|
65
|
+
if (theme !== undefined)
|
|
66
|
+
merged.theme = theme;
|
|
67
|
+
const custom = { ...(base.customProperties ?? {}), ...(update.customProperties ?? {}) };
|
|
68
|
+
if (Object.keys(custom).length > 0)
|
|
69
|
+
merged.customProperties = custom;
|
|
70
|
+
const fontFamily = 'fontFamily' in update ? update.fontFamily : base.fontFamily;
|
|
71
|
+
if (fontFamily !== undefined)
|
|
72
|
+
merged.fontFamily = fontFamily;
|
|
73
|
+
const fontSize = 'fontSize' in update ? update.fontSize : base.fontSize;
|
|
74
|
+
if (fontSize !== undefined)
|
|
75
|
+
merged.fontSize = fontSize;
|
|
76
|
+
const lineHeight = 'lineHeight' in update ? update.lineHeight : base.lineHeight;
|
|
77
|
+
if (lineHeight !== undefined)
|
|
78
|
+
merged.lineHeight = lineHeight;
|
|
79
|
+
const margin = 'margin' in update ? update.margin : base.margin;
|
|
80
|
+
if (margin !== undefined)
|
|
81
|
+
merged.margin = margin;
|
|
82
|
+
const textAlign = 'textAlign' in update ? update.textAlign : base.textAlign;
|
|
83
|
+
if (textAlign !== undefined)
|
|
84
|
+
merged.textAlign = textAlign;
|
|
85
|
+
const justify = 'justify' in update ? update.justify : base.justify;
|
|
86
|
+
if (justify !== undefined)
|
|
87
|
+
merged.justify = justify;
|
|
88
|
+
const hyphenate = 'hyphenate' in update ? update.hyphenate : base.hyphenate;
|
|
89
|
+
if (hyphenate !== undefined)
|
|
90
|
+
merged.hyphenate = hyphenate;
|
|
91
|
+
const columns = 'columns' in update ? update.columns : base.columns;
|
|
92
|
+
if (columns !== undefined)
|
|
93
|
+
merged.columns = columns;
|
|
94
|
+
return merged;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The resolved `--wr-*` variables for a forced theme, or `null` when no theme is
|
|
98
|
+
* forced (the frame follows `prefers-color-scheme` instead). Custom properties
|
|
99
|
+
* merge over the theme's base and win; for `theme: 'custom'` the base is the light
|
|
100
|
+
* theme so an incomplete custom set still yields a complete, readable variable set.
|
|
101
|
+
*/
|
|
102
|
+
export function resolveThemeProperties(appearance) {
|
|
103
|
+
const theme = appearance.theme;
|
|
104
|
+
const custom = appearance.customProperties;
|
|
105
|
+
if (theme === undefined && custom === undefined)
|
|
106
|
+
return null;
|
|
107
|
+
const base = theme === undefined || theme === 'custom'
|
|
108
|
+
? { ...(theme === 'custom' ? DEFAULT_LIGHT : {}) }
|
|
109
|
+
: { ...THEMES[theme] };
|
|
110
|
+
// With no theme and only custom properties, seed from the light theme so a
|
|
111
|
+
// partial custom set is still complete; a forced-null default (below) covers
|
|
112
|
+
// the truly-unset case.
|
|
113
|
+
if (theme === undefined && custom !== undefined)
|
|
114
|
+
Object.assign(base, DEFAULT_LIGHT);
|
|
115
|
+
if (custom !== undefined) {
|
|
116
|
+
for (const [name, value] of Object.entries(custom))
|
|
117
|
+
base[normalizeVarName(name)] = value;
|
|
118
|
+
}
|
|
119
|
+
return base;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The resolved typography `--wr-*` variables for an appearance, or `null` when no
|
|
123
|
+
* typography knob is set. `columns` maps to `--wr-column-count`; `justify` folds
|
|
124
|
+
* into `--wr-text-align` (an explicit `textAlign` wins over `justify`). Only the
|
|
125
|
+
* knobs the caller supplied are emitted — an unset knob leaves the publisher's own
|
|
126
|
+
* value in place rather than forcing a default.
|
|
127
|
+
*/
|
|
128
|
+
export function resolveTypographyProperties(appearance) {
|
|
129
|
+
const vars = {};
|
|
130
|
+
if (appearance.fontFamily !== undefined)
|
|
131
|
+
vars['--wr-font-family'] = appearance.fontFamily;
|
|
132
|
+
if (appearance.fontSize !== undefined)
|
|
133
|
+
vars['--wr-font-size'] = `${appearance.fontSize}px`;
|
|
134
|
+
if (appearance.lineHeight !== undefined)
|
|
135
|
+
vars['--wr-line-height'] = String(appearance.lineHeight);
|
|
136
|
+
const align = resolveTextAlign(appearance);
|
|
137
|
+
if (align !== undefined)
|
|
138
|
+
vars['--wr-text-align'] = align;
|
|
139
|
+
if (appearance.hyphenate !== undefined) {
|
|
140
|
+
vars['--wr-hyphens'] = appearance.hyphenate ? 'auto' : 'manual';
|
|
141
|
+
}
|
|
142
|
+
if (appearance.columns !== undefined)
|
|
143
|
+
vars['--wr-column-count'] = String(appearance.columns);
|
|
144
|
+
return Object.keys(vars).length === 0 ? null : vars;
|
|
145
|
+
}
|
|
146
|
+
/** The effective text alignment: an explicit `textAlign` wins over `justify`. */
|
|
147
|
+
function resolveTextAlign(appearance) {
|
|
148
|
+
if (appearance.textAlign !== undefined)
|
|
149
|
+
return appearance.textAlign;
|
|
150
|
+
if (appearance.justify !== undefined)
|
|
151
|
+
return appearance.justify ? 'justify' : 'start';
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
/** Serialize a variable set into `--name: value;` declarations. */
|
|
155
|
+
function declarations(vars) {
|
|
156
|
+
return Object.entries(vars)
|
|
157
|
+
.map(([name, value]) => `${name}:${value}`)
|
|
158
|
+
.join(';');
|
|
159
|
+
}
|
|
160
|
+
/** The `:root` variable block for a set of resolved theme variables. */
|
|
161
|
+
function forcedRoot(vars) {
|
|
162
|
+
return `:root{${declarations(vars)}}`;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The `prefers-color-scheme`-driven default variables, used when the host does
|
|
166
|
+
* not force a theme. Light values sit at `:root`; a `@media (prefers-color-scheme:
|
|
167
|
+
* dark)` block swaps them, so the frame picks up the OS mode on its own opaque
|
|
168
|
+
* origin — the resolution stays inside the frame rather than being sniffed by the
|
|
169
|
+
* host. A forced theme's explicit `:root` block (emitted after this) overrides it.
|
|
170
|
+
*/
|
|
171
|
+
function preferenceDefaults() {
|
|
172
|
+
return (`:root{${declarations(DEFAULT_LIGHT)}}` +
|
|
173
|
+
`@media (prefers-color-scheme: dark){:root{${declarations(DEFAULT_DARK)}}}`);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The reading surface — the outermost background and base text colour, anchored
|
|
177
|
+
* on the content root. This belongs to the reader, not the book, so it is set
|
|
178
|
+
* unlayered and `!important` at id specificity: an id selector plus `!important`
|
|
179
|
+
* outranks even a publisher `*{…!important}` or `body{…!important}`, so a hostile
|
|
180
|
+
* book cannot repaint the surface out from under the theme. It only pins the
|
|
181
|
+
* content root's *own* background/colour; descendants a book styles (`p{color}`)
|
|
182
|
+
* still win for themselves, because that is a direct match on the descendant.
|
|
183
|
+
*/
|
|
184
|
+
function surfaceGuarantee() {
|
|
185
|
+
return (`#${CONTENT_ROOT_ID}{` +
|
|
186
|
+
`background:var(--wr-background) !important;` +
|
|
187
|
+
`color:var(--wr-color) !important` +
|
|
188
|
+
`}`);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The themeable defaults that consume the `--wr-*` variables: the html/body
|
|
192
|
+
* fallback surface, link colour and selection colours. These live in a cascade
|
|
193
|
+
* layer, so an unlayered publisher rule of any specificity outranks them *for the
|
|
194
|
+
* properties it sets* — a book restyling its own links or background wins — while
|
|
195
|
+
* the `--wr-*` variables themselves are unreachable by publisher CSS (they are
|
|
196
|
+
* custom-property names the book does not know). An unstyled book still themes
|
|
197
|
+
* fully, because nothing overrides the layer.
|
|
198
|
+
*/
|
|
199
|
+
function themeableDefaults() {
|
|
200
|
+
return (`@layer ${THEME_LAYER}{` +
|
|
201
|
+
`html{background:var(--wr-background);color:var(--wr-color)}` +
|
|
202
|
+
`body{background:var(--wr-background);color:var(--wr-color)}` +
|
|
203
|
+
`a{color:var(--wr-link-color)}` +
|
|
204
|
+
`::selection{background:var(--wr-selection-background);color:var(--wr-selection-color)}` +
|
|
205
|
+
`}`);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The unlayered typography block: the reader's own font, size, line height,
|
|
209
|
+
* alignment and hyphenation, anchored on the content root and set `!important` at
|
|
210
|
+
* id specificity — the same cascade device as {@link surfaceGuarantee}. An id
|
|
211
|
+
* selector plus `!important` outranks even a hostile publisher `*{…!important}`,
|
|
212
|
+
* so a user's typography choice wins the reading surface; a descendant the book
|
|
213
|
+
* styles directly (`p{font-size:20px}`) still wins for itself, which is the
|
|
214
|
+
* intended split. Only the knobs actually set emit a declaration, and each reads
|
|
215
|
+
* its own `--wr-*` variable (unreachable by publisher CSS). `column-count` is not
|
|
216
|
+
* here — column geometry is per-chunk and applied frame-side by the paginator.
|
|
217
|
+
*/
|
|
218
|
+
function typographyGuarantee(vars) {
|
|
219
|
+
const rules = [];
|
|
220
|
+
if (vars['--wr-font-family'] !== undefined)
|
|
221
|
+
rules.push('font-family:var(--wr-font-family) !important');
|
|
222
|
+
if (vars['--wr-font-size'] !== undefined)
|
|
223
|
+
rules.push('font-size:var(--wr-font-size) !important');
|
|
224
|
+
if (vars['--wr-line-height'] !== undefined)
|
|
225
|
+
rules.push('line-height:var(--wr-line-height) !important');
|
|
226
|
+
if (vars['--wr-text-align'] !== undefined)
|
|
227
|
+
rules.push('text-align:var(--wr-text-align) !important');
|
|
228
|
+
if (vars['--wr-hyphens'] !== undefined) {
|
|
229
|
+
rules.push('-webkit-hyphens:var(--wr-hyphens) !important', 'hyphens:var(--wr-hyphens) !important');
|
|
230
|
+
}
|
|
231
|
+
if (rules.length === 0)
|
|
232
|
+
return '';
|
|
233
|
+
return `:root{${declarations(vars)}}#${CONTENT_ROOT_ID}{${rules.join(';')}}`;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* The full appearance stylesheet the frame injects at document assembly, before
|
|
237
|
+
* the publisher's `headHtml`. It carries the theme half (colours) and the
|
|
238
|
+
* typography half (font/size/line-height/alignment/hyphenation) through one
|
|
239
|
+
* `--wr-*` namespace. It declares the theme layer first (so its ordering is fixed
|
|
240
|
+
* regardless of any `@layer` a book declares later), emits the themeable defaults
|
|
241
|
+
* and the unlayered surface guarantee, then the `prefers-color-scheme` defaults,
|
|
242
|
+
* then — if a theme is forced — an unlayered `:root` block that overrides the
|
|
243
|
+
* media query, and finally the unlayered typography guarantee. `null` from
|
|
244
|
+
* {@link resolveThemeProperties} means "follow the OS"; a variable set means
|
|
245
|
+
* "force it".
|
|
246
|
+
*/
|
|
247
|
+
export function themeStyleSheet(appearance) {
|
|
248
|
+
const forced = resolveThemeProperties(appearance);
|
|
249
|
+
const typography = resolveTypographyProperties(appearance);
|
|
250
|
+
return (`@layer ${THEME_LAYER};` +
|
|
251
|
+
themeableDefaults() +
|
|
252
|
+
surfaceGuarantee() +
|
|
253
|
+
preferenceDefaults() +
|
|
254
|
+
(forced === null ? '' : forcedRoot(forced)) +
|
|
255
|
+
(typography === null ? '' : typographyGuarantee(typography)));
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The typography knobs that change chunk geometry and therefore require a re-layout
|
|
259
|
+
* (a `paginate`), not just a variable poke: font family, font size, line height,
|
|
260
|
+
* page margin, and column count. Alignment and hyphenation can shift line breaks
|
|
261
|
+
* too, so they are treated as reflowing to be safe. Whether an `update` touches any
|
|
262
|
+
* of these decides which path {@link Reader.setAppearance} takes.
|
|
263
|
+
*/
|
|
264
|
+
export function isReflowingUpdate(update) {
|
|
265
|
+
return (update.fontFamily !== undefined ||
|
|
266
|
+
update.fontSize !== undefined ||
|
|
267
|
+
update.lineHeight !== undefined ||
|
|
268
|
+
update.margin !== undefined ||
|
|
269
|
+
update.textAlign !== undefined ||
|
|
270
|
+
update.justify !== undefined ||
|
|
271
|
+
update.hyphenate !== undefined ||
|
|
272
|
+
update.columns !== undefined);
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=appearance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance.js","sourceRoot":"","sources":["../../src/view/appearance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type CssReferenceKind = 'import' | 'url';
|
|
2
|
+
export interface CssReference {
|
|
3
|
+
readonly kind: CssReferenceKind;
|
|
4
|
+
/** The reference as written, with quotes and escapes removed. */
|
|
5
|
+
readonly value: string;
|
|
6
|
+
/** Index of the first character of the replaceable token. */
|
|
7
|
+
readonly start: number;
|
|
8
|
+
/** Index one past the last character of the replaceable token. */
|
|
9
|
+
readonly end: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Finds every `url(...)` and `@import` target in a stylesheet.
|
|
13
|
+
*
|
|
14
|
+
* This is a token-level scan that understands strings and comments, not a CSS
|
|
15
|
+
* parser: those two constructs are the only ones a renderer has to rewrite, and
|
|
16
|
+
* a conforming parser is orders of magnitude more code for no extra coverage.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findCssReferences(css: string): CssReference[];
|
|
19
|
+
/**
|
|
20
|
+
* Rewrites every reference the scan finds. A replacer returning undefined
|
|
21
|
+
* leaves the reference exactly as written.
|
|
22
|
+
*/
|
|
23
|
+
export declare function rewriteCssReferences(css: string, replace: (reference: CssReference) => Promise<string | undefined>): Promise<string>;
|
|
24
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/view/css.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AA2FD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAsC7D;AAMD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAChE,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
package/dist/view/css.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const IDENT_CHAR = /[A-Za-z0-9_\-\\\u0080-\uFFFF]/;
|
|
2
|
+
function isIdentChar(character) {
|
|
3
|
+
return character !== '' && IDENT_CHAR.test(character);
|
|
4
|
+
}
|
|
5
|
+
function matchesAt(css, index, literal) {
|
|
6
|
+
return css.slice(index, index + literal.length).toLowerCase() === literal;
|
|
7
|
+
}
|
|
8
|
+
function skipComment(css, index) {
|
|
9
|
+
const close = css.indexOf('*/', index + 2);
|
|
10
|
+
return close === -1 ? css.length : close + 2;
|
|
11
|
+
}
|
|
12
|
+
function skipSpace(css, index) {
|
|
13
|
+
let i = index;
|
|
14
|
+
while (i < css.length) {
|
|
15
|
+
const character = css.charAt(i);
|
|
16
|
+
if (character === '/' && css.charAt(i + 1) === '*') {
|
|
17
|
+
i = skipComment(css, i);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (character === ' ' || character === '\t' || character === '\n' || character === '\r' || character === '\f') {
|
|
21
|
+
i += 1;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
return i;
|
|
25
|
+
}
|
|
26
|
+
return i;
|
|
27
|
+
}
|
|
28
|
+
function readString(css, index) {
|
|
29
|
+
const quote = css.charAt(index);
|
|
30
|
+
let i = index + 1;
|
|
31
|
+
let value = '';
|
|
32
|
+
while (i < css.length) {
|
|
33
|
+
const character = css.charAt(i);
|
|
34
|
+
if (character === '\\') {
|
|
35
|
+
if (css.charAt(i + 1) !== '\n')
|
|
36
|
+
value += css.charAt(i + 1);
|
|
37
|
+
i += 2;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (character === quote)
|
|
41
|
+
return { value, end: i + 1 };
|
|
42
|
+
if (character === '\n')
|
|
43
|
+
return null;
|
|
44
|
+
value += character;
|
|
45
|
+
i += 1;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function readUrl(css, index) {
|
|
50
|
+
let i = skipSpace(css, index + 4);
|
|
51
|
+
let value;
|
|
52
|
+
const quote = css.charAt(i);
|
|
53
|
+
if (quote === '"' || quote === "'") {
|
|
54
|
+
const string = readString(css, i);
|
|
55
|
+
if (string === null)
|
|
56
|
+
return null;
|
|
57
|
+
value = string.value;
|
|
58
|
+
i = skipSpace(css, string.end);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
let raw = '';
|
|
62
|
+
while (i < css.length && css.charAt(i) !== ')') {
|
|
63
|
+
if (css.charAt(i) === '\\') {
|
|
64
|
+
raw += css.charAt(i + 1);
|
|
65
|
+
i += 2;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
raw += css.charAt(i);
|
|
69
|
+
i += 1;
|
|
70
|
+
}
|
|
71
|
+
value = raw.trim();
|
|
72
|
+
}
|
|
73
|
+
if (css.charAt(i) !== ')')
|
|
74
|
+
return null;
|
|
75
|
+
return { value, end: i + 1 };
|
|
76
|
+
}
|
|
77
|
+
function readReference(css, index) {
|
|
78
|
+
const character = css.charAt(index);
|
|
79
|
+
if (character === '"' || character === "'")
|
|
80
|
+
return readString(css, index);
|
|
81
|
+
if (matchesAt(css, index, 'url('))
|
|
82
|
+
return readUrl(css, index);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Finds every `url(...)` and `@import` target in a stylesheet.
|
|
87
|
+
*
|
|
88
|
+
* This is a token-level scan that understands strings and comments, not a CSS
|
|
89
|
+
* parser: those two constructs are the only ones a renderer has to rewrite, and
|
|
90
|
+
* a conforming parser is orders of magnitude more code for no extra coverage.
|
|
91
|
+
*/
|
|
92
|
+
export function findCssReferences(css) {
|
|
93
|
+
const references = [];
|
|
94
|
+
let i = 0;
|
|
95
|
+
while (i < css.length) {
|
|
96
|
+
const character = css.charAt(i);
|
|
97
|
+
if (character === '/' && css.charAt(i + 1) === '*') {
|
|
98
|
+
i = skipComment(css, i);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (character === '"' || character === "'") {
|
|
102
|
+
const string = readString(css, i);
|
|
103
|
+
i = string === null ? i + 1 : string.end;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (character === '@' && matchesAt(css, i, '@import') && !isIdentChar(css.charAt(i + 7))) {
|
|
107
|
+
const start = skipSpace(css, i + 7);
|
|
108
|
+
const token = readReference(css, start);
|
|
109
|
+
if (token === null) {
|
|
110
|
+
i += 7;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
references.push({ kind: 'import', value: token.value, start, end: token.end });
|
|
114
|
+
i = token.end;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (matchesAt(css, i, 'url(') && !isIdentChar(css.charAt(i - 1))) {
|
|
118
|
+
const token = readUrl(css, i);
|
|
119
|
+
if (token === null) {
|
|
120
|
+
i += 1;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
references.push({ kind: 'url', value: token.value, start: i, end: token.end });
|
|
124
|
+
i = token.end;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
i += 1;
|
|
128
|
+
}
|
|
129
|
+
return references;
|
|
130
|
+
}
|
|
131
|
+
function escapeCssUrl(url) {
|
|
132
|
+
return url.replace(/[\\"]/g, '\\$&').replace(/[\n\r]/g, '');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Rewrites every reference the scan finds. A replacer returning undefined
|
|
136
|
+
* leaves the reference exactly as written.
|
|
137
|
+
*/
|
|
138
|
+
export async function rewriteCssReferences(css, replace) {
|
|
139
|
+
const references = findCssReferences(css);
|
|
140
|
+
if (references.length === 0)
|
|
141
|
+
return css;
|
|
142
|
+
let out = '';
|
|
143
|
+
let cursor = 0;
|
|
144
|
+
for (const reference of references) {
|
|
145
|
+
const replacement = await replace(reference);
|
|
146
|
+
if (replacement === undefined)
|
|
147
|
+
continue;
|
|
148
|
+
out += `${css.slice(cursor, reference.start)}url("${escapeCssUrl(replacement)}")`;
|
|
149
|
+
cursor = reference.end;
|
|
150
|
+
}
|
|
151
|
+
return out + css.slice(cursor);
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.js","sourceRoot":"","sources":["../../src/view/css.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const CONTENT_ROOT_ID = "wolfy-reader-content";
|
|
2
|
+
/** Class marking each per-chunk container the host emits into the frame body. */
|
|
3
|
+
export declare const CHUNK_CLASS = "wolfy-reader-chunk";
|
|
4
|
+
/** Cumulative character offset of a chunk's first glyph into the section text. */
|
|
5
|
+
export declare const CHUNK_START_ATTR = "data-chunk-start";
|
|
6
|
+
/** Cumulative character offset just past a chunk's last glyph. */
|
|
7
|
+
export declare const CHUNK_END_ATTR = "data-chunk-end";
|
|
8
|
+
/** Zero-based index of a chunk in section order. */
|
|
9
|
+
export declare const CHUNK_INDEX_ATTR = "data-chunk-index";
|
|
10
|
+
/** Class every draw-only decoration overlay box carries, alongside the caller's class. */
|
|
11
|
+
export declare const DECORATION_CLASS = "wolfy-reader-decoration";
|
|
12
|
+
export declare function createNonce(): string;
|
|
13
|
+
export declare function coordinationScript(hostOrigin: string, keyboardNav?: boolean): string;
|
|
14
|
+
/** One chunk's markup plus its character count, as `chunkElement` reports it. */
|
|
15
|
+
export interface ChunkPart {
|
|
16
|
+
readonly html: string;
|
|
17
|
+
readonly chars: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Wraps each chunk in its own container element, tagging it with the cumulative
|
|
21
|
+
* character range it covers in the section's concatenated text. Offsets are
|
|
22
|
+
* end-exclusive: chunk *i* covers `[start, end)`, and chunk *i+1* starts exactly
|
|
23
|
+
* at the previous `end`, so the ranges tile the section text without gap or
|
|
24
|
+
* overlap. The frame reads these attributes to build per-chunk multi-column
|
|
25
|
+
* contexts and to map pages to character offsets.
|
|
26
|
+
*
|
|
27
|
+
* The container is a `<div class="wolfy-reader-chunk">`; the char count comes from
|
|
28
|
+
* `chunkElement` (`textContent.length` of the chunk's nodes), so it matches what
|
|
29
|
+
* the frame measures with `textContent` at runtime.
|
|
30
|
+
*/
|
|
31
|
+
export declare function assembleChunkedBody(chunks: readonly ChunkPart[]): string;
|
|
32
|
+
export interface FrameDocumentParts {
|
|
33
|
+
readonly headHtml: string;
|
|
34
|
+
readonly bodyHtml: string;
|
|
35
|
+
readonly nonce: string;
|
|
36
|
+
readonly hostOrigin: string;
|
|
37
|
+
/**
|
|
38
|
+
* The appearance theme stylesheet ({@link themeStyleSheet}). Injected before
|
|
39
|
+
* the publisher's `headHtml` so its cascade layer loses specificity fights on
|
|
40
|
+
* the properties the book sets, while the theme variables it declares stay
|
|
41
|
+
* unreachable by publisher CSS. Omit for an unthemed document.
|
|
42
|
+
*/
|
|
43
|
+
readonly themeCss?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the host acts on forwarded navigation keydowns. Baked into the
|
|
46
|
+
* coordination script (not a wire message — no protocol change): when `false`
|
|
47
|
+
* the frame still forwards nav keys but no longer `preventDefault`s them, so
|
|
48
|
+
* a key the host will ignore keeps its default action instead of going dead.
|
|
49
|
+
* Defaults to `true`.
|
|
50
|
+
*/
|
|
51
|
+
readonly keyboardNav?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export declare function assembleFrameDocument(parts: FrameDocumentParts): string;
|
|
54
|
+
//# sourceMappingURL=frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/view/frame.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAEtD,iFAAiF;AACjF,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,kEAAkE;AAClE,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,0FAA0F;AAC1F,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AA+C1D,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,OAAc,GAAG,MAAM,CAi2B1F;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAcxE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CA2BvE"}
|