@readium/navigator 2.5.0-beta.1 → 2.5.0-beta.3

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 (29) hide show
  1. package/dist/{ReadiumCSS-after-C-T_0paD.js → ReadiumCSS-after-AX2xHXM6.js} +3 -3
  2. package/dist/{ReadiumCSS-after-lr-n3fz2.js → ReadiumCSS-after-DIfxADJu.js} +4 -4
  3. package/dist/{ReadiumCSS-after-B_e3a-PY.js → ReadiumCSS-after-Djsq77vV.js} +10 -10
  4. package/dist/{ReadiumCSS-after-mXeKKPap.js → ReadiumCSS-after-DwG-6hYO.js} +4 -4
  5. package/dist/{ReadiumCSS-before-CfXPAGaQ.js → ReadiumCSS-before-B8zaPxhu.js} +1 -1
  6. package/dist/{ReadiumCSS-before-KVen5ceo.js → ReadiumCSS-before-BA9Irzag.js} +1 -1
  7. package/dist/{ReadiumCSS-before-CrNWvuyE.js → ReadiumCSS-before-Cz5-ynli.js} +1 -1
  8. package/dist/{ReadiumCSS-before-Bjd3POej.js → ReadiumCSS-before-DKjdmFso.js} +1 -1
  9. package/dist/{ReadiumCSS-default-C63bYOYF.js → ReadiumCSS-default-BGrBd7Sk.js} +1 -1
  10. package/dist/{ReadiumCSS-default-BKAG5pGU.js → ReadiumCSS-default-CcWmjgaR.js} +1 -1
  11. package/dist/{ReadiumCSS-default-DnlgDaBu.js → ReadiumCSS-default-DsgDIxGa.js} +1 -1
  12. package/dist/{ReadiumCSS-default-CclvbeNC.js → ReadiumCSS-default-DzJEDDcb.js} +1 -1
  13. package/dist/index.js +979 -954
  14. package/dist/index.umd.cjs +72 -72
  15. package/package.json +2 -2
  16. package/src/epub/EpubNavigator.ts +13 -8
  17. package/src/epub/css/ReadiumCSS.ts +21 -1
  18. package/src/epub/frame/FrameBlobBuilder.ts +1 -1
  19. package/src/epub/index.ts +0 -1
  20. package/src/helpers/dimensions.ts +7 -0
  21. package/src/helpers/index.ts +1 -0
  22. package/src/{epub/helpers → helpers}/scriptMode.ts +8 -1
  23. package/src/injection/epubInjectables.ts +6 -2
  24. package/src/webpub/WebPubNavigator.ts +9 -4
  25. package/types/src/epub/css/ReadiumCSS.d.ts +3 -0
  26. package/types/src/epub/index.d.ts +0 -1
  27. package/types/src/helpers/dimensions.d.ts +1 -0
  28. package/types/src/helpers/index.d.ts +1 -0
  29. package/types/src/{epub/helpers → helpers}/scriptMode.d.ts +4 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@readium/navigator",
3
- "version": "2.5.0-beta.1",
3
+ "version": "2.5.0-beta.3",
4
4
  "type": "module",
5
5
  "description": "Next generation SDK for publications in Web Apps",
6
6
  "author": "readium",
@@ -50,7 +50,7 @@
50
50
  "generate:css-selector": "node scripts/generate-css-selector.js"
51
51
  },
