@readium/navigator 2.1.1 → 2.2.1

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.
Files changed (52) hide show
  1. package/dist/index.js +3912 -2721
  2. package/dist/index.umd.cjs +286 -71
  3. package/package.json +1 -1
  4. package/src/css/Properties.ts +47 -0
  5. package/src/css/index.ts +1 -0
  6. package/src/epub/css/Properties.ts +10 -48
  7. package/src/epub/preferences/EpubDefaults.ts +1 -1
  8. package/src/epub/preferences/EpubPreferences.ts +1 -1
  9. package/src/epub/preferences/EpubPreferencesEditor.ts +30 -23
  10. package/src/index.ts +3 -1
  11. package/src/preferences/Types.ts +40 -0
  12. package/src/{epub/preferences → preferences}/guards.ts +5 -6
  13. package/src/preferences/index.ts +2 -1
  14. package/src/webpub/WebPubBlobBuilder.ts +167 -0
  15. package/src/webpub/WebPubFrameManager.ts +156 -0
  16. package/src/webpub/WebPubFramePoolManager.ts +221 -0
  17. package/src/webpub/WebPubNavigator.ts +494 -0
  18. package/src/webpub/css/Properties.ts +71 -0
  19. package/src/webpub/css/WebPubCSS.ts +42 -0
  20. package/src/webpub/css/WebPubStylesheet.ts +204 -0
  21. package/src/webpub/css/index.ts +3 -0
  22. package/src/webpub/index.ts +6 -0
  23. package/src/webpub/preferences/WebPubDefaults.ts +61 -0
  24. package/src/webpub/preferences/WebPubPreferences.ts +88 -0
  25. package/src/webpub/preferences/WebPubPreferencesEditor.ts +193 -0
  26. package/src/webpub/preferences/WebPubSettings.ts +88 -0
  27. package/src/webpub/preferences/index.ts +4 -0
  28. package/types/src/css/Properties.d.ts +20 -0
  29. package/types/src/css/index.d.ts +1 -0
  30. package/types/src/epub/css/Properties.d.ts +1 -21
  31. package/types/src/index.d.ts +2 -0
  32. package/types/src/preferences/Types.d.ts +8 -0
  33. package/types/src/preferences/guards.d.ts +9 -0
  34. package/types/src/preferences/index.d.ts +1 -0
  35. package/types/src/web/WebPubBlobBuilder.d.ts +10 -0
  36. package/types/src/web/WebPubFrameManager.d.ts +20 -0
  37. package/types/src/web/WebPubNavigator.d.ts +48 -0
  38. package/types/src/web/index.d.ts +3 -0
  39. package/types/src/webpub/WebPubBlobBuilder.d.ts +16 -0
  40. package/types/src/webpub/WebPubFrameManager.d.ts +24 -0
  41. package/types/src/webpub/WebPubFramePoolManager.d.ts +23 -0
  42. package/types/src/webpub/WebPubNavigator.d.ts +70 -0
  43. package/types/src/webpub/css/Properties.d.ts +36 -0
  44. package/types/src/webpub/css/WebPubCSS.d.ts +10 -0
  45. package/types/src/webpub/css/WebPubStylesheet.d.ts +1 -0
  46. package/types/src/webpub/css/index.d.ts +3 -0
  47. package/types/src/webpub/index.d.ts +6 -0
  48. package/types/src/webpub/preferences/WebPubDefaults.d.ts +32 -0
  49. package/types/src/webpub/preferences/WebPubPreferences.d.ts +36 -0
  50. package/types/src/webpub/preferences/WebPubPreferencesEditor.d.ts +27 -0
  51. package/types/src/webpub/preferences/WebPubSettings.d.ts +35 -0
  52. package/types/src/webpub/preferences/index.d.ts +4 -0
@@ -0,0 +1,204 @@
1
+ // WebPubCSS is equivalent to ReadiumCSS for WebPub
2
+
3
+ export const webPubStylesheet = `
4
+ /* FontFamily */
5
+
6
+ :root[style*="--USER__fontFamily"] {
7
+ font-family: var(--USER__fontFamily) !important;
8
+ }
9
+
10
+ :root[style*="--USER__fontFamily"] * {
11
+ font-family: revert !important;
12
+ }
13
+
14
+ /* FontWeight */
15
+
16
+ :root[style*="--USER__fontWeight"] body {
17
+ font-weight: var(--USER__fontWeight) !important;
18
+ }
19
+
20
+ /* Attempt to handle known bolds */
21
+ :root[style*="--USER__fontWeight"] b,
22
+ :root[style*="--USER__fontWeight"] strong {
23
+ font-weight: bolder;
24
+ }
25
+
26
+ /* Hyphens */
27
+
28
+ :root[style*="--USER__bodyHyphens"] {
29
+ -webkit-hyphens: var(--USER__bodyHyphens) !important;
30
+ -moz-hyphens: var(--USER__bodyHyphens) !important;
31
+ -ms-hyphens: var(--USER__bodyHyphens) !important;
32
+ -epub-hyphens: var(--USER__bodyHyphens) !important;
33
+ hyphens: var(--USER__bodyHyphens) !important;
34
+ }
35
+
36
+ :root[style*="--USER__bodyHyphens"] body,
37
+ :root[style*="--USER__bodyHyphens"] p,
38
+ :root[style*="--USER__bodyHyphens"] li,
39
+ :root[style*="--USER__bodyHyphens"] div,
40
+ :root[style*="--USER__bodyHyphens"] dd {
41
+ -webkit-hyphens: inherit;
42
+ -moz-hyphens: inherit;
43
+ -ms-hyphens: inherit;
44
+ -epub-hyphens: inherit;
45
+ hyphens: inherit;
46
+ }
47
+
48
+ /* LetterSpacing */
49
+
50
+ :root[style*="--USER__letterSpacing"] h1,
51
+ :root[style*="--USER__letterSpacing"] h2,
52
+ :root[style*="--USER__letterSpacing"] h3,
53
+ :root[style*="--USER__letterSpacing"] h4,
54
+ :root[style*="--USER__letterSpacing"] h5,
55
+ :root[style*="--USER__letterSpacing"] h6,
56
+ :root[style*="--USER__letterSpacing"] p,
57
+ :root[style*="--USER__letterSpacing"] li,
58
+ :root[style*="--USER__letterSpacing"] div,
59
+ :root[style*="--USER__letterSpacing"] dt,
60
+ :root[style*="--USER__letterSpacing"] dd {
61
+ letter-spacing: var(--USER__letterSpacing);
62
+ font-variant: none;
63
+ }
64
+
65
+ /* Ligatures */
66
+
67
+ :root[style*="--USER__ligatures"] {
68
+ font-variant-ligatures: var(--USER__ligatures) !important;
69
+ }
70
+
71
+ :root[style*="--USER__ligatures"] * {
72
+ font-variant-ligatures: inherit !important;
73
+ }
74
+
75
+ /* LineHeight */
76
+
77
+ :root[style*="--USER__lineHeight"] {
78
+ line-height: var(--USER__lineHeight) !important;
79
+ }
80
+
81
+ :root[style*="--USER__lineHeight"] body,
82
+ :root[style*="--USER__lineHeight"] p,
83
+ :root[style*="--USER__lineHeight"] li,
84
+ :root[style*="--USER__lineHeight"] div {
85
+ line-height: inherit;
86
+ }
87
+
88
+ /* ParagraphIndent */
89
+
90
+ :root[style*="--USER__paraIndent"] p {
91
+ text-indent: var(--USER__paraIndent) !important;
92
+ }
93
+
94
+ :root[style*="--USER__paraIndent"] p *,
95
+ :root[style*="--USER__paraIndent"] p:first-letter {
96
+ text-indent: 0 !important;
97
+ }
98
+
99
+ /* ParagraphSpacing */
100
+
101
+ :root[style*="--USER__paraSpacing"] p {
102
+ margin-block: var(--USER__paraSpacing) !important;
103
+ }
104
+
105
+ /* Ruby */
106
+
107
+ :root[style*="readium-noRuby-on"] body rt,
108
+ :root[style*="readium-noRuby-on"] body rp {
109
+ display: none;
110
+ }
111
+
112
+ /* TextAlign */
113
+
114
+ :root[style*="--USER__textAlign"] {
115
+ text-align: var(--USER__textAlign);
116
+ }
117
+
118
+ :root[style*="--USER__textAlign"] body,
119
+ :root[style*="--USER__textAlign"] p:not(blockquote p):not(figcaption p):not(hgroup p),
120
+ :root[style*="--USER__textAlign"] li,
121
+ :root[style*="--USER__textAlign"] dd {
122
+ text-align: var(--USER__textAlign) !important;
123
+ -moz-text-align-last: auto !important;
124
+ -epub-text-align-last: auto !important;
125
+ text-align-last: auto !important;
126
+ }
127
+
128
+ /* TextNormalize */
129
+
130
+ :root[style*="readium-a11y-on"] {
131
+ font-weight: normal !important;
132
+ font-style: normal !important;
133
+ }
134
+
135
+ :root[style*="readium-a11y-on"] *:not(code):not(var):not(kbd):not(samp) {
136
+ font-family: inherit !important;
137
+ font-weight: inherit !important;
138
+ font-style: inherit !important;
139
+ }
140
+
141
+ :root[style*="readium-a11y-on"] * {
142
+ text-decoration: none !important;
143
+ font-variant-caps: normal !important;
144
+ font-variant-position: normal !important;
145
+ font-variant-numeric: normal !important;
146
+ }
147
+
148
+ :root[style*="readium-a11y-on"] sup,
149
+ :root[style*="readium-a11y-on"] sub {
150
+ font-size: 1rem !important;
151
+ vertical-align: baseline !important;
152
+ }
153
+
154
+ /* Word Spacing */
155
+
156
+ :root[style*="--USER__wordSpacing"] h1,
157
+ :root[style*="--USER__wordSpacing"] h2,
158
+ :root[style*="--USER__wordSpacing"] h3,
159
+ :root[style*="--USER__wordSpacing"] h4,
160
+ :root[style*="--USER__wordSpacing"] h5,
161
+ :root[style*="--USER__wordSpacing"] h6,
162
+ :root[style*="--USER__wordSpacing"] p,
163
+ :root[style*="--USER__wordSpacing"] li,
164
+ :root[style*="--USER__wordSpacing"] div,
165
+ :root[style*="--USER__wordSpacing"] dt,
166
+ :root[style*="--USER__wordSpacing"] dd {
167
+ word-spacing: var(--USER__wordSpacing);
168
+ }
169
+
170
+ /* Zoom */
171
+
172
+ :root {
173
+ --USER__zoom: 1;
174
+ }
175
+
176
+ :root[style*="--USER__zoom"] body {
177
+ zoom: var(--USER__zoom) !important;
178
+ }
179
+
180
+ @supports selector(figure:has(> img)) {
181
+ :root[style*="--USER__zoom"] figure:has(> img),
182
+ :root[style*="--USER__zoom"] figure:has(> video),
183
+ :root[style*="--USER__zoom"] figure:has(> svg),
184
+ :root[style*="--USER__zoom"] figure:has(> canvas),
185
+ :root[style*="--USER__zoom"] figure:has(> iframe),
186
+ :root[style*="--USER__zoom"] figure:has(> audio),
187
+ :root[style*="--USER__zoom"] div:has(> img),
188
+ :root[style*="--USER__zoom"] div:has(> video),
189
+ :root[style*="--USER__zoom"] div:has(> svg),
190
+ :root[style*="--USER__zoom"] div:has(> canvas),
191
+ :root[style*="--USER__zoom"] div:has(> iframe),
192
+ :root[style*="--USER__zoom"] div:has(> audio),
193
+ :root[style*="--USER__zoom"] table {
194
+ zoom: calc(100% / var(--USER__zoom)) !important;
195
+ }
196
+
197
+ :root[style*="--USER__zoom"] figcaption,
198
+ :root[style*="--USER__zoom"] caption,
199
+ :root[style*="--USER__zoom"] td,
200
+ :root[style*="--USER__zoom"] th {
201
+ zoom: var(--USER__zoom) !important;
202
+ }
203
+ }
204
+ `;
@@ -0,0 +1,3 @@
1
+ export * from "./Properties";
2
+ export * from "./WebPubCSS";
3
+ export * from "./WebPubStylesheet";
@@ -0,0 +1,6 @@
1
+ export * from "./WebPubNavigator";
2
+ export * from "./WebPubBlobBuilder";
3
+ export * from "./WebPubFrameManager";
4
+ export * from "./WebPubFramePoolManager";
5
+ export * from "./preferences";
6
+ export * from "./css";
@@ -0,0 +1,61 @@
1
+ import {
2
+ fontWeightRangeConfig,
3
+ TextAlignment,
4
+ zoomRangeConfig
5
+ } from "../../preferences/Types";
6
+
7
+ import {
8
+ ensureBoolean,
9
+ ensureEnumValue,
10
+ ensureNonNegative,
11
+ ensureValueInRange,
12
+ ensureString
13
+ } from "../../preferences/guards";
14
+
15
+ export interface IWebPubDefaults {
16
+ fontFamily?: string | null,
17
+ fontWeight?: number | null,
18
+ hyphens?: boolean | null,
19
+ letterSpacing?: number | null,
20
+ ligatures?: boolean | null,
21
+ lineHeight?: number | null,
22
+ noRuby?: boolean | null,
23
+ paragraphIndent?: number | null,
24
+ paragraphSpacing?: number | null,
25
+ textAlign?: TextAlignment | null,
26
+ textNormalization?: boolean | null,
27
+ wordSpacing?: number | null,
28
+ zoom?: number | null
29
+ }
30
+
31
+ export class WebPubDefaults {
32
+ fontFamily: string | null;
33
+ fontWeight: number | null;
34
+ hyphens: boolean | null;
35
+ letterSpacing: number | null;
36
+ ligatures: boolean | null;
37
+ lineHeight: number | null;
38
+ noRuby: boolean | null;
39
+ paragraphIndent: number | null;
40
+ paragraphSpacing: number | null;
41
+ textAlign: TextAlignment | null;
42
+ textNormalization: boolean | null;
43
+ wordSpacing: number | null;
44
+ zoom: number;
45
+
46
+ constructor(defaults: IWebPubDefaults) {
47
+ this.fontFamily = ensureString(defaults.fontFamily) || null;
48
+ this.fontWeight = ensureValueInRange(defaults.fontWeight, fontWeightRangeConfig.range) || null;
49
+ this.hyphens = ensureBoolean(defaults.hyphens) ?? null;
50
+ this.letterSpacing = ensureNonNegative(defaults.letterSpacing) || null;
51
+ this.ligatures = ensureBoolean(defaults.ligatures) ?? null;
52
+ this.lineHeight = ensureNonNegative(defaults.lineHeight) || null;
53
+ this.noRuby = ensureBoolean(defaults.noRuby) ?? false;
54
+ this.paragraphIndent = ensureNonNegative(defaults.paragraphIndent) ?? null;
55
+ this.paragraphSpacing = ensureNonNegative(defaults.paragraphSpacing) ?? null;
56
+ this.textAlign = ensureEnumValue<TextAlignment>(defaults.textAlign, TextAlignment) || null;
57
+ this.textNormalization = ensureBoolean(defaults.textNormalization) ?? false;
58
+ this.wordSpacing = ensureNonNegative(defaults.wordSpacing) || null;
59
+ this.zoom = ensureValueInRange(defaults.zoom, zoomRangeConfig.range) || 1;
60
+ }
61
+ }
@@ -0,0 +1,88 @@
1
+ import { ConfigurablePreferences } from "../../preferences/Configurable";
2
+
3
+ import {
4
+ fontWeightRangeConfig,
5
+ TextAlignment,
6
+ zoomRangeConfig
7
+ } from "../../preferences/Types";
8
+
9
+ import {
10
+ ensureBoolean,
11
+ ensureEnumValue,
12
+ ensureNonNegative,
13
+ ensureString,
14
+ ensureValueInRange
15
+ } from "../../preferences/guards";
16
+
17
+ export interface IWebPubPreferences {
18
+ fontFamily?: string | null,
19
+ fontWeight?: number | null,
20
+ hyphens?: boolean | null,
21
+ letterSpacing?: number | null,
22
+ ligatures?: boolean | null,
23
+ lineHeight?: number | null,
24
+ noRuby?: boolean | null,
25
+ paragraphIndent?: number | null,
26
+ paragraphSpacing?: number | null,
27
+ textAlign?: TextAlignment | null,
28
+ textNormalization?: boolean | null,
29
+ wordSpacing?: number | null,
30
+ zoom?: number | null
31
+ }
32
+
33
+ export class WebPubPreferences implements ConfigurablePreferences {
34
+ fontFamily?: string | null;
35
+ fontWeight?: number | null;
36
+ hyphens?: boolean | null;
37
+ letterSpacing?: number | null;
38
+ ligatures?: boolean | null;
39
+ lineHeight?: number | null;
40
+ noRuby?: boolean | null;
41
+ paragraphIndent?: number | null;
42
+ paragraphSpacing?: number | null;
43
+ textAlign?: TextAlignment | null;
44
+ textNormalization?: boolean | null;
45
+ wordSpacing?: number | null;
46
+ zoom?: number | null;
47
+
48
+ constructor(preferences: IWebPubPreferences = {}) {
49
+ this.fontFamily = ensureString(preferences.fontFamily);
50
+ this.fontWeight = ensureValueInRange(preferences.fontWeight, fontWeightRangeConfig.range);
51
+ this.hyphens = ensureBoolean(preferences.hyphens);
52
+ this.letterSpacing = ensureNonNegative(preferences.letterSpacing);
53
+ this.ligatures = ensureBoolean(preferences.ligatures);
54
+ this.lineHeight = ensureNonNegative(preferences.lineHeight);
55
+ this.noRuby = ensureBoolean(preferences.noRuby);
56
+ this.paragraphIndent = ensureNonNegative(preferences.paragraphIndent);
57
+ this.paragraphSpacing = ensureNonNegative(preferences.paragraphSpacing);
58
+ this.textAlign = ensureEnumValue<TextAlignment>(preferences.textAlign, TextAlignment);
59
+ this.textNormalization = ensureBoolean(preferences.textNormalization);
60
+ this.wordSpacing = ensureNonNegative(preferences.wordSpacing);
61
+ this.zoom = ensureValueInRange(preferences.zoom, zoomRangeConfig.range);
62
+ }
63
+
64
+ static serialize(preferences: WebPubPreferences): string {
65
+ const { ...properties } = preferences;
66
+ return JSON.stringify(properties);
67
+ }
68
+
69
+ static deserialize(preferences: string): WebPubPreferences | null {
70
+ try {
71
+ const parsedPreferences = JSON.parse(preferences);
72
+ return new WebPubPreferences(parsedPreferences);
73
+ } catch (error) {
74
+ console.error("Failed to deserialize preferences:", error);
75
+ return null;
76
+ }
77
+ }
78
+
79
+ merging(other: ConfigurablePreferences): ConfigurablePreferences {
80
+ const merged: IWebPubPreferences = { ...this };
81
+ for (const key of Object.keys(other) as (keyof IWebPubPreferences)[]) {
82
+ if (other[key] !== undefined) {
83
+ merged[key] = other[key];
84
+ }
85
+ }
86
+ return new WebPubPreferences(merged);
87
+ }
88
+ }
@@ -0,0 +1,193 @@
1
+ import { Feature, Metadata } from "@readium/shared";
2
+
3
+ import { IPreferencesEditor } from "../../preferences/PreferencesEditor";
4
+ import { WebPubPreferences } from "./WebPubPreferences";
5
+ import { WebPubSettings } from "./WebPubSettings";
6
+ import { BooleanPreference, EnumPreference, Preference, RangePreference } from "../../preferences/Preference";
7
+ import {
8
+ fontWeightRangeConfig,
9
+ letterSpacingRangeConfig,
10
+ lineHeightRangeConfig,
11
+ paragraphIndentRangeConfig,
12
+ paragraphSpacingRangeConfig,
13
+ TextAlignment,
14
+ wordSpacingRangeConfig,
15
+ zoomRangeConfig
16
+ } from "../../preferences/Types";
17
+ export class WebPubPreferencesEditor implements IPreferencesEditor {
18
+ preferences: WebPubPreferences;
19
+ private settings: WebPubSettings;
20
+ private metadata: Metadata | null;
21
+
22
+ constructor(initialPreferences: WebPubPreferences, settings: WebPubSettings, metadata: Metadata) {
23
+ this.preferences = initialPreferences;
24
+ this.settings = settings;
25
+ this.metadata = metadata;
26
+ }
27
+
28
+ clear() {
29
+ this.preferences = new WebPubPreferences({});
30
+ }
31
+
32
+ private updatePreference<K extends keyof WebPubPreferences>(key: K, value: WebPubPreferences[K]) {
33
+ this.preferences[key] = value;
34
+ }
35
+
36
+ get fontFamily(): Preference<string> {
37
+ return new Preference<string>({
38
+ initialValue: this.preferences.fontFamily,
39
+ effectiveValue: this.settings.fontFamily || null,
40
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
41
+ onChange: (newValue: string | null | undefined) => {
42
+ this.updatePreference("fontFamily", newValue || null);
43
+ }
44
+ });
45
+ }
46
+
47
+ get fontWeight(): RangePreference<number> {
48
+ return new RangePreference<number>({
49
+ initialValue: this.preferences.fontWeight,
50
+ effectiveValue: this.settings.fontWeight || 400,
51
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
52
+ onChange: (newValue: number | null | undefined) => {
53
+ this.updatePreference("fontWeight", newValue || null);
54
+ },
55
+ supportedRange: fontWeightRangeConfig.range,
56
+ step: fontWeightRangeConfig.step
57
+ });
58
+ }
59
+
60
+ get hyphens(): BooleanPreference {
61
+ return new BooleanPreference({
62
+ initialValue: this.preferences.hyphens,
63
+ effectiveValue: this.settings.hyphens || false,
64
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
65
+ onChange: (newValue: boolean | null | undefined) => {
66
+ this.updatePreference("hyphens", newValue || null);
67
+ }
68
+ });
69
+ }
70
+
71
+ get letterSpacing(): RangePreference<number> {
72
+ return new RangePreference<number>({
73
+ initialValue: this.preferences.letterSpacing,
74
+ effectiveValue: this.settings.letterSpacing || 0,
75
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
76
+ onChange: (newValue: number | null | undefined) => {
77
+ this.updatePreference("letterSpacing", newValue || null);
78
+ },
79
+ supportedRange: letterSpacingRangeConfig.range,
80
+ step: letterSpacingRangeConfig.step
81
+ });
82
+ }
83
+
84
+ get ligatures(): BooleanPreference {
85
+ return new BooleanPreference({
86
+ initialValue: this.preferences.ligatures,
87
+ effectiveValue: this.settings.ligatures || true,
88
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
89
+ onChange: (newValue: boolean | null | undefined) => {
90
+ this.updatePreference("ligatures", newValue || null);
91
+ }
92
+ });
93
+ }
94
+
95
+ get lineHeight(): RangePreference<number> {
96
+ return new RangePreference<number>({
97
+ initialValue: this.preferences.lineHeight,
98
+ effectiveValue: this.settings.lineHeight,
99
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
100
+ onChange: (newValue: number | null | undefined) => {
101
+ this.updatePreference("lineHeight", newValue || null);
102
+ },
103
+ supportedRange: lineHeightRangeConfig.range,
104
+ step: lineHeightRangeConfig.step
105
+ });
106
+ }
107
+
108
+ get noRuby(): BooleanPreference {
109
+ return new BooleanPreference({
110
+ initialValue: this.preferences.noRuby,
111
+ effectiveValue: this.settings.noRuby || false,
112
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
113
+ onChange: (newValue: boolean | null | undefined) => {
114
+ this.updatePreference("noRuby", newValue || null);
115
+ }
116
+ });
117
+ }
118
+
119
+ get paragraphIndent(): RangePreference<number> {
120
+ return new RangePreference<number>({
121
+ initialValue: this.preferences.paragraphIndent,
122
+ effectiveValue: this.settings.paragraphIndent || 0,
123
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
124
+ onChange: (newValue: number | null | undefined) => {
125
+ this.updatePreference("paragraphIndent", newValue || null);
126
+ },
127
+ supportedRange: paragraphIndentRangeConfig.range,
128
+ step: paragraphIndentRangeConfig.step
129
+ });
130
+ }
131
+
132
+ get paragraphSpacing(): RangePreference<number> {
133
+ return new RangePreference<number>({
134
+ initialValue: this.preferences.paragraphSpacing,
135
+ effectiveValue: this.settings.paragraphSpacing || 0,
136
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
137
+ onChange: (newValue: number | null | undefined) => {
138
+ this.updatePreference("paragraphSpacing", newValue || null);
139
+ },
140
+ supportedRange: paragraphSpacingRangeConfig.range,
141
+ step: paragraphSpacingRangeConfig.step
142
+ });
143
+ }
144
+
145
+ get textAlign(): EnumPreference<TextAlignment> {
146
+ return new EnumPreference<TextAlignment>({
147
+ initialValue: this.preferences.textAlign,
148
+ effectiveValue: this.settings.textAlign || TextAlignment.start,
149
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
150
+ onChange: (newValue: TextAlignment | null | undefined) => {
151
+ this.updatePreference("textAlign", newValue || null);
152
+ },
153
+ supportedValues: Object.values(TextAlignment)
154
+ });
155
+ }
156
+
157
+ get textNormalization(): BooleanPreference {
158
+ return new BooleanPreference({
159
+ initialValue: this.preferences.textNormalization,
160
+ effectiveValue: this.settings.textNormalization || false,
161
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
162
+ onChange: (newValue: boolean | null | undefined) => {
163
+ this.updatePreference("textNormalization", newValue || null);
164
+ }
165
+ });
166
+ }
167
+
168
+ get wordSpacing(): RangePreference<number> {
169
+ return new RangePreference<number>({
170
+ initialValue: this.preferences.wordSpacing,
171
+ effectiveValue: this.settings.wordSpacing || 0,
172
+ isEffective: this.metadata?.accessibility?.feature?.includes(Feature.DISPLAY_TRANSFORMABILITY) ?? false,
173
+ onChange: (newValue: number | null | undefined) => {
174
+ this.updatePreference("wordSpacing", newValue || null);
175
+ },
176
+ supportedRange: wordSpacingRangeConfig.range,
177
+ step: wordSpacingRangeConfig.step
178
+ });
179
+ }
180
+
181
+ get zoom(): RangePreference<number> {
182
+ return new RangePreference<number>({
183
+ initialValue: this.preferences.zoom,
184
+ effectiveValue: this.settings.zoom || 1,
185
+ isEffective: CSS.supports("zoom", "1") ?? false,
186
+ onChange: (newValue: number | null | undefined) => {
187
+ this.updatePreference("zoom", newValue || null);
188
+ },
189
+ supportedRange: zoomRangeConfig.range,
190
+ step: zoomRangeConfig.step
191
+ });
192
+ }
193
+ }
@@ -0,0 +1,88 @@
1
+ import { ConfigurableSettings } from "../../preferences/Configurable";
2
+ import { TextAlignment } from "../../preferences/Types";
3
+ import { WebPubDefaults } from "./WebPubDefaults";
4
+ import { WebPubPreferences } from "./WebPubPreferences";
5
+
6
+ export interface IWebPubSettings {
7
+ fontFamily?: string | null,
8
+ fontWeight?: number | null,
9
+ hyphens?: boolean | null,
10
+ letterSpacing?: number | null,
11
+ ligatures?: boolean | null,
12
+ lineHeight?: number | null,
13
+ noRuby?: boolean | null,
14
+ paragraphIndent?: number | null,
15
+ paragraphSpacing?: number | null,
16
+ textAlign?: TextAlignment | null,
17
+ textNormalization?: boolean | null,
18
+ wordSpacing?: number | null,
19
+ zoom?: number | null;
20
+ }
21
+
22
+ export class WebPubSettings implements ConfigurableSettings {
23
+ fontFamily: string | null;
24
+ fontWeight: number | null;
25
+ hyphens: boolean | null;
26
+ letterSpacing: number | null;
27
+ ligatures: boolean | null;
28
+ lineHeight: number | null;
29
+ noRuby: boolean | null;
30
+ paragraphIndent: number | null;
31
+ paragraphSpacing: number | null;
32
+ textAlign: TextAlignment | null;
33
+ textNormalization: boolean | null;
34
+ wordSpacing: number | null;
35
+ zoom: number | null;
36
+
37
+ constructor(preferences: WebPubPreferences, defaults: WebPubDefaults) {
38
+ this.fontFamily = preferences.fontFamily || defaults.fontFamily || null;
39
+ this.fontWeight = preferences.fontWeight !== undefined
40
+ ? preferences.fontWeight
41
+ : defaults.fontWeight !== undefined
42
+ ? defaults.fontWeight
43
+ : null;
44
+ this.hyphens = typeof preferences.hyphens === "boolean"
45
+ ? preferences.hyphens
46
+ : defaults.hyphens ?? null;
47
+ this.letterSpacing = preferences.letterSpacing !== undefined
48
+ ? preferences.letterSpacing
49
+ : defaults.letterSpacing !== undefined
50
+ ? defaults.letterSpacing
51
+ : null;
52
+ this.ligatures = typeof preferences.ligatures === "boolean"
53
+ ? preferences.ligatures
54
+ : defaults.ligatures ?? null;
55
+ this.lineHeight = preferences.lineHeight !== undefined
56
+ ? preferences.lineHeight
57
+ : defaults.lineHeight !== undefined
58
+ ? defaults.lineHeight
59
+ : null;
60
+ this.noRuby = typeof preferences.noRuby === "boolean"
61
+ ? preferences.noRuby
62
+ : defaults.noRuby ?? null;
63
+ this.paragraphIndent = preferences.paragraphIndent !== undefined
64
+ ? preferences.paragraphIndent
65
+ : defaults.paragraphIndent !== undefined
66
+ ? defaults.paragraphIndent
67
+ : null;
68
+ this.paragraphSpacing = preferences.paragraphSpacing !== undefined
69
+ ? preferences.paragraphSpacing
70
+ : defaults.paragraphSpacing !== undefined
71
+ ? defaults.paragraphSpacing
72
+ : null;
73
+ this.textAlign = preferences.textAlign || defaults.textAlign || null;
74
+ this.textNormalization = typeof preferences.textNormalization === "boolean"
75
+ ? preferences.textNormalization
76
+ : defaults.textNormalization ?? null;
77
+ this.wordSpacing = preferences.wordSpacing !== undefined
78
+ ? preferences.wordSpacing
79
+ : defaults.wordSpacing !== undefined
80
+ ? defaults.wordSpacing
81
+ : null;
82
+ this.zoom = preferences.zoom !== undefined
83
+ ? preferences.zoom
84
+ : defaults.zoom !== undefined
85
+ ? defaults.zoom
86
+ : null;
87
+ }
88
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./WebPubDefaults";
2
+ export * from "./WebPubPreferencesEditor";
3
+ export * from "./WebPubPreferences";
4
+ export * from "./WebPubSettings";
@@ -0,0 +1,20 @@
1
+ export type BodyHyphens = "auto" | "none";
2
+ export type BoxSizing = "content-box" | "border-box";
3
+ export type FontOpticalSizing = "auto" | "none";
4
+ export type FontWidth = "ultra-condensed" | "extra-condensed" | "condensed" | "semi-condensed" | "normal" | "semi-expanded" | "expanded" | "extra-expanded" | "ultra-expanded" | number;
5
+ export type Ligatures = "common-ligatures" | "none";
6
+ export type TypeScale = 1 | 1.067 | 1.125 | 1.2 | 1.25 | 1.333 | 1.414 | 1.5 | 1.618;
7
+ export type View = "paged" | "scroll";
8
+ export declare abstract class Properties {
9
+ constructor();
10
+ protected toFlag(name: string): string;
11
+ protected toUnitless(value: number): string;
12
+ protected toPercentage(value: number, ratio?: boolean): string;
13
+ protected toVw(value: number): string;
14
+ protected toVh(value: number): string;
15
+ protected toPx(value: number): string;
16
+ protected toRem(value: number): string;
17
+ abstract toCSSProperties(): {
18
+ [key: string]: string;
19
+ };
20
+ }
@@ -0,0 +1 @@
1
+ export * from "./Properties";