@readium/navigator 1.3.3 → 2.0.0-beta.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 (55) hide show
  1. package/dist/index.js +3744 -2819
  2. package/dist/index.umd.cjs +16 -16
  3. package/package.json +9 -9
  4. package/src/epub/EpubNavigator.ts +184 -7
  5. package/src/epub/css/Properties.ts +376 -0
  6. package/src/epub/css/ReadiumCSS.ts +348 -0
  7. package/src/epub/css/index.ts +2 -0
  8. package/src/epub/frame/FrameBlobBuilder.ts +59 -9
  9. package/src/epub/frame/FrameManager.ts +25 -6
  10. package/src/epub/frame/FramePoolManager.ts +61 -2
  11. package/src/epub/fxl/FXLFramePoolManager.ts +3 -15
  12. package/src/epub/index.ts +3 -1
  13. package/src/epub/preferences/EpubDefaults.ts +154 -0
  14. package/src/epub/preferences/EpubPreferences.ts +183 -0
  15. package/src/epub/preferences/EpubPreferencesEditor.ts +501 -0
  16. package/src/epub/preferences/EpubSettings.ts +212 -0
  17. package/src/epub/preferences/guards.ts +86 -0
  18. package/src/epub/preferences/index.ts +4 -0
  19. package/src/helpers/dimensions.ts +13 -0
  20. package/src/helpers/index.ts +1 -0
  21. package/src/helpers/lineLength.ts +293 -0
  22. package/src/helpers/sML.ts +18 -1
  23. package/src/index.ts +2 -1
  24. package/src/preferences/Configurable.ts +16 -0
  25. package/src/preferences/Preference.ts +272 -0
  26. package/src/preferences/PreferencesEditor.ts +6 -0
  27. package/src/preferences/Types.ts +39 -0
  28. package/src/preferences/index.ts +4 -0
  29. package/types/src/epub/EpubNavigator.d.ts +27 -3
  30. package/types/src/epub/css/Properties.d.ts +177 -0
  31. package/types/src/epub/css/ReadiumCSS.d.ts +32 -0
  32. package/types/src/epub/css/index.d.ts +2 -0
  33. package/types/src/epub/frame/FrameBlobBuilder.d.ts +5 -1
  34. package/types/src/epub/frame/FrameManager.d.ts +5 -0
  35. package/types/src/epub/frame/FramePoolManager.d.ts +8 -1
  36. package/types/src/epub/fxl/FXLFramePoolManager.d.ts +1 -3
  37. package/types/src/epub/index.d.ts +2 -0
  38. package/types/src/epub/preferences/EpubDefaults.d.ts +82 -0
  39. package/types/src/epub/preferences/EpubPreferences.d.ts +86 -0
  40. package/types/src/epub/preferences/EpubPreferencesEditor.d.ts +53 -0
  41. package/types/src/epub/preferences/EpubSettings.d.ts +85 -0
  42. package/types/src/epub/preferences/guards.d.ts +9 -0
  43. package/types/src/epub/preferences/index.d.ts +4 -0
  44. package/types/src/helpers/dimensions.d.ts +7 -0
  45. package/types/src/helpers/index.d.ts +1 -0
  46. package/types/src/helpers/lineLength.d.ts +68 -0
  47. package/types/src/helpers/sML.d.ts +6 -1
  48. package/types/src/index.d.ts +1 -0
  49. package/types/src/preferences/Configurable.d.ts +13 -0
  50. package/types/src/preferences/Preference.d.ts +117 -0
  51. package/types/src/preferences/PreferencesEditor.d.ts +5 -0
  52. package/types/src/preferences/PreferencesSerializer.d.ts +5 -0
  53. package/types/src/preferences/Types.d.ts +24 -0
  54. package/types/src/preferences/index.d.ts +4 -0
  55. package/LICENSE +0 -28