52
52
  "devDependencies": {
53
- "@readium/css": "^2.0.1",
53
+ "@readium/css": "^2.0.2",
54
54
  "@readium/navigator-html-injectables": "workspace:*",
55
55
  "@readium/shared": "workspace:*",
56
56
  "@types/path-browserify": "^1.0.3",
@@ -19,7 +19,7 @@ import { IInjectableRule, IInjectablesConfig } from "../injection/Injectable.ts"
19
19
  import { IContentProtectionConfig, IKeyboardPeripheralsConfig } from "../Navigator.ts";
20
20
  import { NavigatorProtector, NAVIGATOR_SUSPICIOUS_ACTIVITY_EVENT } from "../protection/NavigatorProtector.ts";
21
21
  import { KeyboardPeripherals, NAVIGATOR_KEYBOARD_PERIPHERAL_EVENT } from "../peripherals/KeyboardPeripherals.ts";
22
- import { getScriptMode } from "./helpers/scriptMode.ts";
22
+ import { getScriptMode } from "../helpers/scriptMode.ts";
23
23
 
24
24
  export type ManagerEventKey = "zoom";
25
25
 
@@ -115,9 +115,11 @@ export class EpubNavigator extends VisualNavigator implements Configurable<Confi
115
115
  const scriptMode = getScriptMode(pub.metadata);
116
116
  const isCJKHorizontal = scriptMode === 'cjk-horizontal';
117
117
  const isCJKVertical = scriptMode === 'cjk-vertical';
118
+ const isMongolianVertical = scriptMode === 'mongolian-vertical';
119
+ const isVertical = isCJKVertical || isMongolianVertical;
118
120
  const isCJK = isCJKHorizontal || isCJKVertical;
119
121
  this._css = new ReadiumCSS({
120
- rsProperties: new RSProperties({ noVerticalPagination: isCJKVertical || undefined }),
122
+ rsProperties: new RSProperties({ noVerticalPagination: isVertical || undefined }),
121
123
  userProperties: new UserProperties({}),
122
124
  lineLengths: new LineLengths({
123
125
  optimalChars: this._settings.optimalLineLength,
@@ -133,7 +135,8 @@ export class EpubNavigator extends VisualNavigator implements Configurable<Confi
133
135
  // sample: this.pub.metadata.description
134
136
  }),
135
137
  container: container,
136
- constraint: this._settings.constraint
138
+ constraint: this._settings.constraint,
139
+ isCJKVertical: isVertical
137
140
  });
138
141
 
139
142
  this._layout = EpubNavigator.determineLayout(pub, !!this._settings.scroll);
@@ -209,9 +212,10 @@ export class EpubNavigator extends VisualNavigator implements Configurable<Confi
209
212
  if (layout === Layout.scrolled)
210
213
  return Layout.scrolled;
211
214
 
212
- // CJK vertical writing: force scroll mode so the ScrollSnapper is
213
- // used and column-based pagination doesn't interfere.
214
- if (getScriptMode(pub.metadata) === 'cjk-vertical')
215
+ // CJK/Mongolian vertical writing: force scroll mode so the
216
+ // CJKVerticalSnapper is used and column-based pagination doesn't interfere.
217
+ const sm = getScriptMode(pub.metadata);
218
+ if (sm === 'cjk-vertical' || sm === 'mongolian-vertical')
215
219
  return Layout.scrolled;
216
220
 
217
221
  if (layout === Layout.reflowable && scroll)
@@ -554,8 +558,9 @@ export class EpubNavigator extends VisualNavigator implements Configurable<Confi
554
558
  return modules.filter((m) => FXLModules.includes(m));
555
559
  } else modules = modules.filter((m) => ReflowableModules.includes(m));
556
560
 
557
- // CJK vertical: uses its own X-axis snapper, never column or scroll snappers
558
- if (getScriptMode(this.pub.metadata) === 'cjk-vertical') {
561
+ // CJK/Mongolian vertical: uses the X-axis snapper, never column or scroll snappers
562
+ const mode = getScriptMode(this.pub.metadata);
563
+ if (mode === 'cjk-vertical' || mode === 'mongolian-vertical') {
559
564
  return modules.filter((m) => m !== "column_snapper" && m !== "scroll_snapper");
560
565
  }
561
566
 
@@ -1,5 +1,5 @@
1
1
  import { LineLengths } from "../../helpers/index.ts";
2
- import { getContentWidth } from "../../helpers/dimensions.ts";
2
+ import { getContentWidth, getContentHeight } from "../../helpers/dimensions.ts";
3
3
  import { EpubSettings } from "../preferences/EpubSettings.ts";
4
4
  import { IUserProperties, RSProperties, UserProperties } from "./Properties.ts";
5
5
 
@@ -9,6 +9,7 @@ export interface IReadiumCSS {
9
9
  lineLengths: LineLengths;
10
10
  container: HTMLElement;
11
11
  constraint: number;
12
+ isCJKVertical?: boolean;
12
13
  }
13
14
 
14
15
  export class ReadiumCSS {
@@ -18,6 +19,7 @@ export class ReadiumCSS {
18
19
  container: HTMLElement;
19
20
  containerParent: HTMLElement;
20
21
  constraint: number;
22
+ private readonly isCJKVertical: boolean;
21
23
  private cachedColCount: number | null | undefined;
22
24
  private effectiveContainerWidth: number;
23
25
 
@@ -28,6 +30,7 @@ export class ReadiumCSS {
28
30
  this.container = props.container;
29
31
  this.containerParent = props.container.parentElement || document.documentElement;
30
32
  this.constraint = props.constraint;
33
+ this.isCJKVertical = props.isCJKVertical ?? false;
31
34
  this.cachedColCount = props.userProperties.colCount;
32
35
  this.effectiveContainerWidth = getContentWidth(this.containerParent);
33
36
  }
@@ -131,6 +134,13 @@ export class ReadiumCSS {
131
134
  }
132
135
 
133
136
  private updateLayout(scale: number | null, ignoreCompensation: boolean | null, scroll: boolean | null, colCount?: number | null) {
137
+ // CJK vertical text flows along the block axis (height); the inline axis
138
+ // (width) must not be constrained by line-length at all — use the full
139
+ // parent width minus the known constraint.
140
+ if (this.isCJKVertical) {
141
+ return this.computeCJKVerticalLength(scale, ignoreCompensation);
142
+ }
143
+
134
144
  const isScroll = scroll ?? this.userProperties.view === "scroll";
135
145
 
136
146
  if (isScroll) {
@@ -235,6 +245,16 @@ export class ReadiumCSS {
235
245
  };
236
246
  }
237
247
 
248
+ private computeCJKVerticalLength(scale: number | null, ignoreCompensation: boolean | null) {
249
+ const w = Math.round(getContentWidth(this.containerParent) - this.constraint);
250
+ const h = Math.round(getContentHeight(this.containerParent));
251
+ const metrics = this.getCompensatedMetrics(scale, ignoreCompensation);
252
+ const effectiveLineLength = metrics.maximal !== null
253
+ ? Math.min(Math.round(metrics.maximal * metrics.zoomCompensation), h)
254
+ : h;
255
+ return { colCount: undefined, effectiveContainerWidth: w, effectiveLineLength };
256
+ }
257
+
238
258
  // This behaves as paginate where colCount = 1
239
259
  private computeScrollLength(scale: number | null, ignoreCompensation: boolean | null) {
240
260
  const constrainedWidth = Math.round(getContentWidth(this.containerParent) - (this.constraint));
@@ -1,6 +1,6 @@
1
1
  import { Link, MediaType, Publication, ReadingProgression } from "@readium/shared";
2
2
  import { Injector } from "../../injection/Injector.ts";
3
- import { getScriptMode } from "../helpers/scriptMode.ts";
3
+ import { getScriptMode } from "../../helpers/scriptMode.ts";
4
4
 
5
5
  const csp = (domains: string[]) => {
6
6
  const d = domains.join(" ");
package/src/epub/index.ts CHANGED
@@ -3,4 +3,3 @@ export * from "./frame/index.ts";
3
3
  export * from "./fxl/index.ts";
4
4
  export * from "./preferences/index.ts";
5
5
  export * from "./css/index.ts";
6
- export { getScriptMode, type ScriptMode } from "./helpers/scriptMode.ts";
@@ -11,3 +11,10 @@ export function getContentWidth(el: Element) {
11
11
  return el.clientWidth - paddingLeft - paddingRight;
12
12
  }
13
13
 
14
+ export function getContentHeight(el: Element) {
15
+ const cStyle = getComputedStyle(el);
16
+ const paddingTop = parseFloat(cStyle.paddingTop || "0");
17
+ const paddingBottom = parseFloat(cStyle.paddingBottom || "0");
18
+ return el.clientHeight - paddingTop - paddingBottom;
19
+ }
20
+
@@ -1,2 +1,3 @@
1
1
  export * from "./lineLength.ts";
2
2
  export * from './sML.ts';
3
+ export * from './scriptMode.ts';
@@ -1,6 +1,6 @@
1
1
  import { Metadata, ReadingProgression } from "@readium/shared";
2
2
 
3
- export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical';
3
+ export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical' | 'mongolian-vertical';
4
4
 
5
5
  /**
6
6
  * Derives the script mode from publication metadata.
@@ -14,6 +14,9 @@ export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical';
14
14
  * - For RTL (ar/fa/he): language wins. If the primary language is a RTL
15
15
  * script, RTL mode is applied regardless of the explicit progression
16
16
  * direction declared in the OPF.
17
+ * - For Mongolian (mn): Traditional Mongolian script (mn-Mong) uses
18
+ * writing-mode: vertical-lr. Cyrillic Mongolian (mn-Cyrl) is standard LTR.
19
+ * An explicit script subtag is required; bare `mn` defaults to LTR.
17
20
  */
18
21
  export function getScriptMode(metadata: Metadata): ScriptMode {
19
22
  const primaryLang = metadata.languages?.[0]?.toLowerCase();
@@ -33,6 +36,10 @@ export function getScriptMode(metadata: Metadata): ScriptMode {
33
36
  : 'cjk-horizontal';
34
37
  }
35
38
 
39
+ // Traditional Mongolian script (mn-Mong): writing-mode vertical-lr.
40
+ // Requires an explicit Mong script subtag; mn-Cyrl and bare mn stay LTR.
41
+ if (primaryLang.startsWith('mn-mong')) return 'mongolian-vertical';
42
+
36
43
  // RTL: language is authoritative. ar/fa/he → rtl regardless of
37
44
  // what the OPF says about page-progression-direction.
38
45
  const isRTLScript = primaryLang.startsWith('ar') ||
@@ -1,7 +1,7 @@
1
1
  import { IInjectableRule, IInjectable } from "../injection/Injectable.ts";
2
2
  import { stripJS, stripCSS } from "../helpers/minify.ts";
3
3
  import { Metadata, Layout, Link } from "@readium/shared";
4
- import { getScriptMode } from "../epub/helpers/scriptMode.ts";
4
+ import { getScriptMode } from "../helpers/scriptMode.ts";
5
5
 
6
6
  import cssSelectorGeneratorContent from "../dom/_readium_cssSelectorGenerator.js?raw";
7
7
  import executionPreventionContent from "../dom/_readium_executionPrevention.js?raw";
@@ -86,7 +86,11 @@ export async function createReadiumEpubRules(metadata: Metadata, readingOrderIte
86
86
  cssAfterRaw = after.default;
87
87
  break;
88
88
  }
89
- case 'cjk-vertical': {
89
+ case 'cjk-vertical':
90
+ // Traditional Mongolian (vertical-lr) uses the same Readium CSS
91
+ // layout as CJK vertical-rl — it is an outlier handled by the
92
+ // same stylesheet set per the Readium CSS spec.
93
+ case 'mongolian-vertical': {
90
94
  const [before, def, after] = await Promise.all([
91
95
  import("@readium/css/css/dist/cjk-vertical/ReadiumCSS-before.css?raw"),
92
96
  import("@readium/css/css/dist/cjk-vertical/ReadiumCSS-default.css?raw"),
@@ -2,11 +2,12 @@ import { Feature, Link, Locator, Publication, ReadingProgression, LocatorLocatio
2
2
  import { VisualNavigator, VisualNavigatorViewport, ProgressionRange } from "../Navigator.ts";
3
3
  import { Configurable } from "../preferences/Configurable.ts";
4
4
  import { WebPubFramePoolManager } from "./WebPubFramePoolManager.ts";
5
- import { BasicTextSelection, CommsEventKey, ContextMenuEvent, FrameClickEvent, KeyboardEventData, ModuleLibrary, ModuleName, SuspiciousActivityEvent, WebPubModules } from "@readium/navigator-html-injectables";
5
+ import { BasicTextSelection, CommsEventKey, ContextMenuEvent, FrameClickEvent, KeyboardEventData, ModuleName, SuspiciousActivityEvent, WebPubModules } from "@readium/navigator-html-injectables";
6
6
  import * as path from "path-browserify";
7
7
  import { WebPubFrameManager } from "./WebPubFrameManager.ts";
8
8
 
9
9
  import { ManagerEventKey } from "../epub/EpubNavigator.ts";
10
+ import { getScriptMode } from "../helpers/scriptMode.ts";
10
11
  import { WebPubCSS } from "./css/WebPubCSS.ts";
11
12
  import { WebUserProperties, WebRSProperties } from "./css/Properties.ts";
12
13
  import { IWebPubPreferences, WebPubPreferences } from "./preferences/WebPubPreferences.ts";
@@ -367,10 +368,14 @@ export class WebPubNavigator extends VisualNavigator implements Configurable<Web
367
368
  }
368
369
 
369
370
  private determineModules(): ModuleName[] {
370
- let modules = Array.from(ModuleLibrary.keys()) as ModuleName[];
371
+ const modules = WebPubModules.slice();
371
372
 
372
- // For WebPub, use the predefined WebPubModules array and filter
373
- return modules.filter((m) => WebPubModules.includes(m));
373
+ const mode = getScriptMode(this.pub.metadata);
374
+ if (mode === 'cjk-vertical' || mode === 'mongolian-vertical') {
375
+ return modules.map((m) => m === "webpub_snapper" ? "cjk_vertical_snapper" : m);
376
+ }
377
+
378
+ return modules;
374
379
  }
375
380
 
376
381
  private attachListener() {
@@ -7,6 +7,7 @@ export interface IReadiumCSS {
7
7
  lineLengths: LineLengths;
8
8
  container: HTMLElement;
9
9
  constraint: number;
10
+ isCJKVertical?: boolean;
10
11
  }
11
12
  export declare class ReadiumCSS {
12
13
  rsProperties: RSProperties;
@@ -15,6 +16,7 @@ export declare class ReadiumCSS {
15
16
  container: HTMLElement;
16
17
  containerParent: HTMLElement;
17
18
  constraint: number;
19
+ private readonly isCJKVertical;
18
20
  private cachedColCount;
19
21
  private effectiveContainerWidth;
20
22
  constructor(props: IReadiumCSS);
@@ -22,6 +24,7 @@ export declare class ReadiumCSS {
22
24
  private updateLayout;
23
25
  private getCompensatedMetrics;
24
26
  private paginate;
27
+ private computeCJKVerticalLength;
25
28
  private computeScrollLength;
26
29
  setContainerWidth(): void;
27
30
  resizeHandler(): void;
@@ -3,4 +3,3 @@ export * from "./frame/index.ts";
3
3
  export * from "./fxl/index.ts";
4
4
  export * from "./preferences/index.ts";
5
5
  export * from "./css/index.ts";
6
- export { getScriptMode, type ScriptMode } from "./helpers/scriptMode.ts";
@@ -5,3 +5,4 @@
5
5
  * @param el - The element to measure.
6
6
  */
7
7
  export declare function getContentWidth(el: Element): number;
8
+ export declare function getContentHeight(el: Element): number;
@@ -1,2 +1,3 @@
1
1
  export * from "./lineLength.ts";
2
2
  export * from './sML.ts';
3
+ export * from './scriptMode.ts';
@@ -1,5 +1,5 @@
1
1
  import { Metadata } from "@readium/shared";
2
- export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical';
2
+ export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical' | 'mongolian-vertical';
3
3
  /**
4
4
  * Derives the script mode from publication metadata.
5
5
  *
@@ -12,5 +12,8 @@ export type ScriptMode = 'ltr' | 'rtl' | 'cjk-horizontal' | 'cjk-vertical';
12
12
  * - For RTL (ar/fa/he): language wins. If the primary language is a RTL
13
13
  * script, RTL mode is applied regardless of the explicit progression
14
14
  * direction declared in the OPF.
15
+ * - For Mongolian (mn): Traditional Mongolian script (mn-Mong) uses
16
+ * writing-mode: vertical-lr. Cyrillic Mongolian (mn-Cyrl) is standard LTR.
17
+ * An explicit script subtag is required; bare `mn` defaults to LTR.
15
18
  */
16
19
  export declare function getScriptMode(metadata: Metadata): ScriptMode;