mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-02 14:49:16 +02:00
Lint
This commit is contained in:
parent
f09089cf77
commit
7c7c554ee7
84 changed files with 13879 additions and 14510 deletions
|
@ -1,11 +1,14 @@
|
|||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": "last 2 Chrome versions, last 2 Safari versions, last 2 ChromeAndroid versions, last 2 iOS versions, last 2 Firefox versions, last 2 Edge versions",
|
||||
"corejs": 3,
|
||||
"useBuiltIns": "usage",
|
||||
"bugfixes": true,
|
||||
"modules": "auto"
|
||||
}]
|
||||
],
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
|
54
.eslintrc.js
54
.eslintrc.js
|
@ -1,43 +1,25 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
"globals": {
|
||||
"ePub": true,
|
||||
"JSZip": true
|
||||
globals: {
|
||||
ePub: true,
|
||||
JSZip: true,
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
extends: "eslint:recommended",
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
"tab",
|
||||
{ "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"warn",
|
||||
"double"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"no-unused-vars" : ["warn"],
|
||||
rules: {
|
||||
"linebreak-style": ["error", "unix"],
|
||||
quotes: ["warn", "double"],
|
||||
semi: ["error", "always"],
|
||||
"no-console": ["warn"],
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{ "vars": "all", "args": "none" }
|
||||
],
|
||||
"no-unused-vars": ["error", { vars: "all", args: "none" }],
|
||||
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
||||
"valid-jsdoc": ["warn"]
|
||||
}
|
||||
"no-prototype-builtins": "off",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
"browser": true,
|
||||
"devel": true,
|
||||
"worker": true,
|
||||
|
||||
"trailing": true,
|
||||
"strict": false,
|
||||
|
||||
"boss": true,
|
||||
"funcscope": true,
|
||||
"globalstrict": true,
|
||||
|
@ -14,7 +12,6 @@
|
|||
"nonstandard": true,
|
||||
"sub": true,
|
||||
"validthis": true,
|
||||
|
||||
"globals": {
|
||||
"_": false,
|
||||
"define": false,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
{
|
||||
"ignore_dirs": [
|
||||
".git",
|
||||
"node_modules"
|
||||
]
|
||||
"ignore_dirs": [".git", "node_modules"]
|
||||
}
|
||||
|
|
33
README.md
33
README.md
|
@ -65,6 +65,7 @@ The default manager only displays a single section at a time.
|
|||
```js
|
||||
book.renderTo("area", { method: "continuous", width: "100%", height: "100%" });
|
||||
```
|
||||
|
||||
[View example](http://futurepress.github.io/epub.js/examples/continuous-scrolled.html)
|
||||
|
||||
The continuous manager will display as many sections as need to fill the screen, and preload the next section offscreen. This enables seamless swiping / scrolling between pages on mobile and desktop, but is less performant than the default method.
|
||||
|
@ -72,6 +73,7 @@ The continuous manager will display as many sections as need to fill the screen,
|
|||
## Flow Overrides
|
||||
|
||||
### Auto (Default)
|
||||
|
||||
`book.renderTo("area", { flow: "auto", width: "900", height: "600" });`
|
||||
|
||||
Flow will be based on the settings in the OPF, defaults to `paginated`.
|
||||
|
@ -101,7 +103,7 @@ If a trusted ePub contains interactivity, it can be enabled by passing `allowScr
|
|||
var rendition = book.renderTo("area", {
|
||||
width: 600,
|
||||
height: 400,
|
||||
allowScriptedContent: true
|
||||
allowScriptedContent: true,
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
@ -132,11 +134,11 @@ npm start
|
|||
|
||||
## Examples
|
||||
|
||||
+ [Spreads](http://futurepress.github.io/epub.js/examples/spreads.html)
|
||||
+ [Scrolled](http://futurepress.github.io/epub.js/examples/scrolled.html)
|
||||
+ [Swipe](http://futurepress.github.io/epub.js/examples/swipe.html)
|
||||
+ [Input](http://futurepress.github.io/epub.js/examples/input.html)
|
||||
+ [Highlights](http://futurepress.github.io/epub.js/examples/highlights.html)
|
||||
- [Spreads](http://futurepress.github.io/epub.js/examples/spreads.html)
|
||||
- [Scrolled](http://futurepress.github.io/epub.js/examples/scrolled.html)
|
||||
- [Swipe](http://futurepress.github.io/epub.js/examples/swipe.html)
|
||||
- [Input](http://futurepress.github.io/epub.js/examples/input.html)
|
||||
- [Highlights](http://futurepress.github.io/epub.js/examples/highlights.html)
|
||||
|
||||
[View All Examples](http://futurepress.github.io/epub.js/examples/)
|
||||
|
||||
|
@ -176,28 +178,27 @@ Example hook:
|
|||
|
||||
```javascript
|
||||
rendition.hooks.content.register(function (contents, view) {
|
||||
|
||||
var elements = contents.document.querySelectorAll('[video]');
|
||||
var elements = contents.document.querySelectorAll("[video]");
|
||||
var items = Array.prototype.slice.call(elements);
|
||||
|
||||
items.forEach(function (item) {
|
||||
// do something with the video item
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
The parts of the rendering process that can be hooked into are below.
|
||||
|
||||
```js
|
||||
book.spine.hooks.serialize // Section is being converted to text
|
||||
book.spine.hooks.content // Section has been loaded and parsed
|
||||
rendition.hooks.render // Section is rendered to the screen
|
||||
rendition.hooks.content // Section contents have been loaded
|
||||
rendition.hooks.unloaded // Section contents are being unloaded
|
||||
book.spine.hooks.serialize; // Section is being converted to text
|
||||
book.spine.hooks.content; // Section has been loaded and parsed
|
||||
rendition.hooks.render; // Section is rendered to the screen
|
||||
rendition.hooks.content; // Section contents have been loaded
|
||||
rendition.hooks.unloaded; // Section contents are being unloaded
|
||||
```
|
||||
|
||||
## Reader
|
||||
|
||||
The reader has moved to its own repo at: https://github.com/futurepress/epubjs-reader/
|
||||
|
||||
## Additional Resources
|
||||
|
@ -210,7 +211,7 @@ IRC Server: freenode.net Channel: #epub.js
|
|||
|
||||
Follow us on twitter: @Epubjs
|
||||
|
||||
+ http://twitter.com/#!/Epubjs
|
||||
- http://twitter.com/#!/Epubjs
|
||||
|
||||
## Other
|
||||
|
||||
|
|
14
bower.json
14
bower.json
|
@ -1,19 +1,11 @@
|
|||
{
|
||||
"name": "epubjs",
|
||||
"version": "0.3.0",
|
||||
"authors": [
|
||||
"Fred Chasen <fchasen@gmail.com>"
|
||||
],
|
||||
"authors": ["Fred Chasen <fchasen@gmail.com>"],
|
||||
"description": "Enhanced eBooks in the browser.",
|
||||
"main": "dist/epub.js",
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals",
|
||||
"node"
|
||||
],
|
||||
"keywords": [
|
||||
"epub"
|
||||
],
|
||||
"moduleType": ["amd", "globals", "node"],
|
||||
"keywords": ["epub"],
|
||||
"license": "MIT",
|
||||
"homepage": "http://futurepress.org",
|
||||
"ignore": [
|
||||
|
|
|
@ -3,115 +3,75 @@ webpackConfig.mode = "development";
|
|||
webpackConfig.externals = {};
|
||||
webpackConfig.module.rules.push({
|
||||
test: /\.xhtml$/i,
|
||||
use: 'raw-loader',
|
||||
use: "raw-loader",
|
||||
});
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
basePath: "",
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['mocha'],
|
||||
|
||||
frameworks: ["mocha"],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
{ pattern: "src/*.js", watched: true, included: false, served: false },
|
||||
|
||||
{pattern: 'src/*.js', watched: true, included: false, served: false},
|
||||
{ pattern: "test/*.js", watched: false },
|
||||
|
||||
{pattern: 'test/*.js', watched: false},
|
||||
|
||||
{pattern: 'test/fixtures/**/*', watched: false, included: false, served: true},
|
||||
{
|
||||
pattern: "test/fixtures/**/*",
|
||||
watched: false,
|
||||
included: false,
|
||||
served: true,
|
||||
},
|
||||
|
||||
// {pattern: 'node_modules/jszip/dist/jszip.js', watched: false, included: true, served: true},
|
||||
|
||||
// {pattern: 'node_modules/es6-promise/dist/es6-promise.auto.js', watched: false, included: true, served: true},
|
||||
|
||||
// {pattern: 'libs/url/url-polyfill.js', watched: false, included: true, served: true}
|
||||
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [
|
||||
],
|
||||
|
||||
exclude: [],
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
// add webpack as preprocessor
|
||||
'test/*.js': ['webpack', 'sourcemap'],
|
||||
// 'test/**/*.js': ['webpack', 'sourcemap']
|
||||
"test/*.js": ["webpack", "sourcemap"],
|
||||
},
|
||||
|
||||
webpack: webpackConfig,
|
||||
|
||||
// {
|
||||
// mode: "development",
|
||||
// externals: {
|
||||
// "jszip": "JSZip"
|
||||
// // "xmldom": "xmldom"
|
||||
// },
|
||||
// devtool: 'inline-source-map',
|
||||
// resolve: {
|
||||
// alias: {
|
||||
// path: "path-webpack"
|
||||
// }
|
||||
// },
|
||||
// module: {
|
||||
// rules: [
|
||||
// {
|
||||
// test: /\.js$/,
|
||||
// exclude: /node_modules/,
|
||||
// loader: "babel-loader",
|
||||
// query: {
|
||||
// presets: [["@babel/preset-env", {
|
||||
// targets: "defaults",
|
||||
// }]],
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// test: /\.xhtml$/i,
|
||||
// use: 'raw-loader',
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
|
||||
webpackMiddleware: {
|
||||
stats: 'errors-only'
|
||||
stats: "errors-only",
|
||||
},
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['mocha'],
|
||||
reporters: ["mocha"],
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['ChromeHeadless', 'ChromeHeadlessNoSandbox'],
|
||||
|
||||
browsers: ["ChromeHeadless", "ChromeHeadlessNoSandbox"],
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
|
@ -121,27 +81,19 @@ module.exports = function(config) {
|
|||
// how many browser should be started simultaneous
|
||||
concurrency: Infinity,
|
||||
|
||||
proxies: {
|
||||
"/fixtures/": "/base/test/fixtures/"
|
||||
},
|
||||
proxies: { "/fixtures/": "/base/test/fixtures/" },
|
||||
|
||||
client: {
|
||||
config: {
|
||||
browserConsoleLogOptions: true
|
||||
},
|
||||
config: { browserConsoleLogOptions: true },
|
||||
captureConsole: true,
|
||||
mocha: {
|
||||
reporter: 'html'
|
||||
// bail: true
|
||||
}
|
||||
mocha: { reporter: "html" },
|
||||
},
|
||||
|
||||
customLaunchers: {
|
||||
ChromeHeadlessNoSandbox: {
|
||||
base: 'ChromeHeadless',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
base: "ChromeHeadless",
|
||||
flags: ["--no-sandbox"],
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@ import { EVENTS } from "./utils/constants";
|
|||
* @class
|
||||
*/
|
||||
class Annotations {
|
||||
|
||||
constructor(rendition) {
|
||||
this.rendition = rendition;
|
||||
this.highlights = [];
|
||||
|
@ -42,7 +41,7 @@ class Annotations {
|
|||
sectionIndex,
|
||||
cb,
|
||||
className,
|
||||
styles
|
||||
styles,
|
||||
});
|
||||
|
||||
this._annotations[hash] = annotation;
|
||||
|
@ -96,7 +95,9 @@ class Annotations {
|
|||
* @private
|
||||
*/
|
||||
_removeFromAnnotationBySectionIndex(sectionIndex, hash) {
|
||||
this._annotationsBySectionIndex[sectionIndex] = this._annotationsAt(sectionIndex).filter(h => h !== hash);
|
||||
this._annotationsBySectionIndex[sectionIndex] = this._annotationsAt(
|
||||
sectionIndex
|
||||
).filter((h) => h !== hash);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +108,6 @@ class Annotations {
|
|||
return this._annotationsBySectionIndex[index];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a highlight to the store
|
||||
* @param {EpubCFI} cfiRange EpubCFI range to attach annotation to
|
||||
|
@ -185,18 +185,13 @@ class Annotations {
|
|||
* [Not Implemented] Show annotations
|
||||
* @TODO: needs implementation in View
|
||||
*/
|
||||
show () {
|
||||
|
||||
}
|
||||
show() {}
|
||||
|
||||
/**
|
||||
* [Not Implemented] Hide annotations
|
||||
* @TODO: needs implementation in View
|
||||
*/
|
||||
hide () {
|
||||
|
||||
}
|
||||
|
||||
hide() {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -213,16 +208,7 @@ class Annotations {
|
|||
* @returns {Annotation} annotation
|
||||
*/
|
||||
class Annotation {
|
||||
|
||||
constructor ({
|
||||
type,
|
||||
cfiRange,
|
||||
data,
|
||||
sectionIndex,
|
||||
cb,
|
||||
className,
|
||||
styles
|
||||
}) {
|
||||
constructor({ type, cfiRange, data, sectionIndex, cb, className, styles }) {
|
||||
this.type = type;
|
||||
this.cfiRange = cfiRange;
|
||||
this.data = data;
|
||||
|
@ -246,7 +232,7 @@ class Annotation {
|
|||
* @param {View} view
|
||||
*/
|
||||
attach(view) {
|
||||
let {cfiRange, data, type, mark, cb, className, styles} = this;
|
||||
let { cfiRange, data, type, cb, className, styles } = this;
|
||||
let result;
|
||||
|
||||
if (type === "highlight") {
|
||||
|
@ -289,13 +275,9 @@ class Annotation {
|
|||
* [Not Implemented] Get text of an annotation
|
||||
* @TODO: needs implementation in contents
|
||||
*/
|
||||
text () {
|
||||
|
||||
}
|
||||
|
||||
text() {}
|
||||
}
|
||||
|
||||
EventEmitter(Annotation.prototype);
|
||||
|
||||
|
||||
export default Annotations
|
||||
export default Annotations;
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
import JSZip from "jszip/dist/jszip";
|
||||
import { defer, isXml, parse } from "./utils/core";
|
||||
import request from "./utils/request";
|
||||
import mime from "./utils/mime";
|
||||
import Path from "./utils/path";
|
||||
import JSZip from "jszip/dist/jszip";
|
||||
import request from "./utils/request";
|
||||
|
||||
/**
|
||||
* Handles Unzipping a requesting files from an Epub Archive
|
||||
* @class
|
||||
*/
|
||||
class Archive {
|
||||
|
||||
constructor() {
|
||||
this.zip = undefined;
|
||||
this.urlCache = {};
|
||||
|
||||
this.checkRequirements();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +36,7 @@ class Archive {
|
|||
* @return {Promise} zipfile
|
||||
*/
|
||||
open(input, isBase64) {
|
||||
return this.zip.loadAsync(input, {"base64": isBase64});
|
||||
return this.zip.loadAsync(input, { base64: isBase64 });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,10 +46,11 @@ class Archive {
|
|||
* @return {Promise} zipfile
|
||||
*/
|
||||
openUrl(zipUrl, isBase64) {
|
||||
return request(zipUrl, "binary")
|
||||
.then(function(data){
|
||||
return this.zip.loadAsync(data, {"base64": isBase64});
|
||||
}.bind(this));
|
||||
return request(zipUrl, "binary").then(
|
||||
function (data) {
|
||||
return this.zip.loadAsync(data, { base64: isBase64 });
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,14 +76,16 @@ class Archive {
|
|||
}
|
||||
|
||||
if (response) {
|
||||
response.then(function (r) {
|
||||
response.then(
|
||||
function (r) {
|
||||
let result = this.handleResponse(r, type);
|
||||
deferred.resolve(result);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
deferred.reject({
|
||||
message: "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
|
@ -102,17 +103,11 @@ class Archive {
|
|||
|
||||
if (type == "json") {
|
||||
r = JSON.parse(response);
|
||||
}
|
||||
else
|
||||
if(isXml(type)) {
|
||||
} else if (isXml(type)) {
|
||||
r = parse(response, "text/xml");
|
||||
}
|
||||
else
|
||||
if(type == "xhtml") {
|
||||
} else if (type == "xhtml") {
|
||||
r = parse(response, "application/xhtml+xml");
|
||||
}
|
||||
else
|
||||
if(type == "html" || type == "htm") {
|
||||
} else if (type == "html" || type == "htm") {
|
||||
r = parse(response, "text/html");
|
||||
} else {
|
||||
r = response;
|
||||
|
@ -196,36 +191,31 @@ class Archive {
|
|||
response = this.getBase64(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(tempUrl) {
|
||||
|
||||
response.then(
|
||||
function (tempUrl) {
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
response = this.getBlob(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(blob) {
|
||||
|
||||
response.then(
|
||||
function (blob) {
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!response) {
|
||||
deferred.reject({
|
||||
message: "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
120
src/book.js
120
src/book.js
|
@ -1,24 +1,25 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import {extend, defer} from "./utils/core";
|
||||
import Url from "./utils/url";
|
||||
import Path from "./utils/path";
|
||||
import Spine from "./spine";
|
||||
import Locations from "./locations";
|
||||
import Archive from "./archive";
|
||||
import Container from "./container";
|
||||
import Packaging from "./packaging";
|
||||
import DisplayOptions from "./displayoptions";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Locations from "./locations";
|
||||
import Navigation from "./navigation";
|
||||
import Resources from "./resources";
|
||||
import Packaging from "./packaging";
|
||||
import PageList from "./pagelist";
|
||||
import Rendition from "./rendition";
|
||||
import Archive from "./archive";
|
||||
import request from "./utils/request";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Resources from "./resources";
|
||||
import Spine from "./spine";
|
||||
import Store from "./store";
|
||||
import DisplayOptions from "./displayoptions";
|
||||
import { EPUBJS_VERSION, EVENTS } from "./utils/constants";
|
||||
import { defer, extend } from "./utils/core";
|
||||
import Path from "./utils/path";
|
||||
import request from "./utils/request";
|
||||
import Url from "./utils/url";
|
||||
|
||||
const CONTAINER_PATH = "META-INF/container.xml";
|
||||
const IBOOKS_DISPLAY_OPTIONS_PATH = "META-INF/com.apple.ibooks.display-options.xml";
|
||||
const IBOOKS_DISPLAY_OPTIONS_PATH =
|
||||
"META-INF/com.apple.ibooks.display-options.xml";
|
||||
|
||||
const INPUT_TYPE = {
|
||||
BINARY: "binary",
|
||||
|
@ -26,7 +27,7 @@ const INPUT_TYPE = {
|
|||
EPUB: "epub",
|
||||
OPF: "opf",
|
||||
MANIFEST: "json",
|
||||
DIRECTORY: "directory"
|
||||
DIRECTORY: "directory",
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -50,10 +51,12 @@ const INPUT_TYPE = {
|
|||
class Book {
|
||||
constructor(url, options) {
|
||||
// Allow passing just options to the Book
|
||||
if (typeof(options) === "undefined" &&
|
||||
typeof(url) !== "string" &&
|
||||
if (
|
||||
typeof options === "undefined" &&
|
||||
typeof url !== "string" &&
|
||||
url instanceof Blob === false &&
|
||||
url instanceof ArrayBuffer === false) {
|
||||
url instanceof ArrayBuffer === false
|
||||
) {
|
||||
options = url;
|
||||
url = undefined;
|
||||
}
|
||||
|
@ -66,12 +69,11 @@ class Book {
|
|||
replacements: undefined,
|
||||
canonical: undefined,
|
||||
openAs: undefined,
|
||||
store: undefined
|
||||
store: undefined,
|
||||
});
|
||||
|
||||
extend(this.settings, options);
|
||||
|
||||
|
||||
// Promises
|
||||
this.opening = new defer();
|
||||
/**
|
||||
|
@ -89,7 +91,7 @@ class Book {
|
|||
navigation: new defer(),
|
||||
pageList: new defer(),
|
||||
resources: new defer(),
|
||||
displayOptions: new defer()
|
||||
displayOptions: new defer(),
|
||||
};
|
||||
|
||||
this.loaded = {
|
||||
|
@ -100,7 +102,7 @@ class Book {
|
|||
navigation: this.loading.navigation.promise,
|
||||
pageList: this.loading.pageList.promise,
|
||||
resources: this.loading.resources.promise,
|
||||
displayOptions: this.loading.displayOptions.promise
|
||||
displayOptions: this.loading.displayOptions.promise,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -115,10 +117,9 @@ class Book {
|
|||
this.loaded.cover,
|
||||
this.loaded.navigation,
|
||||
this.loaded.resources,
|
||||
this.loaded.displayOptions
|
||||
this.loaded.displayOptions,
|
||||
]);
|
||||
|
||||
|
||||
// Queue for methods used before opening
|
||||
this.isRendered = false;
|
||||
// this._q = queue(this);
|
||||
|
@ -259,8 +260,12 @@ class Book {
|
|||
} else if (type === INPUT_TYPE.EPUB) {
|
||||
this.archived = true;
|
||||
this.url = new Url("/", "");
|
||||
opening = this.request(input, "binary", this.settings.requestCredentials, this.settings.requestHeaders)
|
||||
.then(this.openEpub.bind(this));
|
||||
opening = this.request(
|
||||
input,
|
||||
"binary",
|
||||
this.settings.requestCredentials,
|
||||
this.settings.requestHeaders
|
||||
).then(this.openEpub.bind(this));
|
||||
} else if (type == INPUT_TYPE.OPF) {
|
||||
this.url = new Url(input);
|
||||
opening = this.openPackaging(this.url.Path.toString());
|
||||
|
@ -269,8 +274,9 @@ class Book {
|
|||
opening = this.openManifest(this.url.Path.toString());
|
||||
} else {
|
||||
this.url = new Url(input);
|
||||
opening = this.openContainer(CONTAINER_PATH)
|
||||
.then(this.openPackaging.bind(this));
|
||||
opening = this.openContainer(CONTAINER_PATH).then(
|
||||
this.openPackaging.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
return opening;
|
||||
|
@ -300,8 +306,7 @@ class Book {
|
|||
* @return {string} packagePath
|
||||
*/
|
||||
openContainer(url) {
|
||||
return this.load(url)
|
||||
.then((xml) => {
|
||||
return this.load(url).then((xml) => {
|
||||
this.container = new Container(xml);
|
||||
return this.resolve(this.container.packagePath);
|
||||
});
|
||||
|
@ -315,8 +320,7 @@ class Book {
|
|||
*/
|
||||
openPackaging(url) {
|
||||
this.path = new Path(url);
|
||||
return this.load(url)
|
||||
.then((xml) => {
|
||||
return this.load(url).then((xml) => {
|
||||
this.packaging = new Packaging(xml);
|
||||
return this.unpack(this.packaging);
|
||||
});
|
||||
|
@ -330,8 +334,7 @@ class Book {
|
|||
*/
|
||||
openManifest(url) {
|
||||
this.path = new Path(url);
|
||||
return this.load(url)
|
||||
.then((json) => {
|
||||
return this.load(url).then((json) => {
|
||||
this.packaging = new Packaging();
|
||||
this.packaging.load(json);
|
||||
return this.unpack(this.packaging);
|
||||
|
@ -348,7 +351,12 @@ class Book {
|
|||
if (this.archived) {
|
||||
return this.archive.request(resolved);
|
||||
} else {
|
||||
return this.request(resolved, null, this.settings.requestCredentials, this.settings.requestHeaders);
|
||||
return this.request(
|
||||
resolved,
|
||||
null,
|
||||
this.settings.requestCredentials,
|
||||
this.settings.requestHeaders
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,7 +371,7 @@ class Book {
|
|||
return;
|
||||
}
|
||||
var resolved = path;
|
||||
var isAbsolute = (path.indexOf("://") > -1);
|
||||
var isAbsolute = path.indexOf("://") > -1;
|
||||
|
||||
if (isAbsolute) {
|
||||
return path;
|
||||
|
@ -416,7 +424,7 @@ class Book {
|
|||
return INPUT_TYPE.BASE64;
|
||||
}
|
||||
|
||||
if(typeof(input) != "string") {
|
||||
if (typeof input != "string") {
|
||||
return INPUT_TYPE.BINARY;
|
||||
}
|
||||
|
||||
|
@ -446,7 +454,6 @@ class Book {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unpack the contents of the Books packaging
|
||||
* @private
|
||||
|
@ -457,10 +464,12 @@ class Book {
|
|||
|
||||
if (this.packaging.metadata.layout === "") {
|
||||
// rendition:layout not set - check display options if book is pre-paginated
|
||||
this.load(this.url.resolve(IBOOKS_DISPLAY_OPTIONS_PATH)).then((xml) => {
|
||||
this.load(this.url.resolve(IBOOKS_DISPLAY_OPTIONS_PATH))
|
||||
.then((xml) => {
|
||||
this.displayOptions = new DisplayOptions(xml);
|
||||
this.loading.displayOptions.resolve(this.displayOptions);
|
||||
}).catch((err) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
this.displayOptions = new DisplayOptions();
|
||||
this.loading.displayOptions.resolve(this.displayOptions);
|
||||
});
|
||||
|
@ -469,13 +478,18 @@ class Book {
|
|||
this.loading.displayOptions.resolve(this.displayOptions);
|
||||
}
|
||||
|
||||
this.spine.unpack(this.packaging, this.resolve.bind(this), this.canonical.bind(this));
|
||||
this.spine.unpack(
|
||||
this.packaging,
|
||||
this.resolve.bind(this),
|
||||
this.canonical.bind(this)
|
||||
);
|
||||
|
||||
this.resources = new Resources(this.packaging.manifest, {
|
||||
archive: this.archive,
|
||||
resolver: this.resolve.bind(this),
|
||||
request: this.request.bind(this),
|
||||
replacements: this.settings.replacements || (this.archived ? "blobUrl" : "base64")
|
||||
replacements:
|
||||
this.settings.replacements || (this.archived ? "blobUrl" : "base64"),
|
||||
});
|
||||
|
||||
this.loadNavigation(this.packaging).then(() => {
|
||||
|
@ -496,8 +510,12 @@ class Book {
|
|||
|
||||
this.isOpen = true;
|
||||
|
||||
if(this.archived || this.settings.replacements && this.settings.replacements != "none") {
|
||||
this.replacements().then(() => {
|
||||
if (
|
||||
this.archived ||
|
||||
(this.settings.replacements && this.settings.replacements != "none")
|
||||
) {
|
||||
this.replacements()
|
||||
.then(() => {
|
||||
this.loaded.displayOptions.then(() => {
|
||||
this.opening.resolve(this);
|
||||
});
|
||||
|
@ -511,7 +529,6 @@ class Book {
|
|||
this.opening.resolve(this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -545,8 +562,7 @@ class Book {
|
|||
});
|
||||
}
|
||||
|
||||
return this.load(navPath, "xml")
|
||||
.then((xml) => {
|
||||
return this.load(navPath, "xml").then((xml) => {
|
||||
this.navigation = new Navigation(xml);
|
||||
this.pageList = new PageList(xml);
|
||||
return this.navigation;
|
||||
|
@ -613,7 +629,8 @@ class Book {
|
|||
*/
|
||||
store(name) {
|
||||
// Use "blobUrl" or "base64" for replacements
|
||||
let replacementsSetting = this.settings.replacements && this.settings.replacements !== "none";
|
||||
let replacementsSetting =
|
||||
this.settings.replacements && this.settings.replacements !== "none";
|
||||
// Save original url
|
||||
let originalUrl = this.url;
|
||||
// Save original request method
|
||||
|
@ -635,8 +652,7 @@ class Book {
|
|||
// Set to use replacements
|
||||
this.resources.settings.replacements = replacementsSetting || "blobUrl";
|
||||
// Create replacement urls
|
||||
this.resources.replacements().
|
||||
then(() => {
|
||||
this.resources.replacements().then(() => {
|
||||
return this.resources.replaceCss();
|
||||
});
|
||||
|
||||
|
@ -653,7 +669,6 @@ class Book {
|
|||
// Remove hook
|
||||
this.spine.hooks.serialize.deregister(substituteResources);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return this.storage;
|
||||
|
@ -687,8 +702,7 @@ class Book {
|
|||
section.output = this.resources.substitute(output, section.url);
|
||||
});
|
||||
|
||||
return this.resources.replacements().
|
||||
then(() => {
|
||||
return this.resources.replacements().then(() => {
|
||||
return this.resources.replaceCss();
|
||||
});
|
||||
}
|
||||
|
@ -719,7 +733,8 @@ class Book {
|
|||
* @return {string} key
|
||||
*/
|
||||
key(identifier) {
|
||||
var ident = identifier || this.packaging.metadata.identifier || this.url.filename;
|
||||
var ident =
|
||||
identifier || this.packaging.metadata.identifier || this.url.filename;
|
||||
return `epubjs:${EPUBJS_VERSION}:${ident}`;
|
||||
}
|
||||
|
||||
|
@ -759,7 +774,6 @@ class Book {
|
|||
this.path = undefined;
|
||||
this.archived = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-- Enable binding events to book
|
||||
|
|
|
@ -8,9 +8,9 @@ import {qs} from "./utils/core";
|
|||
*/
|
||||
class Container {
|
||||
constructor(containerDocument) {
|
||||
this.packagePath = '';
|
||||
this.directory = '';
|
||||
this.encoding = '';
|
||||
this.packagePath = "";
|
||||
this.directory = "";
|
||||
this.encoding = "";
|
||||
|
||||
if (containerDocument) {
|
||||
this.parse(containerDocument);
|
||||
|
|
217
src/contents.js
217
src/contents.js
|
@ -1,17 +1,17 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import {isNumber, prefixed, borders, defaults} from "./utils/core";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Mapping from "./mapping";
|
||||
import { DOM_EVENTS, EPUBJS_VERSION, EVENTS } from "./utils/constants";
|
||||
import { borders, defaults, isNumber, prefixed } from "./utils/core";
|
||||
import { replaceLinks } from "./utils/replacements";
|
||||
import { EPUBJS_VERSION, EVENTS, DOM_EVENTS } from "./utils/constants";
|
||||
|
||||
const hasNavigator = typeof (navigator) !== "undefined";
|
||||
const hasNavigator = typeof navigator !== "undefined";
|
||||
|
||||
const isChrome = hasNavigator && /Chrome/.test(navigator.userAgent);
|
||||
const isWebkit = hasNavigator && !isChrome && /AppleWebKit/.test(navigator.userAgent);
|
||||
const isWebkit =
|
||||
hasNavigator && !isChrome && /AppleWebKit/.test(navigator.userAgent);
|
||||
|
||||
const ELEMENT_NODE = 1;
|
||||
const TEXT_NODE = 3;
|
||||
|
||||
/**
|
||||
* Handles DOM manipulation, queries and events for View contents
|
||||
|
@ -33,7 +33,7 @@ class Contents {
|
|||
|
||||
this._size = {
|
||||
width: 0,
|
||||
height: 0
|
||||
height: 0,
|
||||
};
|
||||
|
||||
this.sectionIndex = sectionIndex || 0;
|
||||
|
@ -71,8 +71,6 @@ class Contents {
|
|||
}
|
||||
|
||||
return parseInt(this.window.getComputedStyle(frame)["width"]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +92,6 @@ class Contents {
|
|||
}
|
||||
|
||||
return parseInt(this.window.getComputedStyle(frame)["height"]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +100,6 @@ class Contents {
|
|||
* @returns {number} width
|
||||
*/
|
||||
contentWidth(w) {
|
||||
|
||||
var content = this.content || this.document.body;
|
||||
|
||||
if (w && isNumber(w)) {
|
||||
|
@ -115,8 +111,6 @@ class Contents {
|
|||
}
|
||||
|
||||
return parseInt(this.window.getComputedStyle(content)["width"]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,7 +119,6 @@ class Contents {
|
|||
* @returns {number} height
|
||||
*/
|
||||
contentHeight(h) {
|
||||
|
||||
var content = this.content || this.document.body;
|
||||
|
||||
if (h && isNumber(h)) {
|
||||
|
@ -137,7 +130,6 @@ class Contents {
|
|||
}
|
||||
|
||||
return parseInt(this.window.getComputedStyle(content)["height"]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,7 +200,6 @@ class Contents {
|
|||
* @param {string} [overflow]
|
||||
*/
|
||||
overflow(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflow = overflow;
|
||||
}
|
||||
|
@ -221,7 +212,6 @@ class Contents {
|
|||
* @param {string} [overflow]
|
||||
*/
|
||||
overflowX(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflowX = overflow;
|
||||
}
|
||||
|
@ -234,7 +224,6 @@ class Contents {
|
|||
* @param {string} [overflow]
|
||||
*/
|
||||
overflowY(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflowY = overflow;
|
||||
}
|
||||
|
@ -271,16 +260,15 @@ class Contents {
|
|||
* @param {string} [options.scalable]
|
||||
*/
|
||||
viewport(options) {
|
||||
var _width, _height, _scale, _minimum, _maximum, _scalable;
|
||||
// var width, height, scale, minimum, maximum, scalable;
|
||||
var $viewport = this.document.querySelector("meta[name='viewport']");
|
||||
var parsed = {
|
||||
"width": undefined,
|
||||
"height": undefined,
|
||||
"scale": undefined,
|
||||
"minimum": undefined,
|
||||
"maximum": undefined,
|
||||
"scalable": undefined
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
scale: undefined,
|
||||
minimum: undefined,
|
||||
maximum: undefined,
|
||||
scalable: undefined,
|
||||
};
|
||||
var newContent = [];
|
||||
var settings = {};
|
||||
|
@ -313,7 +301,11 @@ class Contents {
|
|||
if (_maximum && _maximum.length && typeof _maximum[1] !== "undefined") {
|
||||
parsed.maximum = _maximum[1];
|
||||
}
|
||||
if(_scalable && _scalable.length && typeof _scalable[1] !== "undefined"){
|
||||
if (
|
||||
_scalable &&
|
||||
_scalable.length &&
|
||||
typeof _scalable[1] !== "undefined"
|
||||
) {
|
||||
parsed.scalable = _scalable[1];
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +330,6 @@ class Contents {
|
|||
newContent.push("maximum-scale=" + settings.scale);
|
||||
newContent.push("user-scalable=" + settings.scalable);
|
||||
} else {
|
||||
|
||||
if (settings.scalable) {
|
||||
newContent.push("user-scalable=" + settings.scalable);
|
||||
}
|
||||
|
@ -363,7 +354,6 @@ class Contents {
|
|||
this.window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
@ -409,7 +399,6 @@ class Contents {
|
|||
* @private
|
||||
*/
|
||||
removeListeners() {
|
||||
|
||||
this.removeEventListeners();
|
||||
|
||||
this.removeSelectionListeners();
|
||||
|
@ -431,10 +420,9 @@ class Contents {
|
|||
let height = this.textHeight();
|
||||
|
||||
if (width != this._size.width || height != this._size.height) {
|
||||
|
||||
this._size = {
|
||||
width: width,
|
||||
height: height
|
||||
height: height,
|
||||
};
|
||||
|
||||
this.onResize && this.onResize(this._size);
|
||||
|
@ -447,7 +435,6 @@ class Contents {
|
|||
* @private
|
||||
*/
|
||||
resizeListeners() {
|
||||
var width, height;
|
||||
// Test size again
|
||||
clearTimeout(this.expanding);
|
||||
requestAnimationFrame(this.resizeCheck.bind(this));
|
||||
|
@ -477,13 +464,14 @@ class Contents {
|
|||
transitionListeners() {
|
||||
let body = this.content;
|
||||
|
||||
body.style['transitionProperty'] = "font, font-size, font-size-adjust, font-stretch, font-variation-settings, font-weight, width, height";
|
||||
body.style['transitionDuration'] = "0.001ms";
|
||||
body.style['transitionTimingFunction'] = "linear";
|
||||
body.style['transitionDelay'] = "0";
|
||||
body.style["transitionProperty"] =
|
||||
"font, font-size, font-size-adjust, font-stretch, font-variation-settings, font-weight, width, height";
|
||||
body.style["transitionDuration"] = "0.001ms";
|
||||
body.style["transitionTimingFunction"] = "linear";
|
||||
body.style["transitionDelay"] = "0";
|
||||
|
||||
this._resizeCheck = this.resizeCheck.bind(this);
|
||||
this.document.addEventListener('transitionend', this._resizeCheck);
|
||||
this.document.addEventListener("transitionend", this._resizeCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,7 +532,12 @@ class Contents {
|
|||
});
|
||||
|
||||
// configuration of the observer:
|
||||
let config = { attributes: true, childList: true, characterData: true, subtree: true };
|
||||
let config = {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
subtree: true,
|
||||
};
|
||||
|
||||
// pass in the target node, as well as the observer options
|
||||
this.observer.observe(this.document, config);
|
||||
|
@ -560,8 +553,7 @@ class Contents {
|
|||
for (var i = 0; i < images.length; i++) {
|
||||
img = images[i];
|
||||
|
||||
if (typeof img.naturalWidth !== "undefined" &&
|
||||
img.naturalWidth === 0) {
|
||||
if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) {
|
||||
img.onload = this.expand.bind(this);
|
||||
}
|
||||
}
|
||||
|
@ -576,10 +568,11 @@ class Contents {
|
|||
return;
|
||||
}
|
||||
|
||||
this.document.fonts.ready.then(function () {
|
||||
this.document.fonts.ready.then(
|
||||
function () {
|
||||
this.resizeCheck();
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -599,7 +592,7 @@ class Contents {
|
|||
*/
|
||||
locationOf(target, ignoreClass) {
|
||||
var position;
|
||||
var targetPos = {"left": 0, "top": 0};
|
||||
var targetPos = { left: 0, top: 0 };
|
||||
|
||||
if (!this.document) return targetPos;
|
||||
|
||||
|
@ -608,21 +601,29 @@ class Contents {
|
|||
|
||||
if (range) {
|
||||
try {
|
||||
if (!range.endContainer ||
|
||||
(range.startContainer == range.endContainer
|
||||
&& range.startOffset == range.endOffset)) {
|
||||
if (
|
||||
!range.endContainer ||
|
||||
(range.startContainer == range.endContainer &&
|
||||
range.startOffset == range.endOffset)
|
||||
) {
|
||||
// If the end for the range is not set, it results in collapsed becoming
|
||||
// true. This in turn leads to inconsistent behaviour when calling
|
||||
// getBoundingRect. Wrong bounds lead to the wrong page being displayed.
|
||||
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/15684911/
|
||||
let pos = range.startContainer.textContent.indexOf(" ", range.startOffset);
|
||||
let pos = range.startContainer.textContent.indexOf(
|
||||
" ",
|
||||
range.startOffset
|
||||
);
|
||||
if (pos == -1) {
|
||||
pos = range.startContainer.textContent.length;
|
||||
}
|
||||
range.setEnd(range.startContainer, pos);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("setting end offset to start container length failed", e);
|
||||
console.error(
|
||||
"setting end offset to start container length failed",
|
||||
e
|
||||
);
|
||||
}
|
||||
|
||||
if (range.startContainer.nodeType === Node.ELEMENT_NODE) {
|
||||
|
@ -648,7 +649,8 @@ class Contents {
|
|||
newRange.setStart(container, range.startOffset - 2);
|
||||
newRange.setEnd(container, range.startOffset);
|
||||
position = newRange.getBoundingClientRect();
|
||||
} else { // empty, return the parent element
|
||||
} else {
|
||||
// empty, return the parent element
|
||||
position = container.parentNode.getBoundingClientRect();
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -659,10 +661,7 @@ class Contents {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if(typeof target === "string" &&
|
||||
target.indexOf("#") > -1) {
|
||||
|
||||
} else if (typeof target === "string" && target.indexOf("#") > -1) {
|
||||
let id = target.substring(target.indexOf("#") + 1);
|
||||
let el = this.document.getElementById(id);
|
||||
if (el) {
|
||||
|
@ -690,7 +689,8 @@ class Contents {
|
|||
* @param {string} src url
|
||||
*/
|
||||
addStylesheet(src) {
|
||||
return new Promise(function(resolve, reject){
|
||||
return new Promise(
|
||||
function (resolve, reject) {
|
||||
var $stylesheet;
|
||||
var ready = false;
|
||||
|
||||
|
@ -721,13 +721,13 @@ class Contents {
|
|||
};
|
||||
|
||||
this.document.head.appendChild($stylesheet);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
_getStylesheetNode(key) {
|
||||
var styleEl;
|
||||
key = "epubjs-inserted-css-" + (key || '');
|
||||
key = "epubjs-inserted-css-" + (key || "");
|
||||
|
||||
if (!this.document) return false;
|
||||
|
||||
|
@ -774,7 +774,10 @@ class Contents {
|
|||
|
||||
if (Object.prototype.toString.call(rules) === "[object Array]") {
|
||||
for (var i = 0, rl = rules.length; i < rl; i++) {
|
||||
var j = 1, rule = rules[i], selector = rules[i][0], propStr = "";
|
||||
var j = 1,
|
||||
rule = rules[i],
|
||||
selector = rules[i][0],
|
||||
propStr = "";
|
||||
// If the second argument of a rule is an array of arrays, correct our variables.
|
||||
if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") {
|
||||
rule = rule[1];
|
||||
|
@ -783,11 +786,15 @@ class Contents {
|
|||
|
||||
for (var pl = rule.length; j < pl; j++) {
|
||||
var prop = rule[j];
|
||||
propStr += prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n";
|
||||
propStr +=
|
||||
prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n";
|
||||
}
|
||||
|
||||
// Insert CSS Rule
|
||||
styleSheet.insertRule(selector + "{" + propStr + "}", styleSheet.cssRules.length);
|
||||
styleSheet.insertRule(
|
||||
selector + "{" + propStr + "}",
|
||||
styleSheet.cssRules.length
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const selectors = Object.keys(rules);
|
||||
|
@ -796,17 +803,27 @@ class Contents {
|
|||
if (Array.isArray(definition)) {
|
||||
definition.forEach((item) => {
|
||||
const _rules = Object.keys(item);
|
||||
const result = _rules.map((rule) => {
|
||||
const result = _rules
|
||||
.map((rule) => {
|
||||
return `${rule}:${item[rule]}`;
|
||||
}).join(';');
|
||||
styleSheet.insertRule(`${selector}{${result}}`, styleSheet.cssRules.length);
|
||||
})
|
||||
.join(";");
|
||||
styleSheet.insertRule(
|
||||
`${selector}{${result}}`,
|
||||
styleSheet.cssRules.length
|
||||
);
|
||||
});
|
||||
} else {
|
||||
const _rules = Object.keys(definition);
|
||||
const result = _rules.map((rule) => {
|
||||
const result = _rules
|
||||
.map((rule) => {
|
||||
return `${rule}:${definition[rule]}`;
|
||||
}).join(';');
|
||||
styleSheet.insertRule(`${selector}{${result}}`, styleSheet.cssRules.length);
|
||||
})
|
||||
.join(";");
|
||||
styleSheet.insertRule(
|
||||
`${selector}{${result}}`,
|
||||
styleSheet.cssRules.length
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -818,8 +835,8 @@ class Contents {
|
|||
* @returns {Promise} loaded
|
||||
*/
|
||||
addScript(src) {
|
||||
|
||||
return new Promise(function(resolve, reject){
|
||||
return new Promise(
|
||||
function (resolve, reject) {
|
||||
var $script;
|
||||
var ready = false;
|
||||
|
||||
|
@ -842,8 +859,8 @@ class Contents {
|
|||
};
|
||||
|
||||
this.document.head.appendChild($script);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -860,7 +877,6 @@ class Contents {
|
|||
if (content) {
|
||||
content.classList.add(className);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -877,7 +893,6 @@ class Contents {
|
|||
if (content) {
|
||||
content.classList.remove(className);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -892,9 +907,10 @@ class Contents {
|
|||
this._triggerEvent = this.triggerEvent.bind(this);
|
||||
|
||||
DOM_EVENTS.forEach(function (eventName) {
|
||||
this.document.addEventListener(eventName, this._triggerEvent, { passive: true });
|
||||
this.document.addEventListener(eventName, this._triggerEvent, {
|
||||
passive: true,
|
||||
});
|
||||
}, this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -906,7 +922,9 @@ class Contents {
|
|||
return;
|
||||
}
|
||||
DOM_EVENTS.forEach(function (eventName) {
|
||||
this.document.removeEventListener(eventName, this._triggerEvent, { passive: true });
|
||||
this.document.removeEventListener(eventName, this._triggerEvent, {
|
||||
passive: true,
|
||||
});
|
||||
}, this);
|
||||
this._triggerEvent = undefined;
|
||||
}
|
||||
|
@ -928,7 +946,9 @@ class Contents {
|
|||
return;
|
||||
}
|
||||
this._onSelectionChange = this.onSelectionChange.bind(this);
|
||||
this.document.addEventListener("selectionchange", this._onSelectionChange, { passive: true });
|
||||
this.document.addEventListener("selectionchange", this._onSelectionChange, {
|
||||
passive: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -939,7 +959,11 @@ class Contents {
|
|||
if (!this.document) {
|
||||
return;
|
||||
}
|
||||
this.document.removeEventListener("selectionchange", this._onSelectionChange, { passive: true });
|
||||
this.document.removeEventListener(
|
||||
"selectionchange",
|
||||
this._onSelectionChange,
|
||||
{ passive: true }
|
||||
);
|
||||
this._onSelectionChange = undefined;
|
||||
}
|
||||
|
||||
|
@ -951,10 +975,13 @@ class Contents {
|
|||
if (this.selectionEndTimeout) {
|
||||
clearTimeout(this.selectionEndTimeout);
|
||||
}
|
||||
this.selectionEndTimeout = setTimeout(function() {
|
||||
this.selectionEndTimeout = setTimeout(
|
||||
function () {
|
||||
var selection = this.window.getSelection();
|
||||
this.triggerSelectedEvent(selection);
|
||||
}.bind(this), 250);
|
||||
}.bind(this),
|
||||
250
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1025,7 +1052,7 @@ class Contents {
|
|||
if (width >= 0) {
|
||||
this.width(width);
|
||||
viewport.width = width;
|
||||
this.css("padding", "0 "+(width/12)+"px");
|
||||
this.css("padding", "0 " + width / 12 + "px");
|
||||
}
|
||||
|
||||
if (height >= 0) {
|
||||
|
@ -1036,7 +1063,6 @@ class Contents {
|
|||
this.css("margin", "0");
|
||||
this.css("box-sizing", "border-box");
|
||||
|
||||
|
||||
this.viewport(viewport);
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1080,8 @@ class Contents {
|
|||
let COLUMN_FILL = prefixed("column-fill");
|
||||
|
||||
let writingMode = this.writingMode();
|
||||
let axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
|
||||
let axis =
|
||||
writingMode.indexOf("vertical") === 0 ? "vertical" : "horizontal";
|
||||
|
||||
this.layoutStyle("paginated");
|
||||
|
||||
|
@ -1076,16 +1103,16 @@ class Contents {
|
|||
this.css("margin", "0", true);
|
||||
|
||||
if (axis === "vertical") {
|
||||
this.css("padding-top", (gap / 2) + "px", true);
|
||||
this.css("padding-bottom", (gap / 2) + "px", true);
|
||||
this.css("padding-top", gap / 2 + "px", true);
|
||||
this.css("padding-bottom", gap / 2 + "px", true);
|
||||
this.css("padding-left", "20px");
|
||||
this.css("padding-right", "20px");
|
||||
this.css(COLUMN_AXIS, "vertical");
|
||||
} else {
|
||||
this.css("padding-top", "20px");
|
||||
this.css("padding-bottom", "20px");
|
||||
this.css("padding-left", (gap / 2) + "px", true);
|
||||
this.css("padding-right", (gap / 2) + "px", true);
|
||||
this.css("padding-left", gap / 2 + "px", true);
|
||||
this.css("padding-right", gap / 2 + "px", true);
|
||||
this.css(COLUMN_AXIS, "horizontal");
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1142,8 @@ class Contents {
|
|||
this.css("transform-origin", "top left");
|
||||
|
||||
if (offsetX >= 0 || offsetY >= 0) {
|
||||
translateStr = " translate(" + (offsetX || 0 )+ "px, " + (offsetY || 0 )+ "px )";
|
||||
translateStr =
|
||||
" translate(" + (offsetX || 0) + "px, " + (offsetY || 0) + "px )";
|
||||
}
|
||||
|
||||
this.css("transform", scaleStr + translateStr);
|
||||
|
@ -1153,12 +1181,15 @@ class Contents {
|
|||
// this.scaler(scale, offsetX > 0 ? offsetX : 0, offsetY);
|
||||
|
||||
// background images are not scaled by transform
|
||||
this.css("background-size", viewportWidth * scale + "px " + viewportHeight * scale + "px");
|
||||
this.css(
|
||||
"background-size",
|
||||
viewportWidth * scale + "px " + viewportHeight * scale + "px"
|
||||
);
|
||||
|
||||
this.css("background-color", "transparent");
|
||||
if (section && section.properties.includes("page-spread-left")) {
|
||||
// set margin since scale is weird
|
||||
var marginLeft = width - (viewportWidth * scale);
|
||||
var marginLeft = width - viewportWidth * scale;
|
||||
this.css("margin-left", marginLeft + "px");
|
||||
}
|
||||
}
|
||||
|
@ -1200,7 +1231,9 @@ class Contents {
|
|||
this.documentElement.style[WRITING_MODE] = mode;
|
||||
}
|
||||
|
||||
return this.window.getComputedStyle(this.documentElement)[WRITING_MODE] || '';
|
||||
return (
|
||||
this.window.getComputedStyle(this.documentElement)[WRITING_MODE] || ""
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1209,7 +1242,6 @@ class Contents {
|
|||
* @private
|
||||
*/
|
||||
layoutStyle(style) {
|
||||
|
||||
if (style) {
|
||||
this._layoutStyle = style;
|
||||
navigator.epubReadingSystem.layoutStyle = this._layoutStyle;
|
||||
|
@ -1246,7 +1278,7 @@ class Contents {
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
return navigator.epubReadingSystem;
|
||||
}
|
||||
|
@ -1255,7 +1287,6 @@ class Contents {
|
|||
// this.document.removeEventListener('transitionend', this._resizeCheck);
|
||||
|
||||
this.removeListeners();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
src/epub.js
12
src/epub.js
|
@ -1,13 +1,9 @@
|
|||
import Book from "./book";
|
||||
import Rendition from "./rendition";
|
||||
import CFI from "./epubcfi";
|
||||
import Contents from "./contents";
|
||||
import * as utils from "./utils/core";
|
||||
import CFI from "./epubcfi";
|
||||
import Rendition from "./rendition";
|
||||
import { EPUBJS_VERSION } from "./utils/constants";
|
||||
|
||||
import IframeView from "./managers/views/iframe";
|
||||
import DefaultViewManager from "./managers/default";
|
||||
import ContinuousViewManager from "./managers/continuous";
|
||||
import * as utils from "./utils/core";
|
||||
|
||||
/**
|
||||
* Creates a new Book
|
||||
|
@ -22,7 +18,7 @@ function ePub(url, options) {
|
|||
|
||||
ePub.VERSION = EPUBJS_VERSION;
|
||||
|
||||
if (typeof(global) !== "undefined") {
|
||||
if (typeof global !== "undefined") {
|
||||
global.EPUBJS_VERSION = EPUBJS_VERSION;
|
||||
}
|
||||
|
||||
|
|
224
src/epubcfi.js
224
src/epubcfi.js
|
@ -1,8 +1,13 @@
|
|||
import {extend, type, findChildren, RangeObject, isNumber} from "./utils/core";
|
||||
import {
|
||||
RangeObject,
|
||||
extend,
|
||||
findChildren,
|
||||
isNumber,
|
||||
type,
|
||||
} from "./utils/core";
|
||||
|
||||
const ELEMENT_NODE = 1;
|
||||
const TEXT_NODE = 3;
|
||||
const COMMENT_NODE = 8;
|
||||
const DOCUMENT_NODE = 9;
|
||||
|
||||
/**
|
||||
|
@ -50,7 +55,6 @@ class EpubCFI {
|
|||
|
||||
type = this.checkType(cfiFrom);
|
||||
|
||||
|
||||
if (type === "string") {
|
||||
this.str = cfiFrom;
|
||||
return extend(this, this.parse(cfiFrom));
|
||||
|
@ -65,7 +69,6 @@ class EpubCFI {
|
|||
} else {
|
||||
throw new TypeError("not a valid argument for EpubCFI");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,13 +76,21 @@ class EpubCFI {
|
|||
* @private
|
||||
*/
|
||||
checkType(cfi) {
|
||||
|
||||
if (this.isCfiString(cfi)) {
|
||||
return "string";
|
||||
// Is a range object
|
||||
} else if (cfi && typeof cfi === "object" && (type(cfi) === "Range" || typeof(cfi.startContainer) != "undefined")){
|
||||
} else if (
|
||||
cfi &&
|
||||
typeof cfi === "object" &&
|
||||
(type(cfi) === "Range" || typeof cfi.startContainer != "undefined")
|
||||
) {
|
||||
return "range";
|
||||
} else if (cfi && typeof cfi === "object" && typeof(cfi.nodeType) != "undefined" ){ // || typeof cfi === "function"
|
||||
} else if (
|
||||
cfi &&
|
||||
typeof cfi === "object" &&
|
||||
typeof cfi.nodeType != "undefined"
|
||||
) {
|
||||
// || typeof cfi === "function"
|
||||
return "node";
|
||||
} else if (cfi && typeof cfi === "object" && cfi instanceof EpubCFI) {
|
||||
return "EpubCFI";
|
||||
|
@ -100,7 +111,7 @@ class EpubCFI {
|
|||
base: {},
|
||||
path: {},
|
||||
start: null,
|
||||
end: null
|
||||
end: null,
|
||||
};
|
||||
var baseComponent, pathComponent, range;
|
||||
|
||||
|
@ -147,8 +158,8 @@ class EpubCFI {
|
|||
steps: [],
|
||||
terminal: {
|
||||
offset: null,
|
||||
assertion: null
|
||||
}
|
||||
assertion: null,
|
||||
},
|
||||
};
|
||||
var parts = componentStr.split(":");
|
||||
var steps = parts[0].split("/");
|
||||
|
@ -163,9 +174,11 @@ class EpubCFI {
|
|||
steps.shift(); // Ignore the first slash
|
||||
}
|
||||
|
||||
component.steps = steps.map(function(step){
|
||||
component.steps = steps.map(
|
||||
function (step) {
|
||||
return this.parseStep(step);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
@ -185,7 +198,8 @@ class EpubCFI {
|
|||
return;
|
||||
}
|
||||
|
||||
if(num % 2 === 0) { // Even = is an element
|
||||
if (num % 2 === 0) {
|
||||
// Even = is an element
|
||||
type = "element";
|
||||
index = num / 2 - 1;
|
||||
} else {
|
||||
|
@ -194,9 +208,9 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
return {
|
||||
"type" : type,
|
||||
"index" : index,
|
||||
"id" : id || null
|
||||
type: type,
|
||||
index: index,
|
||||
id: id || null,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -216,39 +230,31 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
return {
|
||||
"offset": characterOffset,
|
||||
"assertion": textLocationAssertion
|
||||
offset: characterOffset,
|
||||
assertion: textLocationAssertion,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
getChapterComponent(cfiStr) {
|
||||
|
||||
var indirection = cfiStr.split("!");
|
||||
|
||||
return indirection[0];
|
||||
}
|
||||
|
||||
getPathComponent(cfiStr) {
|
||||
|
||||
var indirection = cfiStr.split("!");
|
||||
|
||||
if (indirection[1]) {
|
||||
let ranges = indirection[1].split(",");
|
||||
return ranges[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getRange(cfiStr) {
|
||||
|
||||
var ranges = cfiStr.split(",");
|
||||
|
||||
if (ranges.length === 3) {
|
||||
return [
|
||||
ranges[1],
|
||||
ranges[2]
|
||||
];
|
||||
return [ranges[1], ranges[2]];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -264,7 +270,8 @@ class EpubCFI {
|
|||
return "";
|
||||
}
|
||||
|
||||
return steps.map(function(part){
|
||||
return steps
|
||||
.map(function (part) {
|
||||
var segment = "";
|
||||
|
||||
if (part.type === "element") {
|
||||
|
@ -272,7 +279,7 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
if (part.type === "text") {
|
||||
segment += 1 + (2 * part.index); // TODO: double check that this is odd
|
||||
segment += 1 + 2 * part.index; // TODO: double check that this is odd
|
||||
}
|
||||
|
||||
if (part.id) {
|
||||
|
@ -280,9 +287,8 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
return segment;
|
||||
|
||||
}).join("/");
|
||||
|
||||
})
|
||||
.join("/");
|
||||
}
|
||||
|
||||
segmentString(segment) {
|
||||
|
@ -329,7 +335,6 @@ class EpubCFI {
|
|||
return cfiString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare which of two CFIs is earlier in the text
|
||||
* @returns {number} First is earlier = -1, Second is earlier = 1, They are equal = 0
|
||||
|
@ -338,11 +343,6 @@ class EpubCFI {
|
|||
var stepsA, stepsB;
|
||||
var terminalA, terminalB;
|
||||
|
||||
var rangeAStartSteps, rangeAEndSteps;
|
||||
var rangeBEndSteps, rangeBEndSteps;
|
||||
var rangeAStartTerminal, rangeAEndTerminal;
|
||||
var rangeBStartTerminal, rangeBEndTerminal;
|
||||
|
||||
if (typeof cfiOne === "string") {
|
||||
cfiOne = new EpubCFI(cfiOne);
|
||||
}
|
||||
|
@ -408,13 +408,13 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
step(node) {
|
||||
var nodeType = (node.nodeType === TEXT_NODE) ? "text" : "element";
|
||||
var nodeType = node.nodeType === TEXT_NODE ? "text" : "element";
|
||||
|
||||
return {
|
||||
"id" : node.id,
|
||||
"tagName" : node.tagName,
|
||||
"type" : nodeType,
|
||||
"index" : this.position(node)
|
||||
id: node.id,
|
||||
tagName: node.tagName,
|
||||
type: nodeType,
|
||||
index: this.position(node),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -428,13 +428,13 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
// Otherwise add the filter node in
|
||||
nodeType = (filteredNode.nodeType === TEXT_NODE) ? "text" : "element";
|
||||
nodeType = filteredNode.nodeType === TEXT_NODE ? "text" : "element";
|
||||
|
||||
return {
|
||||
"id" : filteredNode.id,
|
||||
"tagName" : filteredNode.tagName,
|
||||
"type" : nodeType,
|
||||
"index" : this.filteredPosition(filteredNode, ignoreClass)
|
||||
id: filteredNode.id,
|
||||
tagName: filteredNode.tagName,
|
||||
type: nodeType,
|
||||
index: this.filteredPosition(filteredNode, ignoreClass),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -443,15 +443,17 @@ class EpubCFI {
|
|||
steps: [],
|
||||
terminal: {
|
||||
offset: null,
|
||||
assertion: null
|
||||
}
|
||||
assertion: null,
|
||||
},
|
||||
};
|
||||
var currentNode = node;
|
||||
var step;
|
||||
|
||||
while(currentNode && currentNode.parentNode &&
|
||||
currentNode.parentNode.nodeType != DOCUMENT_NODE) {
|
||||
|
||||
while (
|
||||
currentNode &&
|
||||
currentNode.parentNode &&
|
||||
currentNode.parentNode.nodeType != DOCUMENT_NODE
|
||||
) {
|
||||
if (ignoreClass) {
|
||||
step = this.filteredStep(currentNode, ignoreClass);
|
||||
} else {
|
||||
|
@ -463,24 +465,20 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
currentNode = currentNode.parentNode;
|
||||
|
||||
}
|
||||
|
||||
if (offset != null && offset >= 0) {
|
||||
|
||||
segment.terminal.offset = offset;
|
||||
|
||||
// Make sure we are getting to a textNode if there is an offset
|
||||
if (segment.steps[segment.steps.length - 1].type != "text") {
|
||||
segment.steps.push({
|
||||
"type" : "text",
|
||||
"index" : 0
|
||||
type: "text",
|
||||
index: 0,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
|
@ -489,9 +487,11 @@ class EpubCFI {
|
|||
return false;
|
||||
}
|
||||
|
||||
if(stepA.index === stepB.index &&
|
||||
if (
|
||||
stepA.index === stepB.index &&
|
||||
stepA.id === stepB.id &&
|
||||
stepA.type === stepB.type) {
|
||||
stepA.type === stepB.type
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -511,7 +511,7 @@ class EpubCFI {
|
|||
base: {},
|
||||
path: {},
|
||||
start: null,
|
||||
end: null
|
||||
end: null,
|
||||
};
|
||||
|
||||
var start = range.startContainer;
|
||||
|
@ -524,10 +524,10 @@ class EpubCFI {
|
|||
|
||||
if (ignoreClass) {
|
||||
// Tell pathTo if / what to ignore
|
||||
needsIgnoring = (start.ownerDocument.querySelector("." + ignoreClass) != null);
|
||||
needsIgnoring =
|
||||
start.ownerDocument.querySelector("." + ignoreClass) != null;
|
||||
}
|
||||
|
||||
|
||||
if (typeof base === "string") {
|
||||
cfi.base = this.parseComponent(base);
|
||||
cfi.spinePos = cfi.base.steps[1].index;
|
||||
|
@ -557,7 +557,7 @@ class EpubCFI {
|
|||
// Create a new empty path
|
||||
cfi.path = {
|
||||
steps: [],
|
||||
terminal: null
|
||||
terminal: null,
|
||||
};
|
||||
|
||||
// Push steps that are shared between start and end to the common path
|
||||
|
@ -577,7 +577,6 @@ class EpubCFI {
|
|||
} else {
|
||||
cfi.path.steps.push(cfi.start.steps[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -605,7 +604,7 @@ class EpubCFI {
|
|||
base: {},
|
||||
path: {},
|
||||
start: null,
|
||||
end: null
|
||||
end: null,
|
||||
};
|
||||
|
||||
if (typeof base === "string") {
|
||||
|
@ -652,7 +651,6 @@ class EpubCFI {
|
|||
// Parent will be ignored on next step
|
||||
return anchor;
|
||||
}
|
||||
|
||||
} else if (needsIgnoring && !isText) {
|
||||
// Otherwise just skip the element node
|
||||
return false;
|
||||
|
@ -660,7 +658,6 @@ class EpubCFI {
|
|||
// No need to filter
|
||||
return anchor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
patchOffset(anchor, offset, ignoreClass) {
|
||||
|
@ -693,29 +690,28 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
return totalOffset;
|
||||
|
||||
}
|
||||
|
||||
normalizedMap(children, nodeType, ignoreClass) {
|
||||
var output = {};
|
||||
var prevIndex = -1;
|
||||
var i, len = children.length;
|
||||
var i,
|
||||
len = children.length;
|
||||
var currNodeType;
|
||||
var prevNodeType;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
currNodeType = children[i].nodeType;
|
||||
|
||||
// Check if needs ignoring
|
||||
if (currNodeType === ELEMENT_NODE &&
|
||||
children[i].classList.contains(ignoreClass)) {
|
||||
if (
|
||||
currNodeType === ELEMENT_NODE &&
|
||||
children[i].classList.contains(ignoreClass)
|
||||
) {
|
||||
currNodeType = TEXT_NODE;
|
||||
}
|
||||
|
||||
if (i > 0 &&
|
||||
currNodeType === TEXT_NODE &&
|
||||
prevNodeType === TEXT_NODE) {
|
||||
if (i > 0 && currNodeType === TEXT_NODE && prevNodeType === TEXT_NODE) {
|
||||
// join text nodes
|
||||
output[i] = prevIndex;
|
||||
} else if (nodeType === currNodeType) {
|
||||
|
@ -724,7 +720,6 @@ class EpubCFI {
|
|||
}
|
||||
|
||||
prevNodeType = currNodeType;
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
@ -762,7 +757,6 @@ class EpubCFI {
|
|||
map = this.normalizedMap(children, TEXT_NODE, ignoreClass);
|
||||
}
|
||||
|
||||
|
||||
index = Array.prototype.indexOf.call(children, anchor);
|
||||
|
||||
return map[index];
|
||||
|
@ -786,7 +780,6 @@ class EpubCFI {
|
|||
return xpath.join("/");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
To get the last step if needed:
|
||||
|
@ -819,12 +812,12 @@ class EpubCFI {
|
|||
});
|
||||
|
||||
return query.join(">");
|
||||
|
||||
}
|
||||
|
||||
textNodes(container, ignoreClass) {
|
||||
return Array.prototype.slice.call(container.childNodes).
|
||||
filter(function (node) {
|
||||
return Array.prototype.slice
|
||||
.call(container.childNodes)
|
||||
.filter(function (node) {
|
||||
if (node.nodeType === TEXT_NODE) {
|
||||
return true;
|
||||
} else if (ignoreClass && node.classList.contains(ignoreClass)) {
|
||||
|
@ -850,8 +843,7 @@ class EpubCFI {
|
|||
//For ex.https://github.com/futurepress/epub.js/issues/561
|
||||
if (step.id) {
|
||||
container = doc.getElementById(step.id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
children = container.children || findChildren(container);
|
||||
container = children[step.index];
|
||||
}
|
||||
|
@ -864,7 +856,6 @@ class EpubCFI {
|
|||
//like navigation
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return container;
|
||||
|
@ -877,7 +868,13 @@ class EpubCFI {
|
|||
|
||||
if (!ignoreClass && typeof doc.evaluate != "undefined") {
|
||||
xpath = this.stepsToXpath(steps);
|
||||
container = doc.evaluate(xpath, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
|
||||
container = doc.evaluate(
|
||||
xpath,
|
||||
doc,
|
||||
null,
|
||||
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
||||
null
|
||||
).singleNodeValue;
|
||||
} else if (ignoreClass) {
|
||||
container = this.walkToNode(steps, doc, ignoreClass);
|
||||
} else {
|
||||
|
@ -916,9 +913,8 @@ class EpubCFI {
|
|||
|
||||
return {
|
||||
container: container,
|
||||
offset: offset
|
||||
offset: offset,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -933,10 +929,12 @@ class EpubCFI {
|
|||
var start, end, startContainer, endContainer;
|
||||
var cfi = this;
|
||||
var startSteps, endSteps;
|
||||
var needsIgnoring = ignoreClass ? (doc.querySelector("." + ignoreClass) != null) : false;
|
||||
var needsIgnoring = ignoreClass
|
||||
? doc.querySelector("." + ignoreClass) != null
|
||||
: false;
|
||||
var missed;
|
||||
|
||||
if (typeof(doc.createRange) !== "undefined") {
|
||||
if (typeof doc.createRange !== "undefined") {
|
||||
range = doc.createRange();
|
||||
} else {
|
||||
range = new RangeObject();
|
||||
|
@ -945,27 +943,42 @@ class EpubCFI {
|
|||
if (cfi.range) {
|
||||
start = cfi.start;
|
||||
startSteps = cfi.path.steps.concat(start.steps);
|
||||
startContainer = this.findNode(startSteps, doc, needsIgnoring ? ignoreClass : null);
|
||||
startContainer = this.findNode(
|
||||
startSteps,
|
||||
doc,
|
||||
needsIgnoring ? ignoreClass : null
|
||||
);
|
||||
end = cfi.end;
|
||||
endSteps = cfi.path.steps.concat(end.steps);
|
||||
endContainer = this.findNode(endSteps, doc, needsIgnoring ? ignoreClass : null);
|
||||
endContainer = this.findNode(
|
||||
endSteps,
|
||||
doc,
|
||||
needsIgnoring ? ignoreClass : null
|
||||
);
|
||||
} else {
|
||||
start = cfi.path;
|
||||
startSteps = cfi.path.steps;
|
||||
startContainer = this.findNode(cfi.path.steps, doc, needsIgnoring ? ignoreClass : null);
|
||||
startContainer = this.findNode(
|
||||
cfi.path.steps,
|
||||
doc,
|
||||
needsIgnoring ? ignoreClass : null
|
||||
);
|
||||
}
|
||||
|
||||
if (startContainer) {
|
||||
try {
|
||||
|
||||
if (start.terminal.offset != null) {
|
||||
range.setStart(startContainer, start.terminal.offset);
|
||||
} else {
|
||||
range.setStart(startContainer, 0);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
missed = this.fixMiss(startSteps, start.terminal.offset, doc, needsIgnoring ? ignoreClass : null);
|
||||
missed = this.fixMiss(
|
||||
startSteps,
|
||||
start.terminal.offset,
|
||||
doc,
|
||||
needsIgnoring ? ignoreClass : null
|
||||
);
|
||||
range.setStart(missed.container, missed.offset);
|
||||
}
|
||||
} else {
|
||||
|
@ -976,20 +989,22 @@ class EpubCFI {
|
|||
|
||||
if (endContainer) {
|
||||
try {
|
||||
|
||||
if (end.terminal.offset != null) {
|
||||
range.setEnd(endContainer, end.terminal.offset);
|
||||
} else {
|
||||
range.setEnd(endContainer, 0);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
missed = this.fixMiss(endSteps, cfi.end.terminal.offset, doc, needsIgnoring ? ignoreClass : null);
|
||||
missed = this.fixMiss(
|
||||
endSteps,
|
||||
cfi.end.terminal.offset,
|
||||
doc,
|
||||
needsIgnoring ? ignoreClass : null
|
||||
);
|
||||
range.setEnd(missed.container, missed.offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// doc.defaultView.getSelection().addRange(range);
|
||||
return range;
|
||||
}
|
||||
|
@ -1000,9 +1015,11 @@ class EpubCFI {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
isCfiString(str) {
|
||||
if(typeof str === "string" &&
|
||||
if (
|
||||
typeof str === "string" &&
|
||||
str.indexOf("epubcfi(") === 0 &&
|
||||
str[str.length-1] === ")") {
|
||||
str[str.length - 1] === ")"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1058,6 @@ class EpubCFI {
|
|||
this.path.steps = this.path.steps.concat(this.end.steps);
|
||||
this.path.terminal = this.end.terminal;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
src/index.js
14
src/index.js
|
@ -1,15 +1,9 @@
|
|||
import Book from "./book";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Rendition from "./rendition";
|
||||
import Contents from "./contents";
|
||||
import Layout from "./layout";
|
||||
import ePub from "./epub";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Layout from "./layout";
|
||||
import Rendition from "./rendition";
|
||||
|
||||
export default ePub;
|
||||
export {
|
||||
Book,
|
||||
EpubCFI,
|
||||
Rendition,
|
||||
Contents,
|
||||
Layout
|
||||
};
|
||||
export { Book, Contents, EpubCFI, Layout, Rendition };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { extend } from "./utils/core";
|
||||
import { EVENTS } from "./utils/constants";
|
||||
import EventEmitter from "event-emitter";
|
||||
import { EVENTS } from "./utils/constants";
|
||||
import { extend } from "./utils/core";
|
||||
|
||||
/**
|
||||
* Figures out the CSS values to apply for a layout
|
||||
|
@ -15,19 +15,20 @@ class Layout {
|
|||
constructor(settings) {
|
||||
this.settings = settings;
|
||||
this.name = settings.layout || "reflowable";
|
||||
this._spread = (settings.spread === "none") ? false : true;
|
||||
this._spread = settings.spread === "none" ? false : true;
|
||||
this._minSpreadWidth = settings.minSpreadWidth || 800;
|
||||
this._evenSpreads = settings.evenSpreads || false;
|
||||
|
||||
if (settings.flow === "scrolled" ||
|
||||
if (
|
||||
settings.flow === "scrolled" ||
|
||||
settings.flow === "scrolled-continuous" ||
|
||||
settings.flow === "scrolled-doc") {
|
||||
settings.flow === "scrolled-doc"
|
||||
) {
|
||||
this._flow = "scrolled";
|
||||
} else {
|
||||
this._flow = "paginated";
|
||||
}
|
||||
|
||||
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.spreadWidth = 0;
|
||||
|
@ -47,9 +48,8 @@ class Layout {
|
|||
delta: 0,
|
||||
columnWidth: 0,
|
||||
gap: 0,
|
||||
divisor: 1
|
||||
divisor: 1,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,10 +58,12 @@ class Layout {
|
|||
* @return {string} simplified flow
|
||||
*/
|
||||
flow(flow) {
|
||||
if (typeof(flow) != "undefined") {
|
||||
if (flow === "scrolled" ||
|
||||
if (typeof flow != "undefined") {
|
||||
if (
|
||||
flow === "scrolled" ||
|
||||
flow === "scrolled-continuous" ||
|
||||
flow === "scrolled-doc") {
|
||||
flow === "scrolled-doc"
|
||||
) {
|
||||
this._flow = "scrolled";
|
||||
} else {
|
||||
this._flow = "paginated";
|
||||
|
@ -80,9 +82,8 @@ class Layout {
|
|||
* @return {boolean} spread true | false
|
||||
*/
|
||||
spread(spread, min) {
|
||||
|
||||
if (spread) {
|
||||
this._spread = (spread === "none") ? false : true;
|
||||
this._spread = spread === "none" ? false : true;
|
||||
// this.props.spread = this._spread;
|
||||
this.update({ spread: this._spread });
|
||||
}
|
||||
|
@ -101,7 +102,6 @@ class Layout {
|
|||
* @param {number} _gap width of the gap between columns
|
||||
*/
|
||||
calculate(_width, _height, _gap) {
|
||||
|
||||
var divisor = 1;
|
||||
var gap = _gap || 0;
|
||||
|
||||
|
@ -123,8 +123,12 @@ class Layout {
|
|||
divisor = 1;
|
||||
}
|
||||
|
||||
if (this.name === "reflowable" && this._flow === "paginated" && !(_gap >= 0)) {
|
||||
gap = ((section % 2 === 0) ? section : section - 1);
|
||||
if (
|
||||
this.name === "reflowable" &&
|
||||
this._flow === "paginated" &&
|
||||
!(_gap >= 0)
|
||||
) {
|
||||
gap = section % 2 === 0 ? section : section - 1;
|
||||
}
|
||||
|
||||
if (this.name === "pre-paginated") {
|
||||
|
@ -136,7 +140,7 @@ class Layout {
|
|||
// width = width - gap;
|
||||
// columnWidth = (width - gap) / divisor;
|
||||
// gap = gap / divisor;
|
||||
columnWidth = (width / divisor) - gap;
|
||||
columnWidth = width / divisor - gap;
|
||||
pageWidth = columnWidth + gap;
|
||||
} else {
|
||||
columnWidth = width;
|
||||
|
@ -147,7 +151,7 @@ class Layout {
|
|||
width = columnWidth;
|
||||
}
|
||||
|
||||
spreadWidth = (columnWidth * divisor) + gap;
|
||||
spreadWidth = columnWidth * divisor + gap;
|
||||
|
||||
delta = width;
|
||||
|
||||
|
@ -179,9 +183,8 @@ class Layout {
|
|||
delta,
|
||||
columnWidth,
|
||||
gap,
|
||||
divisor
|
||||
divisor,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,7 +198,13 @@ class Layout {
|
|||
if (this.name === "pre-paginated") {
|
||||
formating = contents.fit(this.columnWidth, this.height, section);
|
||||
} else if (this._flow === "paginated") {
|
||||
formating = contents.columns(this.width, this.height, this.columnWidth, this.gap, this.settings.direction);
|
||||
formating = contents.columns(
|
||||
this.width,
|
||||
this.height,
|
||||
this.columnWidth,
|
||||
this.gap,
|
||||
this.settings.direction
|
||||
);
|
||||
} else if (axis && axis === "horizontal") {
|
||||
formating = contents.size(null, this.height);
|
||||
} else {
|
||||
|
@ -212,7 +221,6 @@ class Layout {
|
|||
* @return {{spreads: Number, pages: Number}}
|
||||
*/
|
||||
count(totalLength, pageLength) {
|
||||
|
||||
let spreads, pages;
|
||||
|
||||
if (this.name === "pre-paginated") {
|
||||
|
@ -222,7 +230,8 @@ class Layout {
|
|||
pageLength = pageLength || this.delta;
|
||||
spreads = Math.ceil(totalLength / pageLength);
|
||||
pages = spreads * this.divisor;
|
||||
} else { // scrolled
|
||||
} else {
|
||||
// scrolled
|
||||
pageLength = pageLength || this.height;
|
||||
spreads = Math.ceil(totalLength / pageLength);
|
||||
pages = spreads;
|
||||
|
@ -230,9 +239,8 @@ class Layout {
|
|||
|
||||
return {
|
||||
spreads,
|
||||
pages
|
||||
pages,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
109
src/locations.js
109
src/locations.js
|
@ -1,8 +1,8 @@
|
|||
import {qs, sprint, locationOf, defer} from "./utils/core";
|
||||
import Queue from "./utils/queue";
|
||||
import EventEmitter from "event-emitter";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import { EVENTS } from "./utils/constants";
|
||||
import EventEmitter from "event-emitter";
|
||||
import { defer, locationOf, qs, sprint } from "./utils/core";
|
||||
import Queue from "./utils/queue";
|
||||
|
||||
/**
|
||||
* Find Locations for a Book
|
||||
|
@ -22,15 +22,11 @@ class Locations {
|
|||
this._locations = [];
|
||||
this._locationsWords = [];
|
||||
this.total = 0;
|
||||
|
||||
this.break = 150;
|
||||
|
||||
this._current = 0;
|
||||
|
||||
this._wordCounter = 0;
|
||||
|
||||
this.currentLocation = '';
|
||||
this._currentCfi ='';
|
||||
this.currentLocation = "";
|
||||
this._currentCfi = "";
|
||||
this.processingTimeout = undefined;
|
||||
}
|
||||
|
||||
|
@ -40,20 +36,22 @@ class Locations {
|
|||
* @return {Promise<Array<string>>} locations
|
||||
*/
|
||||
generate(chars) {
|
||||
|
||||
if (chars) {
|
||||
this.break = chars;
|
||||
}
|
||||
|
||||
this.q.pause();
|
||||
|
||||
this.spine.each(function(section) {
|
||||
this.spine.each(
|
||||
function (section) {
|
||||
if (section.linear) {
|
||||
this.q.enqueue(this.process.bind(this), section);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return this.q.run().then(function() {
|
||||
return this.q.run().then(
|
||||
function () {
|
||||
this.total = this._locations.length - 1;
|
||||
|
||||
if (this._currentCfi) {
|
||||
|
@ -62,8 +60,8 @@ class Locations {
|
|||
|
||||
return this._locations;
|
||||
// console.log(this.percentage(this.book.rendition.location.start), this.percentage(this.book.rendition.location.end));
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
createRange() {
|
||||
|
@ -71,24 +69,26 @@ class Locations {
|
|||
startContainer: undefined,
|
||||
startOffset: undefined,
|
||||
endContainer: undefined,
|
||||
endOffset: undefined
|
||||
endOffset: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
process(section) {
|
||||
|
||||
return section.load(this.request)
|
||||
.then(function(contents) {
|
||||
return section.load(this.request).then(
|
||||
function (contents) {
|
||||
var completed = new defer();
|
||||
var locations = this.parse(contents, section.cfiBase);
|
||||
this._locations = this._locations.concat(locations);
|
||||
|
||||
section.unload();
|
||||
|
||||
this.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);
|
||||
this.processingTimeout = setTimeout(
|
||||
() => completed.resolve(locations),
|
||||
this.pause
|
||||
);
|
||||
return completed.promise;
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
parse(contents, cfiBase, chars) {
|
||||
|
@ -124,7 +124,6 @@ class Locations {
|
|||
pos = len;
|
||||
}
|
||||
|
||||
|
||||
while (pos < len) {
|
||||
dist = _break - counter;
|
||||
|
||||
|
@ -175,7 +174,6 @@ class Locations {
|
|||
return locations;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load all of sections in the book to generate locations
|
||||
* @param {string} startCfi start position
|
||||
|
@ -189,26 +187,41 @@ class Locations {
|
|||
this._locationsWords = [];
|
||||
this._wordCounter = 0;
|
||||
|
||||
this.spine.each(function(section) {
|
||||
this.spine.each(
|
||||
function (section) {
|
||||
if (section.linear) {
|
||||
if (start) {
|
||||
if (section.index >= start.spinePos) {
|
||||
this.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);
|
||||
this.q.enqueue(
|
||||
this.processWords.bind(this),
|
||||
section,
|
||||
wordCount,
|
||||
start,
|
||||
count
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);
|
||||
this.q.enqueue(
|
||||
this.processWords.bind(this),
|
||||
section,
|
||||
wordCount,
|
||||
start,
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return this.q.run().then(function() {
|
||||
return this.q.run().then(
|
||||
function () {
|
||||
if (this._currentCfi) {
|
||||
this.currentLocation = this._currentCfi;
|
||||
}
|
||||
|
||||
return this._locationsWords;
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
processWords(section, wordCount, startCfi, count) {
|
||||
|
@ -216,18 +229,26 @@ class Locations {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return section.load(this.request)
|
||||
.then(function(contents) {
|
||||
return section.load(this.request).then(
|
||||
function (contents) {
|
||||
var completed = new defer();
|
||||
var locations = this.parseWords(contents, section, wordCount, startCfi);
|
||||
var remainingCount = count - this._locationsWords.length;
|
||||
this._locationsWords = this._locationsWords.concat(locations.length >= count ? locations.slice(0, remainingCount) : locations);
|
||||
this._locationsWords = this._locationsWords.concat(
|
||||
locations.length >= count
|
||||
? locations.slice(0, remainingCount)
|
||||
: locations
|
||||
);
|
||||
|
||||
section.unload();
|
||||
|
||||
this.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);
|
||||
this.processingTimeout = setTimeout(
|
||||
() => completed.resolve(locations),
|
||||
this.pause
|
||||
);
|
||||
return completed.promise;
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/questions/18679576/counting-words-in-string
|
||||
|
@ -243,12 +264,16 @@ class Locations {
|
|||
var locations = [];
|
||||
var doc = contents.ownerDocument;
|
||||
var body = qs(doc, "body");
|
||||
var prev;
|
||||
var _break = wordCount;
|
||||
var foundStartNode = startCfi ? startCfi.spinePos !== section.index : true;
|
||||
var startNode;
|
||||
if (startCfi && section.index === startCfi.spinePos) {
|
||||
startNode = startCfi.findNode(startCfi.range ? startCfi.path.steps.concat(startCfi.start.steps) : startCfi.path.steps, contents.ownerDocument);
|
||||
startNode = startCfi.findNode(
|
||||
startCfi.range
|
||||
? startCfi.path.steps.concat(startCfi.start.steps)
|
||||
: startCfi.path.steps,
|
||||
contents.ownerDocument
|
||||
);
|
||||
}
|
||||
var parser = function (node) {
|
||||
if (!foundStartNode) {
|
||||
|
@ -280,7 +305,6 @@ class Locations {
|
|||
pos = len;
|
||||
}
|
||||
|
||||
|
||||
while (pos < len) {
|
||||
dist = _break - this._wordCounter;
|
||||
|
||||
|
@ -300,7 +324,6 @@ class Locations {
|
|||
this._wordCounter = 0;
|
||||
}
|
||||
}
|
||||
prev = node;
|
||||
};
|
||||
|
||||
sprint(body, parser.bind(this));
|
||||
|
@ -357,7 +380,7 @@ class Locations {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return (loc / this.total);
|
||||
return loc / this.total;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -450,7 +473,7 @@ class Locations {
|
|||
}
|
||||
|
||||
this.emit(EVENTS.LOCATIONS.CHANGED, {
|
||||
percentage: this.percentageFromLocation(loc)
|
||||
percentage: this.percentageFromLocation(loc),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -484,7 +507,7 @@ class Locations {
|
|||
this.q = undefined;
|
||||
this.epubcfi = undefined;
|
||||
|
||||
this._locations = undefined
|
||||
this._locations = undefined;
|
||||
this.total = undefined;
|
||||
|
||||
this.break = undefined;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {extend, defer, requestAnimationFrame} from "../../utils/core";
|
||||
import debounce from "lodash/debounce";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import { defer, extend, requestAnimationFrame } from "../../utils/core";
|
||||
import DefaultViewManager from "../default";
|
||||
import Snap from "../helpers/snap";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import debounce from "lodash/debounce";
|
||||
|
||||
class ContinuousViewManager extends DefaultViewManager {
|
||||
constructor(options) {
|
||||
|
@ -23,7 +23,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
snap: false,
|
||||
afterScrolledTimeout: 10,
|
||||
allowScriptedContent: false,
|
||||
allowPopups: false
|
||||
allowPopups: false,
|
||||
});
|
||||
|
||||
extend(this.settings, options.settings || {});
|
||||
|
@ -42,7 +42,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
height: 0,
|
||||
forceEvenPages: false,
|
||||
allowScriptedContent: this.settings.allowScriptedContent,
|
||||
allowPopups: this.settings.allowPopups
|
||||
allowPopups: this.settings.allowPopups,
|
||||
};
|
||||
|
||||
this.scrollTop = 0;
|
||||
|
@ -50,18 +50,23 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
|
||||
display(section, target) {
|
||||
return DefaultViewManager.prototype.display.call(this, section, target)
|
||||
.then(function () {
|
||||
return DefaultViewManager.prototype.display
|
||||
.call(this, section, target)
|
||||
.then(
|
||||
function () {
|
||||
return this.fill();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
fill(_full) {
|
||||
var full = _full || new defer();
|
||||
|
||||
this.q.enqueue(() => {
|
||||
this.q
|
||||
.enqueue(() => {
|
||||
return this.check();
|
||||
}).then((result) => {
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.fill(full);
|
||||
} else {
|
||||
|
@ -73,20 +78,13 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
|
||||
moveTo(offset) {
|
||||
// var bounds = this.stage.bounds();
|
||||
// var dist = Math.floor(offset.top / bounds.height) * bounds.height;
|
||||
var distX = 0,
|
||||
distY = 0;
|
||||
|
||||
var offsetX = 0,
|
||||
offsetY = 0;
|
||||
|
||||
if (!this.isPaginated) {
|
||||
distY = offset.top;
|
||||
offsetY = offset.top+this.settings.offsetDelta;
|
||||
} else {
|
||||
distX = Math.floor(offset.left / this.layout.delta) * this.layout.delta;
|
||||
offsetX = distX+this.settings.offsetDelta;
|
||||
}
|
||||
|
||||
if (distX > 0 || distY > 0) {
|
||||
|
@ -100,11 +98,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
// Remove Previous Listeners if present
|
||||
removeShownListeners(view) {
|
||||
|
||||
// view.off("shown", this.afterDisplayed);
|
||||
// view.off("shown", this.afterDisplayedAbove);
|
||||
view.onDisplayed = function () {};
|
||||
|
||||
}
|
||||
|
||||
add(section) {
|
||||
|
@ -124,7 +118,6 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this.updateWritingMode(mode);
|
||||
});
|
||||
|
||||
// view.on(EVENTS.VIEWS.SHOWN, this.afterDisplayed.bind(this));
|
||||
view.onDisplayed = this.afterDisplayed.bind(this);
|
||||
view.onResize = this.afterResized.bind(this);
|
||||
|
||||
|
@ -189,7 +182,8 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
var views = this.views.all();
|
||||
var viewsLength = views.length;
|
||||
var visible = [];
|
||||
var offset = typeof _offset != "undefined" ? _offset : (this.settings.offset || 0);
|
||||
var offset =
|
||||
typeof _offset != "undefined" ? _offset : this.settings.offset || 0;
|
||||
var isVisible;
|
||||
var view;
|
||||
|
||||
|
@ -201,15 +195,15 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
isVisible = this.isVisible(view, offset, offset, container);
|
||||
|
||||
if (isVisible === true) {
|
||||
// console.log("visible " + view.index, view.displayed);
|
||||
|
||||
if (!view.displayed) {
|
||||
let displayed = view.display(this.request)
|
||||
.then(function (view) {
|
||||
let displayed = view.display(this.request).then(
|
||||
function (view) {
|
||||
view.show();
|
||||
}, (err) => {
|
||||
},
|
||||
(err) => {
|
||||
view.hide();
|
||||
});
|
||||
}
|
||||
);
|
||||
promises.push(displayed);
|
||||
} else {
|
||||
view.show();
|
||||
|
@ -217,33 +211,32 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
visible.push(view);
|
||||
} else {
|
||||
this.q.enqueue(view.destroy.bind(view));
|
||||
// console.log("hidden " + view.index, view.displayed);
|
||||
|
||||
clearTimeout(this.trimTimeout);
|
||||
this.trimTimeout = setTimeout(function(){
|
||||
this.trimTimeout = setTimeout(
|
||||
function () {
|
||||
this.q.enqueue(this.trim.bind(this));
|
||||
}.bind(this), 250);
|
||||
}.bind(this),
|
||||
250
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
return Promise.all(promises)
|
||||
.catch((err) => {
|
||||
return Promise.all(promises).catch((err) => {
|
||||
updating.reject(err);
|
||||
});
|
||||
} else {
|
||||
updating.resolve();
|
||||
return updating.promise;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
check(_offsetLeft, _offsetTop) {
|
||||
var checking = new defer();
|
||||
var newViews = [];
|
||||
|
||||
var horizontal = (this.settings.axis === "horizontal");
|
||||
var horizontal = this.settings.axis === "horizontal";
|
||||
var delta = this.settings.offset || 0;
|
||||
|
||||
if (_offsetLeft && horizontal) {
|
||||
|
@ -254,12 +247,18 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
delta = _offsetTop;
|
||||
}
|
||||
|
||||
var bounds = this._bounds; // bounds saved this until resize
|
||||
// bounds saved this until resize
|
||||
var bounds = this._bounds;
|
||||
|
||||
let offset = horizontal ? this.scrollLeft : this.scrollTop;
|
||||
let visibleLength = horizontal ? Math.floor(bounds.width) : bounds.height;
|
||||
let contentLength = horizontal ? this.container.scrollWidth : this.container.scrollHeight;
|
||||
let writingMode = (this.writingMode && this.writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
|
||||
let contentLength = horizontal
|
||||
? this.container.scrollWidth
|
||||
: this.container.scrollHeight;
|
||||
let writingMode =
|
||||
this.writingMode && this.writingMode.indexOf("vertical") === 0
|
||||
? "vertical"
|
||||
: "horizontal";
|
||||
let rtlScrollType = this.settings.rtlScrollType;
|
||||
let rtl = this.settings.direction === "rtl";
|
||||
|
||||
|
@ -274,8 +273,10 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
} else {
|
||||
// Scroll offset starts at 0 and goes negative
|
||||
if ((horizontal && rtl && rtlScrollType === "negative") ||
|
||||
(!horizontal && rtl && rtlScrollType === "default")) {
|
||||
if (
|
||||
(horizontal && rtl && rtlScrollType === "negative") ||
|
||||
(!horizontal && rtl && rtlScrollType === "default")
|
||||
) {
|
||||
offset = offset * -1;
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +297,6 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
if (next) {
|
||||
newViews.push(this.append(next));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
let end = offset + visibleLength + delta;
|
||||
|
@ -310,7 +310,6 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
prepend();
|
||||
}
|
||||
|
||||
|
||||
let promises = newViews.map((view) => {
|
||||
return view.display(this.request);
|
||||
});
|
||||
|
@ -320,21 +319,24 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
.then(() => {
|
||||
return this.check();
|
||||
})
|
||||
.then(() => {
|
||||
.then(
|
||||
() => {
|
||||
// Check to see if anything new is on screen after rendering
|
||||
return this.update(delta);
|
||||
}, (err) => {
|
||||
},
|
||||
(err) => {
|
||||
return err;
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.q.enqueue(function(){
|
||||
this.q.enqueue(
|
||||
function () {
|
||||
this.update();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
checking.resolve(false);
|
||||
return checking.promise;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
trim() {
|
||||
|
@ -361,8 +363,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
return task.promise;
|
||||
}
|
||||
|
||||
erase(view, above){ //Trim
|
||||
|
||||
erase(view, above) {
|
||||
var prevTop;
|
||||
var prevLeft;
|
||||
|
||||
|
@ -382,7 +383,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
if (this.settings.axis === "vertical") {
|
||||
this.scrollTo(0, prevTop - bounds.height, true);
|
||||
} else {
|
||||
if(this.settings.direction === 'rtl') {
|
||||
if (this.settings.direction === "rtl") {
|
||||
if (!this.settings.fullsize) {
|
||||
this.scrollTo(prevLeft, 0, true);
|
||||
} else {
|
||||
|
@ -393,30 +394,37 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addEventListeners(stage) {
|
||||
|
||||
window.addEventListener("unload", function(e){
|
||||
window.addEventListener(
|
||||
"unload",
|
||||
function (e) {
|
||||
this.ignore = true;
|
||||
// this.scrollTo(0,0);
|
||||
this.destroy();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
this.addScrollListeners();
|
||||
|
||||
if (this.isPaginated && this.settings.snap) {
|
||||
this.snapper = new Snap(this, this.settings.snap && (typeof this.settings.snap === "object") && this.settings.snap);
|
||||
this.snapper = new Snap(
|
||||
this,
|
||||
this.settings.snap &&
|
||||
typeof this.settings.snap === "object" &&
|
||||
this.settings.snap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
addScrollListeners() {
|
||||
var scroller;
|
||||
|
||||
this.tick = requestAnimationFrame;
|
||||
|
||||
let dir = this.settings.direction === "rtl" && this.settings.rtlScrollType === "default" ? -1 : 1;
|
||||
let dir =
|
||||
this.settings.direction === "rtl" &&
|
||||
this.settings.rtlScrollType === "default"
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
|
@ -434,10 +442,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this._onScroll = this.onScroll.bind(this);
|
||||
scroller.addEventListener("scroll", this._onScroll);
|
||||
this._scrolled = debounce(this.scrolled.bind(this), 30);
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
|
||||
this.didScroll = false;
|
||||
|
||||
}
|
||||
|
||||
removeEventListeners() {
|
||||
|
@ -456,7 +461,11 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
onScroll() {
|
||||
let scrollTop;
|
||||
let scrollLeft;
|
||||
let dir = this.settings.direction === "rtl" && this.settings.rtlScrollType === "default" ? -1 : 1;
|
||||
let dir =
|
||||
this.settings.direction === "rtl" &&
|
||||
this.settings.rtlScrollType === "default"
|
||||
? -1
|
||||
: 1;
|
||||
|
||||
if (!this.settings.fullsize) {
|
||||
scrollTop = this.container.scrollTop;
|
||||
|
@ -470,9 +479,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this.scrollLeft = scrollLeft;
|
||||
|
||||
if (!this.ignore) {
|
||||
|
||||
this._scrolled();
|
||||
|
||||
} else {
|
||||
this.ignore = false;
|
||||
}
|
||||
|
@ -484,86 +491,92 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this.prevScrollLeft = scrollLeft;
|
||||
|
||||
clearTimeout(this.scrollTimeout);
|
||||
this.scrollTimeout = setTimeout(function(){
|
||||
this.scrollTimeout = setTimeout(
|
||||
function () {
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
}.bind(this), 150);
|
||||
}.bind(this),
|
||||
150
|
||||
);
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
|
||||
this.didScroll = false;
|
||||
|
||||
}
|
||||
|
||||
scrolled() {
|
||||
|
||||
this.q.enqueue(function() {
|
||||
this.q.enqueue(
|
||||
function () {
|
||||
return this.check();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
this.emit(EVENTS.MANAGERS.SCROLL, {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
left: this.scrollLeft,
|
||||
});
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
this.afterScrolled = setTimeout(function () {
|
||||
|
||||
this.afterScrolled = setTimeout(
|
||||
function () {
|
||||
// Don't report scroll if we are about the snap
|
||||
if (this.snapper && this.snapper.supportsTouch && this.snapper.needsSnap()) {
|
||||
if (
|
||||
this.snapper &&
|
||||
this.snapper.supportsTouch &&
|
||||
this.snapper.needsSnap()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.emit(EVENTS.MANAGERS.SCROLLED, {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
left: this.scrollLeft,
|
||||
});
|
||||
|
||||
}.bind(this), this.settings.afterScrolledTimeout);
|
||||
}.bind(this),
|
||||
this.settings.afterScrolledTimeout
|
||||
);
|
||||
}
|
||||
|
||||
next() {
|
||||
|
||||
let delta = this.layout.props.name === "pre-paginated" &&
|
||||
this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
|
||||
let delta =
|
||||
this.layout.props.name === "pre-paginated" && this.layout.props.spread
|
||||
? this.layout.props.delta * 2
|
||||
: this.layout.props.delta;
|
||||
|
||||
if (!this.views.length) return;
|
||||
|
||||
if (this.isPaginated && this.settings.axis === "horizontal") {
|
||||
|
||||
this.scrollBy(delta, 0, true);
|
||||
|
||||
} else {
|
||||
|
||||
this.scrollBy(0, this.layout.height, true);
|
||||
|
||||
}
|
||||
|
||||
this.q.enqueue(function() {
|
||||
this.q.enqueue(
|
||||
function () {
|
||||
return this.check();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
prev() {
|
||||
|
||||
let delta = this.layout.props.name === "pre-paginated" &&
|
||||
this.layout.props.spread ? this.layout.props.delta * 2 : this.layout.props.delta;
|
||||
let delta =
|
||||
this.layout.props.name === "pre-paginated" && this.layout.props.spread
|
||||
? this.layout.props.delta * 2
|
||||
: this.layout.props.delta;
|
||||
|
||||
if (!this.views.length) return;
|
||||
|
||||
if (this.isPaginated && this.settings.axis === "horizontal") {
|
||||
|
||||
this.scrollBy(-delta, 0, true);
|
||||
|
||||
} else {
|
||||
|
||||
this.scrollBy(0, -this.layout.height, true);
|
||||
|
||||
}
|
||||
|
||||
this.q.enqueue(function() {
|
||||
this.q.enqueue(
|
||||
function () {
|
||||
return this.check();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
updateFlow(flow) {
|
||||
|
@ -575,7 +588,12 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
super.updateFlow(flow, "scroll");
|
||||
|
||||
if (this.rendered && this.isPaginated && this.settings.snap) {
|
||||
this.snapper = new Snap(this, this.settings.snap && (typeof this.settings.snap === "object") && this.settings.snap);
|
||||
this.snapper = new Snap(
|
||||
this,
|
||||
this.settings.snap &&
|
||||
typeof this.settings.snap === "object" &&
|
||||
this.settings.snap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,7 +604,6 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this.snapper.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ContinuousViewManager;
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import {extend, defer, windowBounds, isNumber} from "../../utils/core";
|
||||
import scrollType from "../../utils/scrolltype";
|
||||
import Mapping from "../../mapping";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import { defer, extend, isNumber, windowBounds } from "../../utils/core";
|
||||
import Queue from "../../utils/queue";
|
||||
import scrollType from "../../utils/scrolltype";
|
||||
import Stage from "../helpers/stage";
|
||||
import Views from "../helpers/views";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
|
||||
class DefaultViewManager {
|
||||
constructor(options) {
|
||||
|
||||
this.name = "default";
|
||||
this.optsSettings = options.settings;
|
||||
this.View = options.view;
|
||||
|
@ -28,7 +27,7 @@ class DefaultViewManager {
|
|||
ignoreClass: "",
|
||||
fullsize: undefined,
|
||||
allowScriptedContent: false,
|
||||
allowPopups: false
|
||||
allowPopups: false,
|
||||
});
|
||||
|
||||
extend(this.settings, options.settings || {});
|
||||
|
@ -43,19 +42,20 @@ class DefaultViewManager {
|
|||
height: 0,
|
||||
forceEvenPages: true,
|
||||
allowScriptedContent: this.settings.allowScriptedContent,
|
||||
allowPopups: this.settings.allowPopups
|
||||
allowPopups: this.settings.allowPopups,
|
||||
};
|
||||
|
||||
this.rendered = false;
|
||||
|
||||
}
|
||||
|
||||
render(element, size) {
|
||||
let tag = element.tagName;
|
||||
|
||||
if (typeof this.settings.fullsize === "undefined" &&
|
||||
tag && (tag.toLowerCase() == "body" ||
|
||||
tag.toLowerCase() == "html")) {
|
||||
if (
|
||||
typeof this.settings.fullsize === "undefined" &&
|
||||
tag &&
|
||||
(tag.toLowerCase() == "body" || tag.toLowerCase() == "html")
|
||||
) {
|
||||
this.settings.fullsize = true;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ class DefaultViewManager {
|
|||
hidden: this.settings.hidden,
|
||||
axis: this.settings.axis,
|
||||
fullsize: this.settings.fullsize,
|
||||
direction: this.settings.direction
|
||||
direction: this.settings.direction,
|
||||
});
|
||||
|
||||
this.stage.attachTo(element);
|
||||
|
@ -111,15 +111,17 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
this.rendered = true;
|
||||
|
||||
}
|
||||
|
||||
addEventListeners() {
|
||||
var scroller;
|
||||
|
||||
window.addEventListener("unload", function(e){
|
||||
window.addEventListener(
|
||||
"unload",
|
||||
function (e) {
|
||||
this.destroy();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
if (!this.settings.fullsize) {
|
||||
scroller = this.container;
|
||||
|
@ -181,7 +183,8 @@ class DefaultViewManager {
|
|||
// happens in window.resize event. Adding a timeout for correct
|
||||
// measurement. See https://github.com/ampproject/amphtml/issues/8479
|
||||
clearTimeout(this.orientationTimeout);
|
||||
this.orientationTimeout = setTimeout(function(){
|
||||
this.orientationTimeout = setTimeout(
|
||||
function () {
|
||||
this.orientationTimeout = undefined;
|
||||
|
||||
if (this.optsSettings.resizeOnOrientationChange) {
|
||||
|
@ -189,8 +192,9 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
this.emit(EVENTS.MANAGERS.ORIENTATION_CHANGE, orientation);
|
||||
}.bind(this), 500);
|
||||
|
||||
}.bind(this),
|
||||
500
|
||||
);
|
||||
}
|
||||
|
||||
onResized(e) {
|
||||
|
@ -203,16 +207,20 @@ class DefaultViewManager {
|
|||
// For Safari, wait for orientation to catch up
|
||||
// if the window is a square
|
||||
this.winBounds = windowBounds();
|
||||
if (this.orientationTimeout &&
|
||||
this.winBounds.width === this.winBounds.height) {
|
||||
if (
|
||||
this.orientationTimeout &&
|
||||
this.winBounds.width === this.winBounds.height
|
||||
) {
|
||||
// reset the stage size for next resize
|
||||
this._stageSize = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._stageSize &&
|
||||
if (
|
||||
this._stageSize &&
|
||||
this._stageSize.width === stageSize.width &&
|
||||
this._stageSize.height === stageSize.height ) {
|
||||
this._stageSize.height === stageSize.height
|
||||
) {
|
||||
// Size is the same, no need to resize
|
||||
return;
|
||||
}
|
||||
|
@ -230,10 +238,14 @@ class DefaultViewManager {
|
|||
|
||||
this.updateLayout();
|
||||
|
||||
this.emit(EVENTS.MANAGERS.RESIZED, {
|
||||
this.emit(
|
||||
EVENTS.MANAGERS.RESIZED,
|
||||
{
|
||||
width: this._stageSize.width,
|
||||
height: this._stageSize.height
|
||||
}, epubcfi);
|
||||
height: this._stageSize.height,
|
||||
},
|
||||
epubcfi
|
||||
);
|
||||
}
|
||||
|
||||
createView(section, forceRight) {
|
||||
|
@ -256,7 +268,6 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
display(section, target) {
|
||||
|
||||
var displaying = new defer();
|
||||
var displayed = displaying.promise;
|
||||
|
||||
|
@ -293,33 +304,40 @@ class DefaultViewManager {
|
|||
this.clear();
|
||||
|
||||
let forceRight = false;
|
||||
if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && section.properties.includes("page-spread-right")) {
|
||||
if (
|
||||
this.layout.name === "pre-paginated" &&
|
||||
this.layout.divisor === 2 &&
|
||||
section.properties.includes("page-spread-right")
|
||||
) {
|
||||
forceRight = true;
|
||||
}
|
||||
|
||||
this.add(section, forceRight)
|
||||
.then(function(view){
|
||||
|
||||
.then(
|
||||
function (view) {
|
||||
// Move to correct place within the section, if needed
|
||||
if (target) {
|
||||
let offset = view.locationOf(target);
|
||||
let width = view.width();
|
||||
this.moveTo(offset, width);
|
||||
}
|
||||
|
||||
}.bind(this), (err) => {
|
||||
}.bind(this),
|
||||
(err) => {
|
||||
displaying.reject(err);
|
||||
})
|
||||
.then(function(){
|
||||
}
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
return this.handleNextPrePaginated(forceRight, section, this.add);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
this.views.show();
|
||||
|
||||
displaying.resolve();
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
// .then(function(){
|
||||
// return this.hooks.display.trigger(view);
|
||||
// }.bind(this))
|
||||
|
@ -356,14 +374,14 @@ class DefaultViewManager {
|
|||
distY = this.container.scrollHeight - this.layout.delta;
|
||||
}
|
||||
}
|
||||
if(this.settings.direction === 'rtl'){
|
||||
if (this.settings.direction === "rtl") {
|
||||
/***
|
||||
the `floor` function above (L343) is on positive values, so we should add one `layout.delta`
|
||||
to distX or use `Math.ceil` function, or multiply offset.left by -1
|
||||
before `Math.floor`
|
||||
*/
|
||||
distX = distX + this.layout.delta
|
||||
distX = distX - width
|
||||
distX = distX + this.layout.delta;
|
||||
distX = distX - width;
|
||||
}
|
||||
this.scrollTo(distX, distY, true);
|
||||
}
|
||||
|
@ -435,7 +453,6 @@ class DefaultViewManager {
|
|||
} else {
|
||||
this.scrollBy(bounds.widthDelta, 0, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// resizeView(view) {
|
||||
|
@ -456,19 +473,28 @@ class DefaultViewManager {
|
|||
|
||||
if (!this.views.length) return;
|
||||
|
||||
if(this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) {
|
||||
|
||||
if (
|
||||
this.isPaginated &&
|
||||
this.settings.axis === "horizontal" &&
|
||||
(!dir || dir === "ltr")
|
||||
) {
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
|
||||
left = this.container.scrollLeft + this.container.offsetWidth + this.layout.delta;
|
||||
left =
|
||||
this.container.scrollLeft +
|
||||
this.container.offsetWidth +
|
||||
this.layout.delta;
|
||||
|
||||
if (left <= this.container.scrollWidth) {
|
||||
this.scrollBy(this.layout.delta, 0, true);
|
||||
} else {
|
||||
next = this.views.last().section.next();
|
||||
}
|
||||
} else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") {
|
||||
|
||||
} else if (
|
||||
this.isPaginated &&
|
||||
this.settings.axis === "horizontal" &&
|
||||
dir === "rtl"
|
||||
) {
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
|
||||
if (this.settings.rtlScrollType === "default") {
|
||||
|
@ -480,7 +506,7 @@ class DefaultViewManager {
|
|||
next = this.views.last().section.next();
|
||||
}
|
||||
} else {
|
||||
left = this.container.scrollLeft + ( this.layout.delta * -1 );
|
||||
left = this.container.scrollLeft + this.layout.delta * -1;
|
||||
|
||||
if (left > this.container.scrollWidth * -1) {
|
||||
this.scrollBy(this.layout.delta, 0, true);
|
||||
|
@ -488,9 +514,7 @@ class DefaultViewManager {
|
|||
next = this.views.last().section.next();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.isPaginated && this.settings.axis === "vertical") {
|
||||
|
||||
this.scrollTop = this.container.scrollTop;
|
||||
|
||||
let top = this.container.scrollTop + this.container.offsetHeight;
|
||||
|
@ -500,7 +524,6 @@ class DefaultViewManager {
|
|||
} else {
|
||||
next = this.views.last().section.next();
|
||||
}
|
||||
|
||||
} else {
|
||||
next = this.views.last().section.next();
|
||||
}
|
||||
|
@ -511,31 +534,38 @@ class DefaultViewManager {
|
|||
this.updateLayout();
|
||||
|
||||
let forceRight = false;
|
||||
if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && next.properties.includes("page-spread-right")) {
|
||||
if (
|
||||
this.layout.name === "pre-paginated" &&
|
||||
this.layout.divisor === 2 &&
|
||||
next.properties.includes("page-spread-right")
|
||||
) {
|
||||
forceRight = true;
|
||||
}
|
||||
|
||||
return this.append(next, forceRight)
|
||||
.then(function(){
|
||||
.then(
|
||||
function () {
|
||||
return this.handleNextPrePaginated(forceRight, next, this.append);
|
||||
}.bind(this), (err) => {
|
||||
}.bind(this),
|
||||
(err) => {
|
||||
return err;
|
||||
})
|
||||
.then(function(){
|
||||
|
||||
}
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
// Reset position to start for scrolled-doc vertical-rl in default mode
|
||||
if (!this.isPaginated &&
|
||||
if (
|
||||
!this.isPaginated &&
|
||||
this.settings.axis === "horizontal" &&
|
||||
this.settings.direction === "rtl" &&
|
||||
this.settings.rtlScrollType === "default") {
|
||||
|
||||
this.settings.rtlScrollType === "default"
|
||||
) {
|
||||
this.scrollTo(this.container.scrollWidth, 0, true);
|
||||
}
|
||||
this.views.show();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
prev() {
|
||||
|
@ -545,8 +575,11 @@ class DefaultViewManager {
|
|||
|
||||
if (!this.views.length) return;
|
||||
|
||||
if(this.isPaginated && this.settings.axis === "horizontal" && (!dir || dir === "ltr")) {
|
||||
|
||||
if (
|
||||
this.isPaginated &&
|
||||
this.settings.axis === "horizontal" &&
|
||||
(!dir || dir === "ltr")
|
||||
) {
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
|
||||
left = this.container.scrollLeft;
|
||||
|
@ -556,9 +589,11 @@ class DefaultViewManager {
|
|||
} else {
|
||||
prev = this.views.first().section.prev();
|
||||
}
|
||||
|
||||
} else if (this.isPaginated && this.settings.axis === "horizontal" && dir === "rtl") {
|
||||
|
||||
} else if (
|
||||
this.isPaginated &&
|
||||
this.settings.axis === "horizontal" &&
|
||||
dir === "rtl"
|
||||
) {
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
|
||||
if (this.settings.rtlScrollType === "default") {
|
||||
|
@ -569,8 +604,7 @@ class DefaultViewManager {
|
|||
} else {
|
||||
prev = this.views.first().section.prev();
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
left = this.container.scrollLeft;
|
||||
|
||||
if (left < 0) {
|
||||
|
@ -579,23 +613,18 @@ class DefaultViewManager {
|
|||
prev = this.views.first().section.prev();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this.isPaginated && this.settings.axis === "vertical") {
|
||||
|
||||
this.scrollTop = this.container.scrollTop;
|
||||
|
||||
let top = this.container.scrollTop;
|
||||
|
||||
if (top > 0) {
|
||||
this.scrollBy(0, -(this.layout.height), true);
|
||||
this.scrollBy(0, -this.layout.height, true);
|
||||
} else {
|
||||
prev = this.views.first().section.prev();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
prev = this.views.first().section.prev();
|
||||
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
|
@ -604,37 +633,56 @@ class DefaultViewManager {
|
|||
this.updateLayout();
|
||||
|
||||
let forceRight = false;
|
||||
if (this.layout.name === "pre-paginated" && this.layout.divisor === 2 && typeof prev.prev() !== "object") {
|
||||
if (
|
||||
this.layout.name === "pre-paginated" &&
|
||||
this.layout.divisor === 2 &&
|
||||
typeof prev.prev() !== "object"
|
||||
) {
|
||||
forceRight = true;
|
||||
}
|
||||
|
||||
return this.prepend(prev, forceRight)
|
||||
.then(function(){
|
||||
.then(
|
||||
function () {
|
||||
var left;
|
||||
if (this.layout.name === "pre-paginated" && this.layout.divisor > 1) {
|
||||
if (
|
||||
this.layout.name === "pre-paginated" &&
|
||||
this.layout.divisor > 1
|
||||
) {
|
||||
left = prev.prev();
|
||||
if (left) {
|
||||
return this.prepend(left);
|
||||
}
|
||||
}
|
||||
}.bind(this), (err) => {
|
||||
}.bind(this),
|
||||
(err) => {
|
||||
return err;
|
||||
})
|
||||
.then(function(){
|
||||
}
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
if (this.isPaginated && this.settings.axis === "horizontal") {
|
||||
if (this.settings.direction === "rtl") {
|
||||
if (this.settings.rtlScrollType === "default") {
|
||||
this.scrollTo(0, 0, true);
|
||||
}
|
||||
else{
|
||||
this.scrollTo((this.container.scrollWidth * -1) + this.layout.delta, 0, true);
|
||||
} else {
|
||||
this.scrollTo(
|
||||
this.container.scrollWidth * -1 + this.layout.delta,
|
||||
0,
|
||||
true
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.scrollTo(this.container.scrollWidth - this.layout.delta, 0, true);
|
||||
this.scrollTo(
|
||||
this.container.scrollWidth - this.layout.delta,
|
||||
0,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
this.views.show();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,9 +696,6 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
clear() {
|
||||
|
||||
// this.q.clear();
|
||||
|
||||
if (this.views) {
|
||||
this.views.hide();
|
||||
this.scrollTo(0, 0, true);
|
||||
|
@ -671,10 +716,13 @@ class DefaultViewManager {
|
|||
scrolledLocation() {
|
||||
let visible = this.visible();
|
||||
let container = this.container.getBoundingClientRect();
|
||||
let pageHeight = (container.height < window.innerHeight) ? container.height : window.innerHeight;
|
||||
let pageWidth = (container.width < window.innerWidth) ? container.width : window.innerWidth;
|
||||
let vertical = (this.settings.axis === "vertical");
|
||||
let rtl = (this.settings.direction === "rtl");
|
||||
let pageHeight =
|
||||
container.height < window.innerHeight
|
||||
? container.height
|
||||
: window.innerHeight;
|
||||
let pageWidth =
|
||||
container.width < window.innerWidth ? container.width : window.innerWidth;
|
||||
let vertical = this.settings.axis === "vertical";
|
||||
|
||||
let offset = 0;
|
||||
let used = 0;
|
||||
|
@ -723,14 +771,19 @@ class DefaultViewManager {
|
|||
pages.push(pg);
|
||||
}
|
||||
|
||||
let mapping = this.mapping.page(view.contents, view.section.cfiBase, startPos, endPos);
|
||||
let mapping = this.mapping.page(
|
||||
view.contents,
|
||||
view.section.cfiBase,
|
||||
startPos,
|
||||
endPos
|
||||
);
|
||||
|
||||
return {
|
||||
index,
|
||||
href,
|
||||
pages,
|
||||
totalPages,
|
||||
mapping
|
||||
mapping,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -761,7 +814,8 @@ class DefaultViewManager {
|
|||
|
||||
if (this.settings.direction === "rtl") {
|
||||
offset = container.right - left;
|
||||
pageWidth = Math.min(Math.abs(offset - position.left), this.layout.width) - used;
|
||||
pageWidth =
|
||||
Math.min(Math.abs(offset - position.left), this.layout.width) - used;
|
||||
end = position.width - (position.right - offset) - used;
|
||||
start = end - pageWidth;
|
||||
} else {
|
||||
|
@ -773,7 +827,12 @@ class DefaultViewManager {
|
|||
|
||||
used += pageWidth;
|
||||
|
||||
let mapping = this.mapping.page(view.contents, view.section.cfiBase, start, end);
|
||||
let mapping = this.mapping.page(
|
||||
view.contents,
|
||||
view.section.cfiBase,
|
||||
start,
|
||||
end
|
||||
);
|
||||
|
||||
let totalPages = this.layout.count(width).pages;
|
||||
let startPage = Math.floor(start / this.layout.pageWidth);
|
||||
|
@ -793,7 +852,6 @@ class DefaultViewManager {
|
|||
endPage = totalPages - tempStartPage;
|
||||
}
|
||||
|
||||
|
||||
for (var i = startPage + 1; i <= endPage; i++) {
|
||||
let pg = i;
|
||||
pages.push(pg);
|
||||
|
@ -804,7 +862,7 @@ class DefaultViewManager {
|
|||
href,
|
||||
pages,
|
||||
totalPages,
|
||||
mapping
|
||||
mapping,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -815,21 +873,21 @@ class DefaultViewManager {
|
|||
var position = view.position();
|
||||
var container = _container || this.bounds();
|
||||
|
||||
if(this.settings.axis === "horizontal" &&
|
||||
if (
|
||||
this.settings.axis === "horizontal" &&
|
||||
position.right > container.left - offsetPrev &&
|
||||
position.left < container.right + offsetNext) {
|
||||
|
||||
position.left < container.right + offsetNext
|
||||
) {
|
||||
return true;
|
||||
|
||||
} else if(this.settings.axis === "vertical" &&
|
||||
} else if (
|
||||
this.settings.axis === "vertical" &&
|
||||
position.bottom > container.top - offsetPrev &&
|
||||
position.top < container.bottom + offsetNext) {
|
||||
|
||||
position.top < container.bottom + offsetNext
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
visible() {
|
||||
|
@ -847,7 +905,6 @@ class DefaultViewManager {
|
|||
if (isVisible === true) {
|
||||
visible.push(view);
|
||||
}
|
||||
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
@ -900,23 +957,22 @@ class DefaultViewManager {
|
|||
if (!this.ignore) {
|
||||
this.emit(EVENTS.MANAGERS.SCROLL, {
|
||||
top: scrollTop,
|
||||
left: scrollLeft
|
||||
left: scrollLeft,
|
||||
});
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
this.afterScrolled = setTimeout(function () {
|
||||
this.afterScrolled = setTimeout(
|
||||
function () {
|
||||
this.emit(EVENTS.MANAGERS.SCROLLED, {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
left: this.scrollLeft,
|
||||
});
|
||||
}.bind(this), 20);
|
||||
|
||||
|
||||
|
||||
}.bind(this),
|
||||
20
|
||||
);
|
||||
} else {
|
||||
this.ignore = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bounds() {
|
||||
|
@ -928,17 +984,18 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
applyLayout(layout) {
|
||||
|
||||
this.layout = layout;
|
||||
this.updateLayout();
|
||||
if (this.views && this.views.length > 0 && this.layout.name === "pre-paginated") {
|
||||
if (
|
||||
this.views &&
|
||||
this.views.length > 0 &&
|
||||
this.layout.name === "pre-paginated"
|
||||
) {
|
||||
this.display(this.views.first().section);
|
||||
}
|
||||
// this.manager.layout(this.layout.format);
|
||||
}
|
||||
|
||||
updateLayout() {
|
||||
|
||||
if (!this.stage) {
|
||||
return;
|
||||
}
|
||||
|
@ -956,9 +1013,6 @@ class DefaultViewManager {
|
|||
|
||||
// Set the look ahead offset for what is visible
|
||||
this.settings.offset = this.layout.delta / this.layout.divisor;
|
||||
|
||||
// this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]);
|
||||
|
||||
}
|
||||
|
||||
// Set the dimensions for views
|
||||
|
@ -969,21 +1023,21 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
setLayout(layout) {
|
||||
|
||||
this.viewSettings.layout = layout;
|
||||
|
||||
this.mapping = new Mapping(layout.props, this.settings.direction, this.settings.axis);
|
||||
this.mapping = new Mapping(
|
||||
layout.props,
|
||||
this.settings.direction,
|
||||
this.settings.axis
|
||||
);
|
||||
|
||||
if (this.views) {
|
||||
|
||||
this.views.forEach(function (view) {
|
||||
if (view) {
|
||||
view.setLayout(layout);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateWritingMode(mode) {
|
||||
|
@ -991,19 +1045,20 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
updateAxis(axis, forceUpdate) {
|
||||
|
||||
if (!forceUpdate && axis === this.settings.axis) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.axis = axis;
|
||||
|
||||
this.stage && this.stage.axis(axis);
|
||||
|
||||
this.viewSettings.axis = axis;
|
||||
|
||||
if (this.mapping) {
|
||||
this.mapping = new Mapping(this.layout.props, this.settings.direction, this.settings.axis);
|
||||
this.mapping = new Mapping(
|
||||
this.layout.props,
|
||||
this.settings.direction,
|
||||
this.settings.axis
|
||||
);
|
||||
}
|
||||
|
||||
if (this.layout) {
|
||||
|
@ -1016,13 +1071,14 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
updateFlow(flow, defaultScrolledOverflow = "auto") {
|
||||
let isPaginated = (flow === "paginated" || flow === "auto");
|
||||
|
||||
let isPaginated = flow === "paginated" || flow === "auto";
|
||||
this.isPaginated = isPaginated;
|
||||
|
||||
if (flow === "scrolled-doc" ||
|
||||
if (
|
||||
flow === "scrolled-doc" ||
|
||||
flow === "scrolled-continuous" ||
|
||||
flow === "scrolled") {
|
||||
flow === "scrolled"
|
||||
) {
|
||||
this.updateAxis("vertical");
|
||||
} else {
|
||||
this.updateAxis("horizontal");
|
||||
|
@ -1037,9 +1093,7 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
this.stage && this.stage.overflow(this.overflow);
|
||||
|
||||
this.updateLayout();
|
||||
|
||||
}
|
||||
|
||||
getContents() {
|
||||
|
@ -1058,11 +1112,8 @@ class DefaultViewManager {
|
|||
|
||||
direction(dir = "ltr") {
|
||||
this.settings.direction = dir;
|
||||
|
||||
this.stage && this.stage.direction(dir);
|
||||
|
||||
this.viewSettings.direction = dir;
|
||||
|
||||
this.updateLayout();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,36 +1,38 @@
|
|||
import {extend, defer, requestAnimationFrame, prefixed} from "../../utils/core";
|
||||
import { EVENTS, DOM_EVENTS } from "../../utils/constants";
|
||||
import EventEmitter from "event-emitter";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import { defer, extend } from "../../utils/core";
|
||||
|
||||
// easing equations from https://github.com/danro/easing-js/blob/master/easing.js
|
||||
const PI_D2 = (Math.PI / 2);
|
||||
const PI_D2 = Math.PI / 2;
|
||||
const EASING_EQUATIONS = {
|
||||
easeOutSine: function (pos) {
|
||||
return Math.sin(pos * PI_D2);
|
||||
},
|
||||
easeInOutSine: function (pos) {
|
||||
return (-0.5 * (Math.cos(Math.PI * pos) - 1));
|
||||
return -0.5 * (Math.cos(Math.PI * pos) - 1);
|
||||
},
|
||||
easeInOutQuint: function (pos) {
|
||||
if ((pos /= 0.5) < 1) {
|
||||
return 0.5 * Math.pow(pos, 5);
|
||||
}
|
||||
return 0.5 * (Math.pow((pos - 2), 5) + 2);
|
||||
return 0.5 * (Math.pow(pos - 2, 5) + 2);
|
||||
},
|
||||
easeInCubic: function (pos) {
|
||||
return Math.pow(pos, 3);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
class Snap {
|
||||
constructor(manager, options) {
|
||||
|
||||
this.settings = extend({
|
||||
this.settings = extend(
|
||||
{
|
||||
duration: 80,
|
||||
minVelocity: 0.2,
|
||||
minDistance: 10,
|
||||
easing: EASING_EQUATIONS['easeInCubic']
|
||||
}, options || {});
|
||||
easing: EASING_EQUATIONS["easeInCubic"],
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
|
||||
this.supportsTouch = this.supportsTouch();
|
||||
|
||||
|
@ -55,8 +57,6 @@ class Snap {
|
|||
this.element.style["WebkitOverflowScrolling"] = "touch";
|
||||
}
|
||||
|
||||
// this.overflow = this.manager.overflow;
|
||||
|
||||
// set lookahead offset to page width
|
||||
this.manager.settings.offset = this.layout.width;
|
||||
this.manager.settings.afterScrolledTimeout = this.settings.duration * 2;
|
||||
|
@ -72,7 +72,6 @@ class Snap {
|
|||
this.resizeCanceler = false;
|
||||
this.snapping = false;
|
||||
|
||||
|
||||
this.scrollLeft;
|
||||
this.scrollTop;
|
||||
|
||||
|
@ -87,7 +86,10 @@ class Snap {
|
|||
}
|
||||
|
||||
supportsTouch() {
|
||||
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
|
||||
if (
|
||||
"ontouchstart" in window ||
|
||||
(window.DocumentTouch && document instanceof DocumentTouch)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -104,44 +106,56 @@ class Snap {
|
|||
|
||||
addListeners() {
|
||||
this._onResize = this.onResize.bind(this);
|
||||
window.addEventListener('resize', this._onResize);
|
||||
window.addEventListener("resize", this._onResize);
|
||||
|
||||
this._onScroll = this.onScroll.bind(this);
|
||||
this.scroller.addEventListener('scroll', this._onScroll);
|
||||
this.scroller.addEventListener("scroll", this._onScroll);
|
||||
|
||||
this._onTouchStart = this.onTouchStart.bind(this);
|
||||
this.scroller.addEventListener('touchstart', this._onTouchStart, { passive: true });
|
||||
this.on('touchstart', this._onTouchStart);
|
||||
this.scroller.addEventListener("touchstart", this._onTouchStart, {
|
||||
passive: true,
|
||||
});
|
||||
this.on("touchstart", this._onTouchStart);
|
||||
|
||||
this._onTouchMove = this.onTouchMove.bind(this);
|
||||
this.scroller.addEventListener('touchmove', this._onTouchMove, { passive: true });
|
||||
this.on('touchmove', this._onTouchMove);
|
||||
this.scroller.addEventListener("touchmove", this._onTouchMove, {
|
||||
passive: true,
|
||||
});
|
||||
this.on("touchmove", this._onTouchMove);
|
||||
|
||||
this._onTouchEnd = this.onTouchEnd.bind(this);
|
||||
this.scroller.addEventListener('touchend', this._onTouchEnd, { passive: true });
|
||||
this.on('touchend', this._onTouchEnd);
|
||||
this.scroller.addEventListener("touchend", this._onTouchEnd, {
|
||||
passive: true,
|
||||
});
|
||||
this.on("touchend", this._onTouchEnd);
|
||||
|
||||
this._afterDisplayed = this.afterDisplayed.bind(this);
|
||||
this.manager.on(EVENTS.MANAGERS.ADDED, this._afterDisplayed);
|
||||
}
|
||||
|
||||
removeListeners() {
|
||||
window.removeEventListener('resize', this._onResize);
|
||||
window.removeEventListener("resize", this._onResize);
|
||||
this._onResize = undefined;
|
||||
|
||||
this.scroller.removeEventListener('scroll', this._onScroll);
|
||||
this.scroller.removeEventListener("scroll", this._onScroll);
|
||||
this._onScroll = undefined;
|
||||
|
||||
this.scroller.removeEventListener('touchstart', this._onTouchStart, { passive: true });
|
||||
this.off('touchstart', this._onTouchStart);
|
||||
this.scroller.removeEventListener("touchstart", this._onTouchStart, {
|
||||
passive: true,
|
||||
});
|
||||
this.off("touchstart", this._onTouchStart);
|
||||
this._onTouchStart = undefined;
|
||||
|
||||
this.scroller.removeEventListener('touchmove', this._onTouchMove, { passive: true });
|
||||
this.off('touchmove', this._onTouchMove);
|
||||
this.scroller.removeEventListener("touchmove", this._onTouchMove, {
|
||||
passive: true,
|
||||
});
|
||||
this.off("touchmove", this._onTouchMove);
|
||||
this._onTouchMove = undefined;
|
||||
|
||||
this.scroller.removeEventListener('touchend', this._onTouchEnd, { passive: true });
|
||||
this.off('touchend', this._onTouchEnd);
|
||||
this.scroller.removeEventListener("touchend", this._onTouchEnd, {
|
||||
passive: true,
|
||||
});
|
||||
this.off("touchend", this._onTouchEnd);
|
||||
this._onTouchEnd = undefined;
|
||||
|
||||
this.manager.off(EVENTS.MANAGERS.ADDED, this._afterDisplayed);
|
||||
|
@ -194,7 +208,6 @@ class Snap {
|
|||
|
||||
this.touchCanceler = true;
|
||||
|
||||
|
||||
if (!this.fullsize && deltaY < 10) {
|
||||
this.element.scrollLeft -= screenX - this.endTouchX;
|
||||
}
|
||||
|
@ -229,10 +242,10 @@ class Snap {
|
|||
|
||||
wasSwiped() {
|
||||
let snapWidth = this.layout.pageWidth * this.layout.divisor;
|
||||
let distance = (this.endTouchX - this.startTouchX);
|
||||
let distance = this.endTouchX - this.startTouchX;
|
||||
let absolute = Math.abs(distance);
|
||||
let time = this.endTime - this.startTime;
|
||||
let velocity = (distance / time);
|
||||
let velocity = distance / time;
|
||||
let minVelocity = this.settings.minVelocity;
|
||||
|
||||
if (absolute <= this.settings.minDistance || absolute >= snapWidth) {
|
||||
|
@ -251,7 +264,7 @@ class Snap {
|
|||
needsSnap() {
|
||||
let left = this.scrollLeft;
|
||||
let snapWidth = this.layout.pageWidth * this.layout.divisor;
|
||||
return (left % snapWidth) !== 0;
|
||||
return left % snapWidth !== 0;
|
||||
}
|
||||
|
||||
snap(howMany = 0) {
|
||||
|
@ -260,7 +273,7 @@ class Snap {
|
|||
let snapTo = Math.round(left / snapWidth) * snapWidth;
|
||||
|
||||
if (howMany) {
|
||||
snapTo += (howMany * snapWidth);
|
||||
snapTo += howMany * snapWidth;
|
||||
}
|
||||
|
||||
return this.smoothScrollTo(snapTo);
|
||||
|
@ -272,16 +285,13 @@ class Snap {
|
|||
const startTime = this.now();
|
||||
|
||||
const duration = this.settings.duration;
|
||||
const easing = this.settings.easing;
|
||||
|
||||
this.snapping = true;
|
||||
|
||||
// add animation loop
|
||||
function tick() {
|
||||
const now = this.now();
|
||||
const time = Math.min(1, ((now - startTime) / duration));
|
||||
const timeFunction = easing(time);
|
||||
|
||||
const time = Math.min(1, (now - startTime) / duration);
|
||||
|
||||
if (this.touchCanceler || this.resizeCanceler) {
|
||||
this.resizeCanceler = false;
|
||||
|
@ -292,7 +302,7 @@ class Snap {
|
|||
|
||||
if (time < 1) {
|
||||
window.requestAnimationFrame(tick.bind(this));
|
||||
this.scrollTo(start + ((destination - start) * time), 0);
|
||||
this.scrollTo(start + (destination - start) * time, 0);
|
||||
} else {
|
||||
this.scrollTo(destination, 0);
|
||||
this.snapping = false;
|
||||
|
@ -315,7 +325,9 @@ class Snap {
|
|||
}
|
||||
|
||||
now() {
|
||||
return ('now' in window.performance) ? performance.now() : new Date().getTime();
|
||||
return "now" in window.performance
|
||||
? performance.now()
|
||||
: new Date().getTime();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import {uuid, isNumber, isElement, windowBounds, extend} from "../../utils/core";
|
||||
import throttle from 'lodash/throttle'
|
||||
import throttle from "lodash/throttle";
|
||||
import {
|
||||
extend,
|
||||
isElement,
|
||||
isNumber,
|
||||
uuid,
|
||||
windowBounds,
|
||||
} from "../../utils/core";
|
||||
|
||||
class Stage {
|
||||
constructor(_options) {
|
||||
|
@ -11,7 +17,6 @@ class Stage {
|
|||
if (this.settings.hidden) {
|
||||
this.wrapper = this.wrap(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,8 +24,8 @@ class Stage {
|
|||
* Resizes to passed width and height or to the elements size
|
||||
*/
|
||||
create(options) {
|
||||
let height = options.height;// !== false ? options.height : "100%";
|
||||
let width = options.width;// !== false ? options.width : "100%";
|
||||
let height = options.height;
|
||||
let width = options.width;
|
||||
let overflow = options.overflow || false;
|
||||
let axis = options.axis || "vertical";
|
||||
let direction = options.direction;
|
||||
|
@ -42,14 +47,12 @@ class Stage {
|
|||
container.classList.add("epub-container");
|
||||
|
||||
// Style Element
|
||||
// container.style.fontSize = "0";
|
||||
container.style.wordSpacing = "0";
|
||||
container.style.lineHeight = "0";
|
||||
container.style.verticalAlign = "top";
|
||||
container.style.position = "relative";
|
||||
|
||||
if (axis === "horizontal") {
|
||||
// container.style.whiteSpace = "nowrap";
|
||||
container.style.display = "flex";
|
||||
container.style.flexDirection = "row";
|
||||
container.style.flexWrap = "nowrap";
|
||||
|
@ -99,7 +102,6 @@ class Stage {
|
|||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
getElement(_element) {
|
||||
var element;
|
||||
|
||||
|
@ -117,7 +119,6 @@ class Stage {
|
|||
}
|
||||
|
||||
attachTo(what) {
|
||||
|
||||
var element = this.getElement(what);
|
||||
var base;
|
||||
|
||||
|
@ -136,7 +137,6 @@ class Stage {
|
|||
this.element = element;
|
||||
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
getContainer() {
|
||||
|
@ -146,17 +146,19 @@ class Stage {
|
|||
onResize(func) {
|
||||
// Only listen to window for resize event if width and height are not fixed.
|
||||
// This applies if it is set to a percent or auto.
|
||||
if(!isNumber(this.settings.width) ||
|
||||
!isNumber(this.settings.height) ) {
|
||||
if (!isNumber(this.settings.width) || !isNumber(this.settings.height)) {
|
||||
this.resizeFunc = throttle(func, 50);
|
||||
window.addEventListener("resize", this.resizeFunc, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onOrientationChange(func) {
|
||||
this.orientationChangeFunc = func;
|
||||
window.addEventListener("orientationchange", this.orientationChangeFunc, false);
|
||||
window.addEventListener(
|
||||
"orientationchange",
|
||||
this.orientationChangeFunc,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
size(width, height) {
|
||||
|
@ -187,7 +189,6 @@ class Stage {
|
|||
height = bounds.height;
|
||||
this.container.style.height = height + "px";
|
||||
}
|
||||
|
||||
} else {
|
||||
if (isNumber(height)) {
|
||||
this.container.style.height = height + "px";
|
||||
|
@ -210,7 +211,7 @@ class Stage {
|
|||
left: parseFloat(this.containerStyles["padding-left"]) || 0,
|
||||
right: parseFloat(this.containerStyles["padding-right"]) || 0,
|
||||
top: parseFloat(this.containerStyles["padding-top"]) || 0,
|
||||
bottom: parseFloat(this.containerStyles["padding-bottom"]) || 0
|
||||
bottom: parseFloat(this.containerStyles["padding-bottom"]) || 0,
|
||||
};
|
||||
|
||||
// Bounds not set, get them from window
|
||||
|
@ -220,30 +221,21 @@ class Stage {
|
|||
left: parseFloat(bodyStyles["padding-left"]) || 0,
|
||||
right: parseFloat(bodyStyles["padding-right"]) || 0,
|
||||
top: parseFloat(bodyStyles["padding-top"]) || 0,
|
||||
bottom: parseFloat(bodyStyles["padding-bottom"]) || 0
|
||||
bottom: parseFloat(bodyStyles["padding-bottom"]) || 0,
|
||||
};
|
||||
|
||||
if (!_width) {
|
||||
width = _windowBounds.width -
|
||||
bodyPadding.left -
|
||||
bodyPadding.right;
|
||||
width = _windowBounds.width - bodyPadding.left - bodyPadding.right;
|
||||
}
|
||||
|
||||
if ((this.settings.fullsize && !_height) || !_height) {
|
||||
height = _windowBounds.height -
|
||||
bodyPadding.top -
|
||||
bodyPadding.bottom;
|
||||
height = _windowBounds.height - bodyPadding.top - bodyPadding.bottom;
|
||||
}
|
||||
|
||||
return {
|
||||
width: width -
|
||||
this.containerPadding.left -
|
||||
this.containerPadding.right,
|
||||
height: height -
|
||||
this.containerPadding.top -
|
||||
this.containerPadding.bottom
|
||||
width: width - this.containerPadding.left - this.containerPadding.right,
|
||||
height: height - this.containerPadding.top - this.containerPadding.bottom,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bounds() {
|
||||
|
@ -257,7 +249,6 @@ class Stage {
|
|||
} else {
|
||||
return box;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getSheet() {
|
||||
|
@ -301,16 +292,6 @@ class Stage {
|
|||
this.settings.axis = axis;
|
||||
}
|
||||
|
||||
// orientation(orientation) {
|
||||
// if (orientation === "landscape") {
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// this.orientation = orientation;
|
||||
// }
|
||||
|
||||
direction(dir) {
|
||||
if (this.container) {
|
||||
this.container.dir = dir;
|
||||
|
@ -339,23 +320,16 @@ class Stage {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
var base;
|
||||
|
||||
if (this.element) {
|
||||
|
||||
if(this.settings.hidden) {
|
||||
base = this.wrapper;
|
||||
} else {
|
||||
base = this.container;
|
||||
}
|
||||
|
||||
if (this.element.contains(this.container)) {
|
||||
this.element.removeChild(this.container);
|
||||
}
|
||||
|
||||
window.removeEventListener("resize", this.resizeFunc);
|
||||
window.removeEventListener("orientationChange", this.orientationChangeFunc);
|
||||
|
||||
window.removeEventListener(
|
||||
"orientationChange",
|
||||
this.orientationChangeFunc
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,10 @@ class Views {
|
|||
|
||||
if (this.container) {
|
||||
if (index < this.container.children.length) {
|
||||
this.container.insertBefore(view.element, this.container.children[index]);
|
||||
this.container.insertBefore(
|
||||
view.element,
|
||||
this.container.children[index]
|
||||
);
|
||||
} else {
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
|
@ -70,7 +73,6 @@ class Views {
|
|||
this._views.splice(index, 1);
|
||||
}
|
||||
|
||||
|
||||
this.destroy(view);
|
||||
|
||||
this.length--;
|
||||
|
@ -110,7 +112,6 @@ class Views {
|
|||
}
|
||||
|
||||
find(section) {
|
||||
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
|
@ -120,7 +121,6 @@ class Views {
|
|||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
displayed() {
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import {extend, borders, uuid, isNumber, bounds, defer, createBlobUrl, revokeBlobUrl} from "../../utils/core";
|
||||
import EpubCFI from "../../epubcfi";
|
||||
import { Highlight, Pane, Underline } from "marks-pane";
|
||||
import Contents from "../../contents";
|
||||
import EpubCFI from "../../epubcfi";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import { Pane, Highlight, Underline } from "marks-pane";
|
||||
import {
|
||||
borders,
|
||||
bounds,
|
||||
createBlobUrl,
|
||||
defer,
|
||||
extend,
|
||||
isNumber,
|
||||
revokeBlobUrl,
|
||||
uuid,
|
||||
} from "../../utils/core";
|
||||
|
||||
class IframeView {
|
||||
constructor(section, options) {
|
||||
this.settings = extend({
|
||||
this.settings = extend(
|
||||
{
|
||||
ignoreClass: "",
|
||||
axis: undefined, //options.layout && options.layout.props.flow === "scrolled" ? "vertical" : "horizontal",
|
||||
direction: undefined,
|
||||
|
@ -18,8 +28,10 @@ class IframeView {
|
|||
method: undefined,
|
||||
forceRight: false,
|
||||
allowScriptedContent: false,
|
||||
allowPopups: false
|
||||
}, options || {});
|
||||
allowPopups: false,
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
|
||||
this.id = "epubjs-view-" + uuid();
|
||||
this.section = section;
|
||||
|
@ -48,7 +60,6 @@ class IframeView {
|
|||
this.highlights = {};
|
||||
this.underlines = {};
|
||||
this.marks = {};
|
||||
|
||||
}
|
||||
|
||||
container(axis) {
|
||||
|
@ -73,7 +84,6 @@ class IframeView {
|
|||
}
|
||||
|
||||
create() {
|
||||
|
||||
if (this.iframe) {
|
||||
return this.iframe;
|
||||
}
|
||||
|
@ -100,34 +110,18 @@ class IframeView {
|
|||
}
|
||||
|
||||
this.iframe.setAttribute("enable-annotation", "true");
|
||||
|
||||
this.resizing = true;
|
||||
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
|
||||
this.iframe.style.width = "0";
|
||||
this.iframe.style.height = "0";
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
|
||||
this.element.setAttribute("ref", this.index);
|
||||
|
||||
this.added = true;
|
||||
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
// if(width || height){
|
||||
// this.resize(width, height);
|
||||
// } else if(this.width && this.height){
|
||||
// this.resize(this.width, this.height);
|
||||
// } else {
|
||||
// this.iframeBounds = bounds(this.iframe);
|
||||
// }
|
||||
|
||||
|
||||
if(("srcdoc" in this.iframe)) {
|
||||
if ("srcdoc" in this.iframe) {
|
||||
this.supportsSrcdoc = true;
|
||||
} else {
|
||||
this.supportsSrcdoc = false;
|
||||
|
@ -141,10 +135,7 @@ class IframeView {
|
|||
}
|
||||
|
||||
render(request, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
this.create();
|
||||
|
||||
// Fit to size of the container, apply padding
|
||||
this.size();
|
||||
|
||||
|
@ -154,23 +145,30 @@ class IframeView {
|
|||
|
||||
// Render Chain
|
||||
return this.sectionRender
|
||||
.then(function(contents){
|
||||
.then(
|
||||
function (contents) {
|
||||
return this.load(contents);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
// find and report the writingMode axis
|
||||
let writingMode = this.contents.writingMode();
|
||||
|
||||
// Set the axis based on the flow and writing mode
|
||||
let axis;
|
||||
if (this.settings.flow === "scrolled") {
|
||||
axis = (writingMode.indexOf("vertical") === 0) ? "horizontal" : "vertical";
|
||||
axis =
|
||||
writingMode.indexOf("vertical") === 0 ? "horizontal" : "vertical";
|
||||
} else {
|
||||
axis = (writingMode.indexOf("vertical") === 0) ? "vertical" : "horizontal";
|
||||
axis =
|
||||
writingMode.indexOf("vertical") === 0 ? "vertical" : "horizontal";
|
||||
}
|
||||
|
||||
if (writingMode.indexOf("vertical") === 0 && this.settings.flow === "paginated") {
|
||||
if (
|
||||
writingMode.indexOf("vertical") === 0 &&
|
||||
this.settings.flow === "paginated"
|
||||
) {
|
||||
this.layout.delta = this.layout.height;
|
||||
}
|
||||
|
||||
|
@ -180,7 +178,6 @@ class IframeView {
|
|||
this.setWritingMode(writingMode);
|
||||
this.emit(EVENTS.VIEWS.WRITING_MODE, writingMode);
|
||||
|
||||
|
||||
// apply the layout function to the contents
|
||||
this.layout.format(this.contents, this.section, this.axis);
|
||||
|
||||
|
@ -196,17 +193,19 @@ class IframeView {
|
|||
}
|
||||
resolve();
|
||||
});
|
||||
|
||||
}.bind(this), function(e){
|
||||
}.bind(this),
|
||||
function (e) {
|
||||
this.emit(EVENTS.VIEWS.LOAD_ERROR, e);
|
||||
return new Promise((resolve, reject) => {
|
||||
reject(e);
|
||||
});
|
||||
}.bind(this))
|
||||
.then(function() {
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
this.emit(EVENTS.VIEWS.RENDERED, this.section);
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
@ -253,31 +252,20 @@ class IframeView {
|
|||
|
||||
if (what == "width" && isNumber(width)) {
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
// this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if (what == "height" && isNumber(height)) {
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
// this.resize(width, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
isNumber(width) &&
|
||||
isNumber(height)){
|
||||
|
||||
if (what === "both" && isNumber(width) && isNumber(height)) {
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
// this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
if (this.displayed && this.iframe) {
|
||||
|
||||
// this.contents.layout();
|
||||
this.expand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Resize a single axis based on content dimensions
|
||||
|
@ -286,8 +274,6 @@ class IframeView {
|
|||
var height = this.lockedHeight;
|
||||
var columns;
|
||||
|
||||
var textWidth, textHeight;
|
||||
|
||||
if (!this.iframe || this._expanding) return;
|
||||
|
||||
this._expanding = true;
|
||||
|
@ -302,24 +288,28 @@ class IframeView {
|
|||
width = this.contents.textWidth();
|
||||
|
||||
if (width % this.layout.pageWidth > 0) {
|
||||
width = Math.ceil(width / this.layout.pageWidth) * this.layout.pageWidth;
|
||||
width =
|
||||
Math.ceil(width / this.layout.pageWidth) * this.layout.pageWidth;
|
||||
}
|
||||
|
||||
if (this.settings.forceEvenPages) {
|
||||
columns = (width / this.layout.pageWidth);
|
||||
if ( this.layout.divisor > 1 &&
|
||||
columns = width / this.layout.pageWidth;
|
||||
if (
|
||||
this.layout.divisor > 1 &&
|
||||
this.layout.name === "reflowable" &&
|
||||
(columns % 2 > 0)) {
|
||||
columns % 2 > 0
|
||||
) {
|
||||
// add a blank page
|
||||
width += this.layout.pageWidth;
|
||||
}
|
||||
}
|
||||
|
||||
} // Expand Vertically
|
||||
else if (this.settings.axis === "vertical") {
|
||||
height = this.contents.textHeight();
|
||||
if (this.settings.flow === "paginated" &&
|
||||
height % this.layout.height > 0) {
|
||||
if (
|
||||
this.settings.flow === "paginated" &&
|
||||
height % this.layout.height > 0
|
||||
) {
|
||||
height = Math.ceil(height / this.layout.height) * this.layout.height;
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +339,9 @@ class IframeView {
|
|||
}
|
||||
|
||||
let widthDelta = this.prevBounds ? width - this.prevBounds.width : width;
|
||||
let heightDelta = this.prevBounds ? height - this.prevBounds.height : height;
|
||||
let heightDelta = this.prevBounds
|
||||
? height - this.prevBounds.height
|
||||
: height;
|
||||
|
||||
size = {
|
||||
width: width,
|
||||
|
@ -377,10 +369,8 @@ class IframeView {
|
|||
this.prevBounds = size;
|
||||
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
}
|
||||
|
||||
|
||||
load(contents) {
|
||||
var loading = new defer();
|
||||
var loaded = loading.promise;
|
||||
|
@ -391,9 +381,7 @@ class IframeView {
|
|||
}
|
||||
|
||||
this.iframe.onload = function (event) {
|
||||
|
||||
this.onLoad(event, loading);
|
||||
|
||||
}.bind(this);
|
||||
|
||||
if (this.settings.method === "blobUrl") {
|
||||
|
@ -404,7 +392,6 @@ class IframeView {
|
|||
this.iframe.srcdoc = contents;
|
||||
this.element.appendChild(this.iframe);
|
||||
} else {
|
||||
|
||||
this.element.appendChild(this.iframe);
|
||||
|
||||
this.document = this.iframe.contentDocument;
|
||||
|
@ -425,18 +412,21 @@ class IframeView {
|
|||
this.iframe.contentDocument.write(contents);
|
||||
}
|
||||
this.iframe.contentDocument.close();
|
||||
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
onLoad(event, promise) {
|
||||
|
||||
this.window = this.iframe.contentWindow;
|
||||
this.document = this.iframe.contentDocument;
|
||||
|
||||
this.contents = new Contents(this.document, this.document.body, this.section.cfiBase, this.section.index);
|
||||
this.contents = new Contents(
|
||||
this.document,
|
||||
this.document.body,
|
||||
this.section.cfiBase,
|
||||
this.section.index
|
||||
);
|
||||
|
||||
this.rendering = false;
|
||||
|
||||
|
@ -481,7 +471,6 @@ class IframeView {
|
|||
}
|
||||
|
||||
setAxis(axis) {
|
||||
|
||||
this.settings.axis = axis;
|
||||
|
||||
if (axis == "horizontal") {
|
||||
|
@ -491,11 +480,9 @@ class IframeView {
|
|||
}
|
||||
|
||||
this.size();
|
||||
|
||||
}
|
||||
|
||||
setWritingMode(mode) {
|
||||
// this.element.style.writingMode = writingMode;
|
||||
this.writingMode = mode;
|
||||
}
|
||||
|
||||
|
@ -511,30 +498,26 @@ class IframeView {
|
|||
var displayed = new defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
|
||||
this.render(request)
|
||||
.then(function () {
|
||||
|
||||
this.render(request).then(
|
||||
function () {
|
||||
this.emit(EVENTS.VIEWS.DISPLAYED, this);
|
||||
this.onDisplayed(this);
|
||||
|
||||
this.displayed = true;
|
||||
displayed.resolve(this);
|
||||
|
||||
}.bind(this), function (err) {
|
||||
}.bind(this),
|
||||
function (err) {
|
||||
displayed.reject(err, this);
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
|
||||
|
||||
return displayed.promise;
|
||||
}
|
||||
|
||||
show() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
if (this.iframe) {
|
||||
|
@ -550,7 +533,6 @@ class IframeView {
|
|||
}
|
||||
|
||||
hide() {
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
|
||||
|
@ -561,8 +543,8 @@ class IframeView {
|
|||
offset() {
|
||||
return {
|
||||
top: this.element.offsetTop,
|
||||
left: this.element.offsetLeft
|
||||
}
|
||||
left: this.element.offsetLeft,
|
||||
};
|
||||
}
|
||||
|
||||
width() {
|
||||
|
@ -578,12 +560,11 @@ class IframeView {
|
|||
}
|
||||
|
||||
locationOf(target) {
|
||||
var parentPos = this.iframe.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
return {
|
||||
"left": targetPos.left,
|
||||
"top": targetPos.top
|
||||
left: targetPos.left,
|
||||
top: targetPos.top,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -607,7 +588,10 @@ class IframeView {
|
|||
if (!this.contents) {
|
||||
return;
|
||||
}
|
||||
const attributes = Object.assign({"fill": "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply"}, styles);
|
||||
const attributes = Object.assign(
|
||||
{ fill: "yellow", "fill-opacity": "0.3", "mix-blend-mode": "multiply" },
|
||||
styles
|
||||
);
|
||||
let range = this.contents.range(cfiRange);
|
||||
|
||||
let emitter = () => {
|
||||
|
@ -623,7 +607,11 @@ class IframeView {
|
|||
let m = new Highlight(range, className, data, attributes);
|
||||
let h = this.pane.addMark(m);
|
||||
|
||||
this.highlights[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] };
|
||||
this.highlights[cfiRange] = {
|
||||
mark: h,
|
||||
element: h.element,
|
||||
listeners: [emitter, cb],
|
||||
};
|
||||
|
||||
h.element.setAttribute("ref", className);
|
||||
h.element.addEventListener("click", emitter);
|
||||
|
@ -640,7 +628,14 @@ class IframeView {
|
|||
if (!this.contents) {
|
||||
return;
|
||||
}
|
||||
const attributes = Object.assign({"stroke": "black", "stroke-opacity": "0.3", "mix-blend-mode": "multiply"}, styles);
|
||||
const attributes = Object.assign(
|
||||
{
|
||||
stroke: "black",
|
||||
"stroke-opacity": "0.3",
|
||||
"mix-blend-mode": "multiply",
|
||||
},
|
||||
styles
|
||||
);
|
||||
let range = this.contents.range(cfiRange);
|
||||
let emitter = () => {
|
||||
this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data);
|
||||
|
@ -655,7 +650,11 @@ class IframeView {
|
|||
let m = new Underline(range, className, data, attributes);
|
||||
let h = this.pane.addMark(m);
|
||||
|
||||
this.underlines[cfiRange] = { "mark": h, "element": h.element, "listeners": [emitter, cb] };
|
||||
this.underlines[cfiRange] = {
|
||||
mark: h,
|
||||
element: h.element,
|
||||
listeners: [emitter, cb],
|
||||
};
|
||||
|
||||
h.element.setAttribute("ref", className);
|
||||
h.element.addEventListener("click", emitter);
|
||||
|
@ -683,7 +682,7 @@ class IframeView {
|
|||
return;
|
||||
}
|
||||
let container = range.commonAncestorContainer;
|
||||
let parent = (container.nodeType === 1) ? container : container.parentNode;
|
||||
let parent = container.nodeType === 1 ? container : container.parentNode;
|
||||
|
||||
let emitter = (e) => {
|
||||
this.emit(EVENTS.VIEWS.MARK_CLICKED, cfiRange, data);
|
||||
|
@ -692,7 +691,8 @@ class IframeView {
|
|||
if (range.collapsed && container.nodeType === 1) {
|
||||
range = new Range();
|
||||
range.selectNodeContents(container);
|
||||
} else if (range.collapsed) { // Webkit doesn't like collapsed ranges
|
||||
} else if (range.collapsed) {
|
||||
// Webkit doesn't like collapsed ranges
|
||||
range = new Range();
|
||||
range.selectNodeContents(parent);
|
||||
}
|
||||
|
@ -721,7 +721,11 @@ class IframeView {
|
|||
|
||||
this.element.appendChild(mark);
|
||||
|
||||
this.marks[cfiRange] = { "element": mark, "range": range, "listeners": [emitter, cb] };
|
||||
this.marks[cfiRange] = {
|
||||
element: mark,
|
||||
range: range,
|
||||
listeners: [emitter, cb],
|
||||
};
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
@ -729,8 +733,10 @@ class IframeView {
|
|||
placeMark(element, range) {
|
||||
let top, right, left;
|
||||
|
||||
if(this.layout.name === "pre-paginated" ||
|
||||
this.settings.axis !== "horizontal") {
|
||||
if (
|
||||
this.layout.name === "pre-paginated" ||
|
||||
this.settings.axis !== "horizontal"
|
||||
) {
|
||||
let pos = range.getBoundingClientRect();
|
||||
top = pos.top;
|
||||
right = pos.right;
|
||||
|
@ -743,8 +749,10 @@ class IframeView {
|
|||
rect = rects[i];
|
||||
if (!left || rect.left < left) {
|
||||
left = rect.left;
|
||||
// right = rect.right;
|
||||
right = Math.ceil(left / this.layout.props.pageWidth) * this.layout.props.pageWidth - (this.layout.gap / 2);
|
||||
right =
|
||||
Math.ceil(left / this.layout.props.pageWidth) *
|
||||
this.layout.props.pageWidth -
|
||||
this.layout.gap / 2;
|
||||
top = rect.top;
|
||||
}
|
||||
}
|
||||
|
@ -764,7 +772,7 @@ class IframeView {
|
|||
if (l) {
|
||||
item.element.removeEventListener("click", l);
|
||||
item.element.removeEventListener("touchstart", l);
|
||||
};
|
||||
}
|
||||
});
|
||||
delete this.highlights[cfiRange];
|
||||
}
|
||||
|
@ -779,7 +787,7 @@ class IframeView {
|
|||
if (l) {
|
||||
item.element.removeEventListener("click", l);
|
||||
item.element.removeEventListener("touchstart", l);
|
||||
};
|
||||
}
|
||||
});
|
||||
delete this.underlines[cfiRange];
|
||||
}
|
||||
|
@ -794,14 +802,13 @@ class IframeView {
|
|||
if (l) {
|
||||
item.element.removeEventListener("click", l);
|
||||
item.element.removeEventListener("touchstart", l);
|
||||
};
|
||||
}
|
||||
});
|
||||
delete this.marks[cfiRange];
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
||||
for (let cfiRange in this.highlights) {
|
||||
this.unhighlight(cfiRange);
|
||||
}
|
||||
|
@ -840,9 +847,6 @@ class IframeView {
|
|||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,31 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import {extend, borders, uuid, isNumber, bounds, defer, qs, parse} from "../../utils/core";
|
||||
import EpubCFI from "../../epubcfi";
|
||||
import Contents from "../../contents";
|
||||
import EpubCFI from "../../epubcfi";
|
||||
import { EVENTS } from "../../utils/constants";
|
||||
import {
|
||||
borders,
|
||||
bounds,
|
||||
defer,
|
||||
extend,
|
||||
isNumber,
|
||||
parse,
|
||||
qs,
|
||||
uuid,
|
||||
} from "../../utils/core";
|
||||
|
||||
class InlineView {
|
||||
constructor(section, options) {
|
||||
this.settings = extend({
|
||||
this.settings = extend(
|
||||
{
|
||||
ignoreClass: "",
|
||||
axis: "vertical",
|
||||
width: 0,
|
||||
height: 0,
|
||||
layout: undefined,
|
||||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
|
||||
this.id = "epubjs-view:" + uuid();
|
||||
this.section = section;
|
||||
|
@ -35,24 +47,11 @@ class InlineView {
|
|||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
|
||||
}
|
||||
|
||||
container(axis) {
|
||||
var element = document.createElement("div");
|
||||
|
||||
element.classList.add("epub-view");
|
||||
|
||||
// if(this.settings.axis === "horizontal") {
|
||||
// element.style.width = "auto";
|
||||
// element.style.height = "0";
|
||||
// } else {
|
||||
// element.style.width = "0";
|
||||
// element.style.height = "auto";
|
||||
// }
|
||||
|
||||
element.style.overflow = "hidden";
|
||||
|
||||
if (axis && axis == "horizontal") {
|
||||
|
@ -65,7 +64,6 @@ class InlineView {
|
|||
}
|
||||
|
||||
create() {
|
||||
|
||||
if (this.frame) {
|
||||
return this.frame;
|
||||
}
|
||||
|
@ -82,7 +80,6 @@ class InlineView {
|
|||
|
||||
this.resizing = true;
|
||||
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
|
@ -106,56 +103,37 @@ class InlineView {
|
|||
}
|
||||
|
||||
render(request, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
this.create();
|
||||
|
||||
// Fit to size of the container, apply padding
|
||||
this.size();
|
||||
|
||||
// Render Chain
|
||||
return this.section.render(request)
|
||||
.then(function(contents){
|
||||
return this.section
|
||||
.render(request)
|
||||
.then(
|
||||
function (contents) {
|
||||
return this.load(contents);
|
||||
}.bind(this))
|
||||
// .then(function(doc){
|
||||
// return this.hooks.content.trigger(view, this);
|
||||
// }.bind(this))
|
||||
.then(function(){
|
||||
// this.settings.layout.format(view.contents);
|
||||
// return this.hooks.layout.trigger(view, this);
|
||||
}.bind(this))
|
||||
// .then(function(){
|
||||
// return this.display();
|
||||
// }.bind(this))
|
||||
// .then(function(){
|
||||
// return this.hooks.render.trigger(view, this);
|
||||
// }.bind(this))
|
||||
.then(function(){
|
||||
|
||||
}.bind(this)
|
||||
)
|
||||
.then(function () {}.bind(this))
|
||||
.then(
|
||||
function () {
|
||||
// apply the layout function to the contents
|
||||
this.settings.layout.format(this.contents);
|
||||
|
||||
// Expand the iframe to the full size of the content
|
||||
// this.expand();
|
||||
|
||||
// Listen for events that require an expansion of the iframe
|
||||
this.addListeners();
|
||||
|
||||
if (show !== false) {
|
||||
//this.q.enqueue(function(view){
|
||||
this.show();
|
||||
//}, view);
|
||||
}
|
||||
// this.map = new Map(view, this.layout);
|
||||
//this.hooks.show.trigger(view, this);
|
||||
this.emit(EVENTS.VIEWS.RENDERED, this.section);
|
||||
|
||||
}.bind(this))
|
||||
.catch(function(e){
|
||||
}.bind(this)
|
||||
)
|
||||
.catch(
|
||||
function (e) {
|
||||
this.emit(EVENTS.VIEWS.LOAD_ERROR, e);
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
// Determine locks base on settings
|
||||
|
@ -171,7 +149,6 @@ class InlineView {
|
|||
} else {
|
||||
this.lock("width", width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
|
@ -195,16 +172,12 @@ class InlineView {
|
|||
this.resize(false, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
isNumber(width) &&
|
||||
isNumber(height)){
|
||||
|
||||
if (what === "both" && isNumber(width) && isNumber(height)) {
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Resize a single axis based on content dimensions
|
||||
|
@ -243,9 +216,7 @@ class InlineView {
|
|||
return this.frame.scrollHeight;
|
||||
}
|
||||
|
||||
|
||||
resize(width, height) {
|
||||
|
||||
if (!this.frame) return;
|
||||
|
||||
if (isNumber(width)) {
|
||||
|
@ -272,32 +243,13 @@ class InlineView {
|
|||
this.onResize(this, size);
|
||||
|
||||
this.emit(EVENTS.VIEWS.RESIZED, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
load(contents) {
|
||||
var loading = new defer();
|
||||
var loaded = loading.promise;
|
||||
var doc = parse(contents, "text/html");
|
||||
var body = qs(doc, "body");
|
||||
|
||||
/*
|
||||
var srcs = doc.querySelectorAll("[src]");
|
||||
|
||||
Array.prototype.slice.call(srcs)
|
||||
.forEach(function(item) {
|
||||
var src = item.getAttribute("src");
|
||||
var assetUri = URI(src);
|
||||
var origin = assetUri.origin();
|
||||
var absoluteUri;
|
||||
|
||||
if (!origin) {
|
||||
absoluteUri = assetUri.absoluteTo(this.section.url);
|
||||
item.src = absoluteUri;
|
||||
}
|
||||
}.bind(this));
|
||||
*/
|
||||
this.frame.innerHTML = body.innerHTML;
|
||||
|
||||
this.document = this.frame.ownerDocument;
|
||||
|
@ -309,7 +261,6 @@ class InlineView {
|
|||
|
||||
loading.resolve(this.contents);
|
||||
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
|
@ -317,12 +268,7 @@ class InlineView {
|
|||
this.layout = layout;
|
||||
}
|
||||
|
||||
|
||||
resizeListenters() {
|
||||
// Test size again
|
||||
// clearTimeout(this.expanding);
|
||||
// this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
}
|
||||
resizeListenters() {}
|
||||
|
||||
addListeners() {
|
||||
//TODO: Add content listeners for expanding
|
||||
|
@ -336,28 +282,24 @@ class InlineView {
|
|||
var displayed = new defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
|
||||
this.render(request).then(function () {
|
||||
|
||||
this.render(request).then(
|
||||
function () {
|
||||
this.emit(EVENTS.VIEWS.DISPLAYED, this);
|
||||
this.onDisplayed(this);
|
||||
|
||||
this.displayed = true;
|
||||
|
||||
displayed.resolve(this);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
|
||||
|
||||
return displayed.promise;
|
||||
}
|
||||
|
||||
show() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
if (this.frame) {
|
||||
|
@ -368,7 +310,6 @@ class InlineView {
|
|||
}
|
||||
|
||||
hide() {
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
|
@ -385,8 +326,8 @@ class InlineView {
|
|||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
return {
|
||||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
left: window.scrollX + parentPos.left + targetPos.left,
|
||||
top: window.scrollY + parentPos.top + targetPos.top,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -406,7 +347,6 @@ class InlineView {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
|
||||
if (this.displayed) {
|
||||
this.displayed = false;
|
||||
|
||||
|
@ -422,8 +362,6 @@ class InlineView {
|
|||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import { nodeBounds } from "./utils/core";
|
|||
class Mapping {
|
||||
constructor(layout, direction, axis, dev = false) {
|
||||
this.layout = layout;
|
||||
this.horizontal = (axis === "horizontal") ? true : false;
|
||||
this.horizontal = axis === "horizontal" ? true : false;
|
||||
this.direction = direction || "ltr";
|
||||
this._dev = dev;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Mapping {
|
|||
|
||||
result = this.rangePairToCfiPair(cfiBase, {
|
||||
start: this.findStart(root, start, end),
|
||||
end: this.findEnd(root, start, end)
|
||||
end: this.findEnd(root, start, end),
|
||||
});
|
||||
|
||||
if (this._dev === true) {
|
||||
|
@ -86,12 +86,17 @@ class Mapping {
|
|||
} else {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
var safeFilter = filter.acceptNode;
|
||||
safeFilter.acceptNode = filter.acceptNode;
|
||||
|
||||
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, safeFilter, false);
|
||||
var treeWalker = document.createTreeWalker(
|
||||
root,
|
||||
NodeFilter.SHOW_TEXT,
|
||||
safeFilter,
|
||||
false
|
||||
);
|
||||
var node;
|
||||
var result;
|
||||
while ((node = treeWalker.nextNode())) {
|
||||
|
@ -113,10 +118,10 @@ class Mapping {
|
|||
|
||||
for (var i = 0; i < count.pages; i++) {
|
||||
start = (columnWidth + gap) * i;
|
||||
end = (columnWidth * (i+1)) + (gap * i);
|
||||
end = columnWidth * (i + 1) + gap * i;
|
||||
columns.push({
|
||||
start: this.findStart(view.document.body, start, end),
|
||||
end: this.findEnd(view.document.body, start, end)
|
||||
end: this.findEnd(view.document.body, start, end),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -138,19 +143,15 @@ class Mapping {
|
|||
var $prev = root;
|
||||
|
||||
while (stack.length) {
|
||||
|
||||
$el = stack.shift();
|
||||
|
||||
found = this.walk($el, (node) => {
|
||||
var left, right, top, bottom;
|
||||
var elPos;
|
||||
var elRange;
|
||||
|
||||
|
||||
elPos = nodeBounds(node);
|
||||
|
||||
if (this.horizontal && this.direction === "ltr") {
|
||||
|
||||
left = this.horizontal ? elPos.left : elPos.top;
|
||||
right = this.horizontal ? elPos.right : elPos.bottom;
|
||||
|
||||
|
@ -162,9 +163,7 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
} else if (this.horizontal && this.direction === "rtl") {
|
||||
|
||||
left = elPos.left;
|
||||
right = elPos.right;
|
||||
|
||||
|
@ -176,9 +175,7 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
top = elPos.top;
|
||||
bottom = elPos.bottom;
|
||||
|
||||
|
@ -190,16 +187,12 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
if (found) {
|
||||
return this.findTextStartRange(found, start, end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return last element
|
||||
|
@ -221,19 +214,15 @@ class Mapping {
|
|||
var found;
|
||||
|
||||
while (stack.length) {
|
||||
|
||||
$el = stack.shift();
|
||||
|
||||
found = this.walk($el, (node) => {
|
||||
|
||||
var left, right, top, bottom;
|
||||
var elPos;
|
||||
var elRange;
|
||||
|
||||
elPos = nodeBounds(node);
|
||||
|
||||
if (this.horizontal && this.direction === "ltr") {
|
||||
|
||||
left = Math.round(elPos.left);
|
||||
right = Math.round(elPos.right);
|
||||
|
||||
|
@ -245,9 +234,7 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
} else if (this.horizontal && this.direction === "rtl") {
|
||||
|
||||
left = Math.round(this.horizontal ? elPos.left : elPos.top);
|
||||
right = Math.round(this.horizontal ? elPos.right : elPos.bottom);
|
||||
|
||||
|
@ -259,9 +246,7 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
top = Math.round(elPos.top);
|
||||
bottom = Math.round(elPos.bottom);
|
||||
|
||||
|
@ -273,16 +258,12 @@ class Mapping {
|
|||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
if (found) {
|
||||
return this.findTextEndRange(found, start, end);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// end of chapter
|
||||
|
@ -309,30 +290,21 @@ class Mapping {
|
|||
pos = range.getBoundingClientRect();
|
||||
|
||||
if (this.horizontal && this.direction === "ltr") {
|
||||
|
||||
left = pos.left;
|
||||
if (left >= start) {
|
||||
return range;
|
||||
}
|
||||
|
||||
} else if (this.horizontal && this.direction === "rtl") {
|
||||
|
||||
right = pos.right;
|
||||
if (right <= end) {
|
||||
return range;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
top = pos.top;
|
||||
if (top >= start) {
|
||||
return range;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// prev = range;
|
||||
|
||||
}
|
||||
|
||||
return ranges[0];
|
||||
|
@ -359,7 +331,6 @@ class Mapping {
|
|||
pos = range.getBoundingClientRect();
|
||||
|
||||
if (this.horizontal && this.direction === "ltr") {
|
||||
|
||||
left = pos.left;
|
||||
right = pos.right;
|
||||
|
||||
|
@ -368,10 +339,8 @@ class Mapping {
|
|||
} else if (right > end) {
|
||||
return range;
|
||||
}
|
||||
|
||||
} else if (this.horizontal && this.direction === "rtl") {
|
||||
|
||||
left = pos.left
|
||||
left = pos.left;
|
||||
right = pos.right;
|
||||
|
||||
if (right < start && prev) {
|
||||
|
@ -379,9 +348,7 @@ class Mapping {
|
|||
} else if (left < start) {
|
||||
return range;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
top = pos.top;
|
||||
bottom = pos.bottom;
|
||||
|
||||
|
@ -390,17 +357,13 @@ class Mapping {
|
|||
} else if (bottom > end) {
|
||||
return range;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
prev = range;
|
||||
|
||||
}
|
||||
|
||||
// Ends before limit
|
||||
return ranges[ranges.length - 1];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -433,10 +396,8 @@ class Mapping {
|
|||
range = false;
|
||||
|
||||
while (pos != -1) {
|
||||
|
||||
pos = text.indexOf(splitter, pos + 1);
|
||||
if (pos > 0) {
|
||||
|
||||
if (range) {
|
||||
range.setEnd(node, pos);
|
||||
ranges.push(range);
|
||||
|
@ -455,7 +416,6 @@ class Mapping {
|
|||
return ranges;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Turn a pair of ranges into a pair of CFIs
|
||||
* @private
|
||||
|
@ -464,7 +424,6 @@ class Mapping {
|
|||
* @return {object} { start: "epubcfi(...)", end: "epubcfi(...)" }
|
||||
*/
|
||||
rangePairToCfiPair(cfiBase, rangePair) {
|
||||
|
||||
var startRange = rangePair.start;
|
||||
var endRange = rangePair.end;
|
||||
|
||||
|
@ -476,9 +435,8 @@ class Mapping {
|
|||
|
||||
return {
|
||||
start: startCfi,
|
||||
end: endCfi
|
||||
end: endCfi,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
rangeListToCfiList(cfiBase, columns) {
|
||||
|
@ -489,7 +447,6 @@ class Mapping {
|
|||
cifPair = this.rangePairToCfiPair(cfiBase, columns[i]);
|
||||
|
||||
map.push(cifPair);
|
||||
|
||||
}
|
||||
|
||||
return map;
|
||||
|
@ -502,7 +459,7 @@ class Mapping {
|
|||
*/
|
||||
axis(axis) {
|
||||
if (axis) {
|
||||
this.horizontal = (axis === "horizontal") ? true : false;
|
||||
this.horizontal = axis === "horizontal" ? true : false;
|
||||
}
|
||||
return this.horizontal;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {qs, qsa, querySelectorByType, filterChildren, getParentByTagName} from "./utils/core";
|
||||
import { filterChildren, qs, qsa, querySelectorByType } from "./utils/core";
|
||||
|
||||
/**
|
||||
* Navigation Parser
|
||||
|
@ -72,7 +72,6 @@ class Navigation {
|
|||
this.unpack(item.subitems);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,8 +190,8 @@ class Navigation {
|
|||
*/
|
||||
navItem(item, parent) {
|
||||
let id = item.getAttribute("id") || undefined;
|
||||
let content = filterChildren(item, "a", true)
|
||||
|| filterChildren(item, "span", true);
|
||||
let content =
|
||||
filterChildren(item, "a", true) || filterChildren(item, "span", true);
|
||||
|
||||
if (!content) {
|
||||
return;
|
||||
|
@ -212,11 +211,11 @@ class Navigation {
|
|||
}
|
||||
|
||||
return {
|
||||
"id": id,
|
||||
"href": src,
|
||||
"label": text,
|
||||
"subitems" : subitems,
|
||||
"parent" : parent
|
||||
id: id,
|
||||
href: src,
|
||||
label: text,
|
||||
subitems: subitems,
|
||||
parent: parent,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -260,14 +259,16 @@ class Navigation {
|
|||
return;
|
||||
}
|
||||
|
||||
let type = content.getAttributeNS("http://www.idpf.org/2007/ops", "type") || undefined;
|
||||
let type =
|
||||
content.getAttributeNS("http://www.idpf.org/2007/ops", "type") ||
|
||||
undefined;
|
||||
let href = content.getAttribute("href") || "";
|
||||
let text = content.textContent || "";
|
||||
|
||||
return {
|
||||
"href": href,
|
||||
"label": text,
|
||||
"type" : type
|
||||
href: href,
|
||||
label: text,
|
||||
type: type,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -317,17 +318,20 @@ class Navigation {
|
|||
parentNode = item.parentNode,
|
||||
parent;
|
||||
|
||||
if(parentNode && (parentNode.nodeName === "navPoint" || parentNode.nodeName.split(':').slice(-1)[0] === "navPoint")) {
|
||||
if (
|
||||
parentNode &&
|
||||
(parentNode.nodeName === "navPoint" ||
|
||||
parentNode.nodeName.split(":").slice(-1)[0] === "navPoint")
|
||||
) {
|
||||
parent = parentNode.getAttribute("id");
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
"id": id,
|
||||
"href": src,
|
||||
"label": text,
|
||||
"subitems" : subitems,
|
||||
"parent" : parent
|
||||
id: id,
|
||||
href: src,
|
||||
label: text,
|
||||
subitems: subitems,
|
||||
parent: parent,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -337,7 +341,7 @@ class Navigation {
|
|||
* @return {Array} navItems
|
||||
*/
|
||||
load(json) {
|
||||
return json.map(item => {
|
||||
return json.map((item) => {
|
||||
item.label = item.title;
|
||||
item.subitems = item.children ? this.load(item.children) : [];
|
||||
return item;
|
||||
|
|
105
src/packaging.js
105
src/packaging.js
|
@ -1,4 +1,4 @@
|
|||
import {qs, qsa, qsp, indexOfElementNode} from "./utils/core";
|
||||
import { indexOfElementNode, qs, qsa, qsp } from "./utils/core";
|
||||
|
||||
/**
|
||||
* Open Packaging Format Parser
|
||||
|
@ -8,9 +8,9 @@ import {qs, qsa, qsp, indexOfElementNode} from "./utils/core";
|
|||
class Packaging {
|
||||
constructor(packageDocument) {
|
||||
this.manifest = {};
|
||||
this.navPath = '';
|
||||
this.ncxPath = '';
|
||||
this.coverPath = '';
|
||||
this.navPath = "";
|
||||
this.ncxPath = "";
|
||||
this.coverPath = "";
|
||||
this.spineNodeIndex = 0;
|
||||
this.spine = [];
|
||||
this.metadata = {};
|
||||
|
@ -59,16 +59,18 @@ class Packaging {
|
|||
this.uniqueIdentifier = this.findUniqueIdentifier(packageDocument);
|
||||
this.metadata = this.parseMetadata(metadataNode);
|
||||
|
||||
this.metadata.direction = spineNode.getAttribute("page-progression-direction");
|
||||
this.metadata.direction = spineNode.getAttribute(
|
||||
"page-progression-direction"
|
||||
);
|
||||
|
||||
return {
|
||||
"metadata" : this.metadata,
|
||||
"spine" : this.spine,
|
||||
"manifest" : this.manifest,
|
||||
"navPath" : this.navPath,
|
||||
"ncxPath" : this.ncxPath,
|
||||
"coverPath": this.coverPath,
|
||||
"spineNodeIndex" : this.spineNodeIndex
|
||||
metadata: this.metadata,
|
||||
spine: this.spine,
|
||||
manifest: this.manifest,
|
||||
navPath: this.navPath,
|
||||
ncxPath: this.ncxPath,
|
||||
coverPath: this.coverPath,
|
||||
spineNodeIndex: this.spineNodeIndex,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,10 @@ class Packaging {
|
|||
metadata.orientation = this.getPropertyText(xml, "rendition:orientation");
|
||||
metadata.flow = this.getPropertyText(xml, "rendition:flow");
|
||||
metadata.viewport = this.getPropertyText(xml, "rendition:viewport");
|
||||
metadata.media_active_class = this.getPropertyText(xml, "media:active-class");
|
||||
metadata.media_active_class = this.getPropertyText(
|
||||
xml,
|
||||
"media:active-class"
|
||||
);
|
||||
metadata.spread = this.getPropertyText(xml, "rendition:spread");
|
||||
// metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
|
||||
|
||||
|
@ -129,17 +134,15 @@ class Packaging {
|
|||
properties = item.getAttribute("properties") || "";
|
||||
|
||||
manifest[id] = {
|
||||
"href" : href,
|
||||
href: href,
|
||||
// "url" : href,
|
||||
"type" : type,
|
||||
"overlay" : overlay,
|
||||
"properties" : properties.length ? properties.split(" ") : []
|
||||
type: type,
|
||||
overlay: overlay,
|
||||
properties: properties.length ? properties.split(" ") : [],
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
return manifest;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,13 +170,13 @@ class Packaging {
|
|||
// var manifestPropArray = manifestProps.length ? manifestProps.split(" ") : [];
|
||||
|
||||
var itemref = {
|
||||
"id" : item.getAttribute("id"),
|
||||
"idref" : idref,
|
||||
"linear" : item.getAttribute("linear") || "yes",
|
||||
"properties" : propArray,
|
||||
id: item.getAttribute("id"),
|
||||
idref: idref,
|
||||
linear: item.getAttribute("linear") || "yes",
|
||||
properties: propArray,
|
||||
// "href" : manifest[Id].href,
|
||||
// "url" : manifest[Id].url,
|
||||
"index" : index
|
||||
index: index,
|
||||
// "cfiBase" : cfiBase
|
||||
};
|
||||
spine.push(itemref);
|
||||
|
@ -189,7 +192,8 @@ class Packaging {
|
|||
* @return {string} Unique Identifier text
|
||||
*/
|
||||
findUniqueIdentifier(packageXml) {
|
||||
var uniqueIdentifierId = packageXml.documentElement.getAttribute("unique-identifier");
|
||||
var uniqueIdentifierId =
|
||||
packageXml.documentElement.getAttribute("unique-identifier");
|
||||
if (!uniqueIdentifierId) {
|
||||
return "";
|
||||
}
|
||||
|
@ -198,8 +202,13 @@ class Packaging {
|
|||
return "";
|
||||
}
|
||||
|
||||
if (identifier.localName === "identifier" && identifier.namespaceURI === "http://purl.org/dc/elements/1.1/") {
|
||||
return identifier.childNodes.length > 0 ? identifier.childNodes[0].nodeValue.trim() : "";
|
||||
if (
|
||||
identifier.localName === "identifier" &&
|
||||
identifier.namespaceURI === "http://purl.org/dc/elements/1.1/"
|
||||
) {
|
||||
return identifier.childNodes.length > 0
|
||||
? identifier.childNodes[0].nodeValue.trim()
|
||||
: "";
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -215,7 +224,7 @@ class Packaging {
|
|||
// Find item with property "nav"
|
||||
// Should catch nav regardless of order
|
||||
// var node = manifestNode.querySelector("item[properties$='nav'], item[properties^='nav '], item[properties*=' nav ']");
|
||||
var node = qsp(manifestNode, "item", {"properties":"nav"});
|
||||
var node = qsp(manifestNode, "item", { properties: "nav" });
|
||||
return node ? node.getAttribute("href") : false;
|
||||
}
|
||||
|
||||
|
@ -229,7 +238,9 @@ class Packaging {
|
|||
*/
|
||||
findNcxPath(manifestNode, spineNode) {
|
||||
// var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
|
||||
var node = qsp(manifestNode, "item", {"media-type":"application/x-dtbncx+xml"});
|
||||
var node = qsp(manifestNode, "item", {
|
||||
"media-type": "application/x-dtbncx+xml",
|
||||
});
|
||||
var tocId;
|
||||
|
||||
// If we can't find the toc by media-type then try to look for id of the item in the spine attributes as
|
||||
|
@ -255,24 +266,18 @@ class Packaging {
|
|||
* @return {string} href
|
||||
*/
|
||||
findCoverPath(packageXml) {
|
||||
var pkg = qs(packageXml, "package");
|
||||
var epubVersion = pkg.getAttribute("version");
|
||||
|
||||
// Try parsing cover with epub 3.
|
||||
// var node = packageXml.querySelector("item[properties='cover-image']");
|
||||
var node = qsp(packageXml, "item", {"properties":"cover-image"});
|
||||
var node = qsp(packageXml, "item", { properties: "cover-image" });
|
||||
if (node) return node.getAttribute("href");
|
||||
|
||||
// Fallback to epub 2.
|
||||
var metaCover = qsp(packageXml, "meta", {"name":"cover"});
|
||||
var metaCover = qsp(packageXml, "meta", { name: "cover" });
|
||||
|
||||
if (metaCover) {
|
||||
var coverId = metaCover.getAttribute("content");
|
||||
// var cover = packageXml.querySelector("item[id='" + coverId + "']");
|
||||
var cover = packageXml.getElementById(coverId);
|
||||
return cover ? cover.getAttribute("href") : "";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +290,10 @@ class Packaging {
|
|||
* @return {string} text
|
||||
*/
|
||||
getElementText(xml, tag) {
|
||||
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag);
|
||||
var found = xml.getElementsByTagNameNS(
|
||||
"http://purl.org/dc/elements/1.1/",
|
||||
tag
|
||||
);
|
||||
var el;
|
||||
|
||||
if (!found || found.length === 0) return "";
|
||||
|
@ -297,7 +305,6 @@ class Packaging {
|
|||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -308,7 +315,7 @@ class Packaging {
|
|||
* @return {string} text
|
||||
*/
|
||||
getPropertyText(xml, property) {
|
||||
var el = qsp(xml, "meta", {"property":property});
|
||||
var el = qsp(xml, "meta", { property: property });
|
||||
|
||||
if (el && el.childNodes.length) {
|
||||
return el.childNodes[0].nodeValue;
|
||||
|
@ -348,14 +355,14 @@ class Packaging {
|
|||
});
|
||||
|
||||
return {
|
||||
"metadata" : this.metadata,
|
||||
"spine" : this.spine,
|
||||
"manifest" : this.manifest,
|
||||
"navPath" : this.navPath,
|
||||
"ncxPath" : this.ncxPath,
|
||||
"coverPath": this.coverPath,
|
||||
"spineNodeIndex" : this.spineNodeIndex,
|
||||
"toc" : this.toc
|
||||
metadata: this.metadata,
|
||||
spine: this.spine,
|
||||
manifest: this.manifest,
|
||||
navPath: this.navPath,
|
||||
ncxPath: this.ncxPath,
|
||||
coverPath: this.coverPath,
|
||||
spineNodeIndex: this.spineNodeIndex,
|
||||
toc: this.toc,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import EpubCFI from "./epubcfi";
|
||||
import {
|
||||
indexOfSorted,
|
||||
locationOf,
|
||||
qs,
|
||||
qsa,
|
||||
querySelectorByType,
|
||||
indexOfSorted,
|
||||
locationOf
|
||||
} from "./utils/core";
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,6 @@ class PageList {
|
|||
} else if (ncx) {
|
||||
return this.parseNcx(xml);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,8 +108,8 @@ class PageList {
|
|||
var page = parseInt(pageText, 10);
|
||||
|
||||
return {
|
||||
"href": href,
|
||||
"page": page,
|
||||
href: href,
|
||||
page: page,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -135,15 +134,15 @@ class PageList {
|
|||
packageUrl = split[0];
|
||||
cfi = split.length > 1 ? split[1] : false;
|
||||
return {
|
||||
"cfi" : cfi,
|
||||
"href" : href,
|
||||
"packageUrl" : packageUrl,
|
||||
"page" : page
|
||||
cfi: cfi,
|
||||
href: href,
|
||||
packageUrl: packageUrl,
|
||||
page: page,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
"href" : href,
|
||||
"page" : page
|
||||
href: href,
|
||||
page: page,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +197,6 @@ class PageList {
|
|||
} else {
|
||||
pg = -1;
|
||||
}
|
||||
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
|
|
281
src/rendition.js
281
src/rendition.js
|
@ -1,21 +1,15 @@
|
|||
import EventEmitter from "event-emitter";
|
||||
import { extend, defer, isFloat } from "./utils/core";
|
||||
import Hook from "./utils/hook";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Queue from "./utils/queue";
|
||||
import Layout from "./layout";
|
||||
// import Mapping from "./mapping";
|
||||
import Themes from "./themes";
|
||||
import Contents from "./contents";
|
||||
import Annotations from "./annotations";
|
||||
import { EVENTS, DOM_EVENTS } from "./utils/constants";
|
||||
|
||||
// Default Views
|
||||
import IframeView from "./managers/views/iframe";
|
||||
|
||||
// Default View Managers
|
||||
import DefaultViewManager from "./managers/default/index";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Layout from "./layout";
|
||||
import ContinuousViewManager from "./managers/continuous/index";
|
||||
import DefaultViewManager from "./managers/default/index";
|
||||
import IframeView from "./managers/views/iframe";
|
||||
import Themes from "./themes";
|
||||
import { DOM_EVENTS, EVENTS } from "./utils/constants";
|
||||
import { defer, extend, isFloat } from "./utils/core";
|
||||
import Hook from "./utils/hook";
|
||||
import Queue from "./utils/queue";
|
||||
|
||||
/**
|
||||
* Displays an Epub as a series of Views for each Section.
|
||||
|
@ -42,7 +36,6 @@ import ContinuousViewManager from "./managers/continuous/index";
|
|||
*/
|
||||
class Rendition {
|
||||
constructor(book, options) {
|
||||
|
||||
this.settings = extend(this.settings || {}, {
|
||||
width: null,
|
||||
height: null,
|
||||
|
@ -59,12 +52,12 @@ class Rendition {
|
|||
snap: false,
|
||||
defaultDirection: "ltr",
|
||||
allowScriptedContent: false,
|
||||
allowPopups: false
|
||||
allowPopups: false,
|
||||
});
|
||||
|
||||
extend(this.settings, options);
|
||||
|
||||
if (typeof(this.settings.manager) === "object") {
|
||||
if (typeof this.settings.manager === "object") {
|
||||
this.manager = this.settings.manager;
|
||||
}
|
||||
|
||||
|
@ -210,14 +203,18 @@ class Rendition {
|
|||
* @return {Promise} rendering has started
|
||||
*/
|
||||
start() {
|
||||
if (!this.settings.layout && (this.book.package.metadata.layout === "pre-paginated" || this.book.displayOptions.fixedLayout === "true")) {
|
||||
if (
|
||||
!this.settings.layout &&
|
||||
(this.book.package.metadata.layout === "pre-paginated" ||
|
||||
this.book.displayOptions.fixedLayout === "true")
|
||||
) {
|
||||
this.settings.layout = "pre-paginated";
|
||||
}
|
||||
switch (this.book.package.metadata.spread) {
|
||||
case 'none':
|
||||
this.settings.spread = 'none';
|
||||
case "none":
|
||||
this.settings.spread = "none";
|
||||
break;
|
||||
case 'both':
|
||||
case "both":
|
||||
this.settings.spread = true;
|
||||
break;
|
||||
}
|
||||
|
@ -230,14 +227,18 @@ class Rendition {
|
|||
view: this.View,
|
||||
queue: this.q,
|
||||
request: this.book.load.bind(this.book),
|
||||
settings: this.settings
|
||||
settings: this.settings,
|
||||
});
|
||||
}
|
||||
|
||||
this.direction(this.book.package.metadata.direction || this.settings.defaultDirection);
|
||||
this.direction(
|
||||
this.book.package.metadata.direction || this.settings.defaultDirection
|
||||
);
|
||||
|
||||
// Parse metadata to get layout props
|
||||
this.settings.globalLayoutProperties = this.determineLayoutProperties(this.book.package.metadata);
|
||||
this.settings.globalLayoutProperties = this.determineLayoutProperties(
|
||||
this.book.package.metadata
|
||||
);
|
||||
|
||||
this.flow(this.settings.globalLayoutProperties.flow);
|
||||
|
||||
|
@ -251,7 +252,10 @@ class Rendition {
|
|||
this.manager.on(EVENTS.MANAGERS.RESIZED, this.onResized.bind(this));
|
||||
|
||||
// Listen for rotation
|
||||
this.manager.on(EVENTS.MANAGERS.ORIENTATION_CHANGE, this.onOrientationChange.bind(this));
|
||||
this.manager.on(
|
||||
EVENTS.MANAGERS.ORIENTATION_CHANGE,
|
||||
this.onOrientationChange.bind(this)
|
||||
);
|
||||
|
||||
// Listen for scroll changes
|
||||
this.manager.on(EVENTS.MANAGERS.SCROLLED, this.reportLocation.bind(this));
|
||||
|
@ -274,13 +278,12 @@ class Rendition {
|
|||
* @return {Promise}
|
||||
*/
|
||||
attachTo(element) {
|
||||
|
||||
return this.q.enqueue(function () {
|
||||
|
||||
return this.q.enqueue(
|
||||
function () {
|
||||
// Start rendering
|
||||
this.manager.render(element, {
|
||||
"width" : this.settings.width,
|
||||
"height" : this.settings.height
|
||||
width: this.settings.width,
|
||||
height: this.settings.height,
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -289,9 +292,8 @@ class Rendition {
|
|||
* @memberof Rendition
|
||||
*/
|
||||
this.emit(EVENTS.RENDITION.ATTACHED);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,11 +321,9 @@ class Rendition {
|
|||
if (!this.book) {
|
||||
return;
|
||||
}
|
||||
var isCfiString = this.epubcfi.isCfiString(target);
|
||||
var displaying = new defer();
|
||||
var displayed = displaying.promise;
|
||||
var section;
|
||||
var moveTo;
|
||||
|
||||
this.displaying = displaying;
|
||||
|
||||
|
@ -339,8 +339,8 @@ class Rendition {
|
|||
return displayed;
|
||||
}
|
||||
|
||||
this.manager.display(section, target)
|
||||
.then(() => {
|
||||
this.manager.display(section, target).then(
|
||||
() => {
|
||||
displaying.resolve(section);
|
||||
this.displaying = undefined;
|
||||
|
||||
|
@ -352,7 +352,8 @@ class Rendition {
|
|||
*/
|
||||
this.emit(EVENTS.RENDITION.DISPLAYED, section);
|
||||
this.reportLocation();
|
||||
}, (err) => {
|
||||
},
|
||||
(err) => {
|
||||
/**
|
||||
* Emit that has been an error displaying
|
||||
* @event displayError
|
||||
|
@ -360,67 +361,23 @@ class Rendition {
|
|||
* @memberof Rendition
|
||||
*/
|
||||
this.emit(EVENTS.RENDITION.DISPLAY_ERROR, err);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return displayed;
|
||||
}
|
||||
|
||||
/*
|
||||
render(view, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
view.create();
|
||||
|
||||
// Fit to size of the container, apply padding
|
||||
this.manager.resizeView(view);
|
||||
|
||||
// Render Chain
|
||||
return view.section.render(this.book.request)
|
||||
.then(function(contents){
|
||||
return view.load(contents);
|
||||
}.bind(this))
|
||||
.then(function(doc){
|
||||
return this.hooks.content.trigger(view, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
this.layout.format(view.contents);
|
||||
return this.hooks.layout.trigger(view, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
return view.display();
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
return this.hooks.render.trigger(view, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
if(show !== false) {
|
||||
this.q.enqueue(function(view){
|
||||
view.show();
|
||||
}, view);
|
||||
}
|
||||
// this.map = new Map(view, this.layout);
|
||||
this.hooks.show.trigger(view, this);
|
||||
this.trigger("rendered", view.section);
|
||||
|
||||
}.bind(this))
|
||||
.catch(function(e){
|
||||
this.trigger("loaderror", e);
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Report what section has been displayed
|
||||
* @private
|
||||
* @param {*} view
|
||||
*/
|
||||
afterDisplayed(view) {
|
||||
view.on(EVENTS.VIEWS.MARK_CLICKED, (cfiRange, data) =>
|
||||
this.triggerMarkEvent(cfiRange, data, view.contents)
|
||||
);
|
||||
|
||||
view.on(EVENTS.VIEWS.MARK_CLICKED, (cfiRange, data) => this.triggerMarkEvent(cfiRange, data, view.contents));
|
||||
|
||||
this.hooks.render.trigger(view, this)
|
||||
.then(() => {
|
||||
this.hooks.render.trigger(view, this).then(() => {
|
||||
if (view.contents) {
|
||||
this.hooks.content.trigger(view.contents, this).then(() => {
|
||||
/**
|
||||
|
@ -436,7 +393,6 @@ class Rendition {
|
|||
this.emit(EVENTS.RENDITION.RENDERED, view.section, view);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -462,7 +418,6 @@ class Rendition {
|
|||
* @private
|
||||
*/
|
||||
onResized(size, epubcfi) {
|
||||
|
||||
/**
|
||||
* Emit that the rendition has been resized
|
||||
* @event resized
|
||||
|
@ -471,15 +426,18 @@ class Rendition {
|
|||
* @param {string} epubcfi (optional)
|
||||
* @memberof Rendition
|
||||
*/
|
||||
this.emit(EVENTS.RENDITION.RESIZED, {
|
||||
this.emit(
|
||||
EVENTS.RENDITION.RESIZED,
|
||||
{
|
||||
width: size.width,
|
||||
height: size.height
|
||||
}, epubcfi);
|
||||
height: size.height,
|
||||
},
|
||||
epubcfi
|
||||
);
|
||||
|
||||
if (this.location && this.location.start) {
|
||||
this.display(epubcfi || this.location.start.cfi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -533,7 +491,8 @@ class Rendition {
|
|||
* @return {Promise}
|
||||
*/
|
||||
next() {
|
||||
return this.q.enqueue(this.manager.next.bind(this.manager))
|
||||
return this.q
|
||||
.enqueue(this.manager.next.bind(this.manager))
|
||||
.then(this.reportLocation.bind(this));
|
||||
}
|
||||
|
||||
|
@ -542,7 +501,8 @@ class Rendition {
|
|||
* @return {Promise}
|
||||
*/
|
||||
prev() {
|
||||
return this.q.enqueue(this.manager.prev.bind(this.manager))
|
||||
return this.q
|
||||
.enqueue(this.manager.prev.bind(this.manager))
|
||||
.then(this.reportLocation.bind(this));
|
||||
}
|
||||
|
||||
|
@ -557,14 +517,18 @@ class Rendition {
|
|||
var properties;
|
||||
var layout = this.settings.layout || metadata.layout || "reflowable";
|
||||
var spread = this.settings.spread || metadata.spread || "auto";
|
||||
var orientation = this.settings.orientation || metadata.orientation || "auto";
|
||||
var orientation =
|
||||
this.settings.orientation || metadata.orientation || "auto";
|
||||
var flow = this.settings.flow || metadata.flow || "auto";
|
||||
var viewport = metadata.viewport || "";
|
||||
var minSpreadWidth = this.settings.minSpreadWidth || metadata.minSpreadWidth || 800;
|
||||
var minSpreadWidth =
|
||||
this.settings.minSpreadWidth || metadata.minSpreadWidth || 800;
|
||||
var direction = this.settings.direction || metadata.direction || "ltr";
|
||||
|
||||
if ((this.settings.width === 0 || this.settings.width > 0) &&
|
||||
(this.settings.height === 0 || this.settings.height > 0)) {
|
||||
if (
|
||||
(this.settings.width === 0 || this.settings.width > 0) &&
|
||||
(this.settings.height === 0 || this.settings.height > 0)
|
||||
) {
|
||||
// viewport = "width="+this.settings.width+", height="+this.settings.height+"";
|
||||
}
|
||||
|
||||
|
@ -575,7 +539,7 @@ class Rendition {
|
|||
flow: flow,
|
||||
viewport: viewport,
|
||||
minSpreadWidth: minSpreadWidth,
|
||||
direction: direction
|
||||
direction: direction,
|
||||
};
|
||||
|
||||
return properties;
|
||||
|
@ -588,9 +552,11 @@ class Rendition {
|
|||
*/
|
||||
flow(flow) {
|
||||
var _flow = flow;
|
||||
if (flow === "scrolled" ||
|
||||
if (
|
||||
flow === "scrolled" ||
|
||||
flow === "scrolled-doc" ||
|
||||
flow === "scrolled-continuous") {
|
||||
flow === "scrolled-continuous"
|
||||
) {
|
||||
_flow = "scrolled";
|
||||
}
|
||||
|
||||
|
@ -631,7 +597,7 @@ class Rendition {
|
|||
|
||||
this._layout.on(EVENTS.LAYOUT.UPDATED, (props, changed) => {
|
||||
this.emit(EVENTS.RENDITION.LAYOUT, props, changed);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (this.manager && this._layout) {
|
||||
|
@ -647,7 +613,6 @@ class Rendition {
|
|||
* @param {int} [min] min width to use spreads at
|
||||
*/
|
||||
spread(spread, min) {
|
||||
|
||||
this.settings.spread = spread;
|
||||
|
||||
if (min) {
|
||||
|
@ -668,7 +633,6 @@ class Rendition {
|
|||
* @param {string} dir
|
||||
*/
|
||||
direction(dir) {
|
||||
|
||||
this.settings.direction = dir || "ltr";
|
||||
|
||||
if (this.manager) {
|
||||
|
@ -687,11 +651,18 @@ class Rendition {
|
|||
* @fires locationChanged
|
||||
*/
|
||||
reportLocation() {
|
||||
return this.q.enqueue(function reportedLocation(){
|
||||
requestAnimationFrame(function reportedLocationAfterRAF() {
|
||||
return this.q.enqueue(
|
||||
function reportedLocation() {
|
||||
requestAnimationFrame(
|
||||
function reportedLocationAfterRAF() {
|
||||
var location = this.manager.currentLocation();
|
||||
if (location && location.then && typeof location.then === "function") {
|
||||
location.then(function(result) {
|
||||
if (
|
||||
location &&
|
||||
location.then &&
|
||||
typeof location.then === "function"
|
||||
) {
|
||||
location.then(
|
||||
function (result) {
|
||||
let located = this.located(result);
|
||||
|
||||
if (!located || !located.start || !located.end) {
|
||||
|
@ -705,11 +676,12 @@ class Rendition {
|
|||
href: this.location.start.href,
|
||||
start: this.location.start.cfi,
|
||||
end: this.location.end.cfi,
|
||||
percentage: this.location.start.percentage
|
||||
percentage: this.location.start.percentage,
|
||||
});
|
||||
|
||||
this.emit(EVENTS.RENDITION.RELOCATED, this.location);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
} else if (location) {
|
||||
let located = this.located(location);
|
||||
|
||||
|
@ -735,7 +707,7 @@ class Rendition {
|
|||
href: this.location.start.href,
|
||||
start: this.location.start.cfi,
|
||||
end: this.location.end.cfi,
|
||||
percentage: this.location.start.percentage
|
||||
percentage: this.location.start.percentage,
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -745,8 +717,10 @@ class Rendition {
|
|||
*/
|
||||
this.emit(EVENTS.RENDITION.RELOCATED, this.location);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -756,10 +730,12 @@ class Rendition {
|
|||
currentLocation() {
|
||||
var location = this.manager.currentLocation();
|
||||
if (location && location.then && typeof location.then === "function") {
|
||||
location.then(function(result) {
|
||||
location.then(
|
||||
function (result) {
|
||||
let located = this.located(result);
|
||||
return located;
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
} else if (location) {
|
||||
let located = this.located(location);
|
||||
return located;
|
||||
|
@ -786,8 +762,8 @@ class Rendition {
|
|||
cfi: start.mapping.start,
|
||||
displayed: {
|
||||
page: start.pages[0] || 1,
|
||||
total: start.totalPages
|
||||
}
|
||||
total: start.totalPages,
|
||||
},
|
||||
},
|
||||
end: {
|
||||
index: end.index,
|
||||
|
@ -795,21 +771,25 @@ class Rendition {
|
|||
cfi: end.mapping.end,
|
||||
displayed: {
|
||||
page: end.pages[end.pages.length - 1] || 1,
|
||||
total: end.totalPages
|
||||
}
|
||||
}
|
||||
total: end.totalPages,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let locationStart = this.book.locations.locationFromCfi(start.mapping.start);
|
||||
let locationStart = this.book.locations.locationFromCfi(
|
||||
start.mapping.start
|
||||
);
|
||||
let locationEnd = this.book.locations.locationFromCfi(end.mapping.end);
|
||||
|
||||
if (locationStart != null) {
|
||||
located.start.location = locationStart;
|
||||
located.start.percentage = this.book.locations.percentageFromLocation(locationStart);
|
||||
located.start.percentage =
|
||||
this.book.locations.percentageFromLocation(locationStart);
|
||||
}
|
||||
if (locationEnd != null) {
|
||||
located.end.location = locationEnd;
|
||||
located.end.percentage = this.book.locations.percentageFromLocation(locationEnd);
|
||||
located.end.percentage =
|
||||
this.book.locations.percentageFromLocation(locationEnd);
|
||||
}
|
||||
|
||||
let pageStart = this.book.pageList.pageFromCfi(start.mapping.start);
|
||||
|
@ -822,13 +802,17 @@ class Rendition {
|
|||
located.end.page = pageEnd;
|
||||
}
|
||||
|
||||
if (end.index === this.book.spine.last().index &&
|
||||
located.end.displayed.page >= located.end.displayed.total) {
|
||||
if (
|
||||
end.index === this.book.spine.last().index &&
|
||||
located.end.displayed.page >= located.end.displayed.total
|
||||
) {
|
||||
located.atEnd = true;
|
||||
}
|
||||
|
||||
if (start.index === this.book.spine.first().index &&
|
||||
located.start.displayed.page === 1) {
|
||||
if (
|
||||
start.index === this.book.spine.first().index &&
|
||||
located.start.displayed.page === 1
|
||||
) {
|
||||
located.atStart = true;
|
||||
}
|
||||
|
||||
|
@ -864,8 +848,6 @@ class Rendition {
|
|||
|
||||
// this.starting = undefined;
|
||||
// this.started = undefined;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -878,7 +860,9 @@ class Rendition {
|
|||
contents.on(e, (ev) => this.triggerViewEvent(ev, contents));
|
||||
});
|
||||
|
||||
contents.on(EVENTS.CONTENTS.SELECTED, (e) => this.triggerSelectedEvent(e, contents));
|
||||
contents.on(EVENTS.CONTENTS.SELECTED, (e) =>
|
||||
this.triggerSelectedEvent(e, contents)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -947,7 +931,6 @@ class Rendition {
|
|||
* @private
|
||||
*/
|
||||
adjustImages(contents) {
|
||||
|
||||
if (this._layout.name === "pre-paginated") {
|
||||
return new Promise(function (resolve) {
|
||||
resolve();
|
||||
|
@ -955,24 +938,35 @@ class Rendition {
|
|||
}
|
||||
|
||||
let computed = contents.window.getComputedStyle(contents.content, null);
|
||||
let height = (contents.content.offsetHeight - (parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom))) * .95;
|
||||
let horizontalPadding = parseFloat(computed.paddingLeft) + parseFloat(computed.paddingRight);
|
||||
let height =
|
||||
(contents.content.offsetHeight -
|
||||
(parseFloat(computed.paddingTop) +
|
||||
parseFloat(computed.paddingBottom))) *
|
||||
0.95;
|
||||
let horizontalPadding =
|
||||
parseFloat(computed.paddingLeft) + parseFloat(computed.paddingRight);
|
||||
|
||||
contents.addStylesheetRules({
|
||||
"img" : {
|
||||
"max-width": (this._layout.columnWidth ? (this._layout.columnWidth - horizontalPadding) + "px" : "100%") + "!important",
|
||||
img: {
|
||||
"max-width":
|
||||
(this._layout.columnWidth
|
||||
? this._layout.columnWidth - horizontalPadding + "px"
|
||||
: "100%") + "!important",
|
||||
"max-height": height + "px" + "!important",
|
||||
"object-fit": "contain",
|
||||
"page-break-inside": "avoid",
|
||||
"break-inside": "avoid",
|
||||
"box-sizing": "border-box"
|
||||
"box-sizing": "border-box",
|
||||
},
|
||||
"svg" : {
|
||||
"max-width": (this._layout.columnWidth ? (this._layout.columnWidth - horizontalPadding) + "px" : "100%") + "!important",
|
||||
svg: {
|
||||
"max-width":
|
||||
(this._layout.columnWidth
|
||||
? this._layout.columnWidth - horizontalPadding + "px"
|
||||
: "100%") + "!important",
|
||||
"max-height": height + "px" + "!important",
|
||||
"page-break-inside": "avoid",
|
||||
"break-inside": "avoid"
|
||||
}
|
||||
"break-inside": "avoid",
|
||||
},
|
||||
});
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
@ -1060,7 +1054,6 @@ class Rendition {
|
|||
}
|
||||
doc.getElementsByTagName("head")[0].appendChild(meta);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-- Enable binding events to Renderer
|
||||
|
|
105
src/resources.js
105
src/resources.js
|
@ -1,9 +1,9 @@
|
|||
import {substitute} from "./utils/replacements";
|
||||
import {createBase64Url, createBlobUrl, blob2base64} from "./utils/core";
|
||||
import Url from "./utils/url";
|
||||
import path from "path-webpack";
|
||||
import { blob2base64, createBase64Url, createBlobUrl } from "./utils/core";
|
||||
import mime from "./utils/mime";
|
||||
import Path from "./utils/path";
|
||||
import path from "path-webpack";
|
||||
import { substitute } from "./utils/replacements";
|
||||
import Url from "./utils/url";
|
||||
|
||||
/**
|
||||
* Handle Package Resources
|
||||
|
@ -18,9 +18,9 @@ class Resources {
|
|||
constructor(manifest, options) {
|
||||
this.settings = {
|
||||
replacements: (options && options.replacements) || "base64",
|
||||
archive: (options && options.archive),
|
||||
resolver: (options && options.resolver),
|
||||
request: (options && options.request)
|
||||
archive: options && options.archive,
|
||||
resolver: options && options.resolver,
|
||||
request: options && options.request,
|
||||
};
|
||||
|
||||
this.process(manifest);
|
||||
|
@ -32,8 +32,7 @@ class Resources {
|
|||
*/
|
||||
process(manifest) {
|
||||
this.manifest = manifest;
|
||||
this.resources = Object.keys(manifest).
|
||||
map(function (key){
|
||||
this.resources = Object.keys(manifest).map(function (key) {
|
||||
return manifest[key];
|
||||
});
|
||||
|
||||
|
@ -55,28 +54,22 @@ class Resources {
|
|||
* @private
|
||||
*/
|
||||
split() {
|
||||
|
||||
// HTML
|
||||
this.html = this.resources.
|
||||
filter(function (item){
|
||||
if (item.type === "application/xhtml+xml" ||
|
||||
item.type === "text/html") {
|
||||
this.html = this.resources.filter(function (item) {
|
||||
if (item.type === "application/xhtml+xml" || item.type === "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Exclude HTML
|
||||
this.assets = this.resources.
|
||||
filter(function (item){
|
||||
if (item.type !== "application/xhtml+xml" &&
|
||||
item.type !== "text/html") {
|
||||
this.assets = this.resources.filter(function (item) {
|
||||
if (item.type !== "application/xhtml+xml" && item.type !== "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Only CSS
|
||||
this.css = this.resources.
|
||||
filter(function (item){
|
||||
this.css = this.resources.filter(function (item) {
|
||||
if (item.type === "text/css") {
|
||||
return true;
|
||||
}
|
||||
|
@ -88,18 +81,17 @@ class Resources {
|
|||
* @private
|
||||
*/
|
||||
splitUrls() {
|
||||
|
||||
// All Assets Urls
|
||||
this.urls = this.assets.
|
||||
map(function(item) {
|
||||
this.urls = this.assets.map(
|
||||
function (item) {
|
||||
return item.href;
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
// Css Urls
|
||||
this.cssUrls = this.css.map(function (item) {
|
||||
return item.href;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,10 +104,13 @@ class Resources {
|
|||
var mimeType = mime.lookup(parsedUrl.filename);
|
||||
|
||||
if (this.settings.archive) {
|
||||
return this.settings.archive.createUrl(url, {"base64": (this.settings.replacements === "base64")});
|
||||
return this.settings.archive.createUrl(url, {
|
||||
base64: this.settings.replacements === "base64",
|
||||
});
|
||||
} else {
|
||||
if (this.settings.replacements === "base64") {
|
||||
return this.settings.request(url, 'blob')
|
||||
return this.settings
|
||||
.request(url, "blob")
|
||||
.then((blob) => {
|
||||
return blob2base64(blob);
|
||||
})
|
||||
|
@ -123,9 +118,9 @@ class Resources {
|
|||
return createBase64Url(blob, mimeType);
|
||||
});
|
||||
} else {
|
||||
return this.settings.request(url, 'blob').then((blob) => {
|
||||
return this.settings.request(url, "blob").then((blob) => {
|
||||
return createBlobUrl(blob, mimeType);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,25 +131,24 @@ class Resources {
|
|||
*/
|
||||
replacements() {
|
||||
if (this.settings.replacements === "none") {
|
||||
return new Promise(function(resolve) {
|
||||
return new Promise(
|
||||
function (resolve) {
|
||||
resolve(this.urls);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
var replacements = this.urls.map((url) => {
|
||||
var absolute = this.settings.resolver(url);
|
||||
|
||||
return this.createUrl(absolute).
|
||||
catch((err) => {
|
||||
console.error(err);
|
||||
return this.createUrl(absolute).catch(() => {
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(replacements)
|
||||
.then( (replacementUrls) => {
|
||||
return Promise.all(replacements).then((replacementUrls) => {
|
||||
this.replacementUrls = replacementUrls.filter((url) => {
|
||||
return (typeof(url) === "string");
|
||||
return typeof url === "string";
|
||||
});
|
||||
return replacementUrls;
|
||||
});
|
||||
|
@ -171,19 +165,21 @@ class Resources {
|
|||
var replaced = [];
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
this.cssUrls.forEach(function(href) {
|
||||
var replacement = this.createCssFile(href, archive, resolver)
|
||||
.then(function (replacementUrl) {
|
||||
this.cssUrls.forEach(
|
||||
function (href) {
|
||||
var replacement = this.createCssFile(href, archive, resolver).then(
|
||||
function (replacementUrl) {
|
||||
// switch the url in the replacementUrls
|
||||
var indexInUrls = this.urls.indexOf(href);
|
||||
if (indexInUrls > -1) {
|
||||
this.replacementUrls[indexInUrls] = replacementUrl;
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
replaced.push(replacement);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
return Promise.all(replaced);
|
||||
}
|
||||
|
||||
|
@ -228,7 +224,8 @@ class Resources {
|
|||
});
|
||||
}
|
||||
|
||||
return textResponse.then( (text) => {
|
||||
return textResponse.then(
|
||||
(text) => {
|
||||
// Replacements in the css text
|
||||
text = substitute(text, relUrls, this.replacementUrls);
|
||||
|
||||
|
@ -240,13 +237,14 @@ class Resources {
|
|||
}
|
||||
|
||||
return newUrl;
|
||||
}, (err) => {
|
||||
},
|
||||
(err) => {
|
||||
// handle response errors
|
||||
return new Promise(function (resolve) {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,12 +257,13 @@ class Resources {
|
|||
resolver = resolver || this.settings.resolver;
|
||||
|
||||
// Get Urls relative to current sections
|
||||
return this.urls.
|
||||
map(function(href) {
|
||||
return this.urls.map(
|
||||
function (href) {
|
||||
var resolved = resolver(href);
|
||||
var relative = new Path(absolute).relative(resolved);
|
||||
return relative;
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +277,11 @@ class Resources {
|
|||
return;
|
||||
}
|
||||
if (this.replacementUrls.length) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
return new Promise(
|
||||
function (resolve, reject) {
|
||||
resolve(this.replacementUrls[indexInUrls]);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
return this.createUrl(path);
|
||||
}
|
||||
|
|
108
src/section.js
108
src/section.js
|
@ -1,10 +1,9 @@
|
|||
import { defer } from "./utils/core";
|
||||
import { DOMParser as XMLDOMSerializer } from "@xmldom/xmldom";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import { defer, sprint } from "./utils/core";
|
||||
import Hook from "./utils/hook";
|
||||
import { sprint } from "./utils/core";
|
||||
import { replaceBase } from "./utils/replacements";
|
||||
import Request from "./utils/request";
|
||||
import { DOMParser as XMLDOMSerializer } from "@xmldom/xmldom";
|
||||
|
||||
/**
|
||||
* Represents a Section of the Book
|
||||
|
@ -54,17 +53,21 @@ class Section {
|
|||
loading.resolve(this.contents);
|
||||
} else {
|
||||
request(this.url)
|
||||
.then(function(xml){
|
||||
.then(
|
||||
function (xml) {
|
||||
// var directory = new Url(this.url).directory;
|
||||
|
||||
this.document = xml;
|
||||
this.contents = xml.documentElement;
|
||||
|
||||
return this.hooks.content.trigger(this.document, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
loading.resolve(this.contents);
|
||||
}.bind(this))
|
||||
}.bind(this)
|
||||
)
|
||||
.catch(function (error) {
|
||||
loading.reject(error);
|
||||
});
|
||||
|
@ -91,10 +94,12 @@ class Section {
|
|||
var rendered = rendering.promise;
|
||||
this.output; // TODO: better way to return this from hooks?
|
||||
|
||||
this.load(_request).
|
||||
then(function(contents){
|
||||
var userAgent = (typeof navigator !== 'undefined' && navigator.userAgent) || '';
|
||||
var isIE = userAgent.indexOf('Trident') >= 0;
|
||||
this.load(_request)
|
||||
.then(
|
||||
function (contents) {
|
||||
var userAgent =
|
||||
(typeof navigator !== "undefined" && navigator.userAgent) || "";
|
||||
var isIE = userAgent.indexOf("Trident") >= 0;
|
||||
var Serializer;
|
||||
if (typeof XMLSerializer === "undefined" || isIE) {
|
||||
Serializer = XMLDOMSerializer;
|
||||
|
@ -104,13 +109,18 @@ class Section {
|
|||
var serializer = new Serializer();
|
||||
this.output = serializer.serializeToString(contents);
|
||||
return this.output;
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
return this.hooks.serialize.trigger(this.output, this);
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
}.bind(this)
|
||||
)
|
||||
.then(
|
||||
function () {
|
||||
rendering.resolve(this.output);
|
||||
}.bind(this))
|
||||
}.bind(this)
|
||||
)
|
||||
.catch(function (error) {
|
||||
rendering.reject(error);
|
||||
});
|
||||
|
@ -151,16 +161,18 @@ class Section {
|
|||
// Generate the excerpt
|
||||
if (node.textContent.length < limit) {
|
||||
excerpt = node.textContent;
|
||||
}
|
||||
else {
|
||||
excerpt = node.textContent.substring(pos - limit/2, pos + limit/2);
|
||||
} else {
|
||||
excerpt = node.textContent.substring(
|
||||
pos - limit / 2,
|
||||
pos + limit / 2
|
||||
);
|
||||
excerpt = "..." + excerpt + "...";
|
||||
}
|
||||
|
||||
// Add the CFI to the matches list
|
||||
matches.push({
|
||||
cfi: cfi,
|
||||
excerpt: excerpt
|
||||
excerpt: excerpt,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -173,8 +185,7 @@ class Section {
|
|||
});
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a string in multiple sequential Element of the section. If the document.createTreeWalker api is missed(eg: IE8), use `find` as a fallback.
|
||||
|
@ -183,7 +194,7 @@ class Section {
|
|||
* @return {object[]} A list of matches, with form {cfi, excerpt}
|
||||
*/
|
||||
search(_query, maxSeqEle = 5) {
|
||||
if (typeof(document.createTreeWalker) == "undefined") {
|
||||
if (typeof document.createTreeWalker == "undefined") {
|
||||
return this.find(_query);
|
||||
}
|
||||
let matches = [];
|
||||
|
@ -197,8 +208,10 @@ class Section {
|
|||
const text = textWithCase.toLowerCase();
|
||||
const pos = text.indexOf(query);
|
||||
if (pos != -1) {
|
||||
const startNodeIndex = 0 , endPos = pos + query.length;
|
||||
let endNodeIndex = 0 , l = 0;
|
||||
const startNodeIndex = 0,
|
||||
endPos = pos + query.length;
|
||||
let endNodeIndex = 0,
|
||||
l = 0;
|
||||
if (pos < nodeList[startNodeIndex].length) {
|
||||
let cfi;
|
||||
while (endNodeIndex < nodeList.length - 1) {
|
||||
|
@ -209,29 +222,52 @@ class Section {
|
|||
endNodeIndex += 1;
|
||||
}
|
||||
|
||||
let startNode = nodeList[startNodeIndex] , endNode = nodeList[endNodeIndex];
|
||||
let startNode = nodeList[startNodeIndex],
|
||||
endNode = nodeList[endNodeIndex];
|
||||
let range = section.document.createRange();
|
||||
range.setStart(startNode, pos);
|
||||
let beforeEndLengthCount = nodeList.slice(0, endNodeIndex).reduce((acc,current)=>{return acc+current.textContent.length;},0) ;
|
||||
range.setEnd(endNode, beforeEndLengthCount > endPos ? endPos : endPos - beforeEndLengthCount );
|
||||
let beforeEndLengthCount = nodeList
|
||||
.slice(0, endNodeIndex)
|
||||
.reduce((acc, current) => {
|
||||
return acc + current.textContent.length;
|
||||
}, 0);
|
||||
range.setEnd(
|
||||
endNode,
|
||||
beforeEndLengthCount > endPos
|
||||
? endPos
|
||||
: endPos - beforeEndLengthCount
|
||||
);
|
||||
cfi = section.cfiFromRange(range);
|
||||
|
||||
let excerpt = nodeList.slice(0, endNodeIndex+1).reduce((acc,current)=>{return acc+current.textContent ;},"");
|
||||
let excerpt = nodeList
|
||||
.slice(0, endNodeIndex + 1)
|
||||
.reduce((acc, current) => {
|
||||
return acc + current.textContent;
|
||||
}, "");
|
||||
if (excerpt.length > excerptLimit) {
|
||||
excerpt = excerpt.substring(pos - excerptLimit/2, pos + excerptLimit/2);
|
||||
excerpt = excerpt.substring(
|
||||
pos - excerptLimit / 2,
|
||||
pos + excerptLimit / 2
|
||||
);
|
||||
excerpt = "..." + excerpt + "...";
|
||||
}
|
||||
matches.push({
|
||||
cfi: cfi,
|
||||
excerpt: excerpt
|
||||
excerpt: excerpt,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const treeWalker = document.createTreeWalker(section.document, NodeFilter.SHOW_TEXT, null, false);
|
||||
let node , nodeList = [];
|
||||
while (node = treeWalker.nextNode()) {
|
||||
const treeWalker = document.createTreeWalker(
|
||||
section.document,
|
||||
NodeFilter.SHOW_TEXT,
|
||||
null,
|
||||
false
|
||||
);
|
||||
let node,
|
||||
nodeList = [];
|
||||
while ((node = treeWalker.nextNode())) {
|
||||
nodeList.push(node);
|
||||
if (nodeList.length == maxSeqEle) {
|
||||
search(nodeList.slice(0, maxSeqEle));
|
||||
|
@ -255,7 +291,7 @@ class Section {
|
|||
var settings = {
|
||||
layout: globalLayout.layout,
|
||||
spread: globalLayout.spread,
|
||||
orientation : globalLayout.orientation
|
||||
orientation: globalLayout.orientation,
|
||||
};
|
||||
|
||||
//-- Get the chapter's display type
|
||||
|
|
30
src/spine.js
30
src/spine.js
|
@ -1,7 +1,11 @@
|
|||
import EpubCFI from "./epubcfi";
|
||||
import Hook from "./utils/hook";
|
||||
import Section from "./section";
|
||||
import {replaceBase, replaceCanonical, replaceMeta} from "./utils/replacements";
|
||||
import Hook from "./utils/hook";
|
||||
import {
|
||||
replaceBase,
|
||||
replaceCanonical,
|
||||
replaceMeta,
|
||||
} from "./utils/replacements";
|
||||
|
||||
/**
|
||||
* A collection of Spine Items
|
||||
|
@ -22,9 +26,7 @@ class Spine {
|
|||
this.hooks.content.register(replaceMeta);
|
||||
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.loaded = false;
|
||||
|
||||
this.items = undefined;
|
||||
this.manifest = undefined;
|
||||
this.spineNodeIndex = undefined;
|
||||
|
@ -39,7 +41,6 @@ class Spine {
|
|||
* @param {method} canonical Resolve canonical url
|
||||
*/
|
||||
unpack(_package, resolver, canonical) {
|
||||
|
||||
this.items = _package.spine;
|
||||
this.manifest = _package.manifest;
|
||||
this.spineNodeIndex = _package.spineNodeIndex;
|
||||
|
@ -51,7 +52,11 @@ class Spine {
|
|||
var spineItem;
|
||||
|
||||
item.index = index;
|
||||
item.cfiBase = this.epubcfi.generateChapterComponent(this.spineNodeIndex, item.index, item.id);
|
||||
item.cfiBase = this.epubcfi.generateChapterComponent(
|
||||
this.spineNodeIndex,
|
||||
item.index,
|
||||
item.id
|
||||
);
|
||||
|
||||
if (item.href) {
|
||||
item.url = resolver(item.href, true);
|
||||
|
@ -94,18 +99,15 @@ class Spine {
|
|||
} else {
|
||||
item.prev = function () {
|
||||
return;
|
||||
}
|
||||
};
|
||||
item.next = function () {
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
spineItem = new Section(item, this.hooks);
|
||||
|
||||
this.append(spineItem);
|
||||
|
||||
|
||||
});
|
||||
|
||||
this.loaded = true;
|
||||
|
@ -251,9 +253,9 @@ class Spine {
|
|||
destroy() {
|
||||
this.each((section) => section.destroy());
|
||||
|
||||
this.spineItems = undefined
|
||||
this.spineByHref = undefined
|
||||
this.spineById = undefined
|
||||
this.spineItems = undefined;
|
||||
this.spineByHref = undefined;
|
||||
this.spineById = undefined;
|
||||
|
||||
this.hooks.serialize.clear();
|
||||
this.hooks.content.clear();
|
||||
|
|
80
src/store.js
80
src/store.js
|
@ -1,9 +1,9 @@
|
|||
import {defer, isXml, parse} from "./utils/core";
|
||||
import httpRequest from "./utils/request";
|
||||
import mime from "./utils/mime";
|
||||
import Path from "./utils/path";
|
||||
import EventEmitter from "event-emitter";
|
||||
import localforage from "localforage";
|
||||
import { defer, isXml, parse } from "./utils/core";
|
||||
import mime from "./utils/mime";
|
||||
import Path from "./utils/path";
|
||||
import httpRequest from "./utils/request";
|
||||
|
||||
/**
|
||||
* Handles saving and requesting files from local storage
|
||||
|
@ -13,20 +13,15 @@ import localforage from "localforage";
|
|||
* @param {function} [resolver]
|
||||
*/
|
||||
class Store {
|
||||
|
||||
constructor(name, requester, resolver) {
|
||||
this.urlCache = {};
|
||||
|
||||
this.storage = undefined;
|
||||
|
||||
this.name = name;
|
||||
this.requester = requester || httpRequest;
|
||||
this.resolver = resolver;
|
||||
|
||||
this.online = true;
|
||||
|
||||
this.checkRequirements();
|
||||
|
||||
this.addListeners();
|
||||
}
|
||||
|
||||
|
@ -42,7 +37,7 @@ class Store {
|
|||
store = localforage;
|
||||
}
|
||||
this.storage = store.createInstance({
|
||||
name: this.name
|
||||
name: this.name,
|
||||
});
|
||||
} catch (e) {
|
||||
throw new Error("localForage lib not loaded");
|
||||
|
@ -55,8 +50,8 @@ class Store {
|
|||
*/
|
||||
addListeners() {
|
||||
this._status = this.status.bind(this);
|
||||
window.addEventListener('online', this._status);
|
||||
window.addEventListener('offline', this._status);
|
||||
window.addEventListener("online", this._status);
|
||||
window.addEventListener("offline", this._status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,8 +59,8 @@ class Store {
|
|||
* @private
|
||||
*/
|
||||
removeListeners() {
|
||||
window.removeEventListener('online', this._status);
|
||||
window.removeEventListener('offline', this._status);
|
||||
window.removeEventListener("online", this._status);
|
||||
window.removeEventListener("offline", this._status);
|
||||
this._status = undefined;
|
||||
}
|
||||
|
||||
|
@ -97,15 +92,13 @@ class Store {
|
|||
|
||||
return this.storage.getItem(encodedUrl).then((item) => {
|
||||
if (!item || force) {
|
||||
return this.requester(url, "binary")
|
||||
.then((data) => {
|
||||
return this.requester(url, "binary").then((data) => {
|
||||
return this.storage.setItem(encodedUrl, data);
|
||||
});
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
return Promise.all(mapped);
|
||||
}
|
||||
|
@ -122,9 +115,11 @@ class Store {
|
|||
|
||||
return this.storage.getItem(encodedUrl).then((result) => {
|
||||
if (!result) {
|
||||
return this.requester(url, "binary", withCredentials, headers).then((data) => {
|
||||
return this.requester(url, "binary", withCredentials, headers).then(
|
||||
(data) => {
|
||||
return this.storage.setItem(encodedUrl, data);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
@ -141,16 +136,17 @@ class Store {
|
|||
request(url, type, withCredentials, headers) {
|
||||
if (this.online) {
|
||||
// From network
|
||||
return this.requester(url, type, withCredentials, headers).then((data) => {
|
||||
return this.requester(url, type, withCredentials, headers).then(
|
||||
(data) => {
|
||||
// save to store if not present
|
||||
this.put(url);
|
||||
return data;
|
||||
})
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// From store
|
||||
return this.retrieve(url, type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,7 +156,6 @@ class Store {
|
|||
* @return {Promise<Blob | string | JSON | Document | XMLDocument>}
|
||||
*/
|
||||
retrieve(url, type) {
|
||||
var deferred = new defer();
|
||||
var response;
|
||||
var path = new Path(url);
|
||||
|
||||
|
@ -175,7 +170,6 @@ class Store {
|
|||
response = this.getText(url);
|
||||
}
|
||||
|
||||
|
||||
return response.then((r) => {
|
||||
var deferred = new defer();
|
||||
var result;
|
||||
|
@ -185,7 +179,7 @@ class Store {
|
|||
} else {
|
||||
deferred.reject({
|
||||
message: "File not found in storage: " + url,
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
|
@ -204,17 +198,11 @@ class Store {
|
|||
|
||||
if (type == "json") {
|
||||
r = JSON.parse(response);
|
||||
}
|
||||
else
|
||||
if(isXml(type)) {
|
||||
} else if (isXml(type)) {
|
||||
r = parse(response, "text/xml");
|
||||
}
|
||||
else
|
||||
if(type == "xhtml") {
|
||||
} else if (type == "xhtml") {
|
||||
r = parse(response, "application/xhtml+xml");
|
||||
}
|
||||
else
|
||||
if(type == "html" || type == "htm") {
|
||||
} else if (type == "html" || type == "htm") {
|
||||
r = parse(response, "text/html");
|
||||
} else {
|
||||
r = response;
|
||||
|
@ -239,7 +227,6 @@ class Store {
|
|||
|
||||
return new Blob([uint8array], { type: mimeType });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,36 +310,31 @@ class Store {
|
|||
response = this.getBase64(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(tempUrl) {
|
||||
|
||||
response.then(
|
||||
function (tempUrl) {
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
response = this.getBlob(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(blob) {
|
||||
|
||||
response.then(
|
||||
function (blob) {
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!response) {
|
||||
deferred.reject({
|
||||
message: "File not found in storage: " + url,
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,18 +9,17 @@ class Themes {
|
|||
constructor(rendition) {
|
||||
this.rendition = rendition;
|
||||
this._themes = {
|
||||
"default" : {
|
||||
"rules" : {},
|
||||
"url" : "",
|
||||
"serialized" : ""
|
||||
}
|
||||
default: {
|
||||
rules: {},
|
||||
url: "",
|
||||
serialized: "",
|
||||
},
|
||||
};
|
||||
this._overrides = {};
|
||||
this._current = "default";
|
||||
this._injected = [];
|
||||
this.rendition.hooks.content.register(this.inject.bind(this));
|
||||
this.rendition.hooks.content.register(this.overrides.bind(this));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,16 +33,16 @@ class Themes {
|
|||
if (arguments.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (arguments.length === 1 && typeof(arguments[0]) === "object") {
|
||||
if (arguments.length === 1 && typeof arguments[0] === "object") {
|
||||
return this.registerThemes(arguments[0]);
|
||||
}
|
||||
if (arguments.length === 1 && typeof(arguments[0]) === "string") {
|
||||
if (arguments.length === 1 && typeof arguments[0] === "string") {
|
||||
return this.default(arguments[0]);
|
||||
}
|
||||
if (arguments.length === 2 && typeof(arguments[1]) === "string") {
|
||||
if (arguments.length === 2 && typeof arguments[1] === "string") {
|
||||
return this.registerUrl(arguments[0], arguments[1]);
|
||||
}
|
||||
if (arguments.length === 2 && typeof(arguments[1]) === "object") {
|
||||
if (arguments.length === 2 && typeof arguments[1] === "object") {
|
||||
return this.registerRules(arguments[0], arguments[1]);
|
||||
}
|
||||
}
|
||||
|
@ -58,10 +57,10 @@ class Themes {
|
|||
if (!theme) {
|
||||
return;
|
||||
}
|
||||
if (typeof(theme) === "string") {
|
||||
if (typeof theme === "string") {
|
||||
return this.registerUrl("default", theme);
|
||||
}
|
||||
if (typeof(theme) === "object") {
|
||||
if (typeof theme === "object") {
|
||||
return this.registerRules("default", theme);
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +72,7 @@ class Themes {
|
|||
registerThemes(themes) {
|
||||
for (var theme in themes) {
|
||||
if (themes.hasOwnProperty(theme)) {
|
||||
if (typeof(themes[theme]) === "string") {
|
||||
if (typeof themes[theme] === "string") {
|
||||
this.registerUrl(theme, themes[theme]);
|
||||
} else {
|
||||
this.registerRules(theme, themes[theme]);
|
||||
|
@ -88,8 +87,8 @@ class Themes {
|
|||
* @param {string} css
|
||||
*/
|
||||
registerCss(name, css) {
|
||||
this._themes[name] = { "serialized" : css };
|
||||
if (this._injected[name] || name == 'default') {
|
||||
this._themes[name] = { serialized: css };
|
||||
if (this._injected[name] || name == "default") {
|
||||
this.update(name);
|
||||
}
|
||||
}
|
||||
|
@ -101,8 +100,8 @@ class Themes {
|
|||
*/
|
||||
registerUrl(name, input) {
|
||||
var url = new Url(input);
|
||||
this._themes[name] = { "url": url.toString() };
|
||||
if (this._injected[name] || name == 'default') {
|
||||
this._themes[name] = { url: url.toString() };
|
||||
if (this._injected[name] || name == "default") {
|
||||
this.update(name);
|
||||
}
|
||||
}
|
||||
|
@ -113,9 +112,9 @@ class Themes {
|
|||
* @param {object} rules
|
||||
*/
|
||||
registerRules(name, rules) {
|
||||
this._themes[name] = { "rules": rules };
|
||||
this._themes[name] = { rules: rules };
|
||||
// TODO: serialize css rules
|
||||
if (this._injected[name] || name == 'default') {
|
||||
if (this._injected[name] || name == "default") {
|
||||
this.update(name);
|
||||
}
|
||||
}
|
||||
|
@ -159,9 +158,15 @@ class Themes {
|
|||
var theme;
|
||||
|
||||
for (var name in themes) {
|
||||
if (themes.hasOwnProperty(name) && (name === this._current || name === "default")) {
|
||||
if (
|
||||
themes.hasOwnProperty(name) &&
|
||||
(name === this._current || name === "default")
|
||||
) {
|
||||
theme = themes[name];
|
||||
if((theme.rules && Object.keys(theme.rules).length > 0) || (theme.url && links.indexOf(theme.url) === -1)) {
|
||||
if (
|
||||
(theme.rules && Object.keys(theme.rules).length > 0) ||
|
||||
(theme.url && links.indexOf(theme.url) === -1)
|
||||
) {
|
||||
this.add(name, contents);
|
||||
}
|
||||
this._injected.push(name);
|
||||
|
@ -207,11 +212,15 @@ class Themes {
|
|||
|
||||
this._overrides[name] = {
|
||||
value: value,
|
||||
priority: priority === true
|
||||
priority: priority === true,
|
||||
};
|
||||
|
||||
contents.forEach((content) => {
|
||||
content.css(name, this._overrides[name].value, this._overrides[name].priority);
|
||||
content.css(
|
||||
name,
|
||||
this._overrides[name].value,
|
||||
this._overrides[name].priority
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -262,7 +271,6 @@ class Themes {
|
|||
this._current = undefined;
|
||||
this._injected = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Themes;
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
export const EPUBJS_VERSION = "0.3";
|
||||
|
||||
// Dom events to listen for
|
||||
export const DOM_EVENTS = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "mousemove", "click", "touchend", "touchstart", "touchmove"];
|
||||
export const DOM_EVENTS = [
|
||||
"keydown",
|
||||
"keyup",
|
||||
"keypressed",
|
||||
"mouseup",
|
||||
"mousedown",
|
||||
"mousemove",
|
||||
"click",
|
||||
"touchend",
|
||||
"touchstart",
|
||||
"touchmove",
|
||||
];
|
||||
|
||||
export const EVENTS = {
|
||||
BOOK: {
|
||||
OPEN_FAILED : "openFailed"
|
||||
OPEN_FAILED: "openFailed",
|
||||
},
|
||||
CONTENTS: {
|
||||
EXPAND: "expand",
|
||||
RESIZE: "resize",
|
||||
SELECTED: "selected",
|
||||
SELECTED_RANGE: "selectedRange",
|
||||
LINK_CLICKED : "linkClicked"
|
||||
LINK_CLICKED: "linkClicked",
|
||||
},
|
||||
LOCATIONS: {
|
||||
CHANGED : "changed"
|
||||
CHANGED: "changed",
|
||||
},
|
||||
MANAGERS: {
|
||||
RESIZE: "resize",
|
||||
|
@ -35,7 +46,7 @@ export const EVENTS = {
|
|||
DISPLAYED: "displayed",
|
||||
SHOWN: "shown",
|
||||
HIDDEN: "hidden",
|
||||
MARK_CLICKED : "markClicked"
|
||||
MARK_CLICKED: "markClicked",
|
||||
},
|
||||
RENDITION: {
|
||||
STARTED: "started",
|
||||
|
@ -50,13 +61,13 @@ export const EVENTS = {
|
|||
RELOCATED: "relocated",
|
||||
MARK_CLICKED: "markClicked",
|
||||
SELECTED: "selected",
|
||||
LAYOUT: "layout"
|
||||
LAYOUT: "layout",
|
||||
},
|
||||
LAYOUT: {
|
||||
UPDATED : "updated"
|
||||
UPDATED: "updated",
|
||||
},
|
||||
ANNOTATION: {
|
||||
ATTACH: "attach",
|
||||
DETACH : "detach"
|
||||
}
|
||||
}
|
||||
DETACH: "detach",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -9,12 +9,21 @@ import { DOMParser as XMLDOMParser } from "@xmldom/xmldom";
|
|||
* @returns {function} requestAnimationFrame
|
||||
* @memberof Core
|
||||
*/
|
||||
export const requestAnimationFrame = (typeof window != "undefined") ? (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame) : false;
|
||||
export const requestAnimationFrame =
|
||||
typeof window != "undefined"
|
||||
? window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame
|
||||
: false;
|
||||
const ELEMENT_NODE = 1;
|
||||
const TEXT_NODE = 3;
|
||||
const COMMENT_NODE = 8;
|
||||
const DOCUMENT_NODE = 9;
|
||||
const _URL = typeof URL != "undefined" ? URL : (typeof window != "undefined" ? (window.URL || window.webkitURL || window.mozURL) : undefined);
|
||||
const _URL =
|
||||
typeof URL != "undefined"
|
||||
? URL
|
||||
: typeof window != "undefined"
|
||||
? window.URL || window.webkitURL || window.mozURL
|
||||
: undefined;
|
||||
|
||||
/**
|
||||
* Generates a UUID
|
||||
|
@ -24,11 +33,14 @@ const _URL = typeof URL != "undefined" ? URL : (typeof window != "undefined" ? (
|
|||
*/
|
||||
export function uuid() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
||||
var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
|
||||
/[xy]/g,
|
||||
function (c) {
|
||||
var r = (d + Math.random() * 16) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
return (c=="x" ? r : (r&0x7|0x8)).toString(16);
|
||||
});
|
||||
return (c == "x" ? r : (r & 0x7) | 0x8).toString(16);
|
||||
}
|
||||
);
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
@ -97,12 +109,15 @@ export function prefixed(unprefixed) {
|
|||
var lower = unprefixed.toLowerCase();
|
||||
var length = vendors.length;
|
||||
|
||||
if (typeof(document) === "undefined" || typeof(document.body.style[lower]) != "undefined") {
|
||||
if (
|
||||
typeof document === "undefined" ||
|
||||
typeof document.body.style[lower] != "undefined"
|
||||
) {
|
||||
return unprefixed;
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (typeof(document.body.style[prefixes[i] + lower]) != "undefined") {
|
||||
if (typeof document.body.style[prefixes[i] + lower] != "undefined") {
|
||||
return prefixes[i] + lower;
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +152,11 @@ export function extend(target) {
|
|||
sources.forEach(function (source) {
|
||||
if (!source) return;
|
||||
Object.getOwnPropertyNames(source).forEach(function (propName) {
|
||||
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
|
||||
Object.defineProperty(
|
||||
target,
|
||||
propName,
|
||||
Object.getOwnPropertyDescriptor(source, propName)
|
||||
);
|
||||
});
|
||||
});
|
||||
return target;
|
||||
|
@ -247,10 +266,25 @@ export function indexOfSorted(item, array, compareFunction, _start, _end) {
|
|||
* @memberof Core
|
||||
*/
|
||||
export function bounds(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
var widthProps = [
|
||||
"width",
|
||||
"paddingRight",
|
||||
"paddingLeft",
|
||||
"marginRight",
|
||||
"marginLeft",
|
||||
"borderRightWidth",
|
||||
"borderLeftWidth",
|
||||
];
|
||||
var heightProps = [
|
||||
"height",
|
||||
"paddingTop",
|
||||
"paddingBottom",
|
||||
"marginTop",
|
||||
"marginBottom",
|
||||
"borderTopWidth",
|
||||
"borderBottomWidth",
|
||||
];
|
||||
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
|
@ -265,9 +299,8 @@ export function bounds(el) {
|
|||
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
width: width,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,10 +311,23 @@ export function bounds(el) {
|
|||
* @memberof Core
|
||||
*/
|
||||
export function borders(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
var widthProps = [
|
||||
"paddingRight",
|
||||
"paddingLeft",
|
||||
"marginRight",
|
||||
"marginLeft",
|
||||
"borderRightWidth",
|
||||
"borderLeftWidth",
|
||||
];
|
||||
var heightProps = [
|
||||
"paddingTop",
|
||||
"paddingBottom",
|
||||
"marginTop",
|
||||
"marginBottom",
|
||||
"borderTopWidth",
|
||||
"borderBottomWidth",
|
||||
];
|
||||
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
|
@ -296,9 +342,8 @@ export function borders(el) {
|
|||
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
width: width,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,7 +372,6 @@ export function nodeBounds(node) {
|
|||
* @memberof Core
|
||||
*/
|
||||
export function windowBounds() {
|
||||
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
|
||||
|
@ -337,9 +381,8 @@ export function windowBounds() {
|
|||
right: width,
|
||||
bottom: height,
|
||||
width: width,
|
||||
height: height
|
||||
height: height,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -442,7 +485,7 @@ export function createBase64Url(content, mime){
|
|||
var data;
|
||||
var datauri;
|
||||
|
||||
if (typeof(content) !== "string") {
|
||||
if (typeof content !== "string") {
|
||||
// Only handles strings
|
||||
return;
|
||||
}
|
||||
|
@ -484,7 +527,7 @@ export function parse(markup, mime, forceXMLDom) {
|
|||
|
||||
// Remove byte order mark before parsing
|
||||
// https://www.w3.org/International/questions/qa-byte-order-mark
|
||||
if(markup.charCodeAt(0) === 0xFEFF) {
|
||||
if (markup.charCodeAt(0) === 0xfeff) {
|
||||
markup = markup.slice(1);
|
||||
}
|
||||
|
||||
|
@ -524,7 +567,6 @@ export function qs(el, sel) {
|
|||
* @memberof Core
|
||||
*/
|
||||
export function qsa(el, sel) {
|
||||
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelectorAll(sel);
|
||||
} else {
|
||||
|
@ -574,14 +616,19 @@ export function qsp(el, sel, props) {
|
|||
*/
|
||||
export function sprint(root, func) {
|
||||
var doc = root.ownerDocument || root;
|
||||
if (typeof(doc.createTreeWalker) !== "undefined") {
|
||||
if (typeof doc.createTreeWalker !== "undefined") {
|
||||
treeWalker(root, func, NodeFilter.SHOW_TEXT);
|
||||
} else {
|
||||
walk(root, function(node) {
|
||||
if (node && node.nodeType === 3) { // Node.TEXT_NODE
|
||||
walk(
|
||||
root,
|
||||
function (node) {
|
||||
if (node && node.nodeType === 3) {
|
||||
// Node.TEXT_NODE
|
||||
func(node);
|
||||
}
|
||||
}, true);
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,7 +684,6 @@ export function blob2base64(blob) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new pending promise and provides methods to resolve or reject it.
|
||||
* From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
|
||||
|
@ -691,8 +737,11 @@ export function querySelectorByType(html, element, type){
|
|||
if (!query || query.length === 0) {
|
||||
query = qsa(html, element);
|
||||
for (var i = 0; i < query.length; i++) {
|
||||
if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type ||
|
||||
query[i].getAttribute("epub:type") === type) {
|
||||
if (
|
||||
query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") ===
|
||||
type ||
|
||||
query[i].getAttribute("epub:type") === type
|
||||
) {
|
||||
return query[i];
|
||||
}
|
||||
}
|
||||
|
@ -730,7 +779,7 @@ export function parents(node) {
|
|||
for (; node; node = node.parentNode) {
|
||||
nodes.unshift(node);
|
||||
}
|
||||
return nodes
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -768,7 +817,7 @@ export function filterChildren(el, nodeName, single) {
|
|||
*/
|
||||
export function getParentByTagName(node, tagname) {
|
||||
let parent;
|
||||
if (node === null || tagname === '') return;
|
||||
if (node === null || tagname === "") return;
|
||||
parent = node.parentNode;
|
||||
while (parent.nodeType === 1) {
|
||||
if (parent.tagName.toLowerCase() === tagname) {
|
||||
|
@ -841,9 +890,10 @@ export class RangeObject {
|
|||
}
|
||||
|
||||
selectNodeContents(referenceNode) {
|
||||
let end = referenceNode.childNodes[referenceNode.childNodes - 1];
|
||||
let endIndex = (referenceNode.nodeType === 3) ?
|
||||
referenceNode.textContent.length : parent.childNodes.length;
|
||||
let endIndex =
|
||||
referenceNode.nodeType === 3
|
||||
? referenceNode.textContent.length
|
||||
: parent.childNodes.length;
|
||||
this.setStart(referenceNode, 0);
|
||||
this.setEnd(referenceNode, endIndex);
|
||||
}
|
||||
|
@ -862,8 +912,10 @@ export class RangeObject {
|
|||
}
|
||||
|
||||
_checkCollapsed() {
|
||||
if (this.startContainer === this.endContainer &&
|
||||
this.startOffset === this.endOffset) {
|
||||
if (
|
||||
this.startContainer === this.endContainer &&
|
||||
this.startOffset === this.endOffset
|
||||
) {
|
||||
this.collapsed = true;
|
||||
} else {
|
||||
this.collapsed = false;
|
||||
|
|
|
@ -56,7 +56,7 @@ class Hook {
|
|||
try {
|
||||
var executing = task.apply(context, args);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
if (executing && typeof executing["then"] === "function") {
|
||||
|
@ -66,7 +66,6 @@ class Hook {
|
|||
// Otherwise Task resolves immediately, continue
|
||||
});
|
||||
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ class Hook {
|
|||
}
|
||||
|
||||
clear() {
|
||||
return this.hooks = [];
|
||||
return (this.hooks = []);
|
||||
}
|
||||
}
|
||||
export default Hook;
|
||||
|
|
|
@ -4,17 +4,17 @@ edited down
|
|||
*/
|
||||
|
||||
var table = {
|
||||
"application" : {
|
||||
"ecmascript" : [ "es", "ecma" ],
|
||||
"javascript" : "js",
|
||||
"ogg" : "ogx",
|
||||
"pdf" : "pdf",
|
||||
"postscript" : [ "ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3" ],
|
||||
application: {
|
||||
ecmascript: ["es", "ecma"],
|
||||
javascript: "js",
|
||||
ogg: "ogx",
|
||||
pdf: "pdf",
|
||||
postscript: ["ps", "ai", "eps", "epsi", "epsf", "eps2", "eps3"],
|
||||
"rdf+xml": "rdf",
|
||||
"smil" : [ "smi", "smil" ],
|
||||
smil: ["smi", "smil"],
|
||||
"xhtml+xml": ["xhtml", "xht"],
|
||||
"xml" : [ "xml", "xsl", "xsd", "opf", "ncx" ],
|
||||
"zip" : "zip",
|
||||
xml: ["xml", "xsl", "xsd", "opf", "ncx"],
|
||||
zip: "zip",
|
||||
"x-httpd-eruby": "rhtml",
|
||||
"x-latex": "latex",
|
||||
"x-maker": ["frm", "maker", "frame", "fm", "fb", "book", "fbdoc"],
|
||||
|
@ -24,16 +24,16 @@ var table = {
|
|||
"epub+zip": "epub",
|
||||
"font-tdpfr": "pfr",
|
||||
"inkml+xml": ["ink", "inkml"],
|
||||
"json" : "json",
|
||||
json: "json",
|
||||
"jsonml+json": "jsonml",
|
||||
"mathml+xml": "mathml",
|
||||
"metalink+xml": "metalink",
|
||||
"mp4" : "mp4s",
|
||||
mp4: "mp4s",
|
||||
// "oebps-package+xml" : "opf",
|
||||
"omdoc+xml": "omdoc",
|
||||
"oxps" : "oxps",
|
||||
oxps: "oxps",
|
||||
"vnd.amazon.ebook": "azw",
|
||||
"widget" : "wgt",
|
||||
widget: "wgt",
|
||||
// "x-dtbncx+xml" : "ncx",
|
||||
"x-dtbook+xml": "dtb",
|
||||
"x-dtbresource+xml": "res",
|
||||
|
@ -59,56 +59,56 @@ var table = {
|
|||
"x-compressed": "tgz",
|
||||
"x-gzip": "gz",
|
||||
},
|
||||
"audio" : {
|
||||
"flac" : "flac",
|
||||
"midi" : [ "mid", "midi", "kar", "rmi" ],
|
||||
"mpeg" : [ "mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a" ],
|
||||
"mpegurl" : "m3u",
|
||||
"ogg" : [ "oga", "ogg", "spx" ],
|
||||
audio: {
|
||||
flac: "flac",
|
||||
midi: ["mid", "midi", "kar", "rmi"],
|
||||
mpeg: ["mpga", "mpega", "mp2", "mp3", "m4a", "mp2a", "m2a", "m3a"],
|
||||
mpegurl: "m3u",
|
||||
ogg: ["oga", "ogg", "spx"],
|
||||
"x-aiff": ["aif", "aiff", "aifc"],
|
||||
"x-ms-wma": "wma",
|
||||
"x-wav": "wav",
|
||||
"adpcm" : "adp",
|
||||
"mp4" : "mp4a",
|
||||
"webm" : "weba",
|
||||
adpcm: "adp",
|
||||
mp4: "mp4a",
|
||||
webm: "weba",
|
||||
"x-aac": "aac",
|
||||
"x-caf": "caf",
|
||||
"x-matroska": "mka",
|
||||
"x-pn-realaudio-plugin": "rmp",
|
||||
"xm" : "xm",
|
||||
"mid" : [ "mid", "rmi" ]
|
||||
xm: "xm",
|
||||
mid: ["mid", "rmi"],
|
||||
},
|
||||
"image" : {
|
||||
"gif" : "gif",
|
||||
"ief" : "ief",
|
||||
"jpeg" : [ "jpeg", "jpg", "jpe" ],
|
||||
"pcx" : "pcx",
|
||||
"png" : "png",
|
||||
image: {
|
||||
gif: "gif",
|
||||
ief: "ief",
|
||||
jpeg: ["jpeg", "jpg", "jpe"],
|
||||
pcx: "pcx",
|
||||
png: "png",
|
||||
"svg+xml": ["svg", "svgz"],
|
||||
"tiff" : [ "tiff", "tif" ],
|
||||
tiff: ["tiff", "tif"],
|
||||
"x-icon": "ico",
|
||||
"bmp" : "bmp",
|
||||
"webp" : "webp",
|
||||
bmp: "bmp",
|
||||
webp: "webp",
|
||||
"x-pict": ["pic", "pct"],
|
||||
"x-tga": "tga",
|
||||
"cis-cod" : "cod"
|
||||
"cis-cod": "cod",
|
||||
},
|
||||
"text" : {
|
||||
text: {
|
||||
"cache-manifest": ["manifest", "appcache"],
|
||||
"css" : "css",
|
||||
"csv" : "csv",
|
||||
"html" : [ "html", "htm", "shtml", "stm" ],
|
||||
"mathml" : "mml",
|
||||
"plain" : [ "txt", "text", "brf", "conf", "def", "list", "log", "in", "bas" ],
|
||||
"richtext" : "rtx",
|
||||
css: "css",
|
||||
csv: "csv",
|
||||
html: ["html", "htm", "shtml", "stm"],
|
||||
mathml: "mml",
|
||||
plain: ["txt", "text", "brf", "conf", "def", "list", "log", "in", "bas"],
|
||||
richtext: "rtx",
|
||||
"tab-separated-values": "tsv",
|
||||
"x-bibtex" : "bib"
|
||||
"x-bibtex": "bib",
|
||||
},
|
||||
"video" : {
|
||||
"mpeg" : [ "mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2" ],
|
||||
"mp4" : [ "mp4", "mp4v", "mpg4" ],
|
||||
"quicktime" : [ "qt", "mov" ],
|
||||
"ogg" : "ogv",
|
||||
video: {
|
||||
mpeg: ["mpeg", "mpg", "mpe", "m1v", "m2v", "mp2", "mpa", "mpv2"],
|
||||
mp4: ["mp4", "mp4v", "mpg4"],
|
||||
quicktime: ["qt", "mov"],
|
||||
ogg: "ogv",
|
||||
"vnd.mpegurl": ["mxu", "m4u"],
|
||||
"x-flv": "flv",
|
||||
"x-la-asf": ["lsf", "lsx"],
|
||||
|
@ -122,25 +122,29 @@ var table = {
|
|||
"x-sgi-movie": "movie",
|
||||
"x-matroska": ["mpv", "mkv", "mk3d", "mks"],
|
||||
"3gpp2": "3g2",
|
||||
"h261" : "h261",
|
||||
"h263" : "h263",
|
||||
"h264" : "h264",
|
||||
"jpeg" : "jpgv",
|
||||
"jpm" : [ "jpm", "jpgm" ],
|
||||
"mj2" : [ "mj2", "mjp2" ],
|
||||
h261: "h261",
|
||||
h263: "h263",
|
||||
h264: "h264",
|
||||
jpeg: "jpgv",
|
||||
jpm: ["jpm", "jpgm"],
|
||||
mj2: ["mj2", "mjp2"],
|
||||
"vnd.ms-playready.media.pyv": "pyv",
|
||||
"vnd.uvvu.mp4": ["uvu", "uvvu"],
|
||||
"vnd.vivo": "viv",
|
||||
"webm" : "webm",
|
||||
webm: "webm",
|
||||
"x-f4v": "f4v",
|
||||
"x-m4v": "m4v",
|
||||
"x-ms-vob": "vob",
|
||||
"x-smv" : "smv"
|
||||
}
|
||||
"x-smv": "smv",
|
||||
},
|
||||
};
|
||||
|
||||
var mimeTypes = (function () {
|
||||
var type, subtype, val, index, mimeTypes = {};
|
||||
var type,
|
||||
subtype,
|
||||
val,
|
||||
index,
|
||||
mimeTypes = {};
|
||||
for (type in table) {
|
||||
if (table.hasOwnProperty(type)) {
|
||||
for (subtype in table[type]) {
|
||||
|
@ -163,7 +167,10 @@ var mimeTypes = (function() {
|
|||
var defaultValue = "text/plain"; //"application/octet-stream";
|
||||
|
||||
function lookup(filename) {
|
||||
return filename && mimeTypes[filename.split(".").pop().toLowerCase()] || defaultValue;
|
||||
};
|
||||
return (
|
||||
(filename && mimeTypes[filename.split(".").pop().toLowerCase()]) ||
|
||||
defaultValue
|
||||
);
|
||||
}
|
||||
|
||||
export default { lookup };
|
||||
|
|
|
@ -29,7 +29,6 @@ class Path {
|
|||
|
||||
this.filename = parsed.base;
|
||||
this.extension = parsed.ext.slice(1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +54,7 @@ class Path {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
isDirectory(what) {
|
||||
return (what.charAt(what.length-1) === "/");
|
||||
return what.charAt(what.length - 1) === "/";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +76,7 @@ class Path {
|
|||
* @returns {string} relative
|
||||
*/
|
||||
relative(what) {
|
||||
var isAbsolute = what && (what.indexOf("://") > -1);
|
||||
var isAbsolute = what && what.indexOf("://") > -1;
|
||||
|
||||
if (isAbsolute) {
|
||||
return what;
|
||||
|
|
|
@ -33,24 +33,21 @@ class Queue {
|
|||
}
|
||||
|
||||
if (typeof task === "function") {
|
||||
|
||||
deferred = new defer();
|
||||
promise = deferred.promise;
|
||||
|
||||
queued = {
|
||||
"task" : task,
|
||||
"args" : args,
|
||||
task: task,
|
||||
args: args,
|
||||
//"context" : context,
|
||||
"deferred" : deferred,
|
||||
"promise" : promise
|
||||
deferred: deferred,
|
||||
promise: promise,
|
||||
};
|
||||
|
||||
} else {
|
||||
// Task is a promise
|
||||
queued = {
|
||||
"promise" : task
|
||||
promise: task,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this._q.push(queued);
|
||||
|
@ -82,30 +79,28 @@ class Queue {
|
|||
|
||||
if (result && typeof result["then"] === "function") {
|
||||
// Task is a function that returns a promise
|
||||
return result.then(function(){
|
||||
return result.then(
|
||||
function () {
|
||||
inwait.deferred.resolve.apply(this.context, arguments);
|
||||
}.bind(this), function() {
|
||||
}.bind(this),
|
||||
function () {
|
||||
inwait.deferred.reject.apply(this.context, arguments);
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
// Task resolves immediately
|
||||
inwait.deferred.resolve.apply(this.context, result);
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if (inwait.promise) {
|
||||
// Task is a promise
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
} else {
|
||||
inwait = new defer();
|
||||
inwait.deferred.resolve();
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run All Immediately
|
||||
|
@ -120,26 +115,22 @@ class Queue {
|
|||
* @return {Promise}
|
||||
*/
|
||||
run() {
|
||||
|
||||
if (!this.running) {
|
||||
this.running = true;
|
||||
this.defered = new defer();
|
||||
}
|
||||
|
||||
this.tick.call(window, () => {
|
||||
|
||||
if (this._q.length) {
|
||||
|
||||
this.dequeue()
|
||||
.then(function(){
|
||||
this.dequeue().then(
|
||||
function () {
|
||||
this.run();
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
} else {
|
||||
this.defered.resolve();
|
||||
this.running = undefined;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Unpause
|
||||
|
@ -155,21 +146,20 @@ class Queue {
|
|||
* @return {Promise}
|
||||
*/
|
||||
flush() {
|
||||
|
||||
if (this.running) {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
if (this._q.length) {
|
||||
this.running = this.dequeue()
|
||||
.then(function(){
|
||||
this.running = this.dequeue().then(
|
||||
function () {
|
||||
this.running = undefined;
|
||||
return this.flush();
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return this.running;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,7 +194,6 @@ class Queue {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new task from a callback
|
||||
* @class
|
||||
|
@ -216,7 +205,6 @@ class Queue {
|
|||
*/
|
||||
class Task {
|
||||
constructor(task, args, context) {
|
||||
|
||||
return function () {
|
||||
var toApply = arguments || [];
|
||||
|
||||
|
@ -233,14 +221,10 @@ class Task {
|
|||
|
||||
// Apply all arguments to the functions
|
||||
task.apply(context || this, toApply);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Queue;
|
||||
export { Task };
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { qs, qsa } from "./core";
|
||||
import { qs } from "./core";
|
||||
import Url from "./url";
|
||||
import Path from "./path";
|
||||
|
||||
export function replaceBase(doc, section) {
|
||||
var base;
|
||||
var head;
|
||||
var url = section.url;
|
||||
var absolute = (url.indexOf("://") > -1);
|
||||
var absolute = url.indexOf("://") > -1;
|
||||
|
||||
if (!doc) {
|
||||
return;
|
||||
|
@ -73,7 +72,6 @@ export function replaceMeta(doc, section){
|
|||
|
||||
// TODO: move me to Contents
|
||||
export function replaceLinks(contents, fn) {
|
||||
|
||||
var links = contents.querySelectorAll("a[href]");
|
||||
|
||||
if (!links.length) {
|
||||
|
@ -89,12 +87,10 @@ export function replaceLinks(contents, fn) {
|
|||
return;
|
||||
}
|
||||
|
||||
var absolute = (href.indexOf("://") > -1);
|
||||
var absolute = href.indexOf("://") > -1;
|
||||
|
||||
if (absolute) {
|
||||
|
||||
link.setAttribute("target", "_blank");
|
||||
|
||||
} else {
|
||||
var linkUrl;
|
||||
try {
|
||||
|
@ -104,7 +100,6 @@ export function replaceLinks(contents, fn) {
|
|||
}
|
||||
|
||||
link.onclick = function () {
|
||||
|
||||
if (linkUrl && linkUrl.hash) {
|
||||
fn(linkUrl.Path.path + linkUrl.hash);
|
||||
} else if (linkUrl) {
|
||||
|
@ -121,8 +116,6 @@ export function replaceLinks(contents, fn) {
|
|||
for (var i = 0; i < links.length; i++) {
|
||||
replaceLink(links[i]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export function substitute(content, urls, replacements) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import {defer, isXml, parse} from "./core";
|
|||
import Path from "./path";
|
||||
|
||||
function request(url, type, withCredentials, headers) {
|
||||
var supportsURL = (typeof window != "undefined") ? window.URL : false; // TODO: fallback for url if window isn't defined
|
||||
var supportsURL = typeof window != "undefined" ? window.URL : false; // TODO: fallback for url if window isn't defined
|
||||
var BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer";
|
||||
|
||||
var deferred = new defer();
|
||||
|
@ -18,7 +18,7 @@ function request(url, type, withCredentials, headers) {
|
|||
if (!("overrideMimeType" in xhrPrototype)) {
|
||||
// IE10 might have response, but not overrideMimeType
|
||||
Object.defineProperty(xhrPrototype, "overrideMimeType", {
|
||||
value: function xmlHttpRequestOverrideMimeType() {}
|
||||
value: function xmlHttpRequestOverrideMimeType() {},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -48,20 +48,10 @@ function request(url, type, withCredentials, headers) {
|
|||
xhr.responseType = BLOB_RESPONSE;
|
||||
}
|
||||
|
||||
|
||||
if (isXml(type)) {
|
||||
// xhr.responseType = "document";
|
||||
xhr.overrideMimeType("text/xml"); // for OPF parsing
|
||||
}
|
||||
|
||||
if(type == "xhtml") {
|
||||
// xhr.responseType = "document";
|
||||
}
|
||||
|
||||
if(type == "html" || type == "htm") {
|
||||
// xhr.responseType = "document";
|
||||
}
|
||||
|
||||
if (type == "binary") {
|
||||
xhr.responseType = "arraybuffer";
|
||||
}
|
||||
|
@ -80,14 +70,15 @@ function request(url, type, withCredentials, headers) {
|
|||
responseXML = this.responseXML;
|
||||
}
|
||||
|
||||
if (this.status === 200 || this.status === 0 || responseXML) { //-- Firefox is reporting 0 for blob urls
|
||||
if (this.status === 200 || this.status === 0 || responseXML) {
|
||||
//-- Firefox is reporting 0 for blob urls
|
||||
var r;
|
||||
|
||||
if (!this.response && !responseXML) {
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message: "Empty Response",
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
@ -97,49 +88,40 @@ function request(url, type, withCredentials, headers) {
|
|||
status: this.status,
|
||||
response: this.response,
|
||||
message: "Forbidden",
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
if (responseXML) {
|
||||
r = this.responseXML;
|
||||
} else
|
||||
if(isXml(type)){
|
||||
} else if (isXml(type)) {
|
||||
// xhr.overrideMimeType("text/xml"); // for OPF parsing
|
||||
// If this.responseXML wasn't set, try to parse using a DOMParser from text
|
||||
r = parse(this.response, "text/xml");
|
||||
}else
|
||||
if(type == "xhtml"){
|
||||
} else if (type == "xhtml") {
|
||||
r = parse(this.response, "application/xhtml+xml");
|
||||
}else
|
||||
if(type == "html" || type == "htm"){
|
||||
} else if (type == "html" || type == "htm") {
|
||||
r = parse(this.response, "text/html");
|
||||
}else
|
||||
if(type == "json"){
|
||||
} else if (type == "json") {
|
||||
r = JSON.parse(this.response);
|
||||
}else
|
||||
if(type == "blob"){
|
||||
|
||||
} else if (type == "blob") {
|
||||
if (supportsURL) {
|
||||
r = this.response;
|
||||
} else {
|
||||
//-- Safari doesn't support responseType blob, so create a blob from arraybuffer
|
||||
r = new Blob([this.response]);
|
||||
}
|
||||
|
||||
} else {
|
||||
r = this.response;
|
||||
}
|
||||
|
||||
deferred.resolve(r);
|
||||
} else {
|
||||
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message: this.response,
|
||||
stack : new Error().stack
|
||||
stack: new Error().stack,
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ export default function scrollType() {
|
|||
if (definer.scrollLeft > 0) {
|
||||
type = "default";
|
||||
} else {
|
||||
if (typeof Element !== 'undefined' && Element.prototype.scrollIntoView) {
|
||||
if (typeof Element !== "undefined" && Element.prototype.scrollIntoView) {
|
||||
definer.children[0].children[1].scrollIntoView();
|
||||
if (definer.scrollLeft < 0) {
|
||||
type = "negative";
|
||||
|
@ -26,7 +26,7 @@ export default function scrollType() {
|
|||
}
|
||||
|
||||
export function createDefiner() {
|
||||
var definer = document.createElement('div');
|
||||
var definer = document.createElement("div");
|
||||
definer.dir = "rtl";
|
||||
|
||||
definer.style.position = "fixed";
|
||||
|
@ -36,14 +36,14 @@ export function createDefiner() {
|
|||
definer.style.left = "0px";
|
||||
definer.style.overflow = "hidden";
|
||||
|
||||
var innerDiv = document.createElement('div');
|
||||
var innerDiv = document.createElement("div");
|
||||
innerDiv.style.width = "2px";
|
||||
|
||||
var spanA = document.createElement('span');
|
||||
var spanA = document.createElement("span");
|
||||
spanA.style.width = "1px";
|
||||
spanA.style.display = "inline-block";
|
||||
|
||||
var spanB = document.createElement('span');
|
||||
var spanB = document.createElement("span");
|
||||
spanB.style.width = "1px";
|
||||
spanB.style.display = "inline-block";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Path from "./path";
|
||||
import path from "path-webpack";
|
||||
import Path from "./path";
|
||||
|
||||
/**
|
||||
* creates a Url object for parsing and manipulation of a url string
|
||||
|
@ -9,7 +9,7 @@ import path from "path-webpack";
|
|||
*/
|
||||
class Url {
|
||||
constructor(urlString, baseString) {
|
||||
var absolute = (urlString.indexOf("://") > -1);
|
||||
var absolute = urlString.indexOf("://") > -1;
|
||||
var pathname = urlString;
|
||||
var basePath;
|
||||
|
||||
|
@ -22,17 +22,21 @@ class Url {
|
|||
this.search = "";
|
||||
this.base = baseString;
|
||||
|
||||
if (!absolute &&
|
||||
if (
|
||||
!absolute &&
|
||||
baseString !== false &&
|
||||
typeof(baseString) !== "string" &&
|
||||
window && window.location) {
|
||||
typeof baseString !== "string" &&
|
||||
window &&
|
||||
window.location
|
||||
) {
|
||||
this.base = window.location.href;
|
||||
}
|
||||
|
||||
// URL Polyfill doesn't throw an error if base is empty
|
||||
if (absolute || this.base) {
|
||||
try {
|
||||
if (this.base) { // Safari doesn't like an undefined base
|
||||
if (this.base) {
|
||||
// Safari doesn't like an undefined base
|
||||
this.Url = new URL(urlString, this.base);
|
||||
} else {
|
||||
this.Url = new URL(urlString);
|
||||
|
@ -44,7 +48,7 @@ class Url {
|
|||
this.hash = this.Url.hash;
|
||||
this.search = this.Url.search;
|
||||
|
||||
pathname = this.Url.pathname + (this.Url.search ? this.Url.search : '');
|
||||
pathname = this.Url.pathname + (this.Url.search ? this.Url.search : "");
|
||||
} catch (e) {
|
||||
// Skip URL parsing
|
||||
this.Url = undefined;
|
||||
|
@ -61,7 +65,6 @@ class Url {
|
|||
this.directory = this.Path.directory;
|
||||
this.filename = this.Path.filename;
|
||||
this.extension = this.Path.extension;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +80,7 @@ class Url {
|
|||
* @returns {string} url
|
||||
*/
|
||||
resolve(what) {
|
||||
var isAbsolute = (what.indexOf("://") > -1);
|
||||
var isAbsolute = what.indexOf("://") > -1;
|
||||
var fullpath;
|
||||
|
||||
if (isAbsolute) {
|
||||
|
|
371
test/old/epub.js
371
test/old/epub.js
|
@ -1,371 +0,0 @@
|
|||
var domain = window.location.origin;
|
||||
|
||||
module('Core');
|
||||
|
||||
test("EPUBJS.core.resolveUrl", 1, function() {
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "/chasen/derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "http://example.com/fred/chasen/derf.html", "resolved" );
|
||||
|
||||
});
|
||||
|
||||
test("EPUBJS.core.resolveUrl ../", 1, function() {
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "../derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "http://example.com/fred/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
|
||||
test("EPUBJS.core.resolveUrl folders", 1, function() {
|
||||
var a = "/fred/chasen/";
|
||||
var b = "/fred/chasen/derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "/fred/chasen/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
test("EPUBJS.core.resolveUrl ../folders", 1, function() {
|
||||
var a = "/fred/chasen/";
|
||||
var b = "../../derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
module('Create');
|
||||
|
||||
asyncTest("Create new ePub(/path/to/epub/)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, "../books/moby-dick/OPS/", "book url is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Create new ePub(/path/to/epub/package.opf)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, domain + "/books/moby-dick/OPS/", "bookPath is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open using ePub(/path/to/epub/package.opf)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open Remote ePub", 1, function() {
|
||||
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open Remote ePub from Package", 1, function() {
|
||||
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Epub Package", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module('Parse');
|
||||
|
||||
//TODO: add mocked tests for parser
|
||||
|
||||
asyncTest("Manifest", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( Object.keys(book.package.manifest).length, 152, "Manifest is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Metadata", 3, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.metadata.creator, "Herman Melville", "Creator metadata is parsed" );
|
||||
equal( book.package.metadata.title, "Moby-Dick", "Title metadata is parsed" );
|
||||
equal( book.package.metadata.identifier, "code.google.com.epub-samples.moby-dick-basic", "Identifier metadata is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Spine", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.spine.length, 144, "Spine is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Cover", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.cover, "../books/moby-dick/OPS/images/9780316000000.jpg", "Cover is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module('Spine');
|
||||
|
||||
asyncTest("Length", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.length, 144, "All spine items present" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Items", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.spineItems.length, 144, "All spine items added" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("First Item", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get(0);
|
||||
equal( section.href, "cover.xhtml", "First spine item href found" );
|
||||
equal( section.cfiBase, "/6/2[cover]", "First spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Item by Href", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("chapter_001.xhtml");
|
||||
equal( section.href, "chapter_001.xhtml", "chap 1 spine item href found" );
|
||||
equal( section.cfiBase, "/6/14[xchapter_001]", "chap 1 spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Item by ID", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
equal( section.href, "chapter_050.xhtml", "chap 50 spine item href found" );
|
||||
equal( section.cfiBase, "/6/112[xchapter_050]", "chap 50 spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Render Spine Item", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
section.render().then(function(content){
|
||||
equal( content.substring(377, 429), "<h1>Chapter 50. Ahab’s Boat and Crew. Fedallah.</h1>", "Chapter text rendered as string" );
|
||||
});
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module('Navigation');
|
||||
|
||||
asyncTest("NCX & Nav", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.navigation.navUrl, "../books/moby-dick/OPS/toc.xhtml", "Nav URL found" );
|
||||
equal( book.navigation.ncxUrl, "../books/moby-dick/OPS/toc.ncx", "NCX URL found" );
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
asyncTest("Load TOC Auto Pick", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
book.navigation.load().then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Load TOC from Nav", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var nav = book.navigation.nav.load();
|
||||
nav.then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Load TOC from NCX", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var ncx = book.navigation.ncx.load();
|
||||
ncx.then(function(toc){
|
||||
equal( toc.length, 14, "Full NCX toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get all TOC", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
equal( book.navigation.get().length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get TOC item by href", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("chapter_001.xhtml");
|
||||
equal( item.id, "toc-chapter_001", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get TOC item by ID", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("#toc-chapter_001");
|
||||
equal( item.href, "chapter_001.xhtml", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module('Hooks');
|
||||
|
||||
asyncTest("Register a new hook", 1, function() {
|
||||
|
||||
var beforeDisplay = new EPUBJS.Hook();
|
||||
beforeDisplay.register(function(args){
|
||||
var defer = new RSVP.defer();
|
||||
console.log("ran", 1);
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
equal( beforeDisplay.hooks.length, 1, "Registered a hook" );
|
||||
start();
|
||||
|
||||
// this.beforeDisplay.trigger(args).then(function(){});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Trigger all new hook", 4, function() {
|
||||
|
||||
var beforeDisplay = new EPUBJS.Hook(this);
|
||||
this.testerObject = {tester: 1};
|
||||
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
|
||||
start();
|
||||
equal( testerObject.tester, 1, "tester is 1" );
|
||||
stop();
|
||||
|
||||
testerObject.tester += 1;
|
||||
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
|
||||
start();
|
||||
equal(testerObject.tester, 2, "tester is 2" );
|
||||
stop();
|
||||
|
||||
testerObject.tester += 1;
|
||||
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
|
||||
start();
|
||||
equal( beforeDisplay.hooks.length, 2, "Added two hooks" );
|
||||
stop();
|
||||
|
||||
beforeDisplay.trigger(this.testerObject).then(function(){
|
||||
|
||||
start();
|
||||
equal( this.testerObject.tester, 3, "tester is 3" );
|
||||
|
||||
}.bind(this));
|
||||
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
module('Rendering');
|
||||
/*
|
||||
asyncTest("Render To", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
var rendition = book.renderTo("qunit-fixture", {width:400, height:600});
|
||||
var displayed = rendition.display(0);
|
||||
|
||||
displayed.then(function(){
|
||||
equal( $( "iframe", "#qunit-fixture" ).length, 1, "iframe added successfully" );
|
||||
start();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
*/
|
63
types/annotations.d.ts
vendored
63
types/annotations.d.ts
vendored
|
@ -1,53 +1,60 @@
|
|||
import Rendition from "./rendition";
|
||||
import View from "./managers/view";
|
||||
import Rendition from "./rendition";
|
||||
|
||||
export default class Annotations {
|
||||
constructor(rendition: Rendition);
|
||||
|
||||
add(type: string, cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): Annotation;
|
||||
|
||||
add(
|
||||
type: string,
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
): Annotation;
|
||||
remove(cfiRange: string, type: string): void;
|
||||
|
||||
highlight(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
|
||||
|
||||
underline(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
|
||||
|
||||
highlight(
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
): void;
|
||||
underline(
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
): void;
|
||||
mark(cfiRange: string, data?: object, cb?: Function): void;
|
||||
each(): Array<Annotation>;
|
||||
|
||||
each(): Array<Annotation>
|
||||
|
||||
private _removeFromAnnotationBySectionIndex(sectionIndex: number, hash: string): void;
|
||||
|
||||
private _removeFromAnnotationBySectionIndex(
|
||||
sectionIndex: number,
|
||||
hash: string
|
||||
): void;
|
||||
private _annotationsAt(index: number): void;
|
||||
|
||||
private inject(view: View): void;
|
||||
|
||||
private clear(view: View): void;
|
||||
}
|
||||
|
||||
declare class Annotation {
|
||||
constructor(options: {
|
||||
type: string,
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
sectionIndex?: number,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
type: string;
|
||||
cfiRange: string;
|
||||
data?: object;
|
||||
sectionIndex?: number;
|
||||
cb?: Function;
|
||||
className?: string;
|
||||
styles?: object;
|
||||
});
|
||||
|
||||
update(data: object): void;
|
||||
|
||||
attach(view: View): any;
|
||||
|
||||
detach(view: View): any;
|
||||
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
}
|
||||
|
|
20
types/archive.d.ts
vendored
20
types/archive.d.ts
vendored
|
@ -1,27 +1,25 @@
|
|||
import JSZip = require('jszip');
|
||||
import JSZip = require("jszip");
|
||||
|
||||
export default class Archive {
|
||||
constructor();
|
||||
|
||||
open(input: BinaryType, isBase64?: boolean): Promise<JSZip>;
|
||||
|
||||
openUrl(zipUrl: string, isBase64?: boolean): Promise<JSZip>;
|
||||
|
||||
request(url: string, type?: string): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
|
||||
request(
|
||||
url: string,
|
||||
type?: string
|
||||
): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
getBlob(url: string, mimeType?: string): Promise<Blob>;
|
||||
|
||||
getText(url: string): Promise<string>;
|
||||
|
||||
getBase64(url: string, mimeType?: string): Promise<string>;
|
||||
|
||||
createUrl(url: string, options: { base64: boolean }): Promise<string>;
|
||||
|
||||
revokeUrl(url: string): void;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private checkRequirements(): void;
|
||||
|
||||
private handleResponse(response: any, type?: string): Blob | string | JSON | Document | XMLDocument;
|
||||
private handleResponse(
|
||||
response: any,
|
||||
type?: string
|
||||
): Blob | string | JSON | Document | XMLDocument;
|
||||
}
|
||||
|
|
90
types/book.d.ts
vendored
90
types/book.d.ts
vendored
|
@ -1,32 +1,34 @@
|
|||
import {
|
||||
import Archive from "./archive";
|
||||
import Container from "./container";
|
||||
import Locations from "./locations";
|
||||
import Navigation from "./navigation";
|
||||
import Packaging, {
|
||||
PackagingManifestObject,
|
||||
PackagingMetadataObject,
|
||||
PackagingSpineItem,
|
||||
PackagingObject
|
||||
} from "./packaging";
|
||||
import Rendition, { RenditionOptions } from "./rendition";
|
||||
import Section, { SpineItem } from "./section";
|
||||
import Archive from "./archive";
|
||||
import Navigation from "./navigation";
|
||||
import PageList, { PageListItem } from "./pagelist";
|
||||
import Spine from "./spine";
|
||||
import Locations from "./locations";
|
||||
import Url from "./utils/url";
|
||||
import Path from "./utils/path";
|
||||
import Rendition, { RenditionOptions } from "./rendition";
|
||||
import Resources from "./resources";
|
||||
import Container from "./container";
|
||||
import Packaging from "./packaging";
|
||||
import Section, { SpineItem } from "./section";
|
||||
import Spine from "./spine";
|
||||
import Store from "./store";
|
||||
import Path from "./utils/path";
|
||||
import Url from "./utils/url";
|
||||
|
||||
export interface BookOptions {
|
||||
requestMethod?: (url: string, type: string, withCredentials: object, headers: object) => Promise<object>;
|
||||
requestCredentials?: object,
|
||||
requestHeaders?: object,
|
||||
encoding?: string,
|
||||
replacements?: string,
|
||||
canonical?: (path: string) => string,
|
||||
openAs?: string,
|
||||
store?: string
|
||||
requestMethod?: (
|
||||
url: string,
|
||||
type: string,
|
||||
withCredentials: object,
|
||||
headers: object
|
||||
) => Promise<object>;
|
||||
requestCredentials?: object;
|
||||
requestHeaders?: object;
|
||||
encoding?: string;
|
||||
replacements?: string;
|
||||
canonical?: (path: string) => string;
|
||||
openAs?: string;
|
||||
store?: string;
|
||||
}
|
||||
|
||||
export default class Book {
|
||||
|
@ -38,14 +40,14 @@ export default class Book {
|
|||
opened: Promise<Book>;
|
||||
isOpen: boolean;
|
||||
loaded: {
|
||||
metadata: Promise<PackagingMetadataObject>,
|
||||
spine: Promise<SpineItem[]>,
|
||||
manifest: Promise<PackagingManifestObject>,
|
||||
cover: Promise<string>,
|
||||
navigation: Promise<Navigation>,
|
||||
pageList: Promise<PageListItem[]>,
|
||||
resources: Promise<string[]>,
|
||||
}
|
||||
metadata: Promise<PackagingMetadataObject>;
|
||||
spine: Promise<SpineItem[]>;
|
||||
manifest: Promise<PackagingManifestObject>;
|
||||
cover: Promise<string>;
|
||||
navigation: Promise<Navigation>;
|
||||
pageList: Promise<PageListItem[]>;
|
||||
resources: Promise<string[]>;
|
||||
};
|
||||
ready: Promise<void>;
|
||||
request: Function;
|
||||
spine: Spine;
|
||||
|
@ -57,66 +59,40 @@ export default class Book {
|
|||
archived: boolean;
|
||||
archive: Archive;
|
||||
resources: Resources;
|
||||
rendition: Rendition
|
||||
rendition: Rendition;
|
||||
container: Container;
|
||||
packaging: Packaging;
|
||||
storage: Store;
|
||||
|
||||
|
||||
canonical(path: string): string;
|
||||
|
||||
coverUrl(): Promise<string | null>;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
determineType(input: string): string;
|
||||
|
||||
getRange(cfiRange: string): Promise<Range>;
|
||||
|
||||
key(identifier?: string): string;
|
||||
|
||||
load(path: string): Promise<object>;
|
||||
|
||||
loadNavigation(opf: XMLDocument): Promise<Navigation>;
|
||||
|
||||
open(input: string, what?: string): Promise<object>;
|
||||
open(input: ArrayBuffer, what?: string): Promise<object>;
|
||||
|
||||
openContainer(url: string): Promise<string>;
|
||||
|
||||
openEpub(data: BinaryType, encoding?: string): Promise<Book>;
|
||||
|
||||
openManifest(url: string): Promise<Book>;
|
||||
|
||||
openPackaging(url: string): Promise<Book>;
|
||||
|
||||
renderTo(element: Element, options?: RenditionOptions): Rendition;
|
||||
renderTo(element: string, options?: RenditionOptions): Rendition;
|
||||
|
||||
private replacements(): Promise<void>;
|
||||
|
||||
resolve(path: string, absolute?: boolean): string;
|
||||
|
||||
section(target: string): Section;
|
||||
section(target: number): Section;
|
||||
|
||||
setRequestCredentials(credentials: object): void;
|
||||
|
||||
setRequestHeaders(headers: object): void;
|
||||
|
||||
unarchive(input: BinaryType, encoding?: string): Promise<Archive>;
|
||||
|
||||
store(name: string): Store;
|
||||
|
||||
unpack(opf: XMLDocument): Promise<Book>;
|
||||
|
||||
private replacements(): Promise<void>;
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
|
||||
}
|
||||
|
|
1
types/container.d.ts
vendored
1
types/container.d.ts
vendored
|
@ -2,6 +2,5 @@ export default class Container {
|
|||
constructor(containerDocument: Document);
|
||||
|
||||
parse(containerDocument: Document): void;
|
||||
|
||||
destroy(): void;
|
||||
}
|
||||
|
|
100
types/contents.d.ts
vendored
100
types/contents.d.ts
vendored
|
@ -1,16 +1,21 @@
|
|||
import EpubCFI from "./epubcfi";
|
||||
|
||||
export interface ViewportSettings {
|
||||
width: string,
|
||||
height: string,
|
||||
scale: string,
|
||||
scalable: string,
|
||||
minimum: string,
|
||||
maximum: string
|
||||
width: string;
|
||||
height: string;
|
||||
scale: string;
|
||||
scalable: string;
|
||||
minimum: string;
|
||||
maximum: string;
|
||||
}
|
||||
|
||||
export default class Contents {
|
||||
constructor(doc: Document, content: Element, cfiBase: string, sectionIndex: number);
|
||||
constructor(
|
||||
doc: Document,
|
||||
content: Element,
|
||||
cfiBase: string,
|
||||
sectionIndex: number
|
||||
);
|
||||
|
||||
epubcfi: EpubCFI;
|
||||
document: Document;
|
||||
|
@ -23,117 +28,80 @@ export default class Contents {
|
|||
static listenedEvents: string[];
|
||||
|
||||
addClass(className: string): void;
|
||||
|
||||
addScript(src: string): Promise<boolean>;
|
||||
|
||||
addStylesheet(src: string): Promise<boolean>;
|
||||
|
||||
addStylesheetRules(rules: Array<object> | object, key: string): Promise<boolean>;
|
||||
|
||||
addStylesheetRules(
|
||||
rules: Array<object> | object,
|
||||
key: string
|
||||
): Promise<boolean>;
|
||||
addStylesheetCss(serializedCss: string, key: string): Promise<boolean>;
|
||||
|
||||
cfiFromNode(node: Node, ignoreClass?: string): string;
|
||||
|
||||
cfiFromRange(range: Range, ignoreClass?: string): string;
|
||||
|
||||
columns(width: number, height: number, columnWidth: number, gap: number, dir: string): void;
|
||||
|
||||
columns(
|
||||
width: number,
|
||||
height: number,
|
||||
columnWidth: number,
|
||||
gap: number,
|
||||
dir: string
|
||||
): void;
|
||||
contentHeight(h: number): number;
|
||||
|
||||
contentWidth(w: number): number;
|
||||
|
||||
css(property: string, value: string, priority?: boolean): string;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
direction(dir: string): void;
|
||||
|
||||
fit(width: number, height: number): void;
|
||||
|
||||
height(h: number): number;
|
||||
|
||||
locationOf(target: string | EpubCFI, ignoreClass?: string): Promise<{ top: number, left: number }>;
|
||||
|
||||
locationOf(
|
||||
target: string | EpubCFI,
|
||||
ignoreClass?: string
|
||||
): Promise<{ top: number; left: number }>;
|
||||
map(layout: any): any;
|
||||
|
||||
mapPage(cfiBase: string, layout: object, start: number, end: number, dev: boolean): any;
|
||||
|
||||
mapPage(
|
||||
cfiBase: string,
|
||||
layout: object,
|
||||
start: number,
|
||||
end: number,
|
||||
dev: boolean
|
||||
): any;
|
||||
overflow(overflow: string): string;
|
||||
|
||||
overflowX(overflow: string): string;
|
||||
|
||||
overflowY(overflow: string): string;
|
||||
|
||||
range(cfi: string, ignoreClass?: string): Range;
|
||||
|
||||
removeClass(className: any): void;
|
||||
|
||||
root(): Element;
|
||||
|
||||
scaler(scale: number, offsetX: number, offsetY: number): void;
|
||||
|
||||
scrollHeight(): number;
|
||||
|
||||
scrollWidth(): number;
|
||||
|
||||
size(width: number, height: number): void;
|
||||
|
||||
textHeight(): number;
|
||||
|
||||
textWidth(): number;
|
||||
|
||||
viewport(options: ViewportSettings): ViewportSettings;
|
||||
|
||||
width(w: number): number;
|
||||
|
||||
writingMode(mode: string): string;
|
||||
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
|
||||
private addEventListeners(): void;
|
||||
|
||||
private addSelectionListeners(): void;
|
||||
|
||||
private epubReadingSystem(name: string, version: string): object;
|
||||
|
||||
private expand(): void;
|
||||
|
||||
private fontLoadListeners(): void;
|
||||
|
||||
private imageLoadListeners(): void;
|
||||
|
||||
private layoutStyle(style: string): string;
|
||||
|
||||
private linksHandler(): void;
|
||||
|
||||
private listeners(): void;
|
||||
|
||||
private mediaQueryListeners(): void;
|
||||
|
||||
private onSelectionChange(e: Event): void;
|
||||
|
||||
private removeEventListeners(): void;
|
||||
|
||||
private removeListeners(): void;
|
||||
|
||||
private removeSelectionListeners(): void;
|
||||
|
||||
private resizeCheck(): void;
|
||||
|
||||
private resizeListeners(): void;
|
||||
|
||||
private resizeObservers(): void;
|
||||
|
||||
private transitionListeners(): void;
|
||||
|
||||
private triggerEvent(e: Event): void;
|
||||
|
||||
private triggerSelectedEvent(selection: Selection): void;
|
||||
}
|
||||
|
|
116
types/core.d.ts
vendored
116
types/core.d.ts
vendored
|
@ -1,83 +1,87 @@
|
|||
export module Core {
|
||||
|
||||
export function uuid(): string;
|
||||
|
||||
export function documentHeight(): number;
|
||||
|
||||
export function isElement(obj: object): boolean;
|
||||
|
||||
export function isNumber(n: any): boolean;
|
||||
|
||||
export function isFloat(n: any): boolean;
|
||||
|
||||
export function prefixed(unprefixed: string): string;
|
||||
|
||||
export function defaults(obj: object): object;
|
||||
|
||||
export function extend(target: object): object;
|
||||
|
||||
export function insert(item: any, array: Array<any>, compareFunction: Function): number;
|
||||
|
||||
export function locationOf(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
|
||||
|
||||
export function indexOfSorted(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
|
||||
|
||||
export function bounds(el: Element): { width: Number, height: Number};
|
||||
|
||||
export function borders(el: Element): { width: Number, height: Number};
|
||||
|
||||
export function insert(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function
|
||||
): number;
|
||||
export function locationOf(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function,
|
||||
_start: Function,
|
||||
_end: Function
|
||||
): number;
|
||||
export function indexOfSorted(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function,
|
||||
_start: Function,
|
||||
_end: Function
|
||||
): number;
|
||||
export function bounds(el: Element): { width: Number; height: Number };
|
||||
export function borders(el: Element): { width: Number; height: Number };
|
||||
export function nodeBounds(node: Node): object;
|
||||
|
||||
export function windowBounds(): { width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number };
|
||||
|
||||
export function windowBounds(): {
|
||||
width: Number;
|
||||
height: Number;
|
||||
top: Number;
|
||||
left: Number;
|
||||
right: Number;
|
||||
bottom: Number;
|
||||
};
|
||||
export function indexOfNode(node: Node, typeId: string): number;
|
||||
|
||||
export function indexOfTextNode(textNode: Node): number;
|
||||
|
||||
export function indexOfElementNode(elementNode: Element): number;
|
||||
|
||||
export function isXml(ext: string): boolean;
|
||||
|
||||
export function createBlob(content: any, mime: string): Blob;
|
||||
|
||||
export function createBlobUrl(content: any, mime: string): string;
|
||||
|
||||
export function revokeBlobUrl(url: string): void;
|
||||
|
||||
export function createBase64Url(content: any, mime: string): string
|
||||
|
||||
export function createBase64Url(content: any, mime: string): string;
|
||||
export function type(obj: object): string;
|
||||
|
||||
export function parse(markup: string, mime: string, forceXMLDom: boolean): Document;
|
||||
|
||||
export function parse(
|
||||
markup: string,
|
||||
mime: string,
|
||||
forceXMLDom: boolean
|
||||
): Document;
|
||||
export function qs(el: Element, sel: string): Element;
|
||||
|
||||
export function qsa(el: Element, sel: string): ArrayLike<Element>;
|
||||
|
||||
export function qsp(el: Element, sel: string, props: Array<object>): ArrayLike<Element>;
|
||||
|
||||
export function qsp(
|
||||
el: Element,
|
||||
sel: string,
|
||||
props: Array<object>
|
||||
): ArrayLike<Element>;
|
||||
export function sprint(root: Node, func: Function): void;
|
||||
|
||||
export function treeWalker(root: Node, func: Function, filter: object | Function): void;
|
||||
|
||||
export function treeWalker(
|
||||
root: Node,
|
||||
func: Function,
|
||||
filter: object | Function
|
||||
): void;
|
||||
export function walk(node: Node, callback: Function): void;
|
||||
|
||||
export function blob2base64(blob: Blob): string;
|
||||
|
||||
export function defer(): Promise<any>;
|
||||
|
||||
export function querySelectorByType(html: Element, element: string, type: string): Array<Element>;
|
||||
|
||||
export function querySelectorByType(
|
||||
html: Element,
|
||||
element: string,
|
||||
type: string
|
||||
): Array<Element>;
|
||||
export function findChildren(el: Element): Array<Element>;
|
||||
|
||||
export function parents(node: Element): Array<Element>;
|
||||
|
||||
export function filterChildren(el: Element, nodeName: string, single: boolean): Array<Element>;
|
||||
|
||||
export function getParentByTagName(node: Element, tagname: string): Array<Element>;
|
||||
|
||||
export class RangeObject extends Range {
|
||||
|
||||
}
|
||||
|
||||
export function filterChildren(
|
||||
el: Element,
|
||||
nodeName: string,
|
||||
single: boolean
|
||||
): Array<Element>;
|
||||
export function getParentByTagName(
|
||||
node: Element,
|
||||
tagname: string
|
||||
): Array<Element>;
|
||||
export class RangeObject extends Range {}
|
||||
}
|
||||
|
|
5
types/epub.d.ts
vendored
5
types/epub.d.ts
vendored
|
@ -2,5 +2,8 @@ import Book, { BookOptions } from "./book";
|
|||
|
||||
export default Epub;
|
||||
|
||||
declare function Epub(urlOrData: string | ArrayBuffer, options?: BookOptions) : Book;
|
||||
declare function Epub(
|
||||
urlOrData: string | ArrayBuffer,
|
||||
options?: BookOptions
|
||||
): Book;
|
||||
declare function Epub(options?: BookOptions): Book;
|
||||
|
|
105
types/epubcfi.d.ts
vendored
105
types/epubcfi.d.ts
vendored
|
@ -1,97 +1,98 @@
|
|||
interface EpubCFISegment {
|
||||
steps: Array<object>,
|
||||
steps: Array<object>;
|
||||
terminal: {
|
||||
offset: number,
|
||||
assertion: string
|
||||
}
|
||||
offset: number;
|
||||
assertion: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface EpubCFIStep {
|
||||
id: string,
|
||||
tagName: string,
|
||||
type: number,
|
||||
index: number
|
||||
id: string;
|
||||
tagName: string;
|
||||
type: number;
|
||||
index: number;
|
||||
}
|
||||
|
||||
interface EpubCFIComponent {
|
||||
steps: Array<EpubCFIStep>,
|
||||
steps: Array<EpubCFIStep>;
|
||||
terminal: {
|
||||
offset: number,
|
||||
assertion: string
|
||||
}
|
||||
offset: number;
|
||||
assertion: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default class EpubCFI {
|
||||
constructor(cfiFrom?: string | Range | Node, base?: string | object, ignoreClass?: string);
|
||||
constructor(
|
||||
cfiFrom?: string | Range | Node,
|
||||
base?: string | object,
|
||||
ignoreClass?: string
|
||||
);
|
||||
|
||||
base: EpubCFIComponent;
|
||||
spinePos: number;
|
||||
range: boolean;
|
||||
|
||||
isCfiString(str: string): boolean;
|
||||
|
||||
fromNode(anchor: Node, base: string | object, ignoreClass?: string): EpubCFI;
|
||||
|
||||
fromRange(range: Range, base: string | object, ignoreClass?: string): EpubCFI;
|
||||
|
||||
parse(cfiStr: string): EpubCFI;
|
||||
|
||||
collapse(toStart?: boolean): void;
|
||||
|
||||
compare(cfiOne: string | EpubCFI, cfiTwo: string | EpubCFI): number;
|
||||
|
||||
equalStep(stepA: object, stepB: object): boolean;
|
||||
|
||||
filter(anchor: Element, ignoreClass?: string): Element | false;
|
||||
|
||||
toRange(_doc?: Document, ignoreClass?: string): Range;
|
||||
|
||||
toString(): string;
|
||||
|
||||
private filteredStep(node: Node, ignoreClass?: string): any;
|
||||
|
||||
private findNode(steps: Array<EpubCFIStep>, _doc?: Document, ignoreClass?: string): Node;
|
||||
|
||||
private fixMiss(steps: Array<EpubCFIStep>, offset: number, _doc?: Document, ignoreClass?: string): any;
|
||||
|
||||
private findNode(
|
||||
steps: Array<EpubCFIStep>,
|
||||
_doc?: Document,
|
||||
ignoreClass?: string
|
||||
): Node;
|
||||
private fixMiss(
|
||||
steps: Array<EpubCFIStep>,
|
||||
offset: number,
|
||||
_doc?: Document,
|
||||
ignoreClass?: string
|
||||
): any;
|
||||
private checkType(cfi: string | Range | Node): string | false;
|
||||
|
||||
private generateChapterComponent(_spineNodeIndex: number, _pos: number, id: string): string;
|
||||
|
||||
private generateChapterComponent(
|
||||
_spineNodeIndex: number,
|
||||
_pos: number,
|
||||
id: string
|
||||
): string;
|
||||
private getChapterComponent(cfiStr: string): string;
|
||||
|
||||
private getCharecterOffsetComponent(cfiStr: string): string;
|
||||
|
||||
private getPathComponent(cfiStr: string): string;
|
||||
|
||||
private getRange(cfiStr: string): string;
|
||||
|
||||
private joinSteps(steps: Array<EpubCFIStep>): Array<EpubCFIStep>;
|
||||
|
||||
private normalizedMap(children: Array<Node>, nodeType: number, ignoreClass?: string): object;
|
||||
|
||||
private normalizedMap(
|
||||
children: Array<Node>,
|
||||
nodeType: number,
|
||||
ignoreClass?: string
|
||||
): object;
|
||||
private parseComponent(componentStr: string): object;
|
||||
|
||||
private parseStep(stepStr: string): object;
|
||||
|
||||
private parseTerminal(termialStr: string): object;
|
||||
|
||||
private patchOffset(anchor: Node, offset: number, ignoreClass?: string): number;
|
||||
|
||||
private pathTo(node: Node, offset: number, ignoreClass?: string): EpubCFISegment;
|
||||
|
||||
private patchOffset(
|
||||
anchor: Node,
|
||||
offset: number,
|
||||
ignoreClass?: string
|
||||
): number;
|
||||
private pathTo(
|
||||
node: Node,
|
||||
offset: number,
|
||||
ignoreClass?: string
|
||||
): EpubCFISegment;
|
||||
private position(anchor: Node): number;
|
||||
|
||||
private segmentString(segment: EpubCFISegment): string;
|
||||
|
||||
private step(node: Node): EpubCFIStep;
|
||||
|
||||
private stepsToQuerySelector(steps: Array<EpubCFIStep>): string;
|
||||
|
||||
private stepsToXpath(steps: Array<EpubCFIStep>): string;
|
||||
|
||||
private textNodes(container: Node, ignoreClass?: string): Array<Node>;
|
||||
|
||||
private walkToNode(steps: Array<EpubCFIStep>, _doc?: Document, ignoreClass?: string): Node;
|
||||
|
||||
private walkToNode(
|
||||
steps: Array<EpubCFIStep>,
|
||||
_doc?: Document,
|
||||
ignoreClass?: string
|
||||
): Node;
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import ePub, { Book } from '../';
|
||||
|
||||
function testEpub() {
|
||||
const epub = ePub("https://s3.amazonaws.com/moby-dick/moby-dick.epub");
|
||||
|
||||
const book = new Book("https://s3.amazonaws.com/moby-dick/moby-dick.epub", {});
|
||||
}
|
||||
|
||||
testEpub();
|
16
types/index.d.ts
vendored
16
types/index.d.ts
vendored
|
@ -8,13 +8,9 @@ export as namespace ePub;
|
|||
|
||||
export default Epub;
|
||||
|
||||
export { default as Book } from './book';
|
||||
export { default as EpubCFI } from './epubcfi';
|
||||
export { default as Rendition, Location } from './rendition';
|
||||
export { default as Contents } from './contents';
|
||||
export { default as Layout } from './layout';
|
||||
export { NavItem } from './navigation';
|
||||
|
||||
declare namespace ePub {
|
||||
|
||||
}
|
||||
export { default as Book } from "./book";
|
||||
export { default as Contents } from "./contents";
|
||||
export { default as EpubCFI } from "./epubcfi";
|
||||
export { default as Layout } from "./layout";
|
||||
export { NavItem } from "./navigation";
|
||||
export { Location, default as Rendition } from "./rendition";
|
||||
|
|
41
types/layout.d.ts
vendored
41
types/layout.d.ts
vendored
|
@ -1,10 +1,10 @@
|
|||
import Contents from "./contents";
|
||||
|
||||
interface LayoutSettings {
|
||||
layout: string,
|
||||
spread: string,
|
||||
minSpreadWidth: number,
|
||||
evenSpreads: boolean
|
||||
layout: string;
|
||||
spread: string;
|
||||
minSpreadWidth: number;
|
||||
evenSpreads: boolean;
|
||||
}
|
||||
|
||||
export default class Layout {
|
||||
|
@ -13,35 +13,30 @@ export default class Layout {
|
|||
settings: LayoutSettings;
|
||||
name: string;
|
||||
props: {
|
||||
name: string,
|
||||
spread: string,
|
||||
flow: string,
|
||||
width: number,
|
||||
height: number,
|
||||
spreadWidth: number,
|
||||
delta: number,
|
||||
columnWidth: number,
|
||||
gap: number,
|
||||
divisor: number
|
||||
name: string;
|
||||
spread: string;
|
||||
flow: string;
|
||||
width: number;
|
||||
height: number;
|
||||
spreadWidth: number;
|
||||
delta: number;
|
||||
columnWidth: number;
|
||||
gap: number;
|
||||
divisor: number;
|
||||
};
|
||||
|
||||
flow(flow: string): string;
|
||||
|
||||
spread(spread: string, min: number): boolean;
|
||||
|
||||
calculate(_width: number, _height: number, _gap?: number): void;
|
||||
|
||||
format(contents: Contents): void | Promise<void>;
|
||||
|
||||
count(totalLength: number, pageLength: number): {spreads: Number, pages: Number};
|
||||
|
||||
count(
|
||||
totalLength: number,
|
||||
pageLength: number
|
||||
): { spreads: Number; pages: Number };
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
|
||||
private update(props: object): void;
|
||||
|
|
24
types/locations.d.ts
vendored
24
types/locations.d.ts
vendored
|
@ -1,41 +1,29 @@
|
|||
import Spine from "./spine";
|
||||
import Section from "./section";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Section from "./section";
|
||||
import Spine from "./spine";
|
||||
|
||||
export default class Locations {
|
||||
constructor(spine: Spine, request?: Function, pause?: number);
|
||||
|
||||
generate(chars: number): Promise<Array<string>>;
|
||||
|
||||
process(section: Section): Promise<Array<string>>;
|
||||
|
||||
locationFromCfi(cfi: string | EpubCFI): Location;
|
||||
|
||||
percentageFromCfi(cfi: string | EpubCFI): number;
|
||||
|
||||
percentageFromLocation(loc: number): number;
|
||||
|
||||
cfiFromLocation(loc: number): string;
|
||||
|
||||
cfiFromPercentage(percentage: number): string;
|
||||
|
||||
load(locations: string): Array<string>;
|
||||
|
||||
save(): string;
|
||||
|
||||
currentLocation(): Location;
|
||||
currentLocation(curr: string | number): void;
|
||||
|
||||
length(): number;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private createRange(): {
|
||||
startContainer: Element,
|
||||
startOffset: number,
|
||||
endContainer: Element,
|
||||
endOffset: number
|
||||
startContainer: Element;
|
||||
startOffset: number;
|
||||
endContainer: Element;
|
||||
endOffset: number;
|
||||
};
|
||||
|
||||
private parse(contents: Node, cfiBase: string, chars: number): Array<string>;
|
||||
}
|
||||
|
|
99
types/managers/manager.d.ts
vendored
99
types/managers/manager.d.ts
vendored
|
@ -1,90 +1,59 @@
|
|||
import Section from "../section";
|
||||
import Layout from "../layout";
|
||||
import Contents from "../contents";
|
||||
import View, { ViewSettings } from "./view";
|
||||
import Layout from "../layout";
|
||||
import { EpubCFIPair } from "../mapping";
|
||||
import Section from "../section";
|
||||
import View, { ViewSettings } from "./view";
|
||||
|
||||
export interface ViewLocation {
|
||||
index: number,
|
||||
href: string,
|
||||
pages: number[],
|
||||
totalPages: number,
|
||||
mapping: EpubCFIPair
|
||||
index: number;
|
||||
href: string;
|
||||
pages: number[];
|
||||
totalPages: number;
|
||||
mapping: EpubCFIPair;
|
||||
}
|
||||
|
||||
export interface ManagerOptions extends ViewSettings {
|
||||
infinite?: boolean,
|
||||
overflow?: string,
|
||||
[key: string]: any
|
||||
infinite?: boolean;
|
||||
overflow?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export default class Manager {
|
||||
constructor(options: object);
|
||||
|
||||
render(element: Element, size?: { width: Number, height: Number }): void;
|
||||
|
||||
resize(width: Number, height: Number): void;
|
||||
|
||||
onOrientationChange(e: Event): void;
|
||||
|
||||
private createView(section: Section): View;
|
||||
|
||||
display(section: Section, target: string | number): Promise<void>;
|
||||
|
||||
private afterDisplayed(view: View): void;
|
||||
|
||||
private afterResized(view: View): void;
|
||||
|
||||
private moveTo(offset: {top: Number, left: Number}): void;
|
||||
|
||||
private append(section: Section): Promise<void>;
|
||||
|
||||
private prepend(section: Section): Promise<void>;
|
||||
|
||||
next(): Promise<void>;
|
||||
|
||||
prev(): Promise<void>;
|
||||
|
||||
current(): View;
|
||||
|
||||
applyLayout(layout: Layout): void;
|
||||
bounds(): object;
|
||||
clear(): void;
|
||||
|
||||
current(): View;
|
||||
currentLocation(): ViewLocation[];
|
||||
|
||||
destroy(): void;
|
||||
direction(dir: string): void;
|
||||
display(section: Section, target: string | number): Promise<void>;
|
||||
getContents(): Contents[];
|
||||
isRendered(): boolean;
|
||||
next(): Promise<void>;
|
||||
onOrientationChange(e: Event): void;
|
||||
prev(): Promise<void>;
|
||||
render(element: Element, size?: { width: Number; height: Number }): void;
|
||||
resize(width: Number, height: Number): void;
|
||||
setLayout(layout: Layout): void;
|
||||
updateAxis(axis: string, forceUpdate: boolean): void;
|
||||
updateFlow(flow: string): void;
|
||||
updateLayout(): void;
|
||||
visible(): View[];
|
||||
|
||||
private createView(section: Section): View;
|
||||
private afterDisplayed(view: View): void;
|
||||
private afterResized(view: View): void;
|
||||
private moveTo(offset: { top: Number; left: Number }): void;
|
||||
private append(section: Section): Promise<void>;
|
||||
private prepend(section: Section): Promise<void>;
|
||||
private scrollBy(x: number, y: number, silent: boolean): void;
|
||||
|
||||
private scrollTo(x: number, y: number, silent: boolean): void;
|
||||
|
||||
private onScroll(): void;
|
||||
|
||||
bounds(): object;
|
||||
|
||||
applyLayout(layout: Layout): void;
|
||||
|
||||
updateLayout(): void;
|
||||
|
||||
setLayout(layout: Layout): void;
|
||||
|
||||
updateAxis(axis: string, forceUpdate: boolean): void;
|
||||
|
||||
updateFlow(flow: string): void;
|
||||
|
||||
getContents(): Contents[];
|
||||
|
||||
direction(dir: string): void;
|
||||
|
||||
isRendered(): boolean;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
}
|
||||
|
|
67
types/managers/view.d.ts
vendored
67
types/managers/view.d.ts
vendored
|
@ -1,80 +1,65 @@
|
|||
import Section from "../section";
|
||||
import Contents from "../contents";
|
||||
import Layout from "../layout";
|
||||
import Section from "../section";
|
||||
|
||||
export interface ViewSettings {
|
||||
ignoreClass?: string,
|
||||
axis?: string,
|
||||
flow?: string,
|
||||
layout?: Layout,
|
||||
method?: string,
|
||||
width?: number,
|
||||
height?: number,
|
||||
forceEvenPages?: boolean,
|
||||
allowScriptedContent?: boolean
|
||||
ignoreClass?: string;
|
||||
axis?: string;
|
||||
flow?: string;
|
||||
layout?: Layout;
|
||||
method?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
forceEvenPages?: boolean;
|
||||
allowScriptedContent?: boolean;
|
||||
}
|
||||
|
||||
export default class View {
|
||||
constructor(section: Section, options: ViewSettings);
|
||||
|
||||
create(): any;
|
||||
|
||||
render(request?: Function, show?: boolean): Promise<void>;
|
||||
|
||||
reset(): void;
|
||||
|
||||
size(_width: Number, _height: Number): void;
|
||||
|
||||
load(content: Contents): Promise<any>;
|
||||
|
||||
setLayout(layout: Layout): void;
|
||||
|
||||
setAxis(axis: string): void;
|
||||
|
||||
display(request?: Function): Promise<any>;
|
||||
|
||||
show(): void;
|
||||
|
||||
hide(): void;
|
||||
|
||||
offset(): { top: Number, left: Number };
|
||||
|
||||
offset(): { top: Number; left: Number };
|
||||
width(): Number;
|
||||
|
||||
height(): Number;
|
||||
|
||||
position(): object;
|
||||
|
||||
locationOf(target: string): { top: Number, left: Number };
|
||||
|
||||
locationOf(target: string): { top: Number; left: Number };
|
||||
onDisplayed(view: View): void;
|
||||
|
||||
onResize(view: View): void;
|
||||
|
||||
bounds(force?: boolean): object;
|
||||
highlight(
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
): void;
|
||||
|
||||
highlight(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
|
||||
|
||||
underline(cfiRange: string, data?: object, cb?: Function, className?: string, styles?: object): void;
|
||||
underline(
|
||||
cfiRange: string,
|
||||
data?: object,
|
||||
cb?: Function,
|
||||
className?: string,
|
||||
styles?: object
|
||||
): void;
|
||||
|
||||
mark(cfiRange: string, data?: object, cb?: Function): void;
|
||||
|
||||
unhighlight(cfiRange: string): void;
|
||||
|
||||
ununderline(cfiRange: string): void;
|
||||
|
||||
unmark(cfiRange: string): void;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private onLoad(event: Event, promise: Promise<any>): void;
|
||||
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
}
|
||||
|
|
29
types/mapping.d.ts
vendored
29
types/mapping.d.ts
vendored
|
@ -1,34 +1,35 @@
|
|||
import Layout from "./layout";
|
||||
import Contents from "./contents";
|
||||
import Layout from "./layout";
|
||||
|
||||
export interface EpubCFIPair {
|
||||
start: string,
|
||||
end: string
|
||||
start: string;
|
||||
end: string;
|
||||
}
|
||||
|
||||
export interface RangePair {
|
||||
start: Range,
|
||||
end: Range
|
||||
start: Range;
|
||||
end: Range;
|
||||
}
|
||||
|
||||
export default class Mapping {
|
||||
constructor(layout: Layout, direction?: string, axis?: string, dev?: boolean);
|
||||
|
||||
page(contents: Contents, cfiBase: string, start: number, end: number): EpubCFIPair;
|
||||
|
||||
page(
|
||||
contents: Contents,
|
||||
cfiBase: string,
|
||||
start: number,
|
||||
end: number
|
||||
): EpubCFIPair;
|
||||
axis(axis: string): boolean;
|
||||
|
||||
private walk(root: Node, func: Function);
|
||||
|
||||
private findStart(root: Node, start: number, end: number): Range;
|
||||
|
||||
private findEnd(root: Node, start: number, end: number): Range;
|
||||
|
||||
private findTextStartRange(node: Node, start: number, end: number): Range;
|
||||
|
||||
private findTextEndRange(node: Node, start: number, end: number): Range;
|
||||
|
||||
private splitTextNodeIntoRanges(node: Node, _splitter?: string): Array<Range>;
|
||||
|
||||
private rangePairToCfiPair(cfiBase: string, rangePair: RangePair): EpubCFIPair;
|
||||
private rangePairToCfiPair(
|
||||
cfiBase: string,
|
||||
rangePair: RangePair
|
||||
): EpubCFIPair;
|
||||
}
|
||||
|
|
33
types/navigation.d.ts
vendored
33
types/navigation.d.ts
vendored
|
@ -1,15 +1,15 @@
|
|||
export interface NavItem {
|
||||
id: string,
|
||||
href: string,
|
||||
label: string,
|
||||
subitems?: Array<NavItem>,
|
||||
parent?: string
|
||||
id: string;
|
||||
href: string;
|
||||
label: string;
|
||||
subitems?: Array<NavItem>;
|
||||
parent?: string;
|
||||
}
|
||||
|
||||
export interface LandmarkItem {
|
||||
href?: string,
|
||||
label?: string,
|
||||
type?: string
|
||||
href?: string;
|
||||
label?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export default class Navigation {
|
||||
|
@ -19,28 +19,21 @@ export default class Navigation {
|
|||
landmarks: Array<LandmarkItem>;
|
||||
|
||||
parse(xml: XMLDocument): void;
|
||||
|
||||
get(target: string): NavItem;
|
||||
|
||||
landmark(type: string): LandmarkItem;
|
||||
|
||||
load(json: string): Array<NavItem>;
|
||||
|
||||
forEach(fn: (item: NavItem) => {}): any;
|
||||
|
||||
private unpack(toc: Array<NavItem>): void;
|
||||
|
||||
private parseNav(navHtml: XMLDocument): Array<NavItem>;
|
||||
|
||||
private navItem(item: Element): NavItem;
|
||||
|
||||
private parseLandmarks(navHtml: XMLDocument): Array<LandmarkItem>;
|
||||
|
||||
private landmarkItem(item: Element): LandmarkItem;
|
||||
|
||||
private parseNcx(navHtml: XMLDocument): Array<NavItem>;
|
||||
|
||||
private ncxItem(item: Element): NavItem;
|
||||
|
||||
private getByIndex(target: string, index: number, navItems: NavItem[]): NavItem;
|
||||
private getByIndex(
|
||||
target: string,
|
||||
index: number,
|
||||
navItems: NavItem[]
|
||||
): NavItem;
|
||||
}
|
||||
|
|
76
types/packaging.d.ts
vendored
76
types/packaging.d.ts
vendored
|
@ -1,47 +1,47 @@
|
|||
import { SpineItem } from "./section";
|
||||
|
||||
export interface PackagingObject {
|
||||
metadata: PackagingMetadataObject,
|
||||
spine: Array<SpineItem>,
|
||||
manifest: PackagingManifestObject,
|
||||
navPath: string,
|
||||
ncxPath: string,
|
||||
coverPath: string,
|
||||
spineNodeIndex: number
|
||||
metadata: PackagingMetadataObject;
|
||||
spine: Array<SpineItem>;
|
||||
manifest: PackagingManifestObject;
|
||||
navPath: string;
|
||||
ncxPath: string;
|
||||
coverPath: string;
|
||||
spineNodeIndex: number;
|
||||
}
|
||||
|
||||
export interface PackagingMetadataObject {
|
||||
title: string,
|
||||
creator: string,
|
||||
description: string,
|
||||
pubdate: string,
|
||||
publisher: string,
|
||||
identifier: string,
|
||||
language: string,
|
||||
rights: string,
|
||||
modified_date: string,
|
||||
layout: string,
|
||||
orientation: string,
|
||||
flow: string,
|
||||
viewport: string,
|
||||
spread: string,
|
||||
direction: string,
|
||||
title: string;
|
||||
creator: string;
|
||||
description: string;
|
||||
pubdate: string;
|
||||
publisher: string;
|
||||
identifier: string;
|
||||
language: string;
|
||||
rights: string;
|
||||
modified_date: string;
|
||||
layout: string;
|
||||
orientation: string;
|
||||
flow: string;
|
||||
viewport: string;
|
||||
spread: string;
|
||||
direction: string;
|
||||
}
|
||||
|
||||
export interface PackagingSpineItem {
|
||||
idref: string,
|
||||
properties: Array<string>,
|
||||
index: number
|
||||
idref: string;
|
||||
properties: Array<string>;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export interface PackagingManifestItem {
|
||||
href: string,
|
||||
type: string,
|
||||
properties: Array<string>
|
||||
href: string;
|
||||
type: string;
|
||||
properties: Array<string>;
|
||||
}
|
||||
|
||||
export interface PackagingManifestObject {
|
||||
[key: string]: PackagingManifestItem
|
||||
[key: string]: PackagingManifestItem;
|
||||
}
|
||||
|
||||
export default class Packaging {
|
||||
|
@ -56,24 +56,18 @@ export default class Packaging {
|
|||
metadata: PackagingMetadataObject;
|
||||
|
||||
parse(packageDocument: XMLDocument): PackagingObject;
|
||||
|
||||
load(json: string): PackagingObject;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private parseMetadata(xml: Node): PackagingMetadataObject;
|
||||
|
||||
private parseManifest(xml: Node): PackagingManifestObject;
|
||||
|
||||
private parseSpine(xml: Node, manifest: PackagingManifestObject): Array<PackagingSpineItem>;
|
||||
|
||||
private parseSpine(
|
||||
xml: Node,
|
||||
manifest: PackagingManifestObject
|
||||
): Array<PackagingSpineItem>;
|
||||
private findNavPath(manifestNode: Node): string | false;
|
||||
|
||||
private findNcxPath(manifestNode: Node, spineNode: Node): string | false;
|
||||
|
||||
private findCoverPath(packageXml: Node): string;
|
||||
|
||||
private getElementText(xml: Node, tag: string): string
|
||||
|
||||
private getPropertyText(xml: Node, property: string): string
|
||||
private getElementText(xml: Node, tag: string): string;
|
||||
private getPropertyText(xml: Node, property: string): string;
|
||||
}
|
||||
|
|
16
types/pagelist.d.ts
vendored
16
types/pagelist.d.ts
vendored
|
@ -1,29 +1,21 @@
|
|||
export interface PageListItem {
|
||||
href: string,
|
||||
page: string,
|
||||
cfi?: string,
|
||||
packageUrl?: string
|
||||
href: string;
|
||||
page: string;
|
||||
cfi?: string;
|
||||
packageUrl?: string;
|
||||
}
|
||||
|
||||
export default class Pagelist {
|
||||
constructor(xml: XMLDocument);
|
||||
|
||||
parse(xml: XMLDocument): Array<PageListItem>;
|
||||
|
||||
pageFromCfi(cfi: string): number;
|
||||
|
||||
cfiFromPage(pg: string | number): string;
|
||||
|
||||
pageFromPercentage(percent: number): number;
|
||||
|
||||
percentageFromPage(pg: number): number;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private parseNav(navHtml: Node): Array<PageListItem>;
|
||||
|
||||
private item(item: Node): PageListItem;
|
||||
|
||||
private process(pageList: Array<PageListItem>): void;
|
||||
|
||||
}
|
||||
|
|
134
types/rendition.d.ts
vendored
134
types/rendition.d.ts
vendored
|
@ -1,67 +1,66 @@
|
|||
import Annotations from "./annotations";
|
||||
import Book from "./book";
|
||||
import Contents from "./contents";
|
||||
import Section from "./section";
|
||||
import View from "./managers/view";
|
||||
import Hook from "./utils/hook";
|
||||
import Themes from "./themes";
|
||||
import EpubCFI from "./epubcfi";
|
||||
import Annotations from "./annotations";
|
||||
import View from "./managers/view";
|
||||
import Section from "./section";
|
||||
import Themes from "./themes";
|
||||
import Hook from "./utils/hook";
|
||||
import Queue from "./utils/queue";
|
||||
|
||||
export interface RenditionOptions {
|
||||
width?: number | string,
|
||||
height?: number | string,
|
||||
ignoreClass?: string,
|
||||
manager?: string | Function | object,
|
||||
view?: string | Function | object,
|
||||
flow?: string,
|
||||
layout?: string,
|
||||
spread?: string,
|
||||
minSpreadWidth?: number,
|
||||
stylesheet?: string,
|
||||
resizeOnOrientationChange?: boolean,
|
||||
script?: string,
|
||||
infinite?: boolean,
|
||||
overflow?: string,
|
||||
snap?: boolean | object,
|
||||
defaultDirection?: string,
|
||||
allowScriptedContent?: boolean,
|
||||
allowPopups?: boolean
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
ignoreClass?: string;
|
||||
manager?: string | Function | object;
|
||||
view?: string | Function | object;
|
||||
flow?: string;
|
||||
layout?: string;
|
||||
spread?: string;
|
||||
minSpreadWidth?: number;
|
||||
stylesheet?: string;
|
||||
resizeOnOrientationChange?: boolean;
|
||||
script?: string;
|
||||
infinite?: boolean;
|
||||
overflow?: string;
|
||||
snap?: boolean | object;
|
||||
defaultDirection?: string;
|
||||
allowScriptedContent?: boolean;
|
||||
allowPopups?: boolean;
|
||||
}
|
||||
|
||||
export interface DisplayedLocation {
|
||||
index: number,
|
||||
href: string,
|
||||
cfi: string,
|
||||
location: number,
|
||||
percentage: number,
|
||||
index: number;
|
||||
href: string;
|
||||
cfi: string;
|
||||
location: number;
|
||||
percentage: number;
|
||||
displayed: {
|
||||
page: number,
|
||||
total: number
|
||||
}
|
||||
page: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Location {
|
||||
start: DisplayedLocation,
|
||||
end: DisplayedLocation,
|
||||
atStart: boolean,
|
||||
atEnd: boolean
|
||||
start: DisplayedLocation;
|
||||
end: DisplayedLocation;
|
||||
atStart: boolean;
|
||||
atEnd: boolean;
|
||||
}
|
||||
|
||||
export default class Rendition {
|
||||
constructor(book: Book, options: RenditionOptions);
|
||||
|
||||
settings: RenditionOptions;
|
||||
book: Book;
|
||||
hooks: {
|
||||
display: Hook,
|
||||
serialize: Hook,
|
||||
content: Hook,
|
||||
unloaded: Hook,
|
||||
layout: Hook,
|
||||
render: Hook,
|
||||
show: Hook
|
||||
}
|
||||
display: Hook;
|
||||
serialize: Hook;
|
||||
content: Hook;
|
||||
unloaded: Hook;
|
||||
layout: Hook;
|
||||
render: Hook;
|
||||
show: Hook;
|
||||
};
|
||||
themes: Themes;
|
||||
annotations: Annotations;
|
||||
epubcfi: EpubCFI;
|
||||
|
@ -70,86 +69,51 @@ export default class Rendition {
|
|||
started: Promise<void>;
|
||||
|
||||
adjustImages(contents: Contents): Promise<void>;
|
||||
|
||||
attachTo(element: Element): Promise<void>;
|
||||
|
||||
clear(): void;
|
||||
|
||||
currentLocation(): DisplayedLocation;
|
||||
currentLocation(): Promise<DisplayedLocation>;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
determineLayoutProperties(metadata: object): object;
|
||||
|
||||
direction(dir: string): void;
|
||||
|
||||
display(target?: string): Promise<void>;
|
||||
display(target?: number): Promise<void>;
|
||||
|
||||
flow(flow: string): void;
|
||||
|
||||
getContents(): Contents;
|
||||
|
||||
getRange(cfi: string, ignoreClass?: string): Range;
|
||||
|
||||
handleLinks(contents: Contents): void;
|
||||
|
||||
injectIdentifier(doc: Document, section: Section): void;
|
||||
|
||||
injectScript(doc: Document, section: Section): void;
|
||||
|
||||
injectStylesheet(doc: Document, section: Section): void;
|
||||
|
||||
layout(settings: any): any;
|
||||
|
||||
located(location: Location): DisplayedLocation;
|
||||
|
||||
moveTo(offset: number): void;
|
||||
|
||||
next(): Promise<void>;
|
||||
|
||||
onOrientationChange(orientation: string): void;
|
||||
|
||||
passEvents(contents: Contents): void;
|
||||
|
||||
prev(): Promise<void>;
|
||||
|
||||
reportLocation(): Promise<void>;
|
||||
|
||||
requireManager(manager: string | Function | object): any;
|
||||
|
||||
requireView(view: string | Function | object): any;
|
||||
|
||||
resize(width: number, height: number): void;
|
||||
|
||||
setManager(manager: Function): void;
|
||||
|
||||
spread(spread: string, min?: number): void;
|
||||
|
||||
start(): void;
|
||||
|
||||
views(): Array<View>;
|
||||
|
||||
// Event emitters
|
||||
emit(type: any, ...args: any[]): void;
|
||||
|
||||
off(type: any, listener: any): any;
|
||||
|
||||
on(type: any, listener: any): any;
|
||||
|
||||
once(type: any, listener: any, ...args: any[]): any;
|
||||
|
||||
private triggerMarkEvent(cfiRange: string, data: object, contents: Contents): void;
|
||||
|
||||
private triggerMarkEvent(
|
||||
cfiRange: string,
|
||||
data: object,
|
||||
contents: Contents
|
||||
): void;
|
||||
private triggerSelectedEvent(cfirange: string, contents: Contents): void;
|
||||
|
||||
private triggerViewEvent(e: Event, contents: Contents): void;
|
||||
|
||||
private onResized(size: { width: number, height: number }): void;
|
||||
|
||||
private onResized(size: { width: number; height: number }): void;
|
||||
private afterDisplayed(view: any): void;
|
||||
|
||||
private afterRemoved(view: any): void;
|
||||
|
||||
}
|
||||
|
|
32
types/resources.d.ts
vendored
32
types/resources.d.ts
vendored
|
@ -1,33 +1,29 @@
|
|||
import { PackagingManifestObject } from "./packaging";
|
||||
import Archive from "./archive";
|
||||
import { PackagingManifestObject } from "./packaging";
|
||||
|
||||
export default class Resources {
|
||||
constructor(manifest: PackagingManifestObject, options: {
|
||||
replacements?: string,
|
||||
archive?: Archive,
|
||||
resolver?: Function,
|
||||
request?: Function
|
||||
});
|
||||
|
||||
constructor(
|
||||
manifest: PackagingManifestObject,
|
||||
options: {
|
||||
replacements?: string;
|
||||
archive?: Archive;
|
||||
resolver?: Function;
|
||||
request?: Function;
|
||||
}
|
||||
);
|
||||
process(manifest: PackagingManifestObject): void;
|
||||
|
||||
createUrl(url: string): Promise<string>;
|
||||
|
||||
replacements(): Promise<Array<string>>;
|
||||
|
||||
relativeTo(absolute: boolean, resolver?: Function): Array<string>;
|
||||
|
||||
get(path: string): string;
|
||||
|
||||
substitute(content: string, url?: string): string;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private split(): void;
|
||||
|
||||
private splitUrls(): void;
|
||||
|
||||
private replaceCss(archive: Archive, resolver?: Function): Promise<Array<string>>;
|
||||
|
||||
private replaceCss(
|
||||
archive: Archive,
|
||||
resolver?: Function
|
||||
): Promise<Array<string>>;
|
||||
private createCssFile(href: string): Promise<string>;
|
||||
}
|
||||
|
|
42
types/section.d.ts
vendored
42
types/section.d.ts
vendored
|
@ -1,32 +1,31 @@
|
|||
import { HooksObject } from "./utils/hook";
|
||||
|
||||
export interface GlobalLayout {
|
||||
layout: string,
|
||||
spread: string,
|
||||
orientation: string
|
||||
layout: string;
|
||||
spread: string;
|
||||
orientation: string;
|
||||
}
|
||||
|
||||
export interface LayoutSettings {
|
||||
layout: string,
|
||||
spread: string,
|
||||
orientation: string
|
||||
layout: string;
|
||||
spread: string;
|
||||
orientation: string;
|
||||
}
|
||||
|
||||
export interface SpineItem {
|
||||
index: number,
|
||||
cfiBase: string,
|
||||
href?: string,
|
||||
url?: string,
|
||||
canonical?: string,
|
||||
properties?: Array<string>,
|
||||
linear?: string,
|
||||
next: () => SpineItem,
|
||||
prev: () => SpineItem,
|
||||
index: number;
|
||||
cfiBase: string;
|
||||
href?: string;
|
||||
url?: string;
|
||||
canonical?: string;
|
||||
properties?: Array<string>;
|
||||
linear?: string;
|
||||
next: () => SpineItem;
|
||||
prev: () => SpineItem;
|
||||
}
|
||||
|
||||
export default class Section {
|
||||
constructor(item: SpineItem, hooks: HooksObject);
|
||||
|
||||
idref: string;
|
||||
linear: boolean;
|
||||
properties: Array<string>;
|
||||
|
@ -37,28 +36,17 @@ export default class Section {
|
|||
next: () => SpineItem;
|
||||
prev: () => SpineItem;
|
||||
cfiBase: string;
|
||||
|
||||
document: Document;
|
||||
contents: Element;
|
||||
output: string;
|
||||
|
||||
hooks: HooksObject;
|
||||
|
||||
load(_request?: Function): Document;
|
||||
|
||||
render(_request?: Function): string;
|
||||
|
||||
find(_query: string): Array<Element>;
|
||||
|
||||
reconcileLayoutSettings(globalLayout: GlobalLayout): LayoutSettings;
|
||||
|
||||
cfiFromRange(_range: Range): string;
|
||||
|
||||
cfiFromElement(el: Element): string;
|
||||
|
||||
unload(): void;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private base(): void;
|
||||
}
|
||||
|
|
14
types/spine.d.ts
vendored
14
types/spine.d.ts
vendored
|
@ -4,27 +4,17 @@ import Hook from "./utils/hook";
|
|||
|
||||
export default class Spine {
|
||||
constructor();
|
||||
|
||||
hooks: {
|
||||
serialize: Hook,
|
||||
content: Hook
|
||||
serialize: Hook;
|
||||
content: Hook;
|
||||
};
|
||||
|
||||
unpack(_package: Packaging, resolver: Function, canonical: Function): void;
|
||||
|
||||
get(target?: string | number): Section;
|
||||
|
||||
each(...args: any[]): any;
|
||||
|
||||
first(): Section;
|
||||
|
||||
last(): Section;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private append(section: Section): number;
|
||||
|
||||
private prepend(section: Section): number;
|
||||
|
||||
private remove(section: Section): number;
|
||||
}
|
||||
|
|
31
types/store.d.ts
vendored
31
types/store.d.ts
vendored
|
@ -1,30 +1,29 @@
|
|||
import localForage = require('localforage');
|
||||
import localForage = require("localforage");
|
||||
import Resources from "./resources";
|
||||
|
||||
export default class Store {
|
||||
constructor(name: string, request?: Function, resolver?: Function);
|
||||
|
||||
add(resources: Resources, force?: boolean): Promise<Array<object>>;
|
||||
|
||||
put(url: string, withCredentials?: boolean, headers?: object): Promise<Blob>;
|
||||
|
||||
request(url: string, type?: string, withCredentials?: boolean, headers?: object): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
|
||||
retrieve(url: string, type?: string): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
|
||||
request(
|
||||
url: string,
|
||||
type?: string,
|
||||
withCredentials?: boolean,
|
||||
headers?: object
|
||||
): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
retrieve(
|
||||
url: string,
|
||||
type?: string
|
||||
): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
getBlob(url: string, mimeType?: string): Promise<Blob>;
|
||||
|
||||
getText(url: string): Promise<string>;
|
||||
|
||||
getBase64(url: string, mimeType?: string): Promise<string>;
|
||||
|
||||
createUrl(url: string, options: { base64: boolean }): Promise<string>;
|
||||
|
||||
revokeUrl(url: string): void;
|
||||
|
||||
destroy(): void;
|
||||
|
||||
private checkRequirements(): void;
|
||||
|
||||
private handleResponse(response: any, type?: string): Blob | string | JSON | Document | XMLDocument;
|
||||
private handleResponse(
|
||||
response: any,
|
||||
type?: string
|
||||
): Blob | string | JSON | Document | XMLDocument;
|
||||
}
|
||||
|
|
19
types/themes.d.ts
vendored
19
types/themes.d.ts
vendored
|
@ -1,40 +1,23 @@
|
|||
import Rendition from "./rendition";
|
||||
import Contents from "./contents";
|
||||
import Rendition from "./rendition";
|
||||
|
||||
export default class Themes {
|
||||
constructor(rendition: Rendition);
|
||||
|
||||
register(themeObject: object): void;
|
||||
|
||||
register(theme: string, url: string): void;
|
||||
|
||||
register(theme: string, themeObject: object): void;
|
||||
|
||||
default(theme: object | string): void;
|
||||
|
||||
registerThemes(themes: object): void;
|
||||
|
||||
registerCss(name: string, css: string): void;
|
||||
|
||||
registerUrl(name: string, input: string): void;
|
||||
|
||||
registerRules(name: string, rules: object): void;
|
||||
|
||||
select(name: string): void;
|
||||
|
||||
update(name: string): void;
|
||||
|
||||
inject(content: Contents): void;
|
||||
|
||||
add(name: string, contents: Contents): void;
|
||||
|
||||
override(name: string, value: string, priority?: boolean): void;
|
||||
|
||||
overrides(contents: Contents): void;
|
||||
|
||||
fontSize(size: string): void;
|
||||
|
||||
font(f: string): void;
|
||||
|
||||
destroy(): void;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"lib": ["es6", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"typeRoots": ["../"],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"epubjs-tests.ts"
|
||||
]
|
||||
"files": ["index.d.ts"]
|
||||
}
|
||||
|
|
6
types/utils/constants.d.ts
vendored
6
types/utils/constants.d.ts
vendored
|
@ -4,6 +4,6 @@ export const DOM_EVENTS: Array<string>;
|
|||
|
||||
export const EVENTS: {
|
||||
[key: string]: {
|
||||
[key: string]: string
|
||||
}
|
||||
}
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
|
|
114
types/utils/core.d.ts
vendored
114
types/utils/core.d.ts
vendored
|
@ -1,79 +1,85 @@
|
|||
export function uuid(): string;
|
||||
|
||||
export function documentHeight(): number;
|
||||
|
||||
export function isElement(obj: object): boolean;
|
||||
|
||||
export function isNumber(n: any): boolean;
|
||||
|
||||
export function isFloat(n: any): boolean;
|
||||
|
||||
export function prefixed(unprefixed: string): string;
|
||||
|
||||
export function defaults(obj: object): object;
|
||||
|
||||
export function extend(target: object): object;
|
||||
|
||||
export function insert(item: any, array: Array<any>, compareFunction: Function): number;
|
||||
|
||||
export function locationOf(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
|
||||
|
||||
export function indexOfSorted(item: any, array: Array<any>, compareFunction: Function, _start: Function, _end: Function): number;
|
||||
|
||||
export function bounds(el: Element): { width: Number, height: Number};
|
||||
|
||||
export function borders(el: Element): { width: Number, height: Number};
|
||||
|
||||
export function insert(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function
|
||||
): number;
|
||||
export function locationOf(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function,
|
||||
_start: Function,
|
||||
_end: Function
|
||||
): number;
|
||||
export function indexOfSorted(
|
||||
item: any,
|
||||
array: Array<any>,
|
||||
compareFunction: Function,
|
||||
_start: Function,
|
||||
_end: Function
|
||||
): number;
|
||||
export function bounds(el: Element): { width: Number; height: Number };
|
||||
export function borders(el: Element): { width: Number; height: Number };
|
||||
export function nodeBounds(node: Node): object;
|
||||
|
||||
export function windowBounds(): { width: Number, height: Number, top: Number, left: Number, right: Number, bottom: Number };
|
||||
|
||||
export function windowBounds(): {
|
||||
width: Number;
|
||||
height: Number;
|
||||
top: Number;
|
||||
left: Number;
|
||||
right: Number;
|
||||
bottom: Number;
|
||||
};
|
||||
export function indexOfNode(node: Node, typeId: string): number;
|
||||
|
||||
export function indexOfTextNode(textNode: Node): number;
|
||||
|
||||
export function indexOfElementNode(elementNode: Element): number;
|
||||
|
||||
export function isXml(ext: string): boolean;
|
||||
|
||||
export function createBlob(content: any, mime: string): Blob;
|
||||
|
||||
export function createBlobUrl(content: any, mime: string): string;
|
||||
|
||||
export function revokeBlobUrl(url: string): void;
|
||||
|
||||
export function createBase64Url(content: any, mime: string): string
|
||||
|
||||
export function createBase64Url(content: any, mime: string): string;
|
||||
export function type(obj: object): string;
|
||||
|
||||
export function parse(markup: string, mime: string, forceXMLDom: boolean): Document;
|
||||
|
||||
export function parse(
|
||||
markup: string,
|
||||
mime: string,
|
||||
forceXMLDom: boolean
|
||||
): Document;
|
||||
export function qs(el: Element, sel: string): Element;
|
||||
|
||||
export function qsa(el: Element, sel: string): ArrayLike<Element>;
|
||||
|
||||
export function qsp(el: Element, sel: string, props: Array<object>): ArrayLike<Element>;
|
||||
|
||||
export function qsp(
|
||||
el: Element,
|
||||
sel: string,
|
||||
props: Array<object>
|
||||
): ArrayLike<Element>;
|
||||
export function sprint(root: Node, func: Function): void;
|
||||
|
||||
export function treeWalker(root: Node, func: Function, filter: object | Function): void;
|
||||
|
||||
export function treeWalker(
|
||||
root: Node,
|
||||
func: Function,
|
||||
filter: object | Function
|
||||
): void;
|
||||
export function walk(node: Node, callback: Function): void;
|
||||
|
||||
export function blob2base64(blob: Blob): string;
|
||||
|
||||
export function defer(): Promise<any>;
|
||||
|
||||
export function querySelectorByType(html: Element, element: string, type: string): Array<Element>;
|
||||
|
||||
export function querySelectorByType(
|
||||
html: Element,
|
||||
element: string,
|
||||
type: string
|
||||
): Array<Element>;
|
||||
export function findChildren(el: Element): Array<Element>;
|
||||
|
||||
export function parents(node: Element): Array<Element>;
|
||||
|
||||
export function filterChildren(el: Element, nodeName: string, single: boolean): Array<Element>;
|
||||
|
||||
export function getParentByTagName(node: Element, tagname: string): Array<Element>;
|
||||
|
||||
export class RangeObject extends Range {
|
||||
|
||||
}
|
||||
export function filterChildren(
|
||||
el: Element,
|
||||
nodeName: string,
|
||||
single: boolean
|
||||
): Array<Element>;
|
||||
export function getParentByTagName(
|
||||
node: Element,
|
||||
tagname: string
|
||||
): Array<Element>;
|
||||
export class RangeObject extends Range {}
|
||||
|
|
6
types/utils/hook.d.ts
vendored
6
types/utils/hook.d.ts
vendored
|
@ -1,5 +1,5 @@
|
|||
interface HooksObject {
|
||||
[key: string]: Hook
|
||||
[key: string]: Hook;
|
||||
}
|
||||
|
||||
export default class Hook {
|
||||
|
@ -7,12 +7,8 @@ export default class Hook {
|
|||
|
||||
register(func: Function): void;
|
||||
register(arr: Array<Function>): void;
|
||||
|
||||
deregister(func: Function): void;
|
||||
|
||||
trigger(...args: any[]): Promise<any>;
|
||||
|
||||
list(): Array<any>;
|
||||
|
||||
clear(): void;
|
||||
}
|
||||
|
|
6
types/utils/path.d.ts
vendored
6
types/utils/path.d.ts
vendored
|
@ -2,16 +2,10 @@ export default class Path {
|
|||
constructor(pathString: string);
|
||||
|
||||
parse(what: string): object;
|
||||
|
||||
isAbsolute(what: string): boolean;
|
||||
|
||||
isDirectory(what: string): boolean;
|
||||
|
||||
resolve(what: string): string;
|
||||
|
||||
relative(what: string): string;
|
||||
|
||||
splitPath(filename: string): string;
|
||||
|
||||
toString(): string;
|
||||
}
|
||||
|
|
18
types/utils/queue.d.ts
vendored
18
types/utils/queue.d.ts
vendored
|
@ -1,31 +1,21 @@
|
|||
import { defer } from "./core";
|
||||
|
||||
export interface QueuedTask {
|
||||
task: any | Task,
|
||||
args: any[],
|
||||
deferred: any, // should be defer, but not working
|
||||
promise: Promise<any>
|
||||
task: any | Task;
|
||||
args: any[];
|
||||
deferred: any; // should be defer, but not working
|
||||
promise: Promise<any>;
|
||||
}
|
||||
|
||||
export default class Queue {
|
||||
constructor(context: any);
|
||||
|
||||
enqueue(func: Promise<Function> | Function, ...args: any[]): Promise<any>;
|
||||
|
||||
dequeue(): Promise<QueuedTask>;
|
||||
|
||||
dump(): void;
|
||||
|
||||
run(): Promise<void>;
|
||||
|
||||
flush(): Promise<void>;
|
||||
|
||||
clear(): void;
|
||||
|
||||
length(): number;
|
||||
|
||||
pause(): void;
|
||||
|
||||
stop(): void;
|
||||
}
|
||||
|
||||
|
|
12
types/utils/replacements.d.ts
vendored
12
types/utils/replacements.d.ts
vendored
|
@ -1,12 +1,12 @@
|
|||
import Section from "../section";
|
||||
import Contents from "../contents";
|
||||
import Section from "../section";
|
||||
|
||||
export function replaceBase(doc: Document, section: Section): void;
|
||||
|
||||
export function replaceCanonical(doc: Document, section: Section): void;
|
||||
|
||||
export function replaceMeta(doc: Document, section: Section): void;
|
||||
|
||||
export function replaceLinks(contents: Contents, fn: Function): void;
|
||||
|
||||
export function substitute(contents: Contents, urls: string[], replacements: string[]): void;
|
||||
export function substitute(
|
||||
contents: Contents,
|
||||
urls: string[],
|
||||
replacements: string[]
|
||||
): void;
|
||||
|
|
7
types/utils/request.d.ts
vendored
7
types/utils/request.d.ts
vendored
|
@ -1 +1,6 @@
|
|||
export default function request(url: string, type?: string, withCredentials?: boolean, headers?: object): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
export default function request(
|
||||
url: string,
|
||||
type?: string,
|
||||
withCredentials?: boolean,
|
||||
headers?: object
|
||||
): Promise<Blob | string | JSON | Document | XMLDocument>;
|
||||
|
|
1
types/utils/scrolltype.d.ts
vendored
1
types/utils/scrolltype.d.ts
vendored
|
@ -1,3 +1,2 @@
|
|||
export default function scrollType(): string;
|
||||
|
||||
export function createDefiner(): Node;
|
||||
|
|
3
types/utils/url.d.ts
vendored
3
types/utils/url.d.ts
vendored
|
@ -4,10 +4,7 @@ export default class Url {
|
|||
constructor(urlString: string, baseString: string);
|
||||
|
||||
path(): Path;
|
||||
|
||||
resolve(what: string): string;
|
||||
|
||||
relative(what: string): string;
|
||||
|
||||
toString(): string;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
var webpack = require("webpack");
|
||||
var path = require("path");
|
||||
var PROD = (process.env.NODE_ENV === "production")
|
||||
var LEGACY = (process.env.LEGACY)
|
||||
var MINIMIZE = (process.env.MINIMIZE === "true")
|
||||
var LEGACY = process.env.LEGACY;
|
||||
var MINIMIZE = process.env.MINIMIZE === "true";
|
||||
var hostname = "localhost";
|
||||
var port = 8080;
|
||||
|
||||
|
@ -22,9 +20,9 @@ if (MINIMIZE) {
|
|||
module.exports = {
|
||||
mode: process.env.NODE_ENV,
|
||||
entry: {
|
||||
"epub": "./src/epub.js",
|
||||
epub: "./src/epub.js",
|
||||
},
|
||||
devtool: MINIMIZE ? false : 'source-map',
|
||||
devtool: MINIMIZE ? false : "source-map",
|
||||
output: {
|
||||
path: path.resolve("./dist"),
|
||||
filename: filename,
|
||||
|
@ -32,20 +30,20 @@ module.exports = {
|
|||
library: "ePub",
|
||||
libraryTarget: "umd",
|
||||
libraryExport: "default",
|
||||
publicPath: "/dist/"
|
||||
publicPath: "/dist/",
|
||||
},
|
||||
optimization: {
|
||||
minimize: MINIMIZE
|
||||
minimize: MINIMIZE,
|
||||
},
|
||||
externals: {
|
||||
"jszip/dist/jszip": "JSZip",
|
||||
"xmldom": "xmldom"
|
||||
xmldom: "xmldom",
|
||||
},
|
||||
plugins: [],
|
||||
resolve: {
|
||||
alias: {
|
||||
path: "path-webpack"
|
||||
}
|
||||
path: "path-webpack",
|
||||
},
|
||||
},
|
||||
devServer: {
|
||||
host: hostname,
|
||||
|
@ -54,8 +52,8 @@ module.exports = {
|
|||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE",
|
||||
"Access-Control-Allow-Headers": "Content-Type"
|
||||
}
|
||||
"Access-Control-Allow-Headers": "Content-Type",
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
@ -65,19 +63,26 @@ module.exports = {
|
|||
use: {
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
presets: [["@babel/preset-env", {
|
||||
targets: LEGACY ? "defaults" : "last 2 Chrome versions, last 2 Safari versions, last 2 ChromeAndroid versions, last 2 iOS versions, last 2 Firefox versions, last 2 Edge versions",
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: LEGACY
|
||||
? "defaults"
|
||||
: "last 2 Chrome versions, last 2 Safari versions, last 2 ChromeAndroid versions, last 2 iOS versions, last 2 Firefox versions, last 2 Edge versions",
|
||||
corejs: 3,
|
||||
useBuiltIns: "usage",
|
||||
bugfixes: true,
|
||||
modules: false
|
||||
}]]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
modules: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
}
|
||||
}
|
||||
hints: false,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue