Skip to content

Commit 60253fe

Browse files
author
Mikkel Vester Petersen
committed
Detect pre-paginated/fixed-layout layout
1 parent 186c4fa commit 60253fe

File tree

3 files changed

+109
-5
lines changed

3 files changed

+109
-5
lines changed

src/book.js

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import Archive from "./archive";
1414
import request from "./utils/request";
1515
import EpubCFI from "./epubcfi";
1616
import Store from "./store";
17+
import DisplayOptions from "./displayoptions";
1718
import { EPUBJS_VERSION, EVENTS } from "./utils/constants";
1819

1920
const CONTAINER_PATH = "META-INF/container.xml";
21+
const IBOOKS_DISPLAY_OPTIONS_PATH = "META-INF/com.apple.ibooks.display-options.xml";
2022

2123
const INPUT_TYPE = {
2224
BINARY: "binary",
@@ -85,7 +87,8 @@ class Book {
8587
cover: new defer(),
8688
navigation: new defer(),
8789
pageList: new defer(),
88-
resources: new defer()
90+
resources: new defer(),
91+
displayOptions: new defer()
8992
};
9093

9194
this.loaded = {
@@ -95,7 +98,8 @@ class Book {
9598
cover: this.loading.cover.promise,
9699
navigation: this.loading.navigation.promise,
97100
pageList: this.loading.pageList.promise,
98-
resources: this.loading.resources.promise
101+
resources: this.loading.resources.promise,
102+
displayOptions: this.loading.displayOptions.promise
99103
};
100104

101105
/**
@@ -109,7 +113,8 @@ class Book {
109113
this.loaded.metadata,
110114
this.loaded.cover,
111115
this.loaded.navigation,
112-
this.loaded.resources
116+
this.loaded.resources,
117+
this.loaded.displayOptions
113118
]);
114119

115120

@@ -211,6 +216,13 @@ class Book {
211216
*/
212217
this.packaging = undefined;
213218

219+
/**
220+
* @member {DisplayOptions} displayOptions
221+
* @memberof DisplayOptions
222+
* @private
223+
*/
224+
this.displayOptions = undefined;
225+
214226
// this.toc = undefined;
215227
if (this.settings.store) {
216228
this.store(this.settings.store);
@@ -437,6 +449,20 @@ class Book {
437449
unpack(packaging) {
438450
this.package = packaging; //TODO: deprecated this
439451

452+
if (this.packaging.metadata.layout === "") {
453+
// rendition:layout not set - check display options if book is pre-paginated
454+
this.load(this.url.resolve(IBOOKS_DISPLAY_OPTIONS_PATH)).then((xml) => {
455+
this.displayOptions = new DisplayOptions(xml);
456+
this.loading.displayOptions.resolve(this.displayOptions);
457+
}).catch((err) => {
458+
this.displayOptions = new DisplayOptions();
459+
this.loading.displayOptions.resolve(this.displayOptions);
460+
});
461+
} else {
462+
this.displayOptions = new DisplayOptions();
463+
this.loading.displayOptions.resolve(this.displayOptions);
464+
}
465+
440466
this.spine.unpack(this.packaging, this.resolve.bind(this), this.canonical.bind(this));
441467

442468
this.resources = new Resources(this.packaging.manifest, {
@@ -466,14 +492,18 @@ class Book {
466492

467493
if(this.archived || this.settings.replacements && this.settings.replacements != "none") {
468494
this.replacements().then(() => {
469-
this.opening.resolve(this);
495+
this.loaded.displayOptions.then(() => {
496+
this.opening.resolve(this);
497+
});
470498
})
471499
.catch((err) => {
472500
console.error(err);
473501
});
474502
} else {
475503
// Resolve book opened promise
476-
this.opening.resolve(this);
504+
this.loaded.displayOptions.then(() => {
505+
this.opening.resolve(this);
506+
});
477507
}
478508

479509
}
@@ -707,6 +737,7 @@ class Book {
707737
this.container && this.container.destroy();
708738
this.packaging && this.packaging.destroy();
709739
this.rendition && this.rendition.destroy();
740+
this.displayOptions && this.displayOptions.destroy();
710741

711742
this.spine = undefined;
712743
this.locations = undefined;

src/displayoptions.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {qs, qsa } from "./utils/core";
2+
3+
/**
4+
* Open DisplayOptions Format Parser
5+
* @class
6+
* @param {document} displayOptionsDocument XML
7+
*/
8+
class DisplayOptions {
9+
constructor(displayOptionsDocument) {
10+
this.interactive = "";
11+
this.fixedLayout = "";
12+
this.openToSpread = "";
13+
this.orientationLock = "";
14+
15+
if (displayOptionsDocument) {
16+
this.parse(displayOptionsDocument);
17+
}
18+
}
19+
20+
/**
21+
* Parse XML
22+
* @param {document} displayOptionsDocument XML
23+
* @return {DisplayOptions} self
24+
*/
25+
parse(displayOptionsDocument) {
26+
if(!displayOptionsDocument) {
27+
return this;
28+
}
29+
30+
const displayOptionsNode = qs(displayOptionsDocument, "display_options");
31+
if(!displayOptionsNode) {
32+
return this;
33+
}
34+
35+
const options = qsa(displayOptionsNode, "option");
36+
options.forEach((el) => {
37+
let value = "";
38+
39+
if (el.childNodes.length) {
40+
value = el.childNodes[0].nodeValue;
41+
}
42+
43+
switch (el.attributes.name.value) {
44+
case "interactive":
45+
this.interactive = value;
46+
break;
47+
case "fixed-layout":
48+
this.fixedLayout = value;
49+
break;
50+
case "open-to-spread":
51+
this.openToSpread = value;
52+
break;
53+
case "orientation-lock":
54+
this.orientationLock = value;
55+
break;
56+
}
57+
});
58+
59+
return this;
60+
}
61+
62+
destroy() {
63+
this.interactive = undefined;
64+
this.fixedLayout = undefined;
65+
this.openToSpread = undefined;
66+
this.orientationLock = undefined;
67+
}
68+
}
69+
70+
export default DisplayOptions;

src/rendition.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ class Rendition {
203203
* @return {Promise} rendering has started
204204
*/
205205
start(){
206+
if (!this.settings.layout && (this.book.package.metadata.layout === "pre-paginated" || this.book.displayOptions.fixedLayout === "true")) {
207+
this.settings.layout = "pre-paginated";
208+
}
206209

207210
if(!this.manager) {
208211
this.ViewManager = this.requireManager(this.settings.manager);

0 commit comments

Comments
 (0)