@@ -39,7 +39,6 @@ export class FXLFramePoolManager {
39
39
  private readonly spreadPresentation: Spread;
40
40
  private orientationInternal = -1; // Portrait = 1, Landscape = 0, Unknown = -1
41
41
  private containerHeightCached: number;
42
- private readonly resizeBoundHandler: EventListenerOrEventListenerObject;
43
42
  private resizeTimeout: number | undefined;
44
43
  // private readonly pages: FXLFrameManager[] = [];
45
44
  public readonly peripherals: FXLPeripherals;
@@ -57,10 +56,6 @@ export class FXLFramePoolManager {
57
56
  // NEW
58
57
  this.spreader = new FXLSpreader(this.pub);
59
58
  this.containerHeightCached = container.clientHeight;
60
- this.resizeBoundHandler = this.nativeResizeHandler.bind(this);
61
-
62
- this.ownerWindow.addEventListener("resize", this.resizeBoundHandler);
63
- this.ownerWindow.addEventListener("orientationchange", this.resizeBoundHandler);
64
59
 
65
60
  this.bookElement = document.createElement("div");
66
61
  this.bookElement.ariaLabel = "Book";
@@ -101,10 +96,6 @@ export class FXLFramePoolManager {
101
96
  return this.peripherals.pan.touchID > 0;
102
97
  }
103
98
 
104
- private nativeResizeHandler(_: Event) {
105
- this.resizeHandler(true);
106
- }
107
-
108
99
  /**
109
100
  * When window resizes, resize slider components as well
110
101
  */
@@ -259,8 +250,8 @@ export class FXLFramePoolManager {
259
250
  return this.spreader.nLandscape;
260
251
  }
261
252
 
262
- public setPerPage(perPage: number) {
263
- if(perPage === 0) {
253
+ public setPerPage(perPage: number | null) {
254
+ if(perPage === null) {
264
255
  // TODO this mode is auto
265
256
  this.spread = true;
266
257
  } else if(perPage === 1) {
@@ -376,9 +367,6 @@ export class FXLFramePoolManager {
376
367
 
377
368
 
378
369
  async destroy() {
379
- this.ownerWindow.removeEventListener("resize", this.resizeBoundHandler);
380
- this.ownerWindow.removeEventListener("orientationchange", this.resizeBoundHandler);
381
-
382
370
  // Wait for all in-progress loads to complete
383
371
  let iit = this.inprogress.values();
384
372
  let inp = iit.next();
@@ -629,4 +617,4 @@ export class FXLFramePoolManager {
629
617
  deselect() {
630
618
  this.currentFrames?.forEach(f => f?.deselect());
631
619
  }
632
- }
620
+ }
package/src/epub/index.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from "./EpubNavigator";
2
2
  export * from "./frame";
3
- export * from "./fxl";
3
+ export * from "./fxl";
4
+ export * from "./preferences";
5
+ export * from "./css";
@@ -0,0 +1,154 @@
1
+ import {
2
+ fontSizeRangeConfig,
3
+ fontWeightRangeConfig,
4
+ fontWidthRangeConfig,
5
+ LayoutStrategy,
6
+ TextAlignment,
7
+ Theme
8
+ } from "../../preferences/Types";
9
+
10
+ import {
11
+ ensureBoolean,
12
+ ensureEnumValue,
13
+ ensureFilter,
14
+ ensureLessThanOrEqual,
15
+ ensureMoreThanOrEqual,
16
+ ensureNonNegative,
17
+ ensureString,
18
+ ensureValueInRange,
19
+ withFallback
20
+ } from "./guards";
21
+
22
+ import { sMLWithRequest } from "../../helpers";
23
+
24
+ export interface IEpubDefaults {
25
+ backgroundColor?: string | null,
26
+ blendFilter?: boolean | null,
27
+ columnCount?: number | null,
28
+ constraint?: number | null,
29
+ darkenFilter?: boolean | number | null,
30
+ deprecatedFontSize?: boolean | null,
31
+ fontFamily?: string | null,
32
+ fontSize?: number | null,
33
+ fontSizeNormalize?: boolean | null,
34
+ fontOpticalSizing?: boolean | null,
35
+ fontOverride?: boolean | null,
36
+ fontWeight?: number | null,
37
+ fontWidth?: number | null,
38
+ hyphens?: boolean | null,
39
+ invertFilter?: boolean | number | null,
40
+ invertGaijiFilter?: boolean | number | null,
41
+ iPadOSPatch?: boolean | null,
42
+ layoutStrategy?: LayoutStrategy | null,
43
+ letterSpacing?: number | null,
44
+ ligatures?: boolean | null,
45
+ lineHeight?: number | null,
46
+ lineLength?: number | null,
47
+ linkColor?: string | null,
48
+ maximalLineLength?: number | null,
49
+ minimalLineLength?: number | null,
50
+ noRuby?: boolean | null,
51
+ optimalLineLength?: number | null,
52
+ pageGutter?: number | null,
53
+ paragraphIndent?: number | null,
54
+ paragraphSpacing?: number | null,
55
+ scroll?: boolean | null,
56
+ selectionBackgroundColor?: string | null,
57
+ selectionTextColor?: string | null,
58
+ textAlign?: TextAlignment | null,
59
+ textColor?: string | null,
60
+ textNormalization?: boolean | null,
61
+ theme?: Theme | null,
62
+ visitedColor?: string | null,
63
+ wordSpacing?: number | null
64
+ }
65
+
66
+ export class EpubDefaults {
67
+ backgroundColor: string | null;
68
+ blendFilter: boolean | null;
69
+ columnCount: number | null;
70
+ constraint: number;
71
+ darkenFilter: boolean | number | null;
72
+ deprecatedFontSize?: boolean | null;
73
+ fontFamily: string | null;
74
+ fontSize: number | null;
75
+ fontSizeNormalize: boolean | null;
76
+ fontOpticalSizing: boolean | null;
77
+ fontOverride: boolean | null;
78
+ fontWeight: number | null;
79
+ fontWidth: number | null;
80
+ hyphens: boolean | null;
81
+ invertFilter: boolean | number | null;
82
+ invertGaijiFilter: boolean | number | null;
83
+ iPadOSPatch: boolean;
84
+ layoutStrategy: LayoutStrategy | null;
85
+ letterSpacing: number | null;
86
+ ligatures: boolean | null;
87
+ lineHeight: number | null;
88
+ lineLength: number | null;
89
+ linkColor: string | null;
90
+ maximalLineLength: number | null;
91
+ minimalLineLength: number | null;
92
+ noRuby: boolean | null;
93
+ optimalLineLength: number;
94
+ pageGutter: number | null;
95
+ paragraphIndent: number | null;
96
+ paragraphSpacing: number | null;
97
+ scroll: boolean | null;
98
+ selectionBackgroundColor: string | null;
99
+ selectionTextColor: string | null;
100
+ textAlign: TextAlignment | null;
101
+ textColor: string | null;
102
+ textNormalization: boolean | null;
103
+ theme: Theme | null;
104
+ visitedColor: string | null;
105
+ wordSpacing: number | null;
106
+
107
+ constructor(defaults: IEpubDefaults) {
108
+ this.backgroundColor = ensureString(defaults.backgroundColor) || null;
109
+ this.blendFilter = ensureBoolean(defaults.blendFilter) ?? false;
110
+ this.constraint = ensureNonNegative(defaults.constraint) || 0;
111
+ this.columnCount = ensureNonNegative(defaults.columnCount) || null;
112
+ this.darkenFilter = ensureFilter(defaults.darkenFilter) ?? false;
113
+ this.deprecatedFontSize = ensureBoolean(defaults.deprecatedFontSize);
114
+ if (this.deprecatedFontSize === false || this.deprecatedFontSize === null) {
115
+ this.deprecatedFontSize = !CSS.supports("zoom", "1");
116
+ }
117
+ this.fontFamily = ensureString(defaults.fontFamily) || null;
118
+ this.fontSize = ensureValueInRange(defaults.fontSize, fontSizeRangeConfig.range) || 1;
119
+ this.fontSizeNormalize = ensureBoolean(defaults.fontSizeNormalize) ?? false;
120
+ this.fontOpticalSizing = ensureBoolean(defaults.fontOpticalSizing) ?? null;
121
+ this.fontOverride = ensureBoolean(defaults.fontOverride) ?? null;
122
+ this.fontWeight = ensureValueInRange(defaults.fontWeight, fontWeightRangeConfig.range) || null;
123
+ this.fontWidth = ensureValueInRange(defaults.fontWidth,fontWidthRangeConfig.range) || null;
124
+ this.hyphens = ensureBoolean(defaults.hyphens) ?? null;
125
+ this.invertFilter = ensureFilter(defaults.invertFilter) ?? false;
126
+ this.invertGaijiFilter = ensureFilter(defaults.invertGaijiFilter) ?? false;
127
+ this.iPadOSPatch = defaults.iPadOSPatch === false
128
+ ? false
129
+ : (sMLWithRequest.OS.iPadOS && sMLWithRequest.iOSRequest === "desktop");
130
+ this.layoutStrategy = ensureEnumValue<LayoutStrategy>(defaults.layoutStrategy, LayoutStrategy) || LayoutStrategy.lineLength;
131
+ this.letterSpacing = ensureNonNegative(defaults.letterSpacing) || null;
132
+ this.ligatures = ensureBoolean(defaults.ligatures) ?? null;
133
+ this.lineHeight = ensureNonNegative(defaults.lineHeight) || null;
134
+ this.linkColor = ensureString(defaults.linkColor) || null;
135
+ this.noRuby = ensureBoolean(defaults.noRuby) ?? false;
136
+ this.pageGutter = withFallback(ensureNonNegative(defaults.pageGutter), 20);
137
+ this.paragraphIndent = ensureNonNegative(defaults.paragraphIndent) ?? null;
138
+ this.paragraphSpacing = ensureNonNegative(defaults.paragraphSpacing) ?? null;
139
+ this.scroll = ensureBoolean(defaults.scroll) ?? false;
140
+ this.selectionBackgroundColor = ensureString(defaults.selectionBackgroundColor) || null;
141
+ this.selectionTextColor = ensureString(defaults.selectionTextColor) || null;
142
+ this.textAlign = ensureEnumValue<TextAlignment>(defaults.textAlign, TextAlignment) || null;
143
+ this.textColor = ensureString(defaults.textColor) || null;
144
+ this.textNormalization = ensureBoolean(defaults.textNormalization) ?? false;
145
+ this.theme = ensureEnumValue<Theme>(defaults.theme, Theme) || null;
146
+ this.visitedColor = ensureString(defaults.visitedColor) || null;
147
+ this.wordSpacing = ensureNonNegative(defaults.wordSpacing) || null;
148
+
149
+ this.lineLength = ensureNonNegative(defaults.lineLength) || null;
150
+ this.optimalLineLength = ensureNonNegative(defaults.optimalLineLength) || 65;
151
+ this.maximalLineLength = withFallback(ensureMoreThanOrEqual(defaults.maximalLineLength, this.lineLength || this.optimalLineLength), 80);
152
+ this.minimalLineLength = withFallback(ensureLessThanOrEqual(defaults.minimalLineLength, this.lineLength || this.optimalLineLength), 40);
153
+ }
154
+ }
@@ -0,0 +1,183 @@
1
+ import { ConfigurablePreferences } from "../../preferences/Configurable";
2
+
3
+ import {
4
+ LayoutStrategy,
5
+ TextAlignment,
6
+ Theme,
7
+ fontSizeRangeConfig,
8
+ fontWeightRangeConfig,
9
+ fontWidthRangeConfig
10
+ } from "../../preferences/Types";
11
+
12
+ import {
13
+ ensureBoolean,
14
+ ensureEnumValue,
15
+ ensureFilter,
16
+ ensureNonNegative,
17
+ ensureString,
18
+ ensureValueInRange
19
+ } from "./guards";
20
+
21
+ export interface IEpubPreferences {
22
+ backgroundColor?: string | null,
23
+ blendFilter?: boolean | null,
24
+ columnCount?: number | null,
25
+ constraint?: number | null,
26
+ darkenFilter?: boolean | number | null,
27
+ deprecatedFontSize?: boolean | null,
28
+ fontFamily?: string | null,
29
+ fontSize?: number | null,
30
+ fontSizeNormalize?: boolean | null,
31
+ fontOpticalSizing?: boolean | null,
32
+ fontOverride?: boolean | null,
33
+ fontWeight?: number | null,
34
+ fontWidth?: number | null,
35
+ hyphens?: boolean | null,
36
+ invertFilter?: boolean | number | null,
37
+ invertGaijiFilter?: boolean | number | null,
38
+ iPadOSPatch?: boolean | null,
39
+ layoutStrategy?: LayoutStrategy | null,
40
+ letterSpacing?: number | null,
41
+ ligatures?: boolean | null,
42
+ lineHeight?: number | null,
43
+ lineLength?: number | null,
44
+ linkColor?: string | null,
45
+ maximalLineLength?: number | null,
46
+ minimalLineLength?: number | null,
47
+ noRuby?: boolean | null,
48
+ optimalLineLength?: number | null,
49
+ pageGutter?: number | null,
50
+ paragraphIndent?: number | null,
51
+ paragraphSpacing?: number | null,
52
+ scroll?: boolean | null,
53
+ selectionBackgroundColor?: string | null,
54
+ selectionTextColor?: string | null,
55
+ textAlign?: TextAlignment | null,
56
+ textColor?: string | null,
57
+ textNormalization?: boolean | null,
58
+ theme?: Theme | null,
59
+ visitedColor?: string | null,
60
+ wordSpacing?: number | null
61
+ }
62
+
63
+ export class EpubPreferences implements ConfigurablePreferences {
64
+ backgroundColor?: string | null;
65
+ blendFilter?: boolean | null;
66
+ constraint?: number | null;
67
+ columnCount?: number | null;
68
+ darkenFilter?: boolean | number | null;
69
+ deprecatedFontSize?: boolean | null;
70
+ fontFamily?: string | null;
71
+ fontSize?: number | null;
72
+ fontSizeNormalize?: boolean | null;
73
+ fontOpticalSizing?: boolean | null;
74
+ fontOverride?: boolean | null;
75
+ fontWeight?: number | null;
76
+ fontWidth?: number | null;
77
+ hyphens?: boolean | null;
78
+ invertFilter?: boolean | number | null;
79
+ invertGaijiFilter?: boolean | number | null;
80
+ iPadOSPatch?: boolean | null;
81
+ layoutStrategy?: LayoutStrategy | null;
82
+ letterSpacing?: number | null;
83
+ ligatures?: boolean | null;
84
+ lineHeight?: number | null;
85
+ lineLength?: number | null;
86
+ linkColor?: string | null;
87
+ maximalLineLength?: number | null;
88
+ minimalLineLength?: number | null;
89
+ noRuby?: boolean | null;
90
+ optimalLineLength?: number | null;
91
+ pageGutter?: number | null;
92
+ paragraphIndent?: number | null;
93
+ paragraphSpacing?: number | null;
94
+ scroll?: boolean | null;
95
+ selectionBackgroundColor?: string | null;
96
+ selectionTextColor?: string | null;
97
+ textAlign?: TextAlignment | null;
98
+ textColor?: string | null;
99
+ textNormalization?: boolean | null;
100
+ theme?: Theme | null;
101
+ visitedColor?: string | null;
102
+ wordSpacing?: number | null;
103
+
104
+ constructor(preferences: IEpubPreferences = {}) {
105
+ this.backgroundColor = ensureString(preferences.backgroundColor);
106
+ this.blendFilter = ensureBoolean(preferences.blendFilter);
107
+ this.constraint = ensureNonNegative(preferences.constraint);
108
+ this.columnCount = ensureNonNegative(preferences.columnCount);
109
+ this.darkenFilter = ensureFilter(preferences.darkenFilter);
110
+ this.deprecatedFontSize = ensureBoolean(preferences.deprecatedFontSize);
111
+ this.fontFamily = ensureString(preferences.fontFamily);
112
+ this.fontSize = ensureValueInRange(preferences.fontSize, fontSizeRangeConfig.range);
113
+ this.fontSizeNormalize = ensureBoolean(preferences.fontSizeNormalize);
114
+ this.fontOpticalSizing = ensureBoolean(preferences.fontOpticalSizing);
115
+ this.fontOverride = ensureBoolean(preferences.fontOverride);
116
+ this.fontWeight = ensureValueInRange(preferences.fontWeight, fontWeightRangeConfig.range);
117
+ this.fontWidth = ensureValueInRange(preferences.fontWidth,fontWidthRangeConfig.range);
118
+ this.hyphens = ensureBoolean(preferences.hyphens);
119
+ this.invertFilter = ensureFilter(preferences.invertFilter);
120
+ this.invertGaijiFilter = ensureFilter(preferences.invertGaijiFilter);
121
+ this.iPadOSPatch = ensureBoolean(preferences.iPadOSPatch);
122
+ this.layoutStrategy = ensureEnumValue<LayoutStrategy>(preferences.layoutStrategy, LayoutStrategy);
123
+ this.letterSpacing = ensureNonNegative(preferences.letterSpacing);
124
+ this.ligatures = ensureBoolean(preferences.ligatures);
125
+ this.lineHeight = ensureNonNegative(preferences.lineHeight);
126
+ this.linkColor = ensureString(preferences.linkColor);
127
+ this.noRuby = ensureBoolean(preferences.noRuby);
128
+ this.pageGutter = ensureNonNegative(preferences.pageGutter);
129
+ this.paragraphIndent = ensureNonNegative(preferences.paragraphIndent);
130
+ this.paragraphSpacing = ensureNonNegative(preferences.paragraphSpacing);
131
+ this.scroll = ensureBoolean(preferences.scroll);
132
+ this.selectionBackgroundColor = ensureString(preferences.selectionBackgroundColor);
133
+ this.selectionTextColor = ensureString(preferences.selectionTextColor);
134
+ this.textAlign = ensureEnumValue<TextAlignment>(preferences.textAlign, TextAlignment);
135
+ this.textColor = ensureString(preferences.textColor);
136
+ this.textNormalization = ensureBoolean(preferences.textNormalization);
137
+ this.theme = ensureEnumValue<Theme>(preferences.theme, Theme);
138
+ this.visitedColor = ensureString(preferences.visitedColor);
139
+ this.wordSpacing = ensureNonNegative(preferences.wordSpacing);
140
+
141
+ this.lineLength = ensureNonNegative(preferences.lineLength);
142
+ this.optimalLineLength = ensureNonNegative(preferences.optimalLineLength);
143
+ this.maximalLineLength = ensureNonNegative(preferences.maximalLineLength);
144
+ this.minimalLineLength = ensureNonNegative(preferences.minimalLineLength);
145
+ }
146
+
147
+ static serialize(preferences: EpubPreferences): string {
148
+ const { ...properties } = preferences;
149
+ return JSON.stringify(properties);
150
+ }
151
+
152
+ static deserialize(preferences: string): EpubPreferences | null {
153
+ try {
154
+ const parsedPreferences = JSON.parse(preferences);
155
+ return new EpubPreferences(parsedPreferences);
156
+ } catch (error) {
157
+ console.error("Failed to deserialize preferences:", error);
158
+ return null;
159
+ }
160
+ }
161
+
162
+ merging(other: ConfigurablePreferences): ConfigurablePreferences {
163
+ const merged: IEpubPreferences = { ...this };
164
+ for (const key of Object.keys(other) as (keyof IEpubPreferences)[]) {
165
+ if (
166
+ other[key] !== undefined &&
167
+ (
168
+ key !== "maximalLineLength" ||
169
+ other[key] === null ||
170
+ (other[key] >= (other.lineLength ?? merged.lineLength ?? other.optimalLineLength ?? merged.optimalLineLength ?? 65))
171
+ ) &&
172
+ (
173
+ key !== "minimalLineLength" ||
174
+ other[key] === null ||
175
+ (other[key] <= (other.lineLength ?? merged.lineLength ?? other.optimalLineLength ?? merged.optimalLineLength ?? 65))
176
+ )
177
+ ) {
178
+ merged[key] = other[key];
179
+ }
180
+ }
181
+ return new EpubPreferences(merged);
182
+ }
183
+ }