@readium/navigator 2.0.0-beta.9 → 2.0.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/dist/index.js +1777 -1791
- package/dist/index.umd.cjs +15 -15
- package/package.json +2 -2
- package/src/Navigator.ts +15 -4
- package/src/epub/EpubNavigator.ts +113 -57
- package/src/epub/css/Properties.ts +4 -0
- package/src/epub/css/ReadiumCSS.ts +33 -101
- package/src/epub/frame/FrameManager.ts +7 -1
- package/src/epub/frame/FramePoolManager.ts +1 -2
- package/src/epub/fxl/FXLFramePoolManager.ts +25 -6
- package/src/epub/fxl/FXLSpreader.ts +21 -8
- package/src/epub/preferences/EpubDefaults.ts +5 -4
- package/src/epub/preferences/EpubPreferences.ts +3 -4
- package/src/epub/preferences/EpubPreferencesEditor.ts +48 -50
- package/src/epub/preferences/EpubSettings.ts +10 -4
- package/src/preferences/Types.ts +0 -6
- package/types/src/Navigator.d.ts +9 -0
- package/types/src/epub/EpubNavigator.d.ts +14 -6
- package/types/src/epub/css/Properties.d.ts +2 -0
- package/types/src/epub/css/ReadiumCSS.d.ts +0 -3
- package/types/src/epub/fxl/FXLFramePoolManager.d.ts +3 -1
- package/types/src/epub/fxl/FXLSpreader.d.ts +11 -0
- package/types/src/epub/preferences/EpubDefaults.d.ts +3 -3
- package/types/src/epub/preferences/EpubPreferences.d.ts +3 -3
- package/types/src/epub/preferences/EpubPreferencesEditor.d.ts +2 -2
- package/types/src/epub/preferences/EpubSettings.d.ts +3 -3
- package/types/src/preferences/Types.d.ts +0 -5
- package/types/src/preferences/PreferencesSerializer.d.ts +0 -5
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { LineLengths } from "../../helpers";
|
|
2
2
|
import { getContentWidth } from "../../helpers/dimensions";
|
|
3
|
-
import { LayoutStrategy } from "../../preferences";
|
|
4
3
|
import { EpubSettings } from "../preferences/EpubSettings";
|
|
5
4
|
import { IUserProperties, RSProperties, UserProperties } from "./Properties";
|
|
6
5
|
|
|
@@ -10,7 +9,6 @@ export interface IReadiumCSS {
|
|
|
10
9
|
lineLengths: LineLengths;
|
|
11
10
|
container: HTMLElement;
|
|
12
11
|
constraint: number;
|
|
13
|
-
layoutStrategy?: LayoutStrategy | null;
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
export class ReadiumCSS {
|
|
@@ -20,7 +18,6 @@ export class ReadiumCSS {
|
|
|
20
18
|
container: HTMLElement;
|
|
21
19
|
containerParent: HTMLElement;
|
|
22
20
|
constraint: number;
|
|
23
|
-
layoutStrategy: LayoutStrategy;
|
|
24
21
|
private cachedColCount: number | null | undefined;
|
|
25
22
|
private effectiveContainerWidth: number;
|
|
26
23
|
|
|
@@ -31,7 +28,6 @@ export class ReadiumCSS {
|
|
|
31
28
|
this.container = props.container;
|
|
32
29
|
this.containerParent = props.container.parentElement || document.documentElement;
|
|
33
30
|
this.constraint = props.constraint;
|
|
34
|
-
this.layoutStrategy = props.layoutStrategy || LayoutStrategy.lineLength;
|
|
35
31
|
this.cachedColCount = props.userProperties.colCount;
|
|
36
32
|
this.effectiveContainerWidth = getContentWidth(this.containerParent);
|
|
37
33
|
}
|
|
@@ -43,9 +39,6 @@ export class ReadiumCSS {
|
|
|
43
39
|
if (settings.constraint !== this.constraint)
|
|
44
40
|
this.constraint = settings.constraint;
|
|
45
41
|
|
|
46
|
-
if (settings.layoutStrategy && settings.layoutStrategy !== this.layoutStrategy)
|
|
47
|
-
this.layoutStrategy = settings.layoutStrategy;
|
|
48
|
-
|
|
49
42
|
if (settings.pageGutter !== this.rsProperties.pageGutter)
|
|
50
43
|
this.rsProperties.pageGutter = settings.pageGutter;
|
|
51
44
|
|
|
@@ -73,7 +66,7 @@ export class ReadiumCSS {
|
|
|
73
66
|
maxChars: settings.maximalLineLength
|
|
74
67
|
});
|
|
75
68
|
|
|
76
|
-
const layout = this.updateLayout(settings.fontSize, settings.deprecatedFontSize, settings.scroll, settings.columnCount);
|
|
69
|
+
const layout = this.updateLayout(settings.fontSize, settings.deprecatedFontSize || settings.iOSPatch, settings.scroll, settings.columnCount);
|
|
77
70
|
|
|
78
71
|
if (layout?.effectiveContainerWidth)
|
|
79
72
|
this.effectiveContainerWidth = layout?.effectiveContainerWidth;
|
|
@@ -103,6 +96,7 @@ export class ReadiumCSS {
|
|
|
103
96
|
fontWidth: settings.fontWidth,
|
|
104
97
|
invertFilter: settings.invertFilter,
|
|
105
98
|
invertGaijiFilter: settings.invertGaijiFilter,
|
|
99
|
+
iOSPatch: settings.iOSPatch,
|
|
106
100
|
iPadOSPatch: settings.iPadOSPatch,
|
|
107
101
|
letterSpacing: settings.letterSpacing,
|
|
108
102
|
ligatures: typeof settings.ligatures !== "boolean"
|
|
@@ -132,23 +126,21 @@ export class ReadiumCSS {
|
|
|
132
126
|
this.userProperties = new UserProperties(updated);
|
|
133
127
|
}
|
|
134
128
|
|
|
135
|
-
private updateLayout(scale: number | null,
|
|
129
|
+
private updateLayout(scale: number | null, ignoreCompensation: boolean | null, scroll: boolean | null, colCount?: number | null) {
|
|
136
130
|
const isScroll = scroll ?? this.userProperties.view === "scroll";
|
|
137
131
|
|
|
138
132
|
if (isScroll) {
|
|
139
|
-
return this.computeScrollLength(scale,
|
|
133
|
+
return this.computeScrollLength(scale, ignoreCompensation);
|
|
140
134
|
} else {
|
|
141
|
-
return this.paginate(scale,
|
|
135
|
+
return this.paginate(scale, ignoreCompensation, colCount);
|
|
142
136
|
}
|
|
143
137
|
}
|
|
144
138
|
|
|
145
|
-
private getCompensatedMetrics(scale: number | null,
|
|
139
|
+
private getCompensatedMetrics(scale: number | null, ignoreCompensation: boolean | null) {
|
|
146
140
|
const zoomFactor = scale || this.userProperties.fontSize || 1;
|
|
147
141
|
const zoomCompensation = zoomFactor < 1
|
|
148
|
-
?
|
|
149
|
-
|
|
150
|
-
: 1 / zoomFactor
|
|
151
|
-
: deprecatedImplem
|
|
142
|
+
? 1 / zoomFactor
|
|
143
|
+
: ignoreCompensation
|
|
152
144
|
? zoomFactor
|
|
153
145
|
: 1;
|
|
154
146
|
|
|
@@ -168,9 +160,9 @@ export class ReadiumCSS {
|
|
|
168
160
|
// Note: Kept intentionally verbose for debugging
|
|
169
161
|
// TODO: As scroll shows, the effective line-length
|
|
170
162
|
// should be the same as uncompensated when scale >= 1
|
|
171
|
-
private paginate(scale: number | null,
|
|
163
|
+
private paginate(scale: number | null, ignoreCompensation: boolean | null, colCount?: number | null) {
|
|
172
164
|
const constrainedWidth = Math.round(getContentWidth(this.containerParent) - (this.constraint));
|
|
173
|
-
const metrics = this.getCompensatedMetrics(scale,
|
|
165
|
+
const metrics = this.getCompensatedMetrics(scale, ignoreCompensation);
|
|
174
166
|
const zoomCompensation = metrics.zoomCompensation;
|
|
175
167
|
const optimal = metrics.optimal;
|
|
176
168
|
const minimal = metrics.minimal;
|
|
@@ -188,61 +180,24 @@ export class ReadiumCSS {
|
|
|
188
180
|
}
|
|
189
181
|
|
|
190
182
|
if (colCount === null) {
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
effectiveContainerWidth = constrainedWidth;
|
|
199
|
-
}
|
|
200
|
-
} else if (this.layoutStrategy === LayoutStrategy.lineLength) {
|
|
201
|
-
if (constrainedWidth < optimal || maximal === null) {
|
|
202
|
-
RCSSColCount = 1;
|
|
203
|
-
effectiveContainerWidth = constrainedWidth;
|
|
204
|
-
} else {
|
|
205
|
-
RCSSColCount = Math.floor(constrainedWidth / optimal);
|
|
206
|
-
const requiredWidth = Math.round(RCSSColCount * (maximal * zoomCompensation));
|
|
207
|
-
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
208
|
-
}
|
|
209
|
-
} else if (this.layoutStrategy === LayoutStrategy.columns) {
|
|
210
|
-
if (constrainedWidth >= optimal) {
|
|
211
|
-
if (maximal === null) {
|
|
212
|
-
RCSSColCount = Math.floor(constrainedWidth / optimal);
|
|
213
|
-
effectiveContainerWidth = constrainedWidth;
|
|
214
|
-
} else {
|
|
215
|
-
RCSSColCount = Math.floor(constrainedWidth / (minimal || optimal));
|
|
216
|
-
const requiredWidth = Math.round((RCSSColCount * (optimal * zoomCompensation)));
|
|
217
|
-
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
218
|
-
}
|
|
219
|
-
} else {
|
|
220
|
-
RCSSColCount = 1;
|
|
221
|
-
effectiveContainerWidth = constrainedWidth;
|
|
222
|
-
}
|
|
183
|
+
if (constrainedWidth < optimal || maximal === null) {
|
|
184
|
+
RCSSColCount = 1;
|
|
185
|
+
effectiveContainerWidth = constrainedWidth;
|
|
186
|
+
} else {
|
|
187
|
+
RCSSColCount = Math.floor(constrainedWidth / optimal);
|
|
188
|
+
const requiredWidth = Math.round(RCSSColCount * (maximal * zoomCompensation));
|
|
189
|
+
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
223
190
|
}
|
|
224
191
|
} else if (colCount > 1) {
|
|
225
192
|
const minRequiredWidth = Math.round(colCount * (minimal !== null ? minimal : optimal));
|
|
226
193
|
|
|
227
194
|
if (constrainedWidth >= minRequiredWidth) {
|
|
228
195
|
RCSSColCount = colCount;
|
|
229
|
-
if (
|
|
230
|
-
|
|
196
|
+
if (maximal === null) {
|
|
197
|
+
effectiveContainerWidth = constrainedWidth
|
|
198
|
+
} else {
|
|
199
|
+
const requiredWidth = Math.round(RCSSColCount * (maximal * zoomCompensation));
|
|
231
200
|
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
232
|
-
} else if (
|
|
233
|
-
this.layoutStrategy === LayoutStrategy.lineLength ||
|
|
234
|
-
this.layoutStrategy === LayoutStrategy.columns
|
|
235
|
-
) {
|
|
236
|
-
if (maximal === null) {
|
|
237
|
-
effectiveContainerWidth = constrainedWidth
|
|
238
|
-
} else {
|
|
239
|
-
const requiredWidth = Math.round(RCSSColCount * (maximal * zoomCompensation));
|
|
240
|
-
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (this.layoutStrategy === LayoutStrategy.columns) {
|
|
244
|
-
console.error("Columns strategy is not compatible with a column count whose value is a number. Falling back to lineLength strategy.");
|
|
245
|
-
}
|
|
246
201
|
}
|
|
247
202
|
} else {
|
|
248
203
|
if (minimal !== null && constrainedWidth < Math.round(colCount * minimal)) {
|
|
@@ -257,23 +212,11 @@ export class ReadiumCSS {
|
|
|
257
212
|
RCSSColCount = 1;
|
|
258
213
|
|
|
259
214
|
if (constrainedWidth >= optimal) {
|
|
260
|
-
if (
|
|
261
|
-
|
|
215
|
+
if (maximal === null) {
|
|
216
|
+
effectiveContainerWidth = constrainedWidth
|
|
217
|
+
} else {
|
|
218
|
+
const requiredWidth = Math.round(maximal * zoomCompensation);
|
|
262
219
|
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
263
|
-
} else if (
|
|
264
|
-
this.layoutStrategy === LayoutStrategy.lineLength ||
|
|
265
|
-
this.layoutStrategy === LayoutStrategy.columns
|
|
266
|
-
) {
|
|
267
|
-
if (maximal === null) {
|
|
268
|
-
effectiveContainerWidth = constrainedWidth
|
|
269
|
-
} else {
|
|
270
|
-
const requiredWidth = Math.round(maximal * zoomCompensation);
|
|
271
|
-
effectiveContainerWidth = Math.min(requiredWidth, constrainedWidth);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (this.layoutStrategy === LayoutStrategy.columns) {
|
|
275
|
-
console.error("Columns strategy is not compatible with a column count whose value is a number. Falling back to lineLength strategy.");
|
|
276
|
-
}
|
|
277
220
|
}
|
|
278
221
|
} else {
|
|
279
222
|
effectiveContainerWidth = constrainedWidth
|
|
@@ -288,9 +231,9 @@ export class ReadiumCSS {
|
|
|
288
231
|
}
|
|
289
232
|
|
|
290
233
|
// This behaves as paginate where colCount = 1
|
|
291
|
-
private computeScrollLength(scale: number | null,
|
|
234
|
+
private computeScrollLength(scale: number | null, ignoreCompensation: boolean | null) {
|
|
292
235
|
const constrainedWidth = Math.round(getContentWidth(this.containerParent) - (this.constraint));
|
|
293
|
-
const metrics = this.getCompensatedMetrics(scale && (scale < 1 ||
|
|
236
|
+
const metrics = this.getCompensatedMetrics(scale && (scale < 1 || ignoreCompensation) ? scale : 1, ignoreCompensation);
|
|
294
237
|
const zoomCompensation = metrics.zoomCompensation;
|
|
295
238
|
const optimal = metrics.optimal;
|
|
296
239
|
const maximal = metrics.maximal;
|
|
@@ -299,22 +242,11 @@ export class ReadiumCSS {
|
|
|
299
242
|
let effectiveContainerWidth = constrainedWidth;
|
|
300
243
|
let effectiveLineLength = Math.round(optimal * zoomCompensation);
|
|
301
244
|
|
|
302
|
-
if (
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.layoutStrategy === LayoutStrategy.columns
|
|
308
|
-
) {
|
|
309
|
-
if (this.layoutStrategy === LayoutStrategy.columns) {
|
|
310
|
-
console.error("Columns strategy is not compatible with scroll. Falling back to lineLength strategy.");
|
|
311
|
-
}
|
|
312
|
-
if (maximal === null) {
|
|
313
|
-
effectiveLineLength = constrainedWidth;
|
|
314
|
-
} else {
|
|
315
|
-
const computedWidth = Math.min(Math.round(maximal * zoomCompensation), constrainedWidth);
|
|
316
|
-
effectiveLineLength = deprecatedImplem ? computedWidth : Math.round(computedWidth * zoomCompensation);
|
|
317
|
-
}
|
|
245
|
+
if (maximal === null) {
|
|
246
|
+
effectiveLineLength = constrainedWidth;
|
|
247
|
+
} else {
|
|
248
|
+
const computedWidth = Math.min(Math.round(maximal * zoomCompensation), constrainedWidth);
|
|
249
|
+
effectiveLineLength = ignoreCompensation ? computedWidth : Math.round(computedWidth * zoomCompensation);
|
|
318
250
|
}
|
|
319
251
|
|
|
320
252
|
return {
|
|
@@ -329,7 +261,7 @@ export class ReadiumCSS {
|
|
|
329
261
|
}
|
|
330
262
|
|
|
331
263
|
resizeHandler() {
|
|
332
|
-
const pagination = this.updateLayout(this.userProperties.fontSize, this.userProperties.deprecatedFontSize, this.userProperties.view === "scroll", this.cachedColCount);
|
|
264
|
+
const pagination = this.updateLayout(this.userProperties.fontSize, this.userProperties.deprecatedFontSize || this.userProperties.iOSPatch, this.userProperties.view === "scroll", this.cachedColCount);
|
|
333
265
|
this.userProperties.colCount = pagination.colCount;
|
|
334
266
|
this.userProperties.lineLength = pagination.effectiveLineLength;
|
|
335
267
|
this.effectiveContainerWidth = pagination.effectiveContainerWidth;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Loader, ModuleName } from "@readium/navigator-html-injectables";
|
|
2
2
|
import { FrameComms } from "./FrameComms";
|
|
3
3
|
import { ReadiumWindow } from "../../../../navigator-html-injectables/types/src/helpers/dom";
|
|
4
|
+
import { sML } from "../../helpers";
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export class FrameManager {
|
|
@@ -95,9 +96,14 @@ export class FrameManager {
|
|
|
95
96
|
this.frame.style.removeProperty("opacity");
|
|
96
97
|
this.frame.style.removeProperty("pointer-events");
|
|
97
98
|
this.hidden = false;
|
|
99
|
+
|
|
100
|
+
if (sML.UA.WebKit) {
|
|
101
|
+
this.comms?.send("force_webkit_recalc", undefined);
|
|
102
|
+
}
|
|
103
|
+
|
|
98
104
|
res();
|
|
99
105
|
}
|
|
100
|
-
if(atProgress
|
|
106
|
+
if(atProgress !== undefined) {
|
|
101
107
|
this.comms?.send("go_progression", atProgress, remove);
|
|
102
108
|
} else {
|
|
103
109
|
remove();
|
|
@@ -155,9 +155,8 @@ export class FramePoolManager {
|
|
|
155
155
|
await newFrame.load(modules); // In order to ensure modules match the latest configuration
|
|
156
156
|
|
|
157
157
|
// Update progression if necessary and show the new frame
|
|
158
|
-
const hasProgression = (locator?.locations?.progression ?? 0) > 0;
|
|
159
158
|
if(newFrame) // If user is speeding through the publication, this can get destroyed
|
|
160
|
-
await newFrame.show(
|
|
159
|
+
await newFrame.show(locator.locations.progression); // Show/activate new frame
|
|
161
160
|
|
|
162
161
|
this._currentFrame = newFrame;
|
|
163
162
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ModuleName } from "@readium/navigator-html-injectables";
|
|
2
|
-
import { Locator, Publication, ReadingProgression,
|
|
2
|
+
import { Locator, Publication, ReadingProgression, Page, Link } from "@readium/shared";
|
|
3
3
|
import { FrameCommsListener } from "../frame";
|
|
4
4
|
import FrameBlobBuider from "../frame/FrameBlobBuilder";
|
|
5
5
|
import { FXLFrameManager } from "./FXLFrameManager";
|
|
6
6
|
import { FXLPeripherals } from "./FXLPeripherals";
|
|
7
|
-
import { FXLSpreader } from "./FXLSpreader";
|
|
7
|
+
import { FXLSpreader, Orientation, Spread } from "./FXLSpreader";
|
|
8
|
+
import { VisualNavigatorViewport } from "../../Navigator";
|
|
8
9
|
|
|
9
10
|
const UPPER_BOUNDARY = 8;
|
|
10
11
|
const LOWER_BOUNDARY = 5;
|
|
@@ -47,7 +48,7 @@ export class FXLFramePoolManager {
|
|
|
47
48
|
this.container = container;
|
|
48
49
|
this.positions = positions;
|
|
49
50
|
this.pub = pub;
|
|
50
|
-
this.spreadPresentation = pub.metadata.
|
|
51
|
+
this.spreadPresentation = pub.metadata.otherMetadata?.spread || Spread.auto;
|
|
51
52
|
|
|
52
53
|
if(this.pub.metadata.effectiveReadingProgression !== ReadingProgression.rtl && this.pub.metadata.effectiveReadingProgression !== ReadingProgression.ltr)
|
|
53
54
|
// TODO support TTB and BTT
|
|
@@ -78,7 +79,7 @@ export class FXLFramePoolManager {
|
|
|
78
79
|
|
|
79
80
|
// this.pages.push(fm);
|
|
80
81
|
this.pool.set(link.href, fm);
|
|
81
|
-
fm.width = 100 / this.length * (link.properties?.
|
|
82
|
+
fm.width = 100 / this.length * (link.properties?.otherProperties["orientation"] === Orientation.landscape || link.properties?.otherProperties["addBlank"] ? this.perPage : 1);
|
|
82
83
|
fm.height = this.height;
|
|
83
84
|
});
|
|
84
85
|
}
|
|
@@ -123,7 +124,7 @@ export class FXLFramePoolManager {
|
|
|
123
124
|
this.pool.forEach((frm, linkHref) => {
|
|
124
125
|
let i = this.pub.readingOrder.items.findIndex(l => l.href === linkHref);
|
|
125
126
|
const link = this.pub.readingOrder.items[i];
|
|
126
|
-
frm.width = 100 / this.length * (link.properties?.
|
|
127
|
+
frm.width = 100 / this.length * (link.properties?.otherProperties["orientation"] === Orientation.landscape || link.properties?.otherProperties["addBlank"] ? this.perPage : 1);
|
|
127
128
|
frm.height = this.height;
|
|
128
129
|
if(!frm.loaded) return;
|
|
129
130
|
const spread = this.spreader.findByLink(link)!;
|
|
@@ -602,7 +603,25 @@ export class FXLFramePoolManager {
|
|
|
602
603
|
return ret as DOMRect;
|
|
603
604
|
}
|
|
604
605
|
|
|
605
|
-
get
|
|
606
|
+
get viewport(): VisualNavigatorViewport {
|
|
607
|
+
const viewport: VisualNavigatorViewport = {
|
|
608
|
+
readingOrder: [],
|
|
609
|
+
progressions: new Map(),
|
|
610
|
+
positions: null
|
|
611
|
+
};
|
|
612
|
+
const currentSpread = this.spreader.currentSpread(this.currentSlide, this.perPage);
|
|
613
|
+
currentSpread.forEach(link => {
|
|
614
|
+
viewport.readingOrder.push(link.href);
|
|
615
|
+
viewport.progressions.set(link.href, { start: 0, end: 1 }); // FXL always uses [0,1] progression
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// Set positions using currentNumbers
|
|
619
|
+
viewport.positions = this.getCurrentNumbers();
|
|
620
|
+
|
|
621
|
+
return viewport;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
private getCurrentNumbers(): number[] {
|
|
606
625
|
if(this.perPage < 2) {
|
|
607
626
|
const link = this.pub.readingOrder.items[this.currentSlide];
|
|
608
627
|
return [link.properties?.otherProperties["number"]];
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import { Link, Links,
|
|
1
|
+
import { Link, Links, Page, Publication, ReadingProgression } from "@readium/shared";
|
|
2
|
+
|
|
3
|
+
export enum Orientation {
|
|
4
|
+
auto = "auto",
|
|
5
|
+
landscape = "landscape",
|
|
6
|
+
portrait = "portrait",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export enum Spread {
|
|
10
|
+
auto = "auto",
|
|
11
|
+
both = "both",
|
|
12
|
+
none = "none",
|
|
13
|
+
landscape = "landscape",
|
|
14
|
+
}
|
|
2
15
|
|
|
3
16
|
export class FXLSpreader {
|
|
4
17
|
shift = true; // TODO getter
|
|
@@ -22,8 +35,8 @@ export class FXLSpreader {
|
|
|
22
35
|
});
|
|
23
36
|
// if(!orientation) item.Properties.Orientation = item.Width > item.Height ? "landscape" : "portrait";
|
|
24
37
|
}
|
|
25
|
-
const isLandscape = item.properties?.
|
|
26
|
-
if((!item.properties?.
|
|
38
|
+
const isLandscape = item.properties?.otherProperties["orientation"] === Orientation.landscape ? true : false;
|
|
39
|
+
if((!item.properties?.page || redo)) item.properties = item.properties?.add({
|
|
27
40
|
"page": isLandscape ? // If a landscape image
|
|
28
41
|
"center" : // Center it
|
|
29
42
|
((((this.shift ? 0 : 1) + index - this.nLandscape) % 2) ?
|
|
@@ -44,21 +57,21 @@ export class FXLSpreader {
|
|
|
44
57
|
if(item.length > 1)
|
|
45
58
|
return; // Only left with single-page "spreads"
|
|
46
59
|
const single = item[0];
|
|
47
|
-
const orientation = single.properties?.
|
|
60
|
+
const orientation = single.properties?.otherProperties["orientation"];
|
|
48
61
|
|
|
49
62
|
// First page is landscape/spread means no shift
|
|
50
|
-
if(index === 0 && (orientation === Orientation.landscape || (orientation !== Orientation.portrait && ((single.width || 0) > (single.height || 0) || single.properties?.
|
|
63
|
+
if(index === 0 && (orientation === Orientation.landscape || (orientation !== Orientation.portrait && ((single.width || 0) > (single.height || 0) || single.properties?.otherProperties["spread"] === Spread.both))))
|
|
51
64
|
this.shift = false;
|
|
52
65
|
|
|
53
66
|
// If last was a true single, and this spread is a center page (that's not special), something's wrong
|
|
54
|
-
if(wasLastSingle && single.properties?.
|
|
67
|
+
if(wasLastSingle && single.properties?.page === Page.center) {
|
|
55
68
|
this.spreads[index - 1][0].addProperties({"addBlank": true});
|
|
56
69
|
/*if(single.findFlag("final"))
|
|
57
70
|
this.nLandscape++;*/
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
// If this single page spread is an orphaned component of a double page spread (and it's not the first page)
|
|
61
|
-
if(orientation === Orientation.portrait && single.properties?.
|
|
74
|
+
if(orientation === Orientation.portrait && single.properties?.page !== "center" && single.properties?.otherProperties["number"] > 1)
|
|
62
75
|
wasLastSingle = true;
|
|
63
76
|
else
|
|
64
77
|
wasLastSingle = false;
|
|
@@ -72,7 +85,7 @@ export class FXLSpreader {
|
|
|
72
85
|
spine.items.forEach((item, index) => {
|
|
73
86
|
if(!index && this.shift) {
|
|
74
87
|
this.spreads.push([item]);
|
|
75
|
-
} else if(item.properties?.
|
|
88
|
+
} else if(item.properties?.page === Page.center) { // If a center (single) page spread, push immediately and reset current set
|
|
76
89
|
if(currentSet.length > 0) this.spreads.push(currentSet);
|
|
77
90
|
this.spreads.push([item]);
|
|
78
91
|
currentSet = [];
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
fontSizeRangeConfig,
|
|
3
3
|
fontWeightRangeConfig,
|
|
4
4
|
fontWidthRangeConfig,
|
|
5
|
-
LayoutStrategy,
|
|
6
5
|
TextAlignment,
|
|
7
6
|
Theme
|
|
8
7
|
} from "../../preferences/Types";
|
|
@@ -37,8 +36,8 @@ export interface IEpubDefaults {
|
|
|
37
36
|
hyphens?: boolean | null,
|
|
38
37
|
invertFilter?: boolean | number | null,
|
|
39
38
|
invertGaijiFilter?: boolean | number | null,
|
|
39
|
+
iOSPatch?: boolean | null,
|
|
40
40
|
iPadOSPatch?: boolean | null,
|
|
41
|
-
layoutStrategy?: LayoutStrategy | null,
|
|
42
41
|
letterSpacing?: number | null,
|
|
43
42
|
ligatures?: boolean | null,
|
|
44
43
|
lineHeight?: number | null,
|
|
@@ -81,8 +80,8 @@ export class EpubDefaults {
|
|
|
81
80
|
hyphens: boolean | null;
|
|
82
81
|
invertFilter: boolean | number | null;
|
|
83
82
|
invertGaijiFilter: boolean | number | null;
|
|
83
|
+
iOSPatch: boolean;
|
|
84
84
|
iPadOSPatch: boolean;
|
|
85
|
-
layoutStrategy: LayoutStrategy | null;
|
|
86
85
|
letterSpacing: number | null;
|
|
87
86
|
ligatures: boolean | null;
|
|
88
87
|
lineHeight: number | null;
|
|
@@ -127,10 +126,12 @@ export class EpubDefaults {
|
|
|
127
126
|
this.hyphens = ensureBoolean(defaults.hyphens) ?? null;
|
|
128
127
|
this.invertFilter = ensureFilter(defaults.invertFilter) ?? false;
|
|
129
128
|
this.invertGaijiFilter = ensureFilter(defaults.invertGaijiFilter) ?? false;
|
|
129
|
+
this.iOSPatch = defaults.iOSPatch === false
|
|
130
|
+
? false
|
|
131
|
+
: ((sMLWithRequest.OS.iOS || sMLWithRequest.OS.iPadOS) && sMLWithRequest.iOSRequest === "mobile");
|
|
130
132
|
this.iPadOSPatch = defaults.iPadOSPatch === false
|
|
131
133
|
? false
|
|
132
134
|
: (sMLWithRequest.OS.iPadOS && sMLWithRequest.iOSRequest === "desktop");
|
|
133
|
-
this.layoutStrategy = ensureEnumValue<LayoutStrategy>(defaults.layoutStrategy, LayoutStrategy) || LayoutStrategy.lineLength;
|
|
134
135
|
this.letterSpacing = ensureNonNegative(defaults.letterSpacing) || null;
|
|
135
136
|
this.ligatures = ensureBoolean(defaults.ligatures) ?? null;
|
|
136
137
|
this.lineHeight = ensureNonNegative(defaults.lineHeight) || null;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ConfigurablePreferences } from "../../preferences/Configurable";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
LayoutStrategy,
|
|
5
4
|
TextAlignment,
|
|
6
5
|
Theme,
|
|
7
6
|
fontSizeRangeConfig,
|
|
@@ -34,8 +33,8 @@ export interface IEpubPreferences {
|
|
|
34
33
|
hyphens?: boolean | null,
|
|
35
34
|
invertFilter?: boolean | number | null,
|
|
36
35
|
invertGaijiFilter?: boolean | number | null,
|
|
36
|
+
iOSPatch?: boolean | null,
|
|
37
37
|
iPadOSPatch?: boolean | null,
|
|
38
|
-
layoutStrategy?: LayoutStrategy | null,
|
|
39
38
|
letterSpacing?: number | null,
|
|
40
39
|
ligatures?: boolean | null,
|
|
41
40
|
lineHeight?: number | null,
|
|
@@ -78,8 +77,8 @@ export class EpubPreferences implements ConfigurablePreferences {
|
|
|
78
77
|
hyphens?: boolean | null;
|
|
79
78
|
invertFilter?: boolean | number | null;
|
|
80
79
|
invertGaijiFilter?: boolean | number | null;
|
|
80
|
+
iOSPatch?: boolean | null;
|
|
81
81
|
iPadOSPatch?: boolean | null;
|
|
82
|
-
layoutStrategy?: LayoutStrategy | null;
|
|
83
82
|
letterSpacing?: number | null;
|
|
84
83
|
ligatures?: boolean | null;
|
|
85
84
|
lineHeight?: number | null;
|
|
@@ -121,8 +120,8 @@ export class EpubPreferences implements ConfigurablePreferences {
|
|
|
121
120
|
this.hyphens = ensureBoolean(preferences.hyphens);
|
|
122
121
|
this.invertFilter = ensureFilter(preferences.invertFilter);
|
|
123
122
|
this.invertGaijiFilter = ensureFilter(preferences.invertGaijiFilter);
|
|
123
|
+
this.iOSPatch = ensureBoolean(preferences.iOSPatch);
|
|
124
124
|
this.iPadOSPatch = ensureBoolean(preferences.iPadOSPatch);
|
|
125
|
-
this.layoutStrategy = ensureEnumValue<LayoutStrategy>(preferences.layoutStrategy, LayoutStrategy);
|
|
126
125
|
this.letterSpacing = ensureNonNegative(preferences.letterSpacing);
|
|
127
126
|
this.ligatures = ensureBoolean(preferences.ligatures);
|
|
128
127
|
this.lineHeight = ensureNonNegative(preferences.lineHeight);
|