mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
Intial move to ES2015
This commit is contained in:
parent
b0944bdff8
commit
353dfa62fd
46 changed files with 16839 additions and 18742 deletions
15
.babelrc
Normal file
15
.babelrc
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"targets": {
|
||||
"chrome": 54,
|
||||
"safari" : 10,
|
||||
"firefox" : 50,
|
||||
"edge" : 14
|
||||
}
|
||||
}]
|
||||
],
|
||||
"plugins": [
|
||||
"add-module-exports"
|
||||
]
|
||||
}
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -5,3 +5,6 @@ components
|
|||
node_modules
|
||||
bower_components
|
||||
books
|
||||
lib
|
||||
dist
|
||||
documentation/html
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
"examples"
|
||||
],
|
||||
"dependencies": {
|
||||
"es6-promise": "~4.0.5"
|
||||
"es6-promise": "~4.0.5",
|
||||
"jszip": "^3.1.1",
|
||||
"path-webpack": "^0.0.2",
|
||||
"stream-browserify": "^2.0.1",
|
||||
"xmldom": "^0.1.22"
|
||||
}
|
||||
}
|
||||
|
|
16668
dist/epub.js
vendored
16668
dist/epub.js
vendored
File diff suppressed because it is too large
Load diff
2
dist/epub.js.map
vendored
2
dist/epub.js.map
vendored
File diff suppressed because one or more lines are too long
5
dist/epub.min.js
vendored
5
dist/epub.min.js
vendored
File diff suppressed because one or more lines are too long
2110
dist/polyfills.js
vendored
2110
dist/polyfills.js
vendored
File diff suppressed because it is too large
Load diff
1
dist/polyfills.js.map
vendored
1
dist/polyfills.js.map
vendored
File diff suppressed because one or more lines are too long
8
dist/polyfills.min.js
vendored
8
dist/polyfills.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -24,7 +24,7 @@ module.exports = function(config) {
|
|||
|
||||
{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: 'node_modules/es6-promise/dist/es6-promise.auto.js', watched: false, included: true, served: true},
|
||||
|
||||
{pattern: 'libs/url/url.js', watched: false, included: true, served: true}
|
||||
|
||||
|
@ -53,6 +53,22 @@ module.exports = function(config) {
|
|||
alias: {
|
||||
path: "path-webpack"
|
||||
}
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "babel-loader",
|
||||
query: {
|
||||
presets: ['es2015'],
|
||||
plugins: [
|
||||
"add-module-exports",
|
||||
"transform-runtime"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
|
|
29
package.json
29
package.json
|
@ -1,20 +1,34 @@
|
|||
{
|
||||
"name": "epubjs",
|
||||
"version": "0.3.0",
|
||||
"description": "Render Epubs",
|
||||
"main": "src/epub.js",
|
||||
"version": "0.3.1",
|
||||
"description": "Parse and Render Epubs",
|
||||
"main": "lib/index.js",
|
||||
"jsnext:main" : "src/index.js",
|
||||
"repository": "https://github.com/futurepress/epub.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS",
|
||||
"start": "webpack-dev-server --inline",
|
||||
"build": "./node_modules/.bin/gulp minify"
|
||||
"documentation": "./node_modules/.bin/gulp docs",
|
||||
"start": "webpack-dev-server --inline --d",
|
||||
"build": "webpack --progress",
|
||||
"minify": "NODE_ENV=production webpack --progress",
|
||||
"legacy": "NODE_ENV=production LEGACY=true webpack --progress",
|
||||
"compile": "babel --optional runtime -d lib/ src/",
|
||||
"prepublish": "npm run compile && npm run build && npm run minify && npm run legacy"
|
||||
},
|
||||
"author": "fchasen@gmail.com",
|
||||
"license": "BSD-2-Clause",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-core": "^6.18.2",
|
||||
"babel-loader": "^6.2.8",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"babel-plugin-transform-runtime": "^6.15.0",
|
||||
"babel-polyfill": "^6.16.0",
|
||||
"babel-preset-env": "0.0.9",
|
||||
"babili-webpack-plugin": "0.0.7",
|
||||
"colors": "^1.1.2",
|
||||
"connect": "^3.0.1",
|
||||
"express": "^4.5.1",
|
||||
|
@ -52,11 +66,10 @@
|
|||
"webpack-dev-server": "^v2.1.0-beta.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"es6-promise": "^4.0.5",
|
||||
"event-emitter": "^0.3.4",
|
||||
"jszip": "^3.1.1",
|
||||
"xmldom": "^0.1.22",
|
||||
"path-webpack": "^0.0.2",
|
||||
"stream-browserify": "^2.0.1"
|
||||
"stream-browserify": "^2.0.1",
|
||||
"xmldom": "^0.1.22"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
var core = require('./core');
|
||||
var request = require('./request');
|
||||
var mime = require('../libs/mime/mime');
|
||||
var Path = require('./core').Path;
|
||||
import {defer, isXml, parse} from './utils/core';
|
||||
import request from './request';
|
||||
import mime from '../libs/mime/mime';
|
||||
import Path from './utils/path';
|
||||
|
||||
/**
|
||||
* Handles Unzipping a requesting files from an Epub Archive
|
||||
* @class
|
||||
*/
|
||||
function Archive() {
|
||||
class Archive {
|
||||
constructor() {
|
||||
this.zip = undefined;
|
||||
this.checkRequirements();
|
||||
this.urlCache = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Checks to see if JSZip exists in global namspace,
|
||||
* Requires JSZip if it isn't there
|
||||
* @private
|
||||
*/
|
||||
Archive.prototype.checkRequirements = function(){
|
||||
checkRequirements(){
|
||||
try {
|
||||
if (typeof JSZip === 'undefined') {
|
||||
JSZip = require('jszip');
|
||||
|
@ -27,39 +28,39 @@ Archive.prototype.checkRequirements = function(){
|
|||
} catch (e) {
|
||||
console.error("JSZip lib not loaded");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Open an archive
|
||||
* @param {binary} input
|
||||
* @param {boolean} isBase64 tells JSZip if the input data is base64 encoded
|
||||
* @return {Promise} zipfile
|
||||
*/
|
||||
Archive.prototype.open = function(input, isBase64){
|
||||
open(input, isBase64){
|
||||
return this.zip.loadAsync(input, {"base64": isBase64});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Load and Open an archive
|
||||
* @param {string} zipUrl
|
||||
* @param {boolean} isBase64 tells JSZip if the input data is base64 encoded
|
||||
* @return {Promise} zipfile
|
||||
*/
|
||||
Archive.prototype.openUrl = function(zipUrl, isBase64){
|
||||
openUrl(zipUrl, isBase64){
|
||||
return request(zipUrl, "binary")
|
||||
.then(function(data){
|
||||
return this.zip.loadAsync(data, {"base64": isBase64});
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Request
|
||||
* @param {string} url a url to request from the archive
|
||||
* @param {[string]} type specify the type of the returned result
|
||||
* @return {Promise}
|
||||
*/
|
||||
Archive.prototype.request = function(url, type){
|
||||
var deferred = new core.defer();
|
||||
request(url, type){
|
||||
var deferred = new defer();
|
||||
var response;
|
||||
var r;
|
||||
var path = new Path(url);
|
||||
|
@ -77,7 +78,7 @@ Archive.prototype.request = function(url, type){
|
|||
|
||||
if (response) {
|
||||
response.then(function (r) {
|
||||
result = this.handleResponse(r, type);
|
||||
let result = this.handleResponse(r, type);
|
||||
deferred.resolve(result);
|
||||
}.bind(this));
|
||||
} else {
|
||||
|
@ -87,46 +88,46 @@ Archive.prototype.request = function(url, type){
|
|||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Handle the response from request
|
||||
* @private
|
||||
* @param {any} response
|
||||
* @param {[string]} type
|
||||
* @return {any} the parsed result
|
||||
*/
|
||||
Archive.prototype.handleResponse = function(response, type){
|
||||
handleResponse(response, type){
|
||||
var r;
|
||||
|
||||
if(type == "json") {
|
||||
r = JSON.parse(response);
|
||||
}
|
||||
else
|
||||
if(core.isXml(type)) {
|
||||
r = core.parse(response, "text/xml");
|
||||
if(isXml(type)) {
|
||||
r = parse(response, "text/xml");
|
||||
}
|
||||
else
|
||||
if(type == 'xhtml') {
|
||||
r = core.parse(response, "application/xhtml+xml");
|
||||
r = parse(response, "application/xhtml+xml");
|
||||
}
|
||||
else
|
||||
if(type == 'html' || type == 'htm') {
|
||||
r = core.parse(response, "text/html");
|
||||
r = parse(response, "text/html");
|
||||
} else {
|
||||
r = response;
|
||||
}
|
||||
|
||||
return r;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a Blob from Archive by Url
|
||||
* @param {string} url
|
||||
* @param {[string]} mimeType
|
||||
* @return {Blob}
|
||||
*/
|
||||
Archive.prototype.getBlob = function(url, mimeType){
|
||||
getBlob(url, mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
|
||||
|
@ -136,15 +137,15 @@ Archive.prototype.getBlob = function(url, mimeType){
|
|||
return new Blob([uint8array], {type : mimeType});
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get Text from Archive by Url
|
||||
* @param {string} url
|
||||
* @param {[string]} encoding
|
||||
* @return {string}
|
||||
*/
|
||||
Archive.prototype.getText = function(url, encoding){
|
||||
getText(url, encoding){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
|
||||
|
@ -153,15 +154,15 @@ Archive.prototype.getText = function(url, encoding){
|
|||
return text;
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a base64 encoded result from Archive by Url
|
||||
* @param {string} url
|
||||
* @param {[string]} mimeType
|
||||
* @return {string} base64 encoded
|
||||
*/
|
||||
Archive.prototype.getBase64 = function(url, mimeType){
|
||||
getBase64(url, mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
|
||||
|
@ -171,16 +172,16 @@ Archive.prototype.getBase64 = function(url, mimeType){
|
|||
return "data:" + mimeType + ";base64," + data;
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a Url from an unarchived item
|
||||
* @param {string} url
|
||||
* @param {[object]} options.base64 use base64 encoding or blob url
|
||||
* @return {Promise} url promise with Url string
|
||||
*/
|
||||
Archive.prototype.createUrl = function(url, options){
|
||||
var deferred = new core.defer();
|
||||
createUrl(url, options){
|
||||
var deferred = new defer();
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var tempUrl;
|
||||
var blob;
|
||||
|
@ -230,16 +231,17 @@ Archive.prototype.createUrl = function(url, options){
|
|||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Revoke Temp Url for a achive item
|
||||
* @param {string} url url of the item in the archive
|
||||
*/
|
||||
Archive.prototype.revokeUrl = function(url){
|
||||
revokeUrl(url){
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var fromCache = this.urlCache[url];
|
||||
if(fromCache) _URL.revokeObjectURL(fromCache);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Archive;
|
||||
export default Archive;
|
||||
|
|
219
src/book.js
219
src/book.js
|
@ -1,22 +1,21 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var path = require('path');
|
||||
var core = require('./core');
|
||||
var Url = require('./core').Url;
|
||||
var Path = require('./core').Path;
|
||||
var Spine = require('./spine');
|
||||
var Locations = require('./locations');
|
||||
var Container = require('./container');
|
||||
var Packaging = require('./packaging');
|
||||
var Navigation = require('./navigation');
|
||||
var Resources = require('./resources');
|
||||
var PageList = require('./pagelist');
|
||||
var Rendition = require('./rendition');
|
||||
var Archive = require('./archive');
|
||||
var request = require('./request');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
import EventEmitter from 'event-emitter';
|
||||
// import path from 'path';
|
||||
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 Container from './container';
|
||||
import Packaging from './packaging';
|
||||
import Navigation from './navigation';
|
||||
import Resources from './resources';
|
||||
import PageList from './pagelist';
|
||||
import Rendition from './rendition';
|
||||
import Archive from './archive';
|
||||
import request from './request';
|
||||
import EpubCFI from './epubcfi';
|
||||
|
||||
// Const
|
||||
var CONTAINER_PATH = "META-INF/container.xml";
|
||||
const CONTAINER_PATH = "META-INF/container.xml";
|
||||
|
||||
/**
|
||||
* Creates a new Book
|
||||
|
@ -32,8 +31,8 @@ var CONTAINER_PATH = "META-INF/container.xml";
|
|||
* @example new Book("/path/to/book.epub", {})
|
||||
* @example new Book({ replacements: "blobUrl" })
|
||||
*/
|
||||
function Book(url, options){
|
||||
|
||||
class Book {
|
||||
constructor(url, options) {
|
||||
// Allow passing just options to the Book
|
||||
if (typeof(options) === "undefined"
|
||||
&& typeof(url) === "object") {
|
||||
|
@ -41,7 +40,7 @@ function Book(url, options){
|
|||
url = undefined;
|
||||
}
|
||||
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
this.settings = extend(this.settings || {}, {
|
||||
requestMethod: undefined,
|
||||
requestCredentials: undefined,
|
||||
requestHeaders: undefined,
|
||||
|
@ -49,11 +48,11 @@ function Book(url, options){
|
|||
replacements: 'base64'
|
||||
});
|
||||
|
||||
core.extend(this.settings, options);
|
||||
extend(this.settings, options);
|
||||
|
||||
|
||||
// Promises
|
||||
this.opening = new core.defer();
|
||||
this.opening = new defer();
|
||||
/**
|
||||
* @property {promise} opened returns after the book is loaded
|
||||
*/
|
||||
|
@ -61,13 +60,13 @@ function Book(url, options){
|
|||
this.isOpen = false;
|
||||
|
||||
this.loading = {
|
||||
manifest: new core.defer(),
|
||||
spine: new core.defer(),
|
||||
metadata: new core.defer(),
|
||||
cover: new core.defer(),
|
||||
navigation: new core.defer(),
|
||||
pageList: new core.defer(),
|
||||
resources: new core.defer()
|
||||
manifest: new defer(),
|
||||
spine: new defer(),
|
||||
metadata: new defer(),
|
||||
cover: new defer(),
|
||||
navigation: new defer(),
|
||||
pageList: new defer(),
|
||||
resources: new defer()
|
||||
};
|
||||
|
||||
this.loaded = {
|
||||
|
@ -95,7 +94,7 @@ function Book(url, options){
|
|||
|
||||
// Queue for methods used before opening
|
||||
this.isRendered = false;
|
||||
// this._q = core.queue(this);
|
||||
// this._q = queue(this);
|
||||
|
||||
/**
|
||||
* @property {method} request
|
||||
|
@ -142,23 +141,23 @@ function Book(url, options){
|
|||
this.archived = false;
|
||||
|
||||
if(url) {
|
||||
this.open(url).catch(function (error) {
|
||||
this.open(url).catch((error) => {
|
||||
var err = new Error("Cannot load book at "+ url );
|
||||
console.error(err);
|
||||
this.emit("openFailed", err);
|
||||
console.log(error);
|
||||
}.bind(this));
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Open a epub or url
|
||||
* @param {string} input URL, Path or ArrayBuffer
|
||||
* @param {string} [what] to force opening
|
||||
* @returns {Promise} of when the book has been loaded
|
||||
* @example book.open("/path/to/book.epub")
|
||||
*/
|
||||
Book.prototype.open = function(input, what){
|
||||
open(input, what) {
|
||||
var opening;
|
||||
var type = what || this.determineType(input);
|
||||
|
||||
|
@ -181,61 +180,61 @@ Book.prototype.open = function(input, what){
|
|||
}
|
||||
|
||||
return opening;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Open an archived epub
|
||||
* @private
|
||||
* @param {binary} data
|
||||
* @param {[string]} encoding
|
||||
* @return {Promise}
|
||||
*/
|
||||
Book.prototype.openEpub = function(data, encoding){
|
||||
openEpub(data, encoding) {
|
||||
return this.unarchive(data, encoding || this.settings.encoding)
|
||||
.then(function() {
|
||||
.then(() => {
|
||||
return this.openContainer(CONTAINER_PATH);
|
||||
}.bind(this))
|
||||
.then(function(packagePath) {
|
||||
})
|
||||
.then((packagePath) => {
|
||||
return this.openPackaging(packagePath);
|
||||
}.bind(this));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Open the epub container
|
||||
* @private
|
||||
* @param {string} url
|
||||
* @return {string} packagePath
|
||||
*/
|
||||
Book.prototype.openContainer = function(url){
|
||||
openContainer(url) {
|
||||
return this.load(url)
|
||||
.then(function(xml) {
|
||||
.then((xml) => {
|
||||
this.container = new Container(xml);
|
||||
return this.resolve(this.container.packagePath);
|
||||
}.bind(this));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Open the Open Packaging Format Xml
|
||||
* @private
|
||||
* @param {string} url
|
||||
* @return {Promise}
|
||||
*/
|
||||
Book.prototype.openPackaging = function(url){
|
||||
openPackaging(url) {
|
||||
var packageUrl;
|
||||
this.path = new Path(url);
|
||||
return this.load(url)
|
||||
.then(function(xml) {
|
||||
.then((xml) => {
|
||||
this.packaging = new Packaging(xml);
|
||||
return this.unpack(this.packaging);
|
||||
}.bind(this));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Load a resource from the Book
|
||||
* @param {string} path path to the resource to load
|
||||
* @return {Promise} returns a promise with the requested resource
|
||||
*/
|
||||
Book.prototype.load = function (path) {
|
||||
load(path) {
|
||||
var resolved;
|
||||
|
||||
if(this.archived) {
|
||||
|
@ -245,15 +244,15 @@ Book.prototype.load = function (path) {
|
|||
resolved = this.resolve(path);
|
||||
return this.request(resolved, null, this.settings.requestCredentials, this.settings.requestHeaders);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Resolve a path to it's absolute position in the Book
|
||||
* @param {string} path
|
||||
* @param {[boolean]} absolute force resolving the full URL
|
||||
* @return {string} the resolved path string
|
||||
*/
|
||||
Book.prototype.resolve = function (path, absolute) {
|
||||
resolve(path, absolute) {
|
||||
var resolved = path;
|
||||
var isAbsolute = (path.indexOf('://') > -1);
|
||||
|
||||
|
@ -270,15 +269,15 @@ Book.prototype.resolve = function (path, absolute) {
|
|||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Determine the type of they input passed to open
|
||||
* @private
|
||||
* @param {string} input
|
||||
* @return {string} binary | directory | epub | opf
|
||||
*/
|
||||
Book.prototype.determineType = function(input) {
|
||||
determineType(input) {
|
||||
var url;
|
||||
var path;
|
||||
var extension;
|
||||
|
@ -302,15 +301,15 @@ Book.prototype.determineType = function(input) {
|
|||
if(extension === "opf"){
|
||||
return "opf";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* unpack the contents of the Books packageXml
|
||||
* @private
|
||||
* @param {document} packageXml XML Document
|
||||
*/
|
||||
Book.prototype.unpack = function(opf){
|
||||
unpack(opf) {
|
||||
this.package = opf;
|
||||
|
||||
this.spine.unpack(this.package, this.resolve.bind(this));
|
||||
|
@ -321,10 +320,10 @@ Book.prototype.unpack = function(opf){
|
|||
replacements: this.settings.replacements
|
||||
});
|
||||
|
||||
this.loadNavigation(this.package).then(function(){
|
||||
this.loadNavigation(this.package).then(() => {
|
||||
this.toc = this.navigation.toc;
|
||||
this.loading.navigation.resolve(this.navigation);
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
this.cover = this.resolve(this.package.coverPath);
|
||||
|
||||
|
@ -340,22 +339,22 @@ Book.prototype.unpack = function(opf){
|
|||
this.isOpen = true;
|
||||
|
||||
if(this.archived) {
|
||||
this.replacements().then(function() {
|
||||
this.replacements().then(() => {
|
||||
this.opening.resolve(this);
|
||||
}.bind(this));
|
||||
});
|
||||
} else {
|
||||
// Resolve book opened promise
|
||||
this.opening.resolve(this);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Load Navigation and PageList from package
|
||||
* @private
|
||||
* @param {document} opf XML Document
|
||||
*/
|
||||
Book.prototype.loadNavigation = function(opf){
|
||||
loadNavigation(opf) {
|
||||
var navPath = opf.navPath || opf.ncxPath;
|
||||
|
||||
if (!navPath) {
|
||||
|
@ -363,28 +362,28 @@ Book.prototype.loadNavigation = function(opf){
|
|||
}
|
||||
|
||||
return this.load(navPath, 'xml')
|
||||
.then(function(xml) {
|
||||
.then((xml) => {
|
||||
this.navigation = new Navigation(xml);
|
||||
this.pageList = new PageList(xml);
|
||||
return this.navigation;
|
||||
}.bind(this));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Alias for book.spine.get
|
||||
* @param {string} target
|
||||
*/
|
||||
Book.prototype.section = function(target) {
|
||||
section(target) {
|
||||
return this.spine.get(target);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sugar to render a book
|
||||
* @param {element} element element to add the views to
|
||||
* @param {[object]} options
|
||||
* @return {Rendition}
|
||||
*/
|
||||
Book.prototype.renderTo = function(element, options) {
|
||||
renderTo(element, options) {
|
||||
// var renderMethod = (options && options.method) ?
|
||||
// options.method :
|
||||
// "single";
|
||||
|
@ -393,78 +392,78 @@ Book.prototype.renderTo = function(element, options) {
|
|||
this.rendition.attachTo(element);
|
||||
|
||||
return this.rendition;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set if request should use withCredentials
|
||||
* @param {boolean} credentials
|
||||
*/
|
||||
Book.prototype.setRequestCredentials = function(credentials) {
|
||||
setRequestCredentials(credentials) {
|
||||
this.settings.requestCredentials = credentials;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set headers request should use
|
||||
* @param {object} headers
|
||||
*/
|
||||
Book.prototype.setRequestHeaders = function(headers) {
|
||||
setRequestHeaders(headers) {
|
||||
this.settings.requestHeaders = headers;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Unarchive a zipped epub
|
||||
* @private
|
||||
* @param {binary} input epub data
|
||||
* @param {[string]} encoding
|
||||
* @return {Archive}
|
||||
*/
|
||||
Book.prototype.unarchive = function(input, encoding){
|
||||
unarchive(input, encoding) {
|
||||
this.archive = new Archive();
|
||||
return this.archive.open(input, encoding);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the cover url
|
||||
* @return {string} coverUrl
|
||||
*/
|
||||
Book.prototype.coverUrl = function(){
|
||||
coverUrl() {
|
||||
var retrieved = this.loaded.cover.
|
||||
then(function(url) {
|
||||
then((url) => {
|
||||
if(this.archived) {
|
||||
// return this.archive.createUrl(this.cover);
|
||||
return this.resources.get(this.cover);
|
||||
}else{
|
||||
return this.cover;
|
||||
}
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
|
||||
|
||||
return retrieved;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* load replacement urls
|
||||
* @private
|
||||
* @return {Promise} completed loading urls
|
||||
*/
|
||||
Book.prototype.replacements = function(){
|
||||
this.spine.hooks.serialize.register(function(output, section) {
|
||||
replacements() {
|
||||
this.spine.hooks.serialize.register((output, section) => {
|
||||
section.output = this.resources.substitute(output, section.url);
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
return this.resources.replacements().
|
||||
then(function() {
|
||||
then(() => {
|
||||
return this.resources.replaceCss();
|
||||
}.bind(this));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Find a DOM Range for a given CFI Range
|
||||
* @param {EpubCFI} cfiRange a epub cfi range
|
||||
* @return {Range}
|
||||
*/
|
||||
Book.prototype.range = function(cfiRange) {
|
||||
range(cfiRange) {
|
||||
var cfi = new EpubCFI(cfiRange);
|
||||
var item = this.spine.get(cfi.spinePos);
|
||||
|
||||
|
@ -472,19 +471,21 @@ Book.prototype.range = function(cfiRange) {
|
|||
var range = cfi.toRange(item.document);
|
||||
return range;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Generates the Book Key using the identifer in the manifest or other string provided
|
||||
* @param {[string]} identifier to use instead of metadata identifier
|
||||
* @return {string} key
|
||||
*/
|
||||
Book.prototype.key = function(identifier){
|
||||
key(identifier) {
|
||||
var ident = identifier || this.package.metadata.identifier || this.url.filename;
|
||||
return "epubjs:" + (EPUBJS_VERSION || ePub.VERSION) + ":" + ident;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-- Enable binding events to book
|
||||
EventEmitter(Book.prototype);
|
||||
|
||||
module.exports = Book;
|
||||
export default Book;
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
var path = require('path');
|
||||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
import path from 'path-webpack';
|
||||
import {qs} from './utils/core';
|
||||
import EpubCFI from './epubcfi';
|
||||
|
||||
/**
|
||||
* Handles Parsing and Accessing an Epub Container
|
||||
* @class
|
||||
* @param {[document]} containerDocument xml document
|
||||
*/
|
||||
function Container(containerDocument) {
|
||||
class Container {
|
||||
constructor(containerDocument) {
|
||||
if (containerDocument) {
|
||||
this.parse(containerDocument);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse the Container XML
|
||||
* @param {document} containerDocument
|
||||
*/
|
||||
Container.prototype.parse = function(containerDocument){
|
||||
parse(containerDocument){
|
||||
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
||||
var rootfile, fullpath, folder, encoding;
|
||||
|
||||
|
@ -26,7 +27,7 @@ Container.prototype.parse = function(containerDocument){
|
|||
return;
|
||||
}
|
||||
|
||||
rootfile = core.qs(containerDocument, "rootfile");
|
||||
rootfile = qs(containerDocument, "rootfile");
|
||||
|
||||
if(!rootfile) {
|
||||
console.error("No RootFile Found");
|
||||
|
@ -36,6 +37,7 @@ Container.prototype.parse = function(containerDocument){
|
|||
this.packagePath = rootfile.getAttribute('full-path');
|
||||
this.directory = path.dirname(this.packagePath);
|
||||
this.encoding = containerDocument.xmlEncoding;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Container;
|
||||
export default Container;
|
||||
|
|
252
src/contents.js
252
src/contents.js
|
@ -1,10 +1,11 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Mapping = require('./mapping');
|
||||
import EventEmitter from 'event-emitter';
|
||||
import {isNumber, prefixed} from './utils/core';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Mapping from './mapping';
|
||||
|
||||
|
||||
function Contents(doc, content, cfiBase) {
|
||||
class Contents {
|
||||
constructor(doc, content, cfiBase) {
|
||||
// Blank Cfi for Parsing
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
|
@ -23,13 +24,13 @@ function Contents(doc, content, cfiBase) {
|
|||
this.cfiBase = cfiBase || "";
|
||||
|
||||
this.listeners();
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.width = function(w) {
|
||||
width(w) {
|
||||
// var frame = this.documentElement;
|
||||
var frame = this.content;
|
||||
|
||||
if (w && core.isNumber(w)) {
|
||||
if (w && isNumber(w)) {
|
||||
w = w + "px";
|
||||
}
|
||||
|
||||
|
@ -41,13 +42,13 @@ Contents.prototype.width = function(w) {
|
|||
return this.window.getComputedStyle(frame)['width'];
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.height = function(h) {
|
||||
height(h) {
|
||||
// var frame = this.documentElement;
|
||||
var frame = this.content;
|
||||
|
||||
if (h && core.isNumber(h)) {
|
||||
if (h && isNumber(h)) {
|
||||
h = h + "px";
|
||||
}
|
||||
|
||||
|
@ -58,13 +59,13 @@ Contents.prototype.height = function(h) {
|
|||
|
||||
return this.window.getComputedStyle(frame)['height'];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.contentWidth = function(w) {
|
||||
contentWidth(w) {
|
||||
|
||||
var content = this.content || this.document.body;
|
||||
|
||||
if (w && core.isNumber(w)) {
|
||||
if (w && isNumber(w)) {
|
||||
w = w + "px";
|
||||
}
|
||||
|
||||
|
@ -75,13 +76,13 @@ Contents.prototype.contentWidth = function(w) {
|
|||
return this.window.getComputedStyle(content)['width'];
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.contentHeight = function(h) {
|
||||
contentHeight(h) {
|
||||
|
||||
var content = this.content || this.document.body;
|
||||
|
||||
if (h && core.isNumber(h)) {
|
||||
if (h && isNumber(h)) {
|
||||
h = h + "px";
|
||||
}
|
||||
|
||||
|
@ -91,9 +92,9 @@ Contents.prototype.contentHeight = function(h) {
|
|||
|
||||
return this.window.getComputedStyle(content)['height'];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.textWidth = function() {
|
||||
textWidth() {
|
||||
var width;
|
||||
var range = this.document.createRange();
|
||||
var content = this.content || this.document.body;
|
||||
|
@ -106,9 +107,9 @@ Contents.prototype.textWidth = function() {
|
|||
|
||||
return width;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.textHeight = function() {
|
||||
textHeight() {
|
||||
var height;
|
||||
var range = this.document.createRange();
|
||||
var content = this.content || this.document.body;
|
||||
|
@ -118,48 +119,48 @@ Contents.prototype.textHeight = function() {
|
|||
height = range.getBoundingClientRect().height;
|
||||
|
||||
return height;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.scrollWidth = function() {
|
||||
scrollWidth() {
|
||||
var width = this.documentElement.scrollWidth;
|
||||
|
||||
return width;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.scrollHeight = function() {
|
||||
scrollHeight() {
|
||||
var height = this.documentElement.scrollHeight;
|
||||
|
||||
return height;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.overflow = function(overflow) {
|
||||
overflow(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflow = overflow;
|
||||
}
|
||||
|
||||
return this.window.getComputedStyle(this.documentElement)['overflow'];
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.overflowX = function(overflow) {
|
||||
overflowX(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflowX = overflow;
|
||||
}
|
||||
|
||||
return this.window.getComputedStyle(this.documentElement)['overflowX'];
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.overflowY = function(overflow) {
|
||||
overflowY(overflow) {
|
||||
|
||||
if (overflow) {
|
||||
this.documentElement.style.overflowY = overflow;
|
||||
}
|
||||
|
||||
return this.window.getComputedStyle(this.documentElement)['overflowY'];
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.css = function(property, value) {
|
||||
css(property, value) {
|
||||
var content = this.content || this.document.body;
|
||||
|
||||
if (value) {
|
||||
|
@ -167,9 +168,9 @@ Contents.prototype.css = function(property, value) {
|
|||
}
|
||||
|
||||
return this.window.getComputedStyle(content)[property];
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.viewport = function(options) {
|
||||
viewport(options) {
|
||||
var width, height, scale, scalable;
|
||||
var $viewport = this.document.querySelector("meta[name='viewport']");
|
||||
var newContent = '';
|
||||
|
@ -220,35 +221,35 @@ Contents.prototype.viewport = function(options) {
|
|||
width: parseInt(width),
|
||||
height: parseInt(height)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Contents.prototype.layout = function(layoutFunc) {
|
||||
//
|
||||
// this.iframe.style.display = "inline-block";
|
||||
//
|
||||
// // Reset Body Styles
|
||||
// this.content.style.margin = "0";
|
||||
// //this.document.body.style.display = "inline-block";
|
||||
// //this.document.documentElement.style.width = "auto";
|
||||
//
|
||||
// if(layoutFunc){
|
||||
// layoutFunc(this);
|
||||
// }
|
||||
//
|
||||
// this.onLayout(this);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// Contents.prototype.onLayout = function(view) {
|
||||
// // stub
|
||||
// };
|
||||
// layout(layoutFunc) {
|
||||
//
|
||||
// this.iframe.style.display = "inline-block";
|
||||
//
|
||||
// // Reset Body Styles
|
||||
// this.content.style.margin = "0";
|
||||
// //this.document.body.style.display = "inline-block";
|
||||
// //this.document.documentElement.style.width = "auto";
|
||||
//
|
||||
// if(layoutFunc){
|
||||
// layoutFunc(this);
|
||||
// }
|
||||
//
|
||||
// this.onLayout(this);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// onLayout(view) {
|
||||
// // stub
|
||||
// };
|
||||
|
||||
Contents.prototype.expand = function() {
|
||||
expand() {
|
||||
this.emit("expand");
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.listeners = function() {
|
||||
listeners() {
|
||||
|
||||
this.imageLoadListeners();
|
||||
|
||||
|
@ -262,16 +263,16 @@ Contents.prototype.listeners = function() {
|
|||
|
||||
this.resizeListeners();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.removeListeners = function() {
|
||||
removeListeners() {
|
||||
|
||||
this.removeEventListeners();
|
||||
|
||||
this.removeSelectionListeners();
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.resizeListeners = function() {
|
||||
resizeListeners() {
|
||||
var width, height;
|
||||
// Test size again
|
||||
clearTimeout(this.expanding);
|
||||
|
@ -290,10 +291,10 @@ Contents.prototype.resizeListeners = function() {
|
|||
}
|
||||
|
||||
this.expanding = setTimeout(this.resizeListeners.bind(this), 350);
|
||||
};
|
||||
};
|
||||
|
||||
//https://github.com/tylergaw/media-query-events/blob/master/js/mq-events.js
|
||||
Contents.prototype.mediaQueryListeners = function() {
|
||||
//https://github.com/tylergaw/media-query-events/blob/master/js/mq-events.js
|
||||
mediaQueryListeners() {
|
||||
var sheets = this.document.styleSheets;
|
||||
var mediaChangeHandler = function(m){
|
||||
if(m.matches && !this._expanding) {
|
||||
|
@ -320,9 +321,9 @@ Contents.prototype.mediaQueryListeners = function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.observe = function(target) {
|
||||
observe(target) {
|
||||
var renderer = this;
|
||||
|
||||
// create an observer instance
|
||||
|
@ -342,9 +343,9 @@ Contents.prototype.observe = function(target) {
|
|||
observer.observe(target, config);
|
||||
|
||||
return observer;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.imageLoadListeners = function(target) {
|
||||
imageLoadListeners(target) {
|
||||
var images = this.document.querySelectorAll("img");
|
||||
var img;
|
||||
for (var i = 0; i < images.length; i++) {
|
||||
|
@ -355,9 +356,9 @@ Contents.prototype.imageLoadListeners = function(target) {
|
|||
img.onload = this.expand.bind(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.fontLoadListeners = function(target) {
|
||||
fontLoadListeners(target) {
|
||||
if (!this.document || !this.document.fonts) {
|
||||
return;
|
||||
}
|
||||
|
@ -366,14 +367,14 @@ Contents.prototype.fontLoadListeners = function(target) {
|
|||
this.expand();
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.root = function() {
|
||||
root() {
|
||||
if(!this.document) return null;
|
||||
return this.document.documentElement;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.locationOf = function(target, ignoreClass) {
|
||||
locationOf(target, ignoreClass) {
|
||||
var position;
|
||||
var targetPos = {"left": 0, "top": 0};
|
||||
|
||||
|
@ -414,9 +415,9 @@ Contents.prototype.locationOf = function(target, ignoreClass) {
|
|||
}
|
||||
|
||||
return targetPos;
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.addStylesheet = function(src) {
|
||||
addStylesheet(src) {
|
||||
return new Promise(function(resolve, reject){
|
||||
var $stylesheet;
|
||||
var ready = false;
|
||||
|
@ -450,10 +451,10 @@ Contents.prototype.addStylesheet = function(src) {
|
|||
this.document.head.appendChild($stylesheet);
|
||||
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule
|
||||
Contents.prototype.addStylesheetRules = function(rules) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule
|
||||
addStylesheetRules(rules) {
|
||||
var styleEl;
|
||||
var styleSheet;
|
||||
var key = "epubjs-inserted-css";
|
||||
|
@ -489,9 +490,9 @@ Contents.prototype.addStylesheetRules = function(rules) {
|
|||
// Insert CSS Rule
|
||||
styleSheet.insertRule(selector + '{' + propStr + '}', styleSheet.cssRules.length);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.addScript = function(src) {
|
||||
addScript(src) {
|
||||
|
||||
return new Promise(function(resolve, reject){
|
||||
var $script;
|
||||
|
@ -518,9 +519,9 @@ Contents.prototype.addScript = function(src) {
|
|||
this.document.head.appendChild($script);
|
||||
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.addClass = function(className) {
|
||||
addClass(className) {
|
||||
var content;
|
||||
|
||||
if(!this.document) return;
|
||||
|
@ -529,9 +530,9 @@ Contents.prototype.addClass = function(className) {
|
|||
|
||||
content.classList.add(className);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.removeClass = function(className) {
|
||||
removeClass(className) {
|
||||
var content;
|
||||
|
||||
if(!this.document) return;
|
||||
|
@ -540,9 +541,9 @@ Contents.prototype.removeClass = function(className) {
|
|||
|
||||
content.classList.remove(className);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.addEventListeners = function(){
|
||||
addEventListeners(){
|
||||
if(!this.document) {
|
||||
return;
|
||||
}
|
||||
|
@ -550,9 +551,9 @@ Contents.prototype.addEventListeners = function(){
|
|||
this.document.addEventListener(eventName, this.triggerEvent.bind(this), false);
|
||||
}, this);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.removeEventListeners = function(){
|
||||
removeEventListeners(){
|
||||
if(!this.document) {
|
||||
return;
|
||||
}
|
||||
|
@ -560,28 +561,28 @@ Contents.prototype.removeEventListeners = function(){
|
|||
this.document.removeEventListener(eventName, this.triggerEvent, false);
|
||||
}, this);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Pass browser events
|
||||
Contents.prototype.triggerEvent = function(e){
|
||||
// Pass browser events
|
||||
triggerEvent(e){
|
||||
this.emit(e.type, e);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.addSelectionListeners = function(){
|
||||
addSelectionListeners(){
|
||||
if(!this.document) {
|
||||
return;
|
||||
}
|
||||
this.document.addEventListener("selectionchange", this.onSelectionChange.bind(this), false);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.removeSelectionListeners = function(){
|
||||
removeSelectionListeners(){
|
||||
if(!this.document) {
|
||||
return;
|
||||
}
|
||||
this.document.removeEventListener("selectionchange", this.onSelectionChange, false);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.onSelectionChange = function(e){
|
||||
onSelectionChange(e){
|
||||
if (this.selectionEndTimeout) {
|
||||
clearTimeout(this.selectionEndTimeout);
|
||||
}
|
||||
|
@ -589,9 +590,9 @@ Contents.prototype.onSelectionChange = function(e){
|
|||
var selection = this.window.getSelection();
|
||||
this.triggerSelectedEvent(selection);
|
||||
}.bind(this), 500);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.triggerSelectedEvent = function(selection){
|
||||
triggerSelectedEvent(selection){
|
||||
var range, cfirange;
|
||||
|
||||
if (selection && selection.rangeCount > 0) {
|
||||
|
@ -603,19 +604,19 @@ Contents.prototype.triggerSelectedEvent = function(selection){
|
|||
this.emit("selectedRange", range);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.range = function(_cfi, ignoreClass){
|
||||
range(_cfi, ignoreClass){
|
||||
var cfi = new EpubCFI(_cfi);
|
||||
return cfi.toRange(this.document, ignoreClass);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.map = function(layout){
|
||||
map(layout){
|
||||
var map = new Mapping(layout);
|
||||
return map.section();
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.size = function(width, height){
|
||||
size(width, height){
|
||||
|
||||
if (width >= 0) {
|
||||
this.width(width);
|
||||
|
@ -628,13 +629,13 @@ Contents.prototype.size = function(width, height){
|
|||
this.css("margin", "0");
|
||||
this.css("boxSizing", "border-box");
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.columns = function(width, height, columnWidth, gap){
|
||||
var COLUMN_AXIS = core.prefixed('columnAxis');
|
||||
var COLUMN_GAP = core.prefixed('columnGap');
|
||||
var COLUMN_WIDTH = core.prefixed('columnWidth');
|
||||
var COLUMN_FILL = core.prefixed('columnFill');
|
||||
columns(width, height, columnWidth, gap){
|
||||
var COLUMN_AXIS = prefixed('columnAxis');
|
||||
var COLUMN_GAP = prefixed('columnGap');
|
||||
var COLUMN_WIDTH = prefixed('columnWidth');
|
||||
var COLUMN_FILL = prefixed('columnFill');
|
||||
var textWidth;
|
||||
|
||||
this.width(width);
|
||||
|
@ -654,9 +655,9 @@ Contents.prototype.columns = function(width, height, columnWidth, gap){
|
|||
|
||||
this.css(COLUMN_GAP, gap+"px");
|
||||
this.css(COLUMN_WIDTH, columnWidth+"px");
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.scale = function(scale, offsetX, offsetY){
|
||||
scaler(scale, offsetX, offsetY){
|
||||
var scale = "scale(" + scale + ")";
|
||||
var translate = '';
|
||||
// this.css("position", "absolute"));
|
||||
|
@ -667,9 +668,9 @@ Contents.prototype.scale = function(scale, offsetX, offsetY){
|
|||
}
|
||||
|
||||
this.css("transform", scale + translate);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.fit = function(width, height){
|
||||
fit(width, height){
|
||||
var viewport = this.viewport();
|
||||
var widthScale = width / viewport.width;
|
||||
var heightScale = height / viewport.height;
|
||||
|
@ -685,18 +686,18 @@ Contents.prototype.fit = function(width, height){
|
|||
this.viewport({ scale: 1.0 });
|
||||
|
||||
// Scale to the correct size
|
||||
this.scale(scale, 0, offsetY);
|
||||
this.scaler(scale, 0, offsetY);
|
||||
|
||||
this.css("backgroundColor", "transparent");
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.mapPage = function(cfiBase, start, end) {
|
||||
mapPage(cfiBase, start, end) {
|
||||
var mapping = new Mapping();
|
||||
|
||||
return mapping.page(this, cfiBase, start, end);
|
||||
};
|
||||
};
|
||||
|
||||
Contents.prototype.destroy = function() {
|
||||
destroy() {
|
||||
// Stop observing
|
||||
if(this.observer) {
|
||||
this.observer.disconnect();
|
||||
|
@ -704,8 +705,9 @@ Contents.prototype.destroy = function() {
|
|||
|
||||
this.removeListeners();
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
EventEmitter(Contents.prototype);
|
||||
|
||||
module.exports = Contents;
|
||||
export default Contents;
|
||||
|
|
10
src/epub.js
10
src/epub.js
|
@ -1,7 +1,7 @@
|
|||
var Book = require('./book');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Rendition = require('./rendition');
|
||||
var Contents = require('./contents');
|
||||
import Book from './book';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Rendition from './rendition';
|
||||
import Contents from './contents';
|
||||
|
||||
/**
|
||||
* Creates a new Book
|
||||
|
@ -51,4 +51,4 @@ ePub.register.view("iframe", require('./managers/views/iframe'));
|
|||
ePub.register.manager("default", require('./managers/default'));
|
||||
ePub.register.manager("continuous", require('./managers/continuous'));
|
||||
|
||||
module.exports = ePub;
|
||||
export default ePub;
|
||||
|
|
182
src/epubcfi.js
182
src/epubcfi.js
|
@ -1,4 +1,4 @@
|
|||
var core = require('./core');
|
||||
import {extend, type, findChildren} from './utils/core';
|
||||
|
||||
/**
|
||||
EPUB CFI spec: http://www.idpf.org/epub/linking/cfi/epub-cfi.html
|
||||
|
@ -19,7 +19,8 @@ var TEXT_NODE = 3;
|
|||
var COMMENT_NODE = 8;
|
||||
var DOCUMENT_NODE = 9;
|
||||
|
||||
function EpubCFI(cfiFrom, base, ignoreClass){
|
||||
class EpubCFI {
|
||||
constructor(cfiFrom, base, ignoreClass){
|
||||
var type;
|
||||
|
||||
this.str = '';
|
||||
|
@ -49,11 +50,11 @@ function EpubCFI(cfiFrom, base, ignoreClass){
|
|||
|
||||
if(type === 'string') {
|
||||
this.str = cfiFrom;
|
||||
return core.extend(this, this.parse(cfiFrom));
|
||||
return extend(this, this.parse(cfiFrom));
|
||||
} else if (type === 'range') {
|
||||
return core.extend(this, this.fromRange(cfiFrom, this.base, ignoreClass));
|
||||
return extend(this, this.fromRange(cfiFrom, this.base, ignoreClass));
|
||||
} else if (type === 'node') {
|
||||
return core.extend(this, this.fromNode(cfiFrom, this.base, ignoreClass));
|
||||
return extend(this, this.fromNode(cfiFrom, this.base, ignoreClass));
|
||||
} else if (type === 'EpubCFI' && cfiFrom.path) {
|
||||
return cfiFrom;
|
||||
} else if (!cfiFrom) {
|
||||
|
@ -62,14 +63,14 @@ function EpubCFI(cfiFrom, base, ignoreClass){
|
|||
throw new TypeError('not a valid argument for EpubCFI');
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.checkType = function(cfi) {
|
||||
checkType(cfi) {
|
||||
|
||||
if (this.isCfiString(cfi)) {
|
||||
return 'string';
|
||||
// Is a range object
|
||||
} else if (typeof cfi === 'object' && (core.type(cfi) === "Range" || typeof(cfi.startContainer) != "undefined")){
|
||||
} else if (typeof cfi === 'object' && (type(cfi) === "Range" || typeof(cfi.startContainer) != "undefined")){
|
||||
return 'range';
|
||||
} else if (typeof cfi === 'object' && typeof(cfi.nodeType) != "undefined" ){ // || typeof cfi === 'function'
|
||||
return 'node';
|
||||
|
@ -78,9 +79,9 @@ EpubCFI.prototype.checkType = function(cfi) {
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.parse = function(cfiStr) {
|
||||
parse(cfiStr) {
|
||||
var cfi = {
|
||||
spinePos: -1,
|
||||
range: false,
|
||||
|
@ -127,9 +128,9 @@ EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.spinePos = cfi.base.steps[1].index;
|
||||
|
||||
return cfi;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.parseComponent = function(componentStr){
|
||||
parseComponent(componentStr){
|
||||
var component = {
|
||||
steps: [],
|
||||
terminal: {
|
||||
|
@ -155,9 +156,9 @@ EpubCFI.prototype.parseComponent = function(componentStr){
|
|||
}.bind(this));
|
||||
|
||||
return component;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.parseStep = function(stepStr){
|
||||
parseStep(stepStr){
|
||||
var type, num, index, has_brackets, id;
|
||||
|
||||
has_brackets = stepStr.match(/\[(.*)\]/);
|
||||
|
@ -185,9 +186,9 @@ EpubCFI.prototype.parseStep = function(stepStr){
|
|||
'index' : index,
|
||||
'id' : id || null
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.parseTerminal = function(termialStr){
|
||||
parseTerminal(termialStr){
|
||||
var characterOffset, textLocationAssertion;
|
||||
var assertion = termialStr.match(/\[(.*)\]/);
|
||||
|
||||
|
@ -203,27 +204,27 @@ EpubCFI.prototype.parseTerminal = function(termialStr){
|
|||
'assertion': textLocationAssertion
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.getChapterComponent = function(cfiStr) {
|
||||
getChapterComponent(cfiStr) {
|
||||
|
||||
var indirection = cfiStr.split("!");
|
||||
|
||||
return indirection[0];
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.getPathComponent = function(cfiStr) {
|
||||
getPathComponent(cfiStr) {
|
||||
|
||||
var indirection = cfiStr.split("!");
|
||||
|
||||
if(indirection[1]) {
|
||||
ranges = indirection[1].split(',');
|
||||
let ranges = indirection[1].split(',');
|
||||
return ranges[0];
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.getRange = function(cfiStr) {
|
||||
getRange(cfiStr) {
|
||||
|
||||
var ranges = cfiStr.split(",");
|
||||
|
||||
|
@ -235,14 +236,14 @@ EpubCFI.prototype.getRange = function(cfiStr) {
|
|||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.getCharecterOffsetComponent = function(cfiStr) {
|
||||
getCharecterOffsetComponent(cfiStr) {
|
||||
var splitStr = cfiStr.split(":");
|
||||
return splitStr[1] || '';
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.joinSteps = function(steps) {
|
||||
joinSteps(steps) {
|
||||
if(!steps) {
|
||||
return "";
|
||||
}
|
||||
|
@ -266,9 +267,9 @@ EpubCFI.prototype.joinSteps = function(steps) {
|
|||
|
||||
}).join('/');
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.segmentString = function(segment) {
|
||||
segmentString(segment) {
|
||||
var segmentString = '/';
|
||||
|
||||
segmentString += this.joinSteps(segment.steps);
|
||||
|
@ -282,9 +283,9 @@ EpubCFI.prototype.segmentString = function(segment) {
|
|||
}
|
||||
|
||||
return segmentString;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.toString = function() {
|
||||
toString() {
|
||||
var cfiString = 'epubcfi(';
|
||||
|
||||
cfiString += this.segmentString(this.base);
|
||||
|
@ -306,9 +307,9 @@ EpubCFI.prototype.toString = function() {
|
|||
cfiString += ")";
|
||||
|
||||
return cfiString;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
||||
compare(cfiOne, cfiTwo) {
|
||||
var stepsA, stepsB;
|
||||
var terminalA, terminalB;
|
||||
|
||||
|
@ -374,9 +375,9 @@ EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
|
|||
|
||||
// CFI's are equal
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.step = function(node) {
|
||||
step(node) {
|
||||
var nodeType = (node.nodeType === TEXT_NODE) ? 'text' : 'element';
|
||||
|
||||
return {
|
||||
|
@ -385,9 +386,9 @@ EpubCFI.prototype.step = function(node) {
|
|||
'type' : nodeType,
|
||||
'index' : this.position(node)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.filteredStep = function(node, ignoreClass) {
|
||||
filteredStep(node, ignoreClass) {
|
||||
var filteredNode = this.filter(node, ignoreClass);
|
||||
var nodeType;
|
||||
|
||||
|
@ -405,9 +406,9 @@ EpubCFI.prototype.filteredStep = function(node, ignoreClass) {
|
|||
'type' : nodeType,
|
||||
'index' : this.filteredPosition(filteredNode, ignoreClass)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.pathTo = function(node, offset, ignoreClass) {
|
||||
pathTo(node, offset, ignoreClass) {
|
||||
var segment = {
|
||||
steps: [],
|
||||
terminal: {
|
||||
|
@ -451,9 +452,9 @@ EpubCFI.prototype.pathTo = function(node, offset, ignoreClass) {
|
|||
|
||||
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
|
||||
EpubCFI.prototype.equalStep = function(stepA, stepB) {
|
||||
equalStep(stepA, stepB) {
|
||||
if (!stepA || !stepB) {
|
||||
return false;
|
||||
}
|
||||
|
@ -465,9 +466,9 @@ EpubCFI.prototype.equalStep = function(stepA, stepB) {
|
|||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.fromRange = function(range, base, ignoreClass) {
|
||||
fromRange(range, base, ignoreClass) {
|
||||
var cfi = {
|
||||
range: false,
|
||||
base: {},
|
||||
|
@ -552,9 +553,9 @@ EpubCFI.prototype.fromRange = function(range, base, ignoreClass) {
|
|||
}
|
||||
|
||||
return cfi;
|
||||
}
|
||||
}
|
||||
|
||||
EpubCFI.prototype.fromNode = function(anchor, base, ignoreClass) {
|
||||
fromNode(anchor, base, ignoreClass) {
|
||||
var cfi = {
|
||||
range: false,
|
||||
base: {},
|
||||
|
@ -580,12 +581,12 @@ EpubCFI.prototype.fromNode = function(anchor, base, ignoreClass) {
|
|||
cfi.path = this.pathTo(anchor, null, ignoreClass);
|
||||
|
||||
return cfi;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.filter = function(anchor, ignoreClass) {
|
||||
filter(anchor, ignoreClass) {
|
||||
var needsIgnoring;
|
||||
var sibling; // to join with
|
||||
var parent, prevSibling, nextSibling;
|
||||
var parent, previousSibling, nextSibling;
|
||||
var isText = false;
|
||||
|
||||
if (anchor.nodeType === TEXT_NODE) {
|
||||
|
@ -623,9 +624,9 @@ EpubCFI.prototype.filter = function(anchor, ignoreClass) {
|
|||
return anchor;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.patchOffset = function(anchor, offset, ignoreClass) {
|
||||
patchOffset(anchor, offset, ignoreClass) {
|
||||
var needsIgnoring;
|
||||
var sibling;
|
||||
|
||||
|
@ -660,9 +661,9 @@ EpubCFI.prototype.patchOffset = function(anchor, offset, ignoreClass) {
|
|||
|
||||
return totalOffset;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.normalizedMap = function(children, nodeType, ignoreClass) {
|
||||
normalizedMap(children, nodeType, ignoreClass) {
|
||||
var output = {};
|
||||
var prevIndex = -1;
|
||||
var i, len = children.length;
|
||||
|
@ -694,15 +695,15 @@ EpubCFI.prototype.normalizedMap = function(children, nodeType, ignoreClass) {
|
|||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.position = function(anchor) {
|
||||
position(anchor) {
|
||||
var children, index, map;
|
||||
var childNodes, node;
|
||||
if (anchor.nodeType === ELEMENT_NODE) {
|
||||
children = anchor.parentNode.children;
|
||||
if (!children) {
|
||||
children = core.children(anchor.parentNode);
|
||||
children = findChildren(anchor.parentNode);
|
||||
}
|
||||
index = Array.prototype.indexOf.call(children, anchor);
|
||||
} else {
|
||||
|
@ -711,9 +712,9 @@ EpubCFI.prototype.position = function(anchor) {
|
|||
}
|
||||
|
||||
return index;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.filteredPosition = function(anchor, ignoreClass) {
|
||||
filteredPosition(anchor, ignoreClass) {
|
||||
var children, index, map;
|
||||
|
||||
if (anchor.nodeType === ELEMENT_NODE) {
|
||||
|
@ -733,9 +734,9 @@ EpubCFI.prototype.filteredPosition = function(anchor, ignoreClass) {
|
|||
index = Array.prototype.indexOf.call(children, anchor);
|
||||
|
||||
return map[index];
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.stepsToXpath = function(steps) {
|
||||
stepsToXpath(steps) {
|
||||
var xpath = [".", "*"];
|
||||
|
||||
steps.forEach(function(step){
|
||||
|
@ -751,25 +752,25 @@ EpubCFI.prototype.stepsToXpath = function(steps) {
|
|||
});
|
||||
|
||||
return xpath.join("/");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
To get the last step if needed:
|
||||
To get the last step if needed:
|
||||
|
||||
// Get the terminal step
|
||||
lastStep = steps[steps.length-1];
|
||||
// Get the query string
|
||||
query = this.stepsToQuery(steps);
|
||||
// Find the containing element
|
||||
startContainerParent = doc.querySelector(query);
|
||||
// Find the text node within that element
|
||||
if(startContainerParent && lastStep.type == "text") {
|
||||
// Get the terminal step
|
||||
lastStep = steps[steps.length-1];
|
||||
// Get the query string
|
||||
query = this.stepsToQuery(steps);
|
||||
// Find the containing element
|
||||
startContainerParent = doc.querySelector(query);
|
||||
// Find the text node within that element
|
||||
if(startContainerParent && lastStep.type == "text") {
|
||||
container = startContainerParent.childNodes[lastStep.index];
|
||||
}
|
||||
*/
|
||||
EpubCFI.prototype.stepsToQuerySelector = function(steps) {
|
||||
}
|
||||
*/
|
||||
stepsToQuerySelector(steps) {
|
||||
var query = ["html"];
|
||||
|
||||
steps.forEach(function(step){
|
||||
|
@ -787,9 +788,9 @@ EpubCFI.prototype.stepsToQuerySelector = function(steps) {
|
|||
|
||||
return query.join(">");
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.textNodes = function(container, ignoreClass) {
|
||||
textNodes(container, ignoreClass) {
|
||||
return Array.prototype.slice.call(container.childNodes).
|
||||
filter(function (node) {
|
||||
if (node.nodeType === TEXT_NODE) {
|
||||
|
@ -799,9 +800,9 @@ EpubCFI.prototype.textNodes = function(container, ignoreClass) {
|
|||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.walkToNode = function(steps, _doc, ignoreClass) {
|
||||
walkToNode(steps, _doc, ignoreClass) {
|
||||
var doc = _doc || document;
|
||||
var container = doc.documentElement;
|
||||
var step;
|
||||
|
@ -820,9 +821,9 @@ EpubCFI.prototype.walkToNode = function(steps, _doc, ignoreClass) {
|
|||
};
|
||||
|
||||
return container;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.findNode = function(steps, _doc, ignoreClass) {
|
||||
findNode(steps, _doc, ignoreClass) {
|
||||
var doc = _doc || document;
|
||||
var container;
|
||||
var xpath;
|
||||
|
@ -837,9 +838,9 @@ EpubCFI.prototype.findNode = function(steps, _doc, ignoreClass) {
|
|||
}
|
||||
|
||||
return container;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.fixMiss = function(steps, offset, _doc, ignoreClass) {
|
||||
fixMiss(steps, offset, _doc, ignoreClass) {
|
||||
var container = this.findNode(steps.slice(0,-1), _doc, ignoreClass);
|
||||
var children = container.childNodes;
|
||||
var map = this.normalizedMap(children, TEXT_NODE, ignoreClass);
|
||||
|
@ -873,9 +874,9 @@ EpubCFI.prototype.fixMiss = function(steps, offset, _doc, ignoreClass) {
|
|||
offset: offset
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.toRange = function(_doc, ignoreClass) {
|
||||
toRange(_doc, ignoreClass) {
|
||||
var doc = _doc || document;
|
||||
var range = doc.createRange();
|
||||
var start, end, startContainer, endContainer;
|
||||
|
@ -933,10 +934,10 @@ EpubCFI.prototype.toRange = function(_doc, ignoreClass) {
|
|||
|
||||
// doc.defaultView.getSelection().addRange(range);
|
||||
return range;
|
||||
};
|
||||
};
|
||||
|
||||
// is a cfi string, should be wrapped with "epubcfi()"
|
||||
EpubCFI.prototype.isCfiString = function(str) {
|
||||
// is a cfi string, should be wrapped with "epubcfi()"
|
||||
isCfiString(str) {
|
||||
if(typeof str === 'string' &&
|
||||
str.indexOf("epubcfi(") === 0 &&
|
||||
str[str.length-1] === ")") {
|
||||
|
@ -944,9 +945,9 @@ EpubCFI.prototype.isCfiString = function(str) {
|
|||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id) {
|
||||
generateChapterComponent(_spineNodeIndex, _pos, id) {
|
||||
var pos = parseInt(_pos),
|
||||
spineNodeIndex = _spineNodeIndex + 1,
|
||||
cfi = '/'+spineNodeIndex+'/';
|
||||
|
@ -958,6 +959,7 @@ EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id)
|
|||
}
|
||||
|
||||
return cfi;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = EpubCFI;
|
||||
export default EpubCFI;
|
||||
|
|
31
src/hook.js
31
src/hook.js
|
@ -5,16 +5,17 @@
|
|||
* @param {any} context scope of this
|
||||
* @example this.content = new EPUBJS.Hook(this);
|
||||
*/
|
||||
function Hook(context){
|
||||
class Hook {
|
||||
constructor(context){
|
||||
this.context = context || this;
|
||||
this.hooks = [];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Adds a function to be run before a hook completes
|
||||
* @example this.content.register(function(){...});
|
||||
*/
|
||||
Hook.prototype.register = function(){
|
||||
register(){
|
||||
for(var i = 0; i < arguments.length; ++i) {
|
||||
if (typeof arguments[i] === "function") {
|
||||
this.hooks.push(arguments[i]);
|
||||
|
@ -25,13 +26,13 @@ Hook.prototype.register = function(){
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Triggers a hook to run all functions
|
||||
* @example this.content.trigger(args).then(function(){...});
|
||||
*/
|
||||
Hook.prototype.trigger = function(){
|
||||
trigger(){
|
||||
var args = arguments;
|
||||
var context = this.context;
|
||||
var promises = [];
|
||||
|
@ -48,15 +49,15 @@ Hook.prototype.trigger = function(){
|
|||
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
};
|
||||
|
||||
// Adds a function to be run before a hook completes
|
||||
Hook.prototype.list = function(){
|
||||
// Adds a function to be run before a hook completes
|
||||
list(){
|
||||
return this.hooks;
|
||||
};
|
||||
};
|
||||
|
||||
Hook.prototype.clear = function(){
|
||||
clear(){
|
||||
return this.hooks = [];
|
||||
};
|
||||
|
||||
module.exports = Hook;
|
||||
};
|
||||
}
|
||||
export default Hook;
|
||||
|
|
15
src/index.js
Normal file
15
src/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import Book from './book';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Rendition from './rendition';
|
||||
import Contents from './contents';
|
||||
import Layout from './layout';
|
||||
import ePub from './epub';
|
||||
|
||||
export default ePub;
|
||||
export {
|
||||
Book,
|
||||
EpubCFI,
|
||||
Rendition,
|
||||
Contents,
|
||||
Layout
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
var core = require('./core');
|
||||
import core from './utils/core';
|
||||
|
||||
/**
|
||||
* Figures out the CSS to apply for a layout
|
||||
|
@ -9,7 +9,8 @@ var core = require('./core');
|
|||
* @param {[int=800]} settings.minSpreadWidth
|
||||
* @param {[boolean=false]} settings.evenSpreads
|
||||
*/
|
||||
function Layout(settings){
|
||||
class Layout {
|
||||
constructor(settings) {
|
||||
this.name = settings.layout || "reflowable";
|
||||
this._spread = (settings.spread === "none") ? false : true;
|
||||
this._minSpreadWidth = settings.minSpreadWidth || 800;
|
||||
|
@ -31,38 +32,38 @@ function Layout(settings){
|
|||
this.columnWidth = 0;
|
||||
this.gap = 0;
|
||||
this.divisor = 1;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Switch the flow between paginated and scrolled
|
||||
* @param {string} flow paginated | scrolled
|
||||
*/
|
||||
Layout.prototype.flow = function(flow) {
|
||||
flow(flow) {
|
||||
this._flow = (flow === "paginated") ? "paginated" : "scrolled";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Switch between using spreads or not, and set the
|
||||
* width at which they switch to single.
|
||||
* @param {string} spread true | false
|
||||
* @param {boolean} min integer in pixels
|
||||
*/
|
||||
Layout.prototype.spread = function(spread, min) {
|
||||
spread(spread, min) {
|
||||
|
||||
this._spread = (spread === "none") ? false : true;
|
||||
|
||||
if (min >= 0) {
|
||||
this._minSpreadWidth = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Calculate the dimensions of the pagination
|
||||
* @param {number} _width [description]
|
||||
* @param {number} _height [description]
|
||||
* @param {number} _gap [description]
|
||||
*/
|
||||
Layout.prototype.calculate = function(_width, _height, _gap){
|
||||
calculate(_width, _height, _gap){
|
||||
|
||||
var divisor = 1;
|
||||
var gap = _gap || 0;
|
||||
|
@ -114,14 +115,14 @@ Layout.prototype.calculate = function(_width, _height, _gap){
|
|||
this.columnWidth = colWidth;
|
||||
this.gap = gap;
|
||||
this.divisor = divisor;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Apply Css to a Document
|
||||
* @param {Contents} contents
|
||||
* @return {[Promise]}
|
||||
*/
|
||||
Layout.prototype.format = function(contents){
|
||||
format(contents){
|
||||
var formating;
|
||||
|
||||
if (this.name === "pre-paginated") {
|
||||
|
@ -133,15 +134,15 @@ Layout.prototype.format = function(contents){
|
|||
}
|
||||
|
||||
return formating; // might be a promise in some View Managers
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Count number of pages
|
||||
* @param {number} totalWidth
|
||||
* @return {number} spreads
|
||||
* @return {number} pages
|
||||
*/
|
||||
Layout.prototype.count = function(totalWidth) {
|
||||
count(totalWidth) {
|
||||
// var totalWidth = contents.scrollWidth();
|
||||
var spreads = Math.ceil( totalWidth / this.spreadWidth);
|
||||
|
||||
|
@ -149,6 +150,7 @@ Layout.prototype.count = function(totalWidth) {
|
|||
spreads : spreads,
|
||||
pages : spreads * this.divisor
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Layout;
|
||||
export default Layout;
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
var core = require('./core');
|
||||
var Queue = require('./queue');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var EventEmitter = require('event-emitter');
|
||||
import {qs, sprint, locationOf} from './utils/core';
|
||||
import Queue from './queue';
|
||||
import EpubCFI from './epubcfi';
|
||||
import EventEmitter from 'event-emitter';
|
||||
|
||||
/**
|
||||
* Find Locations for a Book
|
||||
* @param {Spine} spine
|
||||
* @param {request} request
|
||||
*/
|
||||
function Locations(spine, request) {
|
||||
class Locations {
|
||||
constructor(spine, request) {
|
||||
this.spine = spine;
|
||||
this.request = request;
|
||||
|
||||
|
@ -22,14 +23,14 @@ function Locations(spine, request) {
|
|||
|
||||
this._current = 0;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Load all of sections in the book to generate locations
|
||||
* @param {int} chars how many chars to split on
|
||||
* @return {object} locations
|
||||
*/
|
||||
Locations.prototype.generate = function(chars) {
|
||||
generate(chars) {
|
||||
|
||||
if (chars) {
|
||||
this.break = chars;
|
||||
|
@ -54,18 +55,18 @@ Locations.prototype.generate = function(chars) {
|
|||
// console.log(this.percentage(this.book.rendition.location.start), this.percentage(this.book.rendition.location.end));
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.createRange = function () {
|
||||
createRange () {
|
||||
return {
|
||||
startContainer: undefined,
|
||||
startOffset: undefined,
|
||||
endContainer: undefined,
|
||||
endOffset: undefined
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.process = function(section) {
|
||||
process(section) {
|
||||
|
||||
return section.load(this.request)
|
||||
.then(function(contents) {
|
||||
|
@ -73,13 +74,13 @@ Locations.prototype.process = function(section) {
|
|||
this._locations = this._locations.concat(locations);
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.parse = function(contents, cfiBase, chars) {
|
||||
parse(contents, cfiBase, chars) {
|
||||
var locations = [];
|
||||
var range;
|
||||
var doc = contents.ownerDocument;
|
||||
var body = core.qs(doc, 'body');
|
||||
var body = qs(doc, 'body');
|
||||
var counter = 0;
|
||||
var prev;
|
||||
var _break = chars || this.break;
|
||||
|
@ -121,7 +122,7 @@ Locations.prototype.parse = function(contents, cfiBase, chars) {
|
|||
range.endContainer = node;
|
||||
range.endOffset = pos;
|
||||
// cfi = section.cfiFromRange(range);
|
||||
cfi = new EpubCFI(range, cfiBase).toString();
|
||||
let cfi = new EpubCFI(range, cfiBase).toString();
|
||||
locations.push(cfi);
|
||||
counter = 0;
|
||||
|
||||
|
@ -137,30 +138,30 @@ Locations.prototype.parse = function(contents, cfiBase, chars) {
|
|||
prev = node;
|
||||
};
|
||||
|
||||
core.sprint(body, parser.bind(this));
|
||||
sprint(body, parser.bind(this));
|
||||
|
||||
// Close remaining
|
||||
if (range && range.startContainer && prev) {
|
||||
range.endContainer = prev;
|
||||
range.endOffset = prev.length;
|
||||
// cfi = section.cfiFromRange(range);
|
||||
cfi = new EpubCFI(range, cfiBase).toString();
|
||||
let cfi = new EpubCFI(range, cfiBase).toString();
|
||||
locations.push(cfi);
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
return locations;
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.locationFromCfi = function(cfi){
|
||||
locationFromCfi(cfi){
|
||||
// Check if the location has not been set yet
|
||||
if(this._locations.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
return core.locationOf(cfi.start, this._locations, this.epubcfi.compare);
|
||||
};
|
||||
return locationOf(cfi.start, this._locations, this.epubcfi.compare);
|
||||
};
|
||||
|
||||
Locations.prototype.percentageFromCfi = function(cfi) {
|
||||
percentageFromCfi(cfi) {
|
||||
if(this._locations.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -168,16 +169,16 @@ Locations.prototype.percentageFromCfi = function(cfi) {
|
|||
var loc = this.locationFromCfi(cfi);
|
||||
// Get percentage in total
|
||||
return this.percentageFromLocation(loc);
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.percentageFromLocation = function(loc) {
|
||||
percentageFromLocation(loc) {
|
||||
if (!loc || !this.total) {
|
||||
return 0;
|
||||
}
|
||||
return (loc / this.total);
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.cfiFromLocation = function(loc){
|
||||
cfiFromLocation(loc){
|
||||
var cfi = -1;
|
||||
// check that pg is an int
|
||||
if(typeof loc != "number"){
|
||||
|
@ -189,30 +190,30 @@ Locations.prototype.cfiFromLocation = function(loc){
|
|||
}
|
||||
|
||||
return cfi;
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.cfiFromPercentage = function(value){
|
||||
cfiFromPercentage(value){
|
||||
var percentage = (value > 1) ? value / 100 : value; // Normalize value to 0-1
|
||||
var loc = Math.ceil(this.total * percentage);
|
||||
|
||||
return this.cfiFromLocation(loc);
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.load = function(locations){
|
||||
load(locations){
|
||||
this._locations = JSON.parse(locations);
|
||||
this.total = this._locations.length-1;
|
||||
return this._locations;
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.save = function(json){
|
||||
save(json){
|
||||
return JSON.stringify(this._locations);
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.getCurrent = function(json){
|
||||
getCurrent(json){
|
||||
return this._current;
|
||||
};
|
||||
};
|
||||
|
||||
Locations.prototype.setCurrent = function(curr){
|
||||
setCurrent(curr){
|
||||
var loc;
|
||||
|
||||
if(typeof curr == "string"){
|
||||
|
@ -237,21 +238,21 @@ Locations.prototype.setCurrent = function(curr){
|
|||
this.emit("changed", {
|
||||
percentage: this.percentageFromLocation(loc)
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Object.defineProperty(Locations.prototype, 'currentLocation', {
|
||||
get: function () {
|
||||
get currentLocation() {
|
||||
return this._current;
|
||||
},
|
||||
set: function (curr) {
|
||||
}
|
||||
|
||||
set currentLocation(curr) {
|
||||
this.setCurrent(curr);
|
||||
}
|
||||
});
|
||||
|
||||
Locations.prototype.length = function () {
|
||||
length () {
|
||||
return this._locations.length;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
EventEmitter(Locations.prototype);
|
||||
|
||||
module.exports = Locations;
|
||||
export default Locations;
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
var core = require('../../core');
|
||||
var DefaultViewManager = require('../default');
|
||||
import {extend, defer, requestAnimationFrame} from '../../utils/core';
|
||||
import DefaultViewManager from '../default';
|
||||
|
||||
function ContinuousViewManager(options) {
|
||||
|
||||
DefaultViewManager.apply(this, arguments); // call super constructor.
|
||||
class ContinuousViewManager extends DefaultViewManager {
|
||||
constructor(options) {
|
||||
super(options)
|
||||
// DefaultViewManager.apply(this, arguments); // call super constructor.
|
||||
|
||||
this.name = "continuous";
|
||||
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
this.settings = extend(this.settings || {}, {
|
||||
infinite: true,
|
||||
overflow: "auto",
|
||||
axis: "vertical",
|
||||
|
@ -17,7 +18,7 @@ function ContinuousViewManager(options) {
|
|||
height: undefined
|
||||
});
|
||||
|
||||
core.extend(this.settings, options.settings || {});
|
||||
extend(this.settings, options.settings || {});
|
||||
|
||||
// Gap can be 0, byt defaults doesn't handle that
|
||||
if (options.settings.gap != "undefined" && options.settings.gap === 0) {
|
||||
|
@ -35,21 +36,17 @@ function ContinuousViewManager(options) {
|
|||
|
||||
this.scrollTop = 0;
|
||||
this.scrollLeft = 0;
|
||||
};
|
||||
};
|
||||
|
||||
// subclass extends superclass
|
||||
ContinuousViewManager.prototype = Object.create(DefaultViewManager.prototype);
|
||||
ContinuousViewManager.prototype.constructor = ContinuousViewManager;
|
||||
|
||||
ContinuousViewManager.prototype.display = function(section, target){
|
||||
display(section, target){
|
||||
return DefaultViewManager.prototype.display.call(this, section, target)
|
||||
.then(function () {
|
||||
return this.fill();
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.fill = function(_full){
|
||||
var full = _full || new core.defer();
|
||||
fill(_full){
|
||||
var full = _full || new defer();
|
||||
|
||||
this.check().then(function(result) {
|
||||
if (result) {
|
||||
|
@ -60,9 +57,9 @@ ContinuousViewManager.prototype.fill = function(_full){
|
|||
}.bind(this));
|
||||
|
||||
return full.promise;
|
||||
}
|
||||
}
|
||||
|
||||
ContinuousViewManager.prototype.moveTo = function(offset){
|
||||
moveTo(offset){
|
||||
// var bounds = this.stage.bounds();
|
||||
// var dist = Math.floor(offset.top / bounds.height) * bounds.height;
|
||||
var distX = 0,
|
||||
|
@ -83,10 +80,10 @@ ContinuousViewManager.prototype.moveTo = function(offset){
|
|||
.then(function(){
|
||||
this.scrollBy(distX, distY);
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
ContinuousViewManager.prototype.afterDisplayed = function(currView){
|
||||
/*
|
||||
afterDisplayed(currView){
|
||||
var next = currView.section.next();
|
||||
var prev = currView.section.prev();
|
||||
var index = this.views.indexOf(currView);
|
||||
|
@ -106,10 +103,10 @@ ContinuousViewManager.prototype.afterDisplayed = function(currView){
|
|||
// currView.onShown = this.afterDisplayed.bind(this);
|
||||
this.emit("added", currView.section);
|
||||
|
||||
};
|
||||
*/
|
||||
};
|
||||
*/
|
||||
|
||||
ContinuousViewManager.prototype.resize = function(width, height){
|
||||
resize(width, height){
|
||||
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
|
@ -137,9 +134,9 @@ ContinuousViewManager.prototype.resize = function(width, height){
|
|||
height: this.stage.height
|
||||
});
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.onResized = function(e) {
|
||||
onResized(e) {
|
||||
|
||||
// this.views.clear();
|
||||
|
||||
|
@ -147,56 +144,56 @@ ContinuousViewManager.prototype.onResized = function(e) {
|
|||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.afterResized = function(view){
|
||||
afterResized(view){
|
||||
this.emit("resize", view.section);
|
||||
};
|
||||
};
|
||||
|
||||
// Remove Previous Listeners if present
|
||||
ContinuousViewManager.prototype.removeShownListeners = function(view){
|
||||
// Remove Previous Listeners if present
|
||||
removeShownListeners(view){
|
||||
|
||||
// view.off("shown", this.afterDisplayed);
|
||||
// view.off("shown", this.afterDisplayedAbove);
|
||||
view.onDisplayed = function(){};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// ContinuousViewManager.prototype.append = function(section){
|
||||
// return this.q.enqueue(function() {
|
||||
//
|
||||
// this._append(section);
|
||||
//
|
||||
//
|
||||
// }.bind(this));
|
||||
// };
|
||||
//
|
||||
// ContinuousViewManager.prototype.prepend = function(section){
|
||||
// return this.q.enqueue(function() {
|
||||
//
|
||||
// this._prepend(section);
|
||||
//
|
||||
// }.bind(this));
|
||||
//
|
||||
// };
|
||||
// append(section){
|
||||
// return this.q.enqueue(function() {
|
||||
//
|
||||
// this._append(section);
|
||||
//
|
||||
//
|
||||
// }.bind(this));
|
||||
// };
|
||||
//
|
||||
// prepend(section){
|
||||
// return this.q.enqueue(function() {
|
||||
//
|
||||
// this._prepend(section);
|
||||
//
|
||||
// }.bind(this));
|
||||
//
|
||||
// };
|
||||
|
||||
ContinuousViewManager.prototype.append = function(section){
|
||||
append(section){
|
||||
var view = this.createView(section);
|
||||
this.views.append(view);
|
||||
return view;
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.prepend = function(section){
|
||||
prepend(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
view.on("resized", this.counter.bind(this));
|
||||
|
||||
this.views.prepend(view);
|
||||
return view;
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.counter = function(bounds){
|
||||
counter(bounds){
|
||||
|
||||
if(this.settings.axis === "vertical") {
|
||||
this.scrollBy(0, bounds.heightDelta, true);
|
||||
|
@ -204,9 +201,9 @@ ContinuousViewManager.prototype.counter = function(bounds){
|
|||
this.scrollBy(bounds.widthDelta, 0, true);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.update = function(_offset){
|
||||
update(_offset){
|
||||
var container = this.bounds();
|
||||
var views = this.views.all();
|
||||
var viewsLength = views.length;
|
||||
|
@ -215,7 +212,7 @@ ContinuousViewManager.prototype.update = function(_offset){
|
|||
var isVisible;
|
||||
var view;
|
||||
|
||||
var updating = new core.defer();
|
||||
var updating = new defer();
|
||||
var promises = [];
|
||||
|
||||
for (var i = 0; i < viewsLength; i++) {
|
||||
|
@ -248,12 +245,12 @@ ContinuousViewManager.prototype.update = function(_offset){
|
|||
return updating.promise;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.check = function(_offsetLeft, _offsetTop){
|
||||
check(_offsetLeft, _offsetTop){
|
||||
var last, first, next, prev;
|
||||
|
||||
var checking = new core.defer();
|
||||
var checking = new defer();
|
||||
var newViews = [];
|
||||
|
||||
var horizontal = (this.settings.axis === "horizontal");
|
||||
|
@ -306,10 +303,10 @@ ContinuousViewManager.prototype.check = function(_offsetLeft, _offsetTop){
|
|||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.trim = function(){
|
||||
var task = new core.defer();
|
||||
trim(){
|
||||
var task = new defer();
|
||||
var displayed = this.views.displayed();
|
||||
var first = displayed[0];
|
||||
var last = displayed[displayed.length-1];
|
||||
|
@ -330,9 +327,9 @@ ContinuousViewManager.prototype.trim = function(){
|
|||
|
||||
task.resolve();
|
||||
return task.promise;
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.erase = function(view, above){ //Trim
|
||||
erase(view, above){ //Trim
|
||||
|
||||
var prevTop;
|
||||
var prevLeft;
|
||||
|
@ -358,9 +355,9 @@ ContinuousViewManager.prototype.erase = function(view, above){ //Trim
|
|||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.addEventListeners = function(stage){
|
||||
addEventListeners(stage){
|
||||
|
||||
window.addEventListener('unload', function(e){
|
||||
this.ignore = true;
|
||||
|
@ -369,12 +366,12 @@ ContinuousViewManager.prototype.addEventListeners = function(stage){
|
|||
}.bind(this));
|
||||
|
||||
this.addScrollListeners();
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.addScrollListeners = function() {
|
||||
addScrollListeners() {
|
||||
var scroller;
|
||||
|
||||
this.tick = core.requestAnimationFrame;
|
||||
this.tick = requestAnimationFrame;
|
||||
|
||||
if(this.settings.height) {
|
||||
this.prevScrollTop = this.container.scrollTop;
|
||||
|
@ -403,9 +400,11 @@ ContinuousViewManager.prototype.addScrollListeners = function() {
|
|||
|
||||
this.scrolled = false;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.onScroll = function(){
|
||||
onScroll(){
|
||||
let scrollTop;
|
||||
let scrollLeft;
|
||||
|
||||
// if(!this.ignore) {
|
||||
|
||||
|
@ -472,20 +471,20 @@ ContinuousViewManager.prototype.onScroll = function(){
|
|||
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// ContinuousViewManager.prototype.resizeView = function(view) {
|
||||
//
|
||||
// if(this.settings.axis === "horizontal") {
|
||||
// view.lock("height", this.stage.width, this.stage.height);
|
||||
// } else {
|
||||
// view.lock("width", this.stage.width, this.stage.height);
|
||||
// }
|
||||
//
|
||||
// };
|
||||
// resizeView(view) {
|
||||
//
|
||||
// if(this.settings.axis === "horizontal") {
|
||||
// view.lock("height", this.stage.width, this.stage.height);
|
||||
// } else {
|
||||
// view.lock("width", this.stage.width, this.stage.height);
|
||||
// }
|
||||
//
|
||||
// };
|
||||
|
||||
ContinuousViewManager.prototype.currentLocation = function(){
|
||||
currentLocation(){
|
||||
|
||||
if (this.settings.axis === "vertical") {
|
||||
this.location = this.scrolledLocation();
|
||||
|
@ -494,9 +493,9 @@ ContinuousViewManager.prototype.currentLocation = function(){
|
|||
}
|
||||
|
||||
return this.location;
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.scrolledLocation = function(){
|
||||
scrolledLocation(){
|
||||
|
||||
var visible = this.visible();
|
||||
var startPage, endPage;
|
||||
|
@ -518,9 +517,9 @@ ContinuousViewManager.prototype.scrolledLocation = function(){
|
|||
};
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.paginatedLocation = function(){
|
||||
paginatedLocation(){
|
||||
var visible = this.visible();
|
||||
var startA, startB, endA, endB;
|
||||
var pageLeft, pageRight;
|
||||
|
@ -551,10 +550,10 @@ ContinuousViewManager.prototype.paginatedLocation = function(){
|
|||
end: pageRight.end
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Continuous.prototype.current = function(what){
|
||||
/*
|
||||
current(what){
|
||||
var view, top;
|
||||
var container = this.container.getBoundingClientRect();
|
||||
var length = this.views.length - 1;
|
||||
|
@ -596,10 +595,10 @@ Continuous.prototype.current = function(what){
|
|||
}
|
||||
|
||||
return this._current;
|
||||
};
|
||||
*/
|
||||
};
|
||||
*/
|
||||
|
||||
ContinuousViewManager.prototype.updateLayout = function() {
|
||||
updateLayout() {
|
||||
|
||||
if (!this.stage) {
|
||||
return;
|
||||
|
@ -627,9 +626,9 @@ ContinuousViewManager.prototype.updateLayout = function() {
|
|||
|
||||
this.setLayout(this.layout);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.next = function(){
|
||||
next(){
|
||||
|
||||
if(this.settings.axis === "horizontal") {
|
||||
|
||||
|
@ -646,17 +645,17 @@ ContinuousViewManager.prototype.next = function(){
|
|||
} else {
|
||||
this.scrollBy(0, this.layout.height);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.prev = function(){
|
||||
prev(){
|
||||
if(this.settings.axis === "horizontal") {
|
||||
this.scrollBy(-this.layout.delta, 0);
|
||||
} else {
|
||||
this.scrollBy(0, -this.layout.height);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.updateFlow = function(flow){
|
||||
updateFlow(flow){
|
||||
var axis = (flow === "paginated") ? "horizontal" : "vertical";
|
||||
|
||||
this.settings.axis = axis;
|
||||
|
@ -675,5 +674,7 @@ ContinuousViewManager.prototype.updateFlow = function(flow){
|
|||
this.settings.infinite = false;
|
||||
}
|
||||
|
||||
};
|
||||
module.exports = ContinuousViewManager;
|
||||
};
|
||||
}
|
||||
|
||||
export default ContinuousViewManager;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var core = require('../../core');
|
||||
var EpubCFI = require('../../epubcfi');
|
||||
var Mapping = require('../../mapping');
|
||||
var Queue = require('../../queue');
|
||||
var Stage = require('../helpers/stage');
|
||||
var Views = require('../helpers/views');
|
||||
import EventEmitter from 'event-emitter';
|
||||
import {extend, defer} from '../../utils/core';
|
||||
import EpubCFI from '../../epubcfi';
|
||||
import Mapping from '../../mapping';
|
||||
import Queue from '../../queue';
|
||||
import Stage from '../helpers/stage';
|
||||
import Views from '../helpers/views';
|
||||
|
||||
function DefaultViewManager(options) {
|
||||
class DefaultViewManager {
|
||||
constructor(options) {
|
||||
|
||||
this.name = "default";
|
||||
this.View = options.view;
|
||||
|
@ -14,7 +15,7 @@ function DefaultViewManager(options) {
|
|||
this.renditionQueue = options.queue;
|
||||
this.q = new Queue(this);
|
||||
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
this.settings = extend(this.settings || {}, {
|
||||
infinite: true,
|
||||
hidden: false,
|
||||
width: undefined,
|
||||
|
@ -25,7 +26,7 @@ function DefaultViewManager(options) {
|
|||
ignoreClass: ''
|
||||
});
|
||||
|
||||
core.extend(this.settings, options.settings || {});
|
||||
extend(this.settings, options.settings || {});
|
||||
|
||||
this.viewSettings = {
|
||||
ignoreClass: this.settings.ignoreClass,
|
||||
|
@ -35,9 +36,9 @@ function DefaultViewManager(options) {
|
|||
height: 0
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DefaultViewManager.prototype.render = function(element, size){
|
||||
render(element, size){
|
||||
|
||||
// Save the stage
|
||||
this.stage = new Stage({
|
||||
|
@ -76,15 +77,15 @@ DefaultViewManager.prototype.render = function(element, size){
|
|||
if (this.layout) {
|
||||
this.updateLayout();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.addEventListeners = function(){
|
||||
addEventListeners(){
|
||||
window.addEventListener('unload', function(e){
|
||||
this.destroy();
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.destroy = function(){
|
||||
destroy(){
|
||||
// this.views.each(function(view){
|
||||
// view.destroy();
|
||||
// });
|
||||
|
@ -98,16 +99,16 @@ DefaultViewManager.prototype.destroy = function(){
|
|||
this.element.removeChild(this.container);
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.onResized = function(e) {
|
||||
onResized(e) {
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.resize = function(width, height){
|
||||
resize(width, height){
|
||||
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
|
@ -131,15 +132,15 @@ DefaultViewManager.prototype.resize = function(width, height){
|
|||
height: this.stage.height
|
||||
});
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.createView = function(section) {
|
||||
createView(section) {
|
||||
return new this.View(section, this.viewSettings);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.display = function(section, target){
|
||||
display(section, target){
|
||||
|
||||
var displaying = new core.defer();
|
||||
var displaying = new defer();
|
||||
var displayed = displaying.promise;
|
||||
|
||||
// Check to make sure the section we want isn't already shown
|
||||
|
@ -192,21 +193,21 @@ DefaultViewManager.prototype.display = function(section, target){
|
|||
// this.views.show();
|
||||
// }.bind(this));
|
||||
return displayed;
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.afterDisplayed = function(view){
|
||||
afterDisplayed(view){
|
||||
this.emit("added", view);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.afterResized = function(view){
|
||||
afterResized(view){
|
||||
this.emit("resize", view.section);
|
||||
};
|
||||
};
|
||||
|
||||
// DefaultViewManager.prototype.moveTo = function(offset){
|
||||
// this.scrollTo(offset.left, offset.top);
|
||||
// };
|
||||
// moveTo(offset){
|
||||
// this.scrollTo(offset.left, offset.top);
|
||||
// };
|
||||
|
||||
DefaultViewManager.prototype.moveTo = function(offset){
|
||||
moveTo(offset){
|
||||
var distX = 0,
|
||||
distY = 0;
|
||||
|
||||
|
@ -221,9 +222,9 @@ DefaultViewManager.prototype.moveTo = function(offset){
|
|||
}
|
||||
|
||||
this.scrollTo(distX, distY);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.add = function(section){
|
||||
add(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
this.views.append(view);
|
||||
|
@ -234,31 +235,31 @@ DefaultViewManager.prototype.add = function(section){
|
|||
|
||||
return view.display(this.request);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.append = function(section){
|
||||
append(section){
|
||||
var view = this.createView(section);
|
||||
this.views.append(view);
|
||||
return view.display(this.request);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.prepend = function(section){
|
||||
prepend(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
this.views.prepend(view);
|
||||
return view.display(this.request);
|
||||
};
|
||||
// DefaultViewManager.prototype.resizeView = function(view) {
|
||||
//
|
||||
// if(this.settings.globalLayoutProperties.layout === "pre-paginated") {
|
||||
// view.lock("both", this.bounds.width, this.bounds.height);
|
||||
// } else {
|
||||
// view.lock("width", this.bounds.width, this.bounds.height);
|
||||
// }
|
||||
//
|
||||
// };
|
||||
};
|
||||
// resizeView(view) {
|
||||
//
|
||||
// if(this.settings.globalLayoutProperties.layout === "pre-paginated") {
|
||||
// view.lock("both", this.bounds.width, this.bounds.height);
|
||||
// } else {
|
||||
// view.lock("width", this.bounds.width, this.bounds.height);
|
||||
// }
|
||||
//
|
||||
// };
|
||||
|
||||
DefaultViewManager.prototype.next = function(){
|
||||
next(){
|
||||
var next;
|
||||
var view;
|
||||
var left;
|
||||
|
@ -305,9 +306,9 @@ DefaultViewManager.prototype.next = function(){
|
|||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.prev = function(){
|
||||
prev(){
|
||||
var prev;
|
||||
var view;
|
||||
var left;
|
||||
|
@ -353,18 +354,18 @@ DefaultViewManager.prototype.prev = function(){
|
|||
this.views.show();
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.current = function(){
|
||||
current(){
|
||||
var visible = this.visible();
|
||||
if(visible.length){
|
||||
// Current is the last visible view
|
||||
return visible[visible.length-1];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.currentLocation = function(){
|
||||
currentLocation(){
|
||||
|
||||
if (this.settings.axis === "vertical") {
|
||||
this.location = this.scrolledLocation();
|
||||
|
@ -372,9 +373,9 @@ DefaultViewManager.prototype.currentLocation = function(){
|
|||
this.location = this.paginatedLocation();
|
||||
}
|
||||
return this.location;
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.scrolledLocation = function(){
|
||||
scrolledLocation(){
|
||||
var view;
|
||||
|
||||
if(this.views.length) {
|
||||
|
@ -382,9 +383,9 @@ DefaultViewManager.prototype.scrolledLocation = function(){
|
|||
return this.mapping.page(view, view.section.cfiBase);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.paginatedLocation = function(){
|
||||
paginatedLocation(){
|
||||
var view;
|
||||
var start, end;
|
||||
|
||||
|
@ -395,9 +396,9 @@ DefaultViewManager.prototype.paginatedLocation = function(){
|
|||
return this.mapping.page(view, view.section.cfiBase, start, end);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.isVisible = function(view, offsetPrev, offsetNext, _container){
|
||||
isVisible(view, offsetPrev, offsetNext, _container){
|
||||
var position = view.position();
|
||||
var container = _container || this.bounds();
|
||||
|
||||
|
@ -416,9 +417,9 @@ DefaultViewManager.prototype.isVisible = function(view, offsetPrev, offsetNext,
|
|||
|
||||
return false;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.visible = function(){
|
||||
visible(){
|
||||
// return this.views.displayed();
|
||||
var container = this.bounds();
|
||||
var views = this.views.displayed();
|
||||
|
@ -437,9 +438,9 @@ DefaultViewManager.prototype.visible = function(){
|
|||
|
||||
}
|
||||
return visible;
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.scrollBy = function(x, y, silent){
|
||||
scrollBy(x, y, silent){
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
|
@ -455,9 +456,9 @@ DefaultViewManager.prototype.scrollBy = function(x, y, silent){
|
|||
// console.log("scrollBy", x, y);
|
||||
this.scrolled = true;
|
||||
this.onScroll();
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.scrollTo = function(x, y, silent){
|
||||
scrollTo(x, y, silent){
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
|
@ -479,28 +480,28 @@ DefaultViewManager.prototype.scrollTo = function(x, y, silent){
|
|||
// };
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.onScroll = function(){
|
||||
onScroll(){
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.bounds = function() {
|
||||
bounds() {
|
||||
var bounds;
|
||||
|
||||
bounds = this.stage.bounds();
|
||||
|
||||
return bounds;
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.applyLayout = function(layout) {
|
||||
applyLayout(layout) {
|
||||
|
||||
this.layout = layout;
|
||||
this.updateLayout();
|
||||
|
||||
this.mapping = new Mapping(this.layout);
|
||||
// this.manager.layout(this.layout.format);
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.updateLayout = function() {
|
||||
updateLayout() {
|
||||
if (!this.stage) {
|
||||
return;
|
||||
}
|
||||
|
@ -529,9 +530,9 @@ DefaultViewManager.prototype.updateLayout = function() {
|
|||
|
||||
this.setLayout(this.layout);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.setLayout = function(layout){
|
||||
setLayout(layout){
|
||||
|
||||
this.viewSettings.layout = layout;
|
||||
|
||||
|
@ -543,9 +544,9 @@ DefaultViewManager.prototype.setLayout = function(layout){
|
|||
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.updateFlow = function(flow){
|
||||
updateFlow(flow){
|
||||
var axis = (flow === "paginated") ? "horizontal" : "vertical";
|
||||
|
||||
this.settings.axis = axis;
|
||||
|
@ -557,17 +558,18 @@ DefaultViewManager.prototype.updateFlow = function(flow){
|
|||
// view.setAxis(axis);
|
||||
// });
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
DefaultViewManager.prototype.getContents = function(){
|
||||
getContents(){
|
||||
var contents = [];
|
||||
this.views.each(function(view){
|
||||
contents.push(view.contents);
|
||||
});
|
||||
return contents;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
//-- Enable binding events to Manager
|
||||
EventEmitter(DefaultViewManager.prototype);
|
||||
|
||||
module.exports = DefaultViewManager;
|
||||
export default DefaultViewManager;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
var core = require('../../core');
|
||||
import {uuid, isNumber, isElement, windowBounds} from '../../utils/core';
|
||||
|
||||
function Stage(_options) {
|
||||
class Stage {
|
||||
constructor(_options) {
|
||||
this.settings = _options || {};
|
||||
this.id = "epubjs-container-" + core.uuid();
|
||||
this.id = "epubjs-container-" + uuid();
|
||||
|
||||
this.container = this.create(this.settings);
|
||||
|
||||
|
@ -10,28 +11,28 @@ function Stage(_options) {
|
|||
this.wrapper = this.wrap(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an element to render to.
|
||||
* Resizes to passed width and height or to the elements size
|
||||
*/
|
||||
Stage.prototype.create = function(options){
|
||||
/*
|
||||
* Creates an element to render to.
|
||||
* Resizes to passed width and height or to the elements size
|
||||
*/
|
||||
create(options){
|
||||
var height = options.height;// !== false ? options.height : "100%";
|
||||
var width = options.width;// !== false ? options.width : "100%";
|
||||
var overflow = options.overflow || false;
|
||||
var axis = options.axis || "vertical";
|
||||
|
||||
if(options.height && core.isNumber(options.height)) {
|
||||
if(options.height && isNumber(options.height)) {
|
||||
height = options.height + "px";
|
||||
}
|
||||
|
||||
if(options.width && core.isNumber(options.width)) {
|
||||
if(options.width && isNumber(options.width)) {
|
||||
width = options.width + "px";
|
||||
}
|
||||
|
||||
// Create new container element
|
||||
container = document.createElement("div");
|
||||
let container = document.createElement("div");
|
||||
|
||||
container.id = this.id;
|
||||
container.classList.add("epub-container");
|
||||
|
@ -59,9 +60,9 @@ Stage.prototype.create = function(options){
|
|||
}
|
||||
|
||||
return container;
|
||||
};
|
||||
};
|
||||
|
||||
Stage.wrap = function(container) {
|
||||
wrap(container) {
|
||||
var wrapper = document.createElement("div");
|
||||
|
||||
wrapper.style.visibility = "hidden";
|
||||
|
@ -71,13 +72,13 @@ Stage.wrap = function(container) {
|
|||
|
||||
wrapper.appendChild(container);
|
||||
return wrapper;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Stage.prototype.getElement = function(_element){
|
||||
getElement(_element){
|
||||
var element;
|
||||
|
||||
if(core.isElement(_element)) {
|
||||
if(isElement(_element)) {
|
||||
element = _element;
|
||||
} else if (typeof _element === "string") {
|
||||
element = document.getElementById(_element);
|
||||
|
@ -89,9 +90,9 @@ Stage.prototype.getElement = function(_element){
|
|||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
};
|
||||
|
||||
Stage.prototype.attachTo = function(what){
|
||||
attachTo(what){
|
||||
|
||||
var element = this.getElement(what);
|
||||
var base;
|
||||
|
@ -112,23 +113,23 @@ Stage.prototype.attachTo = function(what){
|
|||
|
||||
return element;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Stage.prototype.getContainer = function() {
|
||||
getContainer() {
|
||||
return this.container;
|
||||
};
|
||||
};
|
||||
|
||||
Stage.prototype.onResize = function(func){
|
||||
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(!core.isNumber(this.settings.width) ||
|
||||
!core.isNumber(this.settings.height) ) {
|
||||
if(!isNumber(this.settings.width) ||
|
||||
!isNumber(this.settings.height) ) {
|
||||
window.addEventListener("resize", func, false);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Stage.prototype.size = function(width, height){
|
||||
size(width, height){
|
||||
var bounds;
|
||||
// var width = _width || this.settings.width;
|
||||
// var height = _height || this.settings.height;
|
||||
|
@ -153,13 +154,13 @@ Stage.prototype.size = function(width, height){
|
|||
|
||||
}
|
||||
|
||||
if(!core.isNumber(width)) {
|
||||
if(!isNumber(width)) {
|
||||
bounds = this.container.getBoundingClientRect();
|
||||
width = bounds.width;
|
||||
//height = bounds.height;
|
||||
}
|
||||
|
||||
if(!core.isNumber(height)) {
|
||||
if(!isNumber(height)) {
|
||||
bounds = bounds || this.container.getBoundingClientRect();
|
||||
//width = bounds.width;
|
||||
height = bounds.height;
|
||||
|
@ -184,19 +185,19 @@ Stage.prototype.size = function(width, height){
|
|||
this.containerPadding.bottom
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Stage.prototype.bounds = function(){
|
||||
bounds(){
|
||||
|
||||
if(!this.container) {
|
||||
return core.windowBounds();
|
||||
return windowBounds();
|
||||
} else {
|
||||
return this.container.getBoundingClientRect();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Stage.prototype.getSheet = function(){
|
||||
getSheet(){
|
||||
var style = document.createElement("style");
|
||||
|
||||
// WebKit hack --> https://davidwalsh.name/add-rules-stylesheets
|
||||
|
@ -205,9 +206,9 @@ Stage.prototype.getSheet = function(){
|
|||
document.head.appendChild(style);
|
||||
|
||||
return style.sheet;
|
||||
}
|
||||
}
|
||||
|
||||
Stage.prototype.addStyleRules = function(selector, rulesArray){
|
||||
addStyleRules(selector, rulesArray){
|
||||
var scope = "#" + this.id + " ";
|
||||
var rules = "";
|
||||
|
||||
|
@ -224,8 +225,7 @@ Stage.prototype.addStyleRules = function(selector, rulesArray){
|
|||
})
|
||||
|
||||
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = Stage;
|
||||
export default Stage;
|
||||
|
|
|
@ -1,53 +1,54 @@
|
|||
function Views(container) {
|
||||
class Views {
|
||||
constructor(container) {
|
||||
this.container = container;
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
this.hidden = false;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.all = function() {
|
||||
all() {
|
||||
return this._views;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.first = function() {
|
||||
first() {
|
||||
return this._views[0];
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.last = function() {
|
||||
last() {
|
||||
return this._views[this._views.length-1];
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.indexOf = function(view) {
|
||||
indexOf(view) {
|
||||
return this._views.indexOf(view);
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.slice = function() {
|
||||
slice() {
|
||||
return this._views.slice.apply(this._views, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.get = function(i) {
|
||||
get(i) {
|
||||
return this._views[i];
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.append = function(view){
|
||||
append(view){
|
||||
this._views.push(view);
|
||||
if(this.container){
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.prepend = function(view){
|
||||
prepend(view){
|
||||
this._views.unshift(view);
|
||||
if(this.container){
|
||||
this.container.insertBefore(view.element, this.container.firstChild);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.insert = function(view, index) {
|
||||
insert(view, index) {
|
||||
this._views.splice(index, 0, view);
|
||||
|
||||
if(this.container){
|
||||
|
@ -60,9 +61,9 @@ Views.prototype.insert = function(view, index) {
|
|||
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.remove = function(view) {
|
||||
remove(view) {
|
||||
var index = this._views.indexOf(view);
|
||||
|
||||
if(index > -1) {
|
||||
|
@ -73,9 +74,9 @@ Views.prototype.remove = function(view) {
|
|||
this.destroy(view);
|
||||
|
||||
this.length--;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.destroy = function(view) {
|
||||
destroy(view) {
|
||||
if(view.displayed){
|
||||
view.destroy();
|
||||
}
|
||||
|
@ -84,15 +85,15 @@ Views.prototype.destroy = function(view) {
|
|||
this.container.removeChild(view.element);
|
||||
}
|
||||
view = null;
|
||||
};
|
||||
};
|
||||
|
||||
// Iterators
|
||||
// Iterators
|
||||
|
||||
Views.prototype.each = function() {
|
||||
each() {
|
||||
return this._views.forEach.apply(this._views, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.clear = function(){
|
||||
clear(){
|
||||
// Remove all views
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
@ -106,9 +107,9 @@ Views.prototype.clear = function(){
|
|||
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.find = function(section){
|
||||
find(section){
|
||||
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
@ -120,9 +121,9 @@ Views.prototype.find = function(section){
|
|||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.displayed = function(){
|
||||
displayed(){
|
||||
var displayed = [];
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
@ -134,9 +135,9 @@ Views.prototype.displayed = function(){
|
|||
}
|
||||
}
|
||||
return displayed;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.show = function(){
|
||||
show(){
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
|
@ -147,9 +148,9 @@ Views.prototype.show = function(){
|
|||
}
|
||||
}
|
||||
this.hidden = false;
|
||||
};
|
||||
};
|
||||
|
||||
Views.prototype.hide = function(){
|
||||
hide(){
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
|
@ -160,6 +161,7 @@ Views.prototype.hide = function(){
|
|||
}
|
||||
}
|
||||
this.hidden = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Views;
|
||||
export default Views;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var core = require('../../core');
|
||||
var EpubCFI = require('../../epubcfi');
|
||||
var Contents = require('../../contents');
|
||||
import EventEmitter from 'event-emitter';
|
||||
import {extend, borders, uuid, isNumber, bounds, defer} from '../../utils/core';
|
||||
import EpubCFI from '../../epubcfi';
|
||||
import Contents from '../../contents';
|
||||
|
||||
function IframeView(section, options) {
|
||||
this.settings = core.extend({
|
||||
class IframeView {
|
||||
constructor(section, options) {
|
||||
this.settings = extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
|
@ -13,7 +14,7 @@ function IframeView(section, options) {
|
|||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
|
||||
this.id = "epubjs-view-" + core.uuid();
|
||||
this.id = "epubjs-view-" + uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
|
||||
|
@ -35,9 +36,9 @@ function IframeView(section, options) {
|
|||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.container = function(axis) {
|
||||
container(axis) {
|
||||
var element = document.createElement('div');
|
||||
|
||||
element.classList.add("epub-view");
|
||||
|
@ -54,9 +55,9 @@ IframeView.prototype.container = function(axis) {
|
|||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.create = function() {
|
||||
create() {
|
||||
|
||||
if(this.iframe) {
|
||||
return this.iframe;
|
||||
|
@ -88,14 +89,14 @@ IframeView.prototype.create = function() {
|
|||
this.element.appendChild(this.iframe);
|
||||
this.added = true;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
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 = core.bounds(this.iframe);
|
||||
// this.iframeBounds = bounds(this.iframe);
|
||||
// }
|
||||
|
||||
// Firefox has trouble with baseURI and srcdoc
|
||||
|
@ -108,9 +109,9 @@ IframeView.prototype.create = function() {
|
|||
}
|
||||
|
||||
return this.iframe;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.render = function(request, show) {
|
||||
render(request, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
this.create();
|
||||
|
@ -166,10 +167,10 @@ IframeView.prototype.render = function(request, show) {
|
|||
this.emit("loaderror", e);
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Determine locks base on settings
|
||||
IframeView.prototype.size = function(_width, _height) {
|
||||
// Determine locks base on settings
|
||||
size(_width, _height) {
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
|
||||
|
@ -181,32 +182,32 @@ IframeView.prototype.size = function(_width, _height) {
|
|||
this.lock("width", width, height);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
IframeView.prototype.lock = function(what, width, height) {
|
||||
var elBorders = core.borders(this.element);
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
lock(what, width, height) {
|
||||
var elBorders = borders(this.element);
|
||||
var iframeBorders;
|
||||
|
||||
if(this.iframe) {
|
||||
iframeBorders = core.borders(this.iframe);
|
||||
iframeBorders = borders(this.iframe);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
if(what == "width" && isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
if(what == "height" && isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(width, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
isNumber(width) &&
|
||||
isNumber(height)){
|
||||
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
|
@ -223,10 +224,10 @@ IframeView.prototype.lock = function(what, width, height) {
|
|||
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Resize a single axis based on content dimensions
|
||||
IframeView.prototype.expand = function(force) {
|
||||
// Resize a single axis based on content dimensions
|
||||
expand(force) {
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
var columns;
|
||||
|
@ -285,9 +286,9 @@ IframeView.prototype.expand = function(force) {
|
|||
}
|
||||
|
||||
this._expanding = false;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.contentWidth = function(min) {
|
||||
contentWidth(min) {
|
||||
var prev;
|
||||
var width;
|
||||
|
||||
|
@ -301,9 +302,9 @@ IframeView.prototype.contentWidth = function(min) {
|
|||
// Reset iframe size back
|
||||
this.iframe.style.width = prev;
|
||||
return width;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.contentHeight = function(min) {
|
||||
contentHeight(min) {
|
||||
var prev;
|
||||
var height;
|
||||
|
||||
|
@ -313,47 +314,47 @@ IframeView.prototype.contentHeight = function(min) {
|
|||
|
||||
this.iframe.style.height = prev;
|
||||
return height;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
IframeView.prototype.resize = function(width, height) {
|
||||
resize(width, height) {
|
||||
|
||||
if(!this.iframe) return;
|
||||
|
||||
if(core.isNumber(width)){
|
||||
if(isNumber(width)){
|
||||
this.iframe.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
if(isNumber(height)){
|
||||
this.iframe.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
|
||||
this.iframeBounds = core.bounds(this.iframe);
|
||||
this.iframeBounds = bounds(this.iframe);
|
||||
|
||||
this.reframe(this.iframeBounds.width, this.iframeBounds.height);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.reframe = function(width, height) {
|
||||
reframe(width, height) {
|
||||
var size;
|
||||
|
||||
// if(!this.displayed) {
|
||||
// this._needsReframe = true;
|
||||
// return;
|
||||
// }
|
||||
if(core.isNumber(width)){
|
||||
if(isNumber(width)){
|
||||
this.element.style.width = width + "px";
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
if(isNumber(height)){
|
||||
this.element.style.height = height + "px";
|
||||
}
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
|
@ -366,11 +367,11 @@ IframeView.prototype.reframe = function(width, height) {
|
|||
|
||||
this.emit("resized", size);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
IframeView.prototype.load = function(contents) {
|
||||
var loading = new core.defer();
|
||||
load(contents) {
|
||||
var loading = new defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
if(!this.iframe) {
|
||||
|
@ -402,9 +403,9 @@ IframeView.prototype.load = function(contents) {
|
|||
}
|
||||
|
||||
return loaded;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.onLoad = function(event, promise) {
|
||||
onLoad(event, promise) {
|
||||
|
||||
this.window = this.iframe.contentWindow;
|
||||
this.document = this.iframe.contentDocument;
|
||||
|
@ -430,55 +431,55 @@ IframeView.prototype.onLoad = function(event, promise) {
|
|||
});
|
||||
|
||||
promise.resolve(this.contents);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
// IframeView.prototype.layout = function(layoutFunc) {
|
||||
//
|
||||
// this.iframe.style.display = "inline-block";
|
||||
//
|
||||
// // Reset Body Styles
|
||||
// // this.document.body.style.margin = "0";
|
||||
// //this.document.body.style.display = "inline-block";
|
||||
// //this.document.documentElement.style.width = "auto";
|
||||
//
|
||||
// if(layoutFunc){
|
||||
// this.layoutFunc = layoutFunc;
|
||||
// }
|
||||
//
|
||||
// this.contents.layout(this.layoutFunc);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// IframeView.prototype.onLayout = function(view) {
|
||||
// // stub
|
||||
// };
|
||||
// layout(layoutFunc) {
|
||||
//
|
||||
// this.iframe.style.display = "inline-block";
|
||||
//
|
||||
// // Reset Body Styles
|
||||
// // this.document.body.style.margin = "0";
|
||||
// //this.document.body.style.display = "inline-block";
|
||||
// //this.document.documentElement.style.width = "auto";
|
||||
//
|
||||
// if(layoutFunc){
|
||||
// this.layoutFunc = layoutFunc;
|
||||
// }
|
||||
//
|
||||
// this.contents.layout(this.layoutFunc);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// onLayout(view) {
|
||||
// // stub
|
||||
// };
|
||||
|
||||
IframeView.prototype.setLayout = function(layout) {
|
||||
setLayout(layout) {
|
||||
this.layout = layout;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.setAxis = function(axis) {
|
||||
setAxis(axis) {
|
||||
this.settings.axis = axis;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.resizeListenters = function() {
|
||||
resizeListenters() {
|
||||
// Test size again
|
||||
clearTimeout(this.expanding);
|
||||
this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.addListeners = function() {
|
||||
addListeners() {
|
||||
//TODO: Add content listeners for expanding
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.removeListeners = function(layoutFunc) {
|
||||
removeListeners(layoutFunc) {
|
||||
//TODO: remove content listeners for expanding
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.display = function(request) {
|
||||
var displayed = new core.defer();
|
||||
display(request) {
|
||||
var displayed = new defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
|
||||
|
@ -498,9 +499,9 @@ IframeView.prototype.display = function(request) {
|
|||
|
||||
|
||||
return displayed.promise;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.show = function() {
|
||||
show() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
|
@ -509,22 +510,22 @@ IframeView.prototype.show = function() {
|
|||
}
|
||||
|
||||
this.emit("shown", this);
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.hide = function() {
|
||||
hide() {
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.emit("hidden", this);
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.position = function() {
|
||||
position() {
|
||||
return this.element.getBoundingClientRect();
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.locationOf = function(target) {
|
||||
locationOf(target) {
|
||||
var parentPos = this.iframe.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
|
@ -532,24 +533,24 @@ IframeView.prototype.locationOf = function(target) {
|
|||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.onDisplayed = function(view) {
|
||||
onDisplayed(view) {
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.onResize = function(view, e) {
|
||||
onResize(view, e) {
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.bounds = function() {
|
||||
bounds() {
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.destroy = function() {
|
||||
destroy() {
|
||||
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
|
@ -568,8 +569,9 @@ IframeView.prototype.destroy = function() {
|
|||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
EventEmitter(IframeView.prototype);
|
||||
|
||||
module.exports = IframeView;
|
||||
export default IframeView;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var core = require('../../core');
|
||||
var EpubCFI = require('../../epubcfi');
|
||||
var Contents = require('../../contents');
|
||||
// var URI = require('urijs');
|
||||
import EventEmitter from 'event-emitter';
|
||||
import {extend, borders, uuid, isNumber, bounds, defer} from '../../utils/core';
|
||||
import EpubCFI from '../../epubcfi';
|
||||
import Contents from '../../contents';
|
||||
// import URI from 'urijs';
|
||||
|
||||
function InlineView(section, options) {
|
||||
this.settings = core.extend({
|
||||
class InlineView {
|
||||
constructor(section, options) {
|
||||
this.settings = extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
|
@ -14,7 +15,7 @@ function InlineView(section, options) {
|
|||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
|
||||
this.id = "epubjs-view:" + core.uuid();
|
||||
this.id = "epubjs-view:" + uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
|
||||
|
@ -37,9 +38,9 @@ function InlineView(section, options) {
|
|||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.container = function(axis) {
|
||||
container(axis) {
|
||||
var element = document.createElement('div');
|
||||
|
||||
element.classList.add("epub-view");
|
||||
|
@ -61,9 +62,9 @@ InlineView.prototype.container = function(axis) {
|
|||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.create = function() {
|
||||
create() {
|
||||
|
||||
if(this.frame) {
|
||||
return this.frame;
|
||||
|
@ -99,12 +100,12 @@ InlineView.prototype.create = function() {
|
|||
this.element.appendChild(this.frame);
|
||||
this.added = true;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
return this.frame;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.render = function(request, show) {
|
||||
render(request, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
this.create();
|
||||
|
@ -155,10 +156,10 @@ InlineView.prototype.render = function(request, show) {
|
|||
this.emit("loaderror", e);
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Determine locks base on settings
|
||||
InlineView.prototype.size = function(_width, _height) {
|
||||
// Determine locks base on settings
|
||||
size(_width, _height) {
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
|
||||
|
@ -171,32 +172,32 @@ InlineView.prototype.size = function(_width, _height) {
|
|||
this.lock("width", width, height);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
InlineView.prototype.lock = function(what, width, height) {
|
||||
var elBorders = core.borders(this.element);
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
lock(what, width, height) {
|
||||
var elBorders = borders(this.element);
|
||||
var iframeBorders;
|
||||
|
||||
if(this.frame) {
|
||||
iframeBorders = core.borders(this.frame);
|
||||
iframeBorders = borders(this.frame);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
if(what == "width" && isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, false); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
if(what == "height" && isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(false, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
isNumber(width) &&
|
||||
isNumber(height)){
|
||||
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
|
@ -204,10 +205,10 @@ InlineView.prototype.lock = function(what, width, height) {
|
|||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Resize a single axis based on content dimensions
|
||||
InlineView.prototype.expand = function(force) {
|
||||
// Resize a single axis based on content dimensions
|
||||
expand(force) {
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
|
||||
|
@ -232,35 +233,35 @@ InlineView.prototype.expand = function(force) {
|
|||
}
|
||||
|
||||
this._expanding = false;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.contentWidth = function(min) {
|
||||
contentWidth(min) {
|
||||
return this.frame.scrollWidth;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.contentHeight = function(min) {
|
||||
contentHeight(min) {
|
||||
console.log(this.frame.scrollHeight);
|
||||
return this.frame.scrollHeight;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.resize = function(width, height) {
|
||||
resize(width, height) {
|
||||
|
||||
if(!this.frame) return;
|
||||
|
||||
if(core.isNumber(width)){
|
||||
if(isNumber(width)){
|
||||
this.frame.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
if(isNumber(height)){
|
||||
this.frame.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
|
@ -273,14 +274,14 @@ InlineView.prototype.resize = function(width, height) {
|
|||
|
||||
this.emit("resized", size);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.load = function(contents) {
|
||||
var loading = new core.defer();
|
||||
load(contents) {
|
||||
var loading = new defer();
|
||||
var loaded = loading.promise;
|
||||
var doc = core.parse(contents, "text/html");
|
||||
var body = core.qs(doc, "body");
|
||||
var doc = parse(contents, "text/html");
|
||||
var body = qs(doc, "body");
|
||||
|
||||
var srcs = doc.querySelectorAll("[src]");
|
||||
Array.prototype.slice.call(srcs)
|
||||
|
@ -309,29 +310,29 @@ InlineView.prototype.load = function(contents) {
|
|||
|
||||
|
||||
return loaded;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.setLayout = function(layout) {
|
||||
setLayout(layout) {
|
||||
this.layout = layout;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.resizeListenters = function() {
|
||||
resizeListenters() {
|
||||
// Test size again
|
||||
// clearTimeout(this.expanding);
|
||||
// this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.addListeners = function() {
|
||||
addListeners() {
|
||||
//TODO: Add content listeners for expanding
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.removeListeners = function(layoutFunc) {
|
||||
removeListeners(layoutFunc) {
|
||||
//TODO: remove content listeners for expanding
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.display = function(request) {
|
||||
var displayed = new core.defer();
|
||||
display(request) {
|
||||
var displayed = new defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
|
||||
|
@ -352,9 +353,9 @@ InlineView.prototype.display = function(request) {
|
|||
|
||||
|
||||
return displayed.promise;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.show = function() {
|
||||
show() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
|
@ -363,22 +364,22 @@ InlineView.prototype.show = function() {
|
|||
}
|
||||
|
||||
this.emit("shown", this);
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.hide = function() {
|
||||
hide() {
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.emit("hidden", this);
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.position = function() {
|
||||
position() {
|
||||
return this.element.getBoundingClientRect();
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.locationOf = function(target) {
|
||||
locationOf(target) {
|
||||
var parentPos = this.frame.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
|
@ -386,24 +387,24 @@ InlineView.prototype.locationOf = function(target) {
|
|||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.onDisplayed = function(view) {
|
||||
onDisplayed(view) {
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.onResize = function(view, e) {
|
||||
onResize(view, e) {
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.bounds = function() {
|
||||
bounds() {
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.destroy = function() {
|
||||
destroy() {
|
||||
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
|
@ -422,8 +423,9 @@ InlineView.prototype.destroy = function() {
|
|||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
EventEmitter(InlineView.prototype);
|
||||
|
||||
module.exports = InlineView;
|
||||
export default InlineView;
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
var EpubCFI = require('./epubcfi');
|
||||
import EpubCFI from './epubcfi';
|
||||
|
||||
function Mapping(layout){
|
||||
class Mapping {
|
||||
constructor(layout) {
|
||||
this.layout = layout;
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.section = function(view) {
|
||||
section(view) {
|
||||
var ranges = this.findRanges(view);
|
||||
var map = this.rangeListToCfiList(view.section.cfiBase, ranges);
|
||||
|
||||
return map;
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.page = function(contents, cfiBase, start, end) {
|
||||
page(contents, cfiBase, start, end) {
|
||||
var root = contents && contents.document ? contents.document.body : false;
|
||||
|
||||
if (!root) {
|
||||
|
@ -22,9 +23,9 @@ Mapping.prototype.page = function(contents, cfiBase, start, end) {
|
|||
start: this.findStart(root, start, end),
|
||||
end: this.findEnd(root, start, end)
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.walk = function(root, func) {
|
||||
walk(root, func) {
|
||||
//var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, null, false);
|
||||
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
||||
acceptNode: function (node) {
|
||||
|
@ -43,9 +44,9 @@ Mapping.prototype.walk = function(root, func) {
|
|||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.findRanges = function(view){
|
||||
findRanges(view){
|
||||
var columns = [];
|
||||
var scrollWidth = view.contents.scrollWidth();
|
||||
var count = this.layout.count(scrollWidth);
|
||||
|
@ -63,9 +64,9 @@ Mapping.prototype.findRanges = function(view){
|
|||
}
|
||||
|
||||
return columns;
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.findStart = function(root, start, end){
|
||||
findStart(root, start, end){
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var found;
|
||||
|
@ -110,9 +111,9 @@ Mapping.prototype.findStart = function(root, start, end){
|
|||
|
||||
// Return last element
|
||||
return this.findTextStartRange($prev, start, end);
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.findEnd = function(root, start, end){
|
||||
findEnd(root, start, end){
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var $prev = root;
|
||||
|
@ -160,10 +161,10 @@ Mapping.prototype.findEnd = function(root, start, end){
|
|||
|
||||
// end of chapter
|
||||
return this.findTextEndRange($prev, start, end);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Mapping.prototype.findTextStartRange = function(node, start, end){
|
||||
findTextStartRange(node, start, end){
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
|
@ -183,9 +184,9 @@ Mapping.prototype.findTextStartRange = function(node, start, end){
|
|||
}
|
||||
|
||||
return ranges[0];
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.findTextEndRange = function(node, start, end){
|
||||
findTextEndRange(node, start, end){
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
|
@ -209,9 +210,9 @@ Mapping.prototype.findTextEndRange = function(node, start, end){
|
|||
// Ends before limit
|
||||
return ranges[ranges.length-1];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.splitTextNodeIntoRanges = function(node, _splitter){
|
||||
splitTextNodeIntoRanges(node, _splitter){
|
||||
var ranges = [];
|
||||
var textContent = node.textContent || "";
|
||||
var text = textContent.trim();
|
||||
|
@ -221,7 +222,7 @@ Mapping.prototype.splitTextNodeIntoRanges = function(node, _splitter){
|
|||
var doc = node.ownerDocument;
|
||||
var splitter = _splitter || " ";
|
||||
|
||||
pos = text.indexOf(splitter);
|
||||
var pos = text.indexOf(splitter);
|
||||
|
||||
if(pos === -1 || node.nodeType != Node.TEXT_NODE) {
|
||||
range = doc.createRange();
|
||||
|
@ -256,11 +257,11 @@ Mapping.prototype.splitTextNodeIntoRanges = function(node, _splitter){
|
|||
}
|
||||
|
||||
return ranges;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
Mapping.prototype.rangePairToCfiPair = function(cfiBase, rangePair){
|
||||
rangePairToCfiPair(cfiBase, rangePair){
|
||||
|
||||
var startRange = rangePair.start;
|
||||
var endRange = rangePair.end;
|
||||
|
@ -270,17 +271,17 @@ Mapping.prototype.rangePairToCfiPair = function(cfiBase, rangePair){
|
|||
|
||||
// startCfi = section.cfiFromRange(startRange);
|
||||
// endCfi = section.cfiFromRange(endRange);
|
||||
startCfi = new EpubCFI(startRange, cfiBase).toString();
|
||||
endCfi = new EpubCFI(endRange, cfiBase).toString();
|
||||
let startCfi = new EpubCFI(startRange, cfiBase).toString();
|
||||
let endCfi = new EpubCFI(endRange, cfiBase).toString();
|
||||
|
||||
return {
|
||||
start: startCfi,
|
||||
end: endCfi
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
Mapping.prototype.rangeListToCfiList = function(cfiBase, columns){
|
||||
rangeListToCfiList(cfiBase, columns){
|
||||
var map = [];
|
||||
var rangePair, cifPair;
|
||||
|
||||
|
@ -292,6 +293,7 @@ Mapping.prototype.rangeListToCfiList = function(cfiBase, columns){
|
|||
}
|
||||
|
||||
return map;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Mapping;
|
||||
export default Mapping;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
var core = require('./core');
|
||||
var path = require('path');
|
||||
import {qs, qsa, querySelectorByType} from './utils/core';
|
||||
|
||||
/**
|
||||
* Navigation Parser
|
||||
* @param {document} xml navigation html / xhtml / ncx
|
||||
*/
|
||||
function Navigation(xml){
|
||||
class Navigation {
|
||||
constructor(xml) {
|
||||
this.toc = [];
|
||||
this.tocByHref = {};
|
||||
this.tocById = {};
|
||||
|
@ -13,15 +13,15 @@ function Navigation(xml){
|
|||
if (xml) {
|
||||
this.parse(xml);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse out the navigation items
|
||||
* @param {document} xml navigation html / xhtml / ncx
|
||||
*/
|
||||
Navigation.prototype.parse = function(xml) {
|
||||
var html = core.qs(xml, "html");
|
||||
var ncx = core.qs(xml, "ncx");
|
||||
parse(xml) {
|
||||
var html = qs(xml, "html");
|
||||
var ncx = qs(xml, "ncx");
|
||||
|
||||
if(html) {
|
||||
this.toc = this.parseNav(xml);
|
||||
|
@ -30,14 +30,14 @@ Navigation.prototype.parse = function(xml) {
|
|||
}
|
||||
|
||||
this.unpack(this.toc);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Unpack navigation items
|
||||
* @private
|
||||
* @param {array} toc
|
||||
*/
|
||||
Navigation.prototype.unpack = function(toc) {
|
||||
unpack(toc) {
|
||||
var item;
|
||||
|
||||
for (var i = 0; i < toc.length; i++) {
|
||||
|
@ -46,14 +46,14 @@ Navigation.prototype.unpack = function(toc) {
|
|||
this.tocById[item.id] = i;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get an item from the navigation
|
||||
* @param {string} target
|
||||
* @return {object} navItems
|
||||
*/
|
||||
Navigation.prototype.get = function(target) {
|
||||
get(target) {
|
||||
var index;
|
||||
|
||||
if(!target) {
|
||||
|
@ -67,17 +67,17 @@ Navigation.prototype.get = function(target) {
|
|||
}
|
||||
|
||||
return this.toc[index];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse from a Epub > 3.0 Nav
|
||||
* @private
|
||||
* @param {document} navHtml
|
||||
* @return {array} navigation list
|
||||
*/
|
||||
Navigation.prototype.parseNav = function(navHtml){
|
||||
var navElement = core.querySelectorByType(navHtml, "nav", "toc");
|
||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||
parseNav(navHtml){
|
||||
var navElement = querySelectorByType(navHtml, "nav", "toc");
|
||||
var navItems = navElement ? qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
|
@ -98,17 +98,17 @@ Navigation.prototype.parseNav = function(navHtml){
|
|||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a navItem
|
||||
* @private
|
||||
* @param {element} item
|
||||
* @return {object} navItem
|
||||
*/
|
||||
Navigation.prototype.navItem = function(item){
|
||||
navItem(item){
|
||||
var id = item.getAttribute('id') || false,
|
||||
content = core.qs(item, "a"),
|
||||
content = qs(item, "a"),
|
||||
src = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
subitems = [],
|
||||
|
@ -126,16 +126,16 @@ Navigation.prototype.navItem = function(item){
|
|||
"subitems" : subitems,
|
||||
"parent" : parent
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse from a Epub > 3.0 NC
|
||||
* @private
|
||||
* @param {document} navHtml
|
||||
* @return {array} navigation list
|
||||
*/
|
||||
Navigation.prototype.parseNcx = function(tocXml){
|
||||
var navPoints = core.qsa(tocXml, "navPoint");
|
||||
parseNcx(tocXml){
|
||||
var navPoints = qsa(tocXml, "navPoint");
|
||||
var length = navPoints.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
|
@ -156,19 +156,19 @@ Navigation.prototype.parseNcx = function(tocXml){
|
|||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a ncxItem
|
||||
* @private
|
||||
* @param {element} item
|
||||
* @return {object} ncxItem
|
||||
*/
|
||||
Navigation.prototype.ncxItem = function(item){
|
||||
ncxItem(item){
|
||||
var id = item.getAttribute('id') || false,
|
||||
content = core.qs(item, "content"),
|
||||
content = qs(item, "content"),
|
||||
src = content.getAttribute('src'),
|
||||
navLabel = core.qs(item, "navLabel"),
|
||||
navLabel = qs(item, "navLabel"),
|
||||
text = navLabel.textContent ? navLabel.textContent : "",
|
||||
subitems = [],
|
||||
parentNode = item.parentNode,
|
||||
|
@ -186,15 +186,16 @@ Navigation.prototype.ncxItem = function(item){
|
|||
"subitems" : subitems,
|
||||
"parent" : parent
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* forEach pass through
|
||||
* @param {Function} fn function to run on each item
|
||||
* @return {method} forEach loop
|
||||
*/
|
||||
Navigation.prototype.forEach = function(fn) {
|
||||
forEach(fn) {
|
||||
return this.toc.forEach(fn);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Navigation;
|
||||
export default Navigation;
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
var path = require('path');
|
||||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
import {qs, qsa, qsp} from './utils/core';
|
||||
import EpubCFI from './epubcfi';
|
||||
|
||||
/**
|
||||
* Open Packaging Format Parser
|
||||
* @class
|
||||
* @param {document} packageDocument OPF XML
|
||||
*/
|
||||
function Packaging(packageDocument) {
|
||||
class Packaging {
|
||||
constructor(packageDocument) {
|
||||
if (packageDocument) {
|
||||
this.parse(packageDocument);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse OPF XML
|
||||
* @param {document} packageDocument OPF XML
|
||||
* @return {object} parsed package parts
|
||||
*/
|
||||
Packaging.prototype.parse = function(packageDocument){
|
||||
parse(packageDocument){
|
||||
var metadataNode, manifestNode, spineNode;
|
||||
|
||||
if(!packageDocument) {
|
||||
|
@ -26,19 +26,19 @@ Packaging.prototype.parse = function(packageDocument){
|
|||
return;
|
||||
}
|
||||
|
||||
metadataNode = core.qs(packageDocument, "metadata");
|
||||
metadataNode = qs(packageDocument, "metadata");
|
||||
if(!metadataNode) {
|
||||
console.error("No Metadata Found");
|
||||
return;
|
||||
}
|
||||
|
||||
manifestNode = core.qs(packageDocument, "manifest");
|
||||
manifestNode = qs(packageDocument, "manifest");
|
||||
if(!manifestNode) {
|
||||
console.error("No Manifest Found");
|
||||
return;
|
||||
}
|
||||
|
||||
spineNode = core.qs(packageDocument, "spine");
|
||||
spineNode = qs(packageDocument, "spine");
|
||||
if(!spineNode) {
|
||||
console.error("No Spine Found");
|
||||
return;
|
||||
|
@ -67,15 +67,15 @@ Packaging.prototype.parse = function(packageDocument){
|
|||
'coverPath': this.coverPath,
|
||||
'spineNodeIndex' : this.spineNodeIndex
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse Metadata
|
||||
* @private
|
||||
* @param {document} xml
|
||||
* @return {object} metadata
|
||||
*/
|
||||
Packaging.prototype.parseMetadata = function(xml){
|
||||
parseMetadata(xml){
|
||||
var metadata = {};
|
||||
|
||||
metadata.title = this.getElementText(xml, 'title');
|
||||
|
@ -99,20 +99,20 @@ Packaging.prototype.parseMetadata = function(xml){
|
|||
// metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
|
||||
|
||||
return metadata;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse Manifest
|
||||
* @private
|
||||
* @param {document} manifestXml
|
||||
* @return {object} manifest
|
||||
*/
|
||||
Packaging.prototype.parseManifest = function(manifestXml){
|
||||
parseManifest(manifestXml){
|
||||
var manifest = {};
|
||||
|
||||
//-- Turn items into an array
|
||||
// var selected = manifestXml.querySelectorAll("item");
|
||||
var selected = core.qsa(manifestXml, "item");
|
||||
var selected = qsa(manifestXml, "item");
|
||||
var items = Array.prototype.slice.call(selected);
|
||||
|
||||
//-- Create an object with the id as key
|
||||
|
@ -133,15 +133,15 @@ Packaging.prototype.parseManifest = function(manifestXml){
|
|||
|
||||
return manifest;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse Spine
|
||||
* @param {document} spineXml
|
||||
* @param {Packaging.manifest} manifest
|
||||
* @return {object} spine
|
||||
*/
|
||||
Packaging.prototype.parseSpine = function(spineXml, manifest){
|
||||
parseSpine(spineXml, manifest){
|
||||
var spine = [];
|
||||
|
||||
var selected = spineXml.getElementsByTagName("itemref"),
|
||||
|
@ -171,28 +171,28 @@ Packaging.prototype.parseSpine = function(spineXml, manifest){
|
|||
});
|
||||
|
||||
return spine;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Find TOC NAV
|
||||
* @private
|
||||
*/
|
||||
Packaging.prototype.findNavPath = function(manifestNode){
|
||||
findNavPath(manifestNode){
|
||||
// Find item with property 'nav'
|
||||
// Should catch nav irregardless of order
|
||||
// var node = manifestNode.querySelector("item[properties$='nav'], item[properties^='nav '], item[properties*=' nav ']");
|
||||
var node = core.qsp(manifestNode, "item", {"properties":"nav"});
|
||||
var node = qsp(manifestNode, "item", {"properties":"nav"});
|
||||
return node ? node.getAttribute('href') : false;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Find TOC NCX
|
||||
* media-type="application/x-dtbncx+xml" href="toc.ncx"
|
||||
* @private
|
||||
*/
|
||||
Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
|
||||
findNcxPath(manifestNode, spineNode){
|
||||
// var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
|
||||
var node = core.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
|
||||
|
@ -207,21 +207,21 @@ Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
|
|||
}
|
||||
|
||||
return node ? node.getAttribute('href') : false;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Find the Cover Path
|
||||
* <item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />
|
||||
* Fallback for Epub 2.0
|
||||
* @param {document} packageXml
|
||||
* @return {string} href
|
||||
*/
|
||||
Packaging.prototype.findCoverPath = function(packageXml){
|
||||
var pkg = core.qs(packageXml, "package");
|
||||
findCoverPath(packageXml){
|
||||
var pkg = qs(packageXml, "package");
|
||||
var epubVersion = pkg.getAttribute('version');
|
||||
|
||||
if (epubVersion === '2.0') {
|
||||
var metaCover = core.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 + "']");
|
||||
|
@ -234,19 +234,19 @@ Packaging.prototype.findCoverPath = function(packageXml){
|
|||
}
|
||||
else {
|
||||
// var node = packageXml.querySelector("item[properties='cover-image']");
|
||||
var node = core.qsp(packageXml, 'item', {'properties':'cover-image'});
|
||||
var node = qsp(packageXml, 'item', {'properties':'cover-image'});
|
||||
return node ? node.getAttribute('href') : '';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get text of a namespaced element
|
||||
* @private
|
||||
* @param {document} xml
|
||||
* @param {string} tag
|
||||
* @return {string} text
|
||||
*/
|
||||
Packaging.prototype.getElementText = function(xml, tag){
|
||||
getElementText(xml, tag){
|
||||
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
|
||||
el;
|
||||
|
||||
|
@ -260,23 +260,24 @@ Packaging.prototype.getElementText = function(xml, tag){
|
|||
|
||||
return '';
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get text by property
|
||||
* @private
|
||||
* @param {document} xml
|
||||
* @param {string} property
|
||||
* @return {string} text
|
||||
*/
|
||||
Packaging.prototype.getPropertyText = function(xml, property){
|
||||
var el = core.qsp(xml, "meta", {"property":property});
|
||||
getPropertyText(xml, property){
|
||||
var el = qsp(xml, "meta", {"property":property});
|
||||
|
||||
if(el && el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Packaging;
|
||||
export default Packaging;
|
||||
|
|
100
src/pagelist.js
100
src/pagelist.js
|
@ -1,11 +1,18 @@
|
|||
var EpubCFI = require('./epubcfi');
|
||||
var core = require('./core');
|
||||
import EpubCFI from './epubcfi';
|
||||
import {
|
||||
qs,
|
||||
qsa,
|
||||
querySelectorByType,
|
||||
indexOfSorted,
|
||||
locationOf
|
||||
} from './utils/core';
|
||||
|
||||
/**
|
||||
* Page List Parser
|
||||
* @param {[document]} xml
|
||||
*/
|
||||
function PageList(xml) {
|
||||
class PageList {
|
||||
constructor(xml) {
|
||||
this.pages = [];
|
||||
this.locations = [];
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
@ -17,15 +24,15 @@ function PageList(xml) {
|
|||
if(this.pageList && this.pageList.length) {
|
||||
this.process(this.pageList);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse PageList Xml
|
||||
* @param {document} xml
|
||||
*/
|
||||
PageList.prototype.parse = function(xml) {
|
||||
var html = core.qs(xml, "html");
|
||||
// var ncx = core.qs(xml, "ncx");
|
||||
parse(xml) {
|
||||
var html = qs(xml, "html");
|
||||
// var ncx = qs(xml, "ncx");
|
||||
|
||||
if(html) {
|
||||
this.toc = this.parseNav(xml);
|
||||
|
@ -34,17 +41,17 @@ PageList.prototype.parse = function(xml) {
|
|||
return;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parse a Nav PageList
|
||||
* @private
|
||||
* @param {document} navHtml
|
||||
* @return {PageList.item[]} list
|
||||
*/
|
||||
PageList.prototype.parseNav = function(navHtml){
|
||||
var navElement = core.querySelectorByType(navHtml, "nav", "page-list");
|
||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||
parseNav(navHtml){
|
||||
var navElement = querySelectorByType(navHtml, "nav", "page-list");
|
||||
var navItems = navElement ? qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
|
@ -59,17 +66,17 @@ PageList.prototype.parseNav = function(navHtml){
|
|||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Page List Item
|
||||
* @private
|
||||
* @param {object} item
|
||||
* @return {object} pageListItem
|
||||
*/
|
||||
PageList.prototype.item = function(item){
|
||||
item(item){
|
||||
var id = item.getAttribute('id') || false,
|
||||
content = core.qs(item, "a"),
|
||||
content = qs(item, "a"),
|
||||
href = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
page = parseInt(text),
|
||||
|
@ -94,14 +101,14 @@ PageList.prototype.item = function(item){
|
|||
"page" : page
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process pageList items
|
||||
* @private
|
||||
* @param {array} pageList
|
||||
*/
|
||||
PageList.prototype.process = function(pageList){
|
||||
process(pageList){
|
||||
pageList.forEach(function(item){
|
||||
this.pages.push(item.page);
|
||||
if (item.cfi) {
|
||||
|
@ -111,14 +118,14 @@ PageList.prototype.process = function(pageList){
|
|||
this.firstPage = parseInt(this.pages[0]);
|
||||
this.lastPage = parseInt(this.pages[this.pages.length-1]);
|
||||
this.totalPages = this.lastPage - this.firstPage;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Replace HREFs with CFI
|
||||
* TODO: implement getting CFI from Href
|
||||
*/
|
||||
PageList.prototype.addCFIs = function() {
|
||||
addCFIs() {
|
||||
this.pageList.forEach(function(pg){
|
||||
if(!pg.cfi) {
|
||||
// epubcfi.generateCfiFromHref(pg.href, book).then(function(cfi){
|
||||
|
@ -127,10 +134,10 @@ PageList.prototype.addCFIs = function() {
|
|||
// });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
||||
/*
|
||||
EPUBJS.generateCfiFromHref(href, book) {
|
||||
var uri = EPUBJS.core.uri(href);
|
||||
var path = uri.path;
|
||||
var fragment = uri.fragment;
|
||||
|
@ -152,15 +159,15 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
|||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
*/
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a PageList result from a EpubCFI
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {string} page
|
||||
*/
|
||||
PageList.prototype.pageFromCfi = function(cfi){
|
||||
pageFromCfi(cfi){
|
||||
var pg = -1;
|
||||
|
||||
// Check if the pageList has not been set yet
|
||||
|
@ -172,14 +179,14 @@ PageList.prototype.pageFromCfi = function(cfi){
|
|||
|
||||
// check if the cfi is in the location list
|
||||
// var index = this.locations.indexOf(cfi);
|
||||
var index = core.indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||
var index = indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||
if(index != -1) {
|
||||
pg = this.pages[index];
|
||||
} else {
|
||||
// Otherwise add it to the list of locations
|
||||
// Insert it in the correct position in the locations page
|
||||
//index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
|
||||
index = EPUBJS.core.locationOf(cfi, this.locations, this.epubcfi.compare);
|
||||
index = locationOf(cfi, this.locations, this.epubcfi.compare);
|
||||
// Get the page at the location just before the new one, or return the first
|
||||
pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
|
||||
if(pg !== undefined) {
|
||||
|
@ -191,14 +198,14 @@ PageList.prototype.pageFromCfi = function(cfi){
|
|||
|
||||
}
|
||||
return pg;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get an EpubCFI from a Page List Item
|
||||
* @param {string} pg
|
||||
* @return {string} cfi
|
||||
*/
|
||||
PageList.prototype.cfiFromPage = function(pg){
|
||||
cfiFromPage(pg){
|
||||
var cfi = -1;
|
||||
// check that pg is an int
|
||||
if(typeof pg != "number"){
|
||||
|
@ -213,37 +220,38 @@ PageList.prototype.cfiFromPage = function(pg){
|
|||
}
|
||||
// TODO: handle pages not in the list
|
||||
return cfi;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a Page from Book percentage
|
||||
* @param {number} percent
|
||||
* @return {string} page
|
||||
*/
|
||||
PageList.prototype.pageFromPercentage = function(percent){
|
||||
pageFromPercentage(percent){
|
||||
var pg = Math.round(this.totalPages * percent);
|
||||
return pg;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a page
|
||||
* @param {int} pg the page
|
||||
* @return {number} percentage
|
||||
*/
|
||||
PageList.prototype.percentageFromPage = function(pg){
|
||||
percentageFromPage(pg){
|
||||
var percentage = (pg - this.firstPage) / this.totalPages;
|
||||
return Math.round(percentage * 1000) / 1000;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns a value between 0 - 1 corresponding to the location of a cfi
|
||||
* @param {string} cfi EpubCFI String
|
||||
* @return {number} percentage
|
||||
*/
|
||||
PageList.prototype.percentageFromCfi = function(cfi){
|
||||
percentageFromCfi(cfi){
|
||||
var pg = this.pageFromCfi(cfi);
|
||||
var percentage = this.percentageFromPage(pg);
|
||||
return percentage;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = PageList;
|
||||
export default PageList;
|
||||
|
|
76
src/queue.js
76
src/queue.js
|
@ -1,23 +1,24 @@
|
|||
var core = require('./core');
|
||||
import {defer, requestAnimationFrame} from './utils/core';
|
||||
|
||||
/**
|
||||
* Queue for handling tasks one at a time
|
||||
* @class
|
||||
* @param {scope} context what this will resolve to in the tasks
|
||||
*/
|
||||
function Queue(context){
|
||||
class Queue {
|
||||
constructor(context){
|
||||
this._q = [];
|
||||
this.context = context;
|
||||
this.tick = core.requestAnimationFrame;
|
||||
this.tick = requestAnimationFrame;
|
||||
this.running = false;
|
||||
this.paused = false;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Add an item to the queue
|
||||
* @return {Promise}
|
||||
*/
|
||||
Queue.prototype.enqueue = function() {
|
||||
enqueue() {
|
||||
var deferred, promise;
|
||||
var queued;
|
||||
var task = [].shift.call(arguments);
|
||||
|
@ -33,7 +34,7 @@ Queue.prototype.enqueue = function() {
|
|||
|
||||
if(typeof task === "function"){
|
||||
|
||||
deferred = new core.defer();
|
||||
deferred = new defer();
|
||||
promise = deferred.promise;
|
||||
|
||||
queued = {
|
||||
|
@ -62,13 +63,13 @@ Queue.prototype.enqueue = function() {
|
|||
}
|
||||
|
||||
return queued.promise;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Run one item
|
||||
* @return {Promise}
|
||||
*/
|
||||
Queue.prototype.dequeue = function(){
|
||||
dequeue(){
|
||||
var inwait, task, result;
|
||||
|
||||
if(this._q.length) {
|
||||
|
@ -83,7 +84,7 @@ Queue.prototype.dequeue = function(){
|
|||
// Task is a function that returns a promise
|
||||
return result.then(function(){
|
||||
inwait.deferred.resolve.apply(this.context, arguments);
|
||||
}, function(reason) {
|
||||
}.bind(this), function(reason) {
|
||||
inwait.deferred.reject.apply(this.context, arguments);
|
||||
}.bind(this));
|
||||
} else {
|
||||
|
@ -100,29 +101,29 @@ Queue.prototype.dequeue = function(){
|
|||
}
|
||||
|
||||
} else {
|
||||
inwait = new core.defer();
|
||||
inwait = new defer();
|
||||
inwait.deferred.resolve();
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// Run All Immediately
|
||||
Queue.prototype.dump = function(){
|
||||
// Run All Immediately
|
||||
dump(){
|
||||
while(this._q.length) {
|
||||
this.dequeue();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Run all tasks sequentially, at convince
|
||||
* @return {Promise}
|
||||
*/
|
||||
Queue.prototype.run = function(){
|
||||
run(){
|
||||
|
||||
if(!this.running){
|
||||
this.running = true;
|
||||
this.defered = new core.defer();
|
||||
this.defered = new defer();
|
||||
}
|
||||
|
||||
this.tick.call(window, function() {
|
||||
|
@ -147,13 +148,13 @@ Queue.prototype.run = function(){
|
|||
}
|
||||
|
||||
return this.defered.promise;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Flush all, as quickly as possible
|
||||
* @return {Promise}
|
||||
*/
|
||||
Queue.prototype.flush = function(){
|
||||
flush(){
|
||||
|
||||
if(this.running){
|
||||
return this.running;
|
||||
|
@ -169,30 +170,32 @@ Queue.prototype.flush = function(){
|
|||
return this.running;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Clear all items in wait
|
||||
*/
|
||||
Queue.prototype.clear = function(){
|
||||
clear(){
|
||||
this._q = [];
|
||||
this.running = false;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the number of tasks in the queue
|
||||
* @return {int} tasks
|
||||
*/
|
||||
Queue.prototype.length = function(){
|
||||
length(){
|
||||
return this._q.length;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Pause a running queue
|
||||
*/
|
||||
Queue.prototype.pause = function(){
|
||||
pause(){
|
||||
this.paused = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new task from a callback
|
||||
|
@ -203,7 +206,8 @@ Queue.prototype.pause = function(){
|
|||
* @param {scope} context
|
||||
* @return {function} task
|
||||
*/
|
||||
function Task(task, args, context){
|
||||
class Task {
|
||||
constructor(task, args, context){
|
||||
|
||||
return function(){
|
||||
var toApply = arguments || [];
|
||||
|
@ -222,6 +226,8 @@ function Task(task, args, context){
|
|||
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Queue;
|
||||
|
||||
export default Queue;
|
||||
|
|
215
src/rendition.js
215
src/rendition.js
|
@ -1,14 +1,13 @@
|
|||
var EventEmitter = require('event-emitter');
|
||||
var path = require('path');
|
||||
var core = require('./core');
|
||||
var replace = require('./replacements');
|
||||
var Hook = require('./hook');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Queue = require('./queue');
|
||||
var Layout = require('./layout');
|
||||
var Mapping = require('./mapping');
|
||||
var Themes = require('./themes');
|
||||
var Path = require('./core').Path;
|
||||
import EventEmitter from 'event-emitter';
|
||||
import { extend, defer, isFloat } from './utils/core';
|
||||
import {replaceLinks} from './replacements';
|
||||
import Hook from './hook';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Queue from './queue';
|
||||
import Layout from './layout';
|
||||
import Mapping from './mapping';
|
||||
import Themes from './themes';
|
||||
import Path from './utils/path';
|
||||
|
||||
/**
|
||||
* [Rendition description]
|
||||
|
@ -24,9 +23,10 @@ var Path = require('./core').Path;
|
|||
* @param {string} options.spread
|
||||
* @param {int} options.minSpreadWidth overridden by spread: none (never) / both (always)
|
||||
*/
|
||||
function Rendition(book, options) {
|
||||
class Rendition {
|
||||
constructor(book, options) {
|
||||
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
this.settings = extend(this.settings || {}, {
|
||||
width: null,
|
||||
height: null,
|
||||
ignoreClass: '',
|
||||
|
@ -38,7 +38,7 @@ function Rendition(book, options) {
|
|||
minSpreadWidth: 800
|
||||
});
|
||||
|
||||
core.extend(this.settings, options);
|
||||
extend(this.settings, options);
|
||||
|
||||
if (typeof(this.settings.manager) === "object") {
|
||||
this.manager = this.settings.manager;
|
||||
|
@ -68,7 +68,7 @@ function Rendition(book, options) {
|
|||
this.hooks.render = new Hook(this);
|
||||
this.hooks.show = new Hook(this);
|
||||
|
||||
this.hooks.content.register(replace.links.bind(this));
|
||||
this.hooks.content.register(replaceLinks.bind(this));
|
||||
this.hooks.content.register(this.passViewEvents.bind(this));
|
||||
|
||||
// this.hooks.display.register(this.afterDisplay.bind(this));
|
||||
|
@ -81,25 +81,25 @@ function Rendition(book, options) {
|
|||
this.q.enqueue(this.book.opened);
|
||||
|
||||
// Block the queue until rendering is started
|
||||
this.starting = new core.defer();
|
||||
this.starting = new defer();
|
||||
this.started = this.starting.promise;
|
||||
this.q.enqueue(this.start);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the manager function
|
||||
* @param {function} manager
|
||||
*/
|
||||
Rendition.prototype.setManager = function(manager) {
|
||||
setManager(manager) {
|
||||
this.manager = manager;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Require the manager from passed string, or as a function
|
||||
* @param {string|function} manager [description]
|
||||
* @return {method}
|
||||
*/
|
||||
Rendition.prototype.requireManager = function(manager) {
|
||||
requireManager(manager) {
|
||||
var viewManager;
|
||||
|
||||
// If manager is a string, try to load from register managers,
|
||||
|
@ -113,14 +113,14 @@ Rendition.prototype.requireManager = function(manager) {
|
|||
}
|
||||
|
||||
return viewManager;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Require the view from passed string, or as a function
|
||||
* @param {string|function} view
|
||||
* @return {view}
|
||||
*/
|
||||
Rendition.prototype.requireView = function(view) {
|
||||
requireView(view) {
|
||||
var View;
|
||||
|
||||
if (typeof view == "string") {
|
||||
|
@ -131,13 +131,13 @@ Rendition.prototype.requireView = function(view) {
|
|||
}
|
||||
|
||||
return View;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Start the rendering
|
||||
* @return {Promise} rendering has started
|
||||
*/
|
||||
Rendition.prototype.start = function(){
|
||||
start(){
|
||||
|
||||
if(!this.manager) {
|
||||
this.ViewManager = this.requireManager(this.settings.manager);
|
||||
|
@ -175,15 +175,15 @@ Rendition.prototype.start = function(){
|
|||
|
||||
// Start processing queue
|
||||
this.starting.resolve();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Call to attach the container to an element in the dom
|
||||
* Container must be attached before rendering can begin
|
||||
* @param {element} element to attach to
|
||||
* @return {Promise}
|
||||
*/
|
||||
Rendition.prototype.attachTo = function(element){
|
||||
attachTo(element){
|
||||
|
||||
return this.q.enqueue(function () {
|
||||
|
||||
|
@ -198,9 +198,9 @@ Rendition.prototype.attachTo = function(element){
|
|||
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Display a point in the book
|
||||
* The request will be added to the rendering Queue,
|
||||
* so it will wait until book is opened, rendering started
|
||||
|
@ -208,27 +208,27 @@ Rendition.prototype.attachTo = function(element){
|
|||
* @param {string} target Url or EpubCFI
|
||||
* @return {Promise}
|
||||
*/
|
||||
Rendition.prototype.display = function(target){
|
||||
display(target){
|
||||
|
||||
return this.q.enqueue(this._display, target);
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Tells the manager what to display immediately
|
||||
* @private
|
||||
* @param {string} target Url or EpubCFI
|
||||
* @return {Promise}
|
||||
*/
|
||||
Rendition.prototype._display = function(target){
|
||||
_display(target){
|
||||
var isCfiString = this.epubcfi.isCfiString(target);
|
||||
var displaying = new core.defer();
|
||||
var displaying = new defer();
|
||||
var displayed = displaying.promise;
|
||||
var section;
|
||||
var moveTo;
|
||||
|
||||
// Check if this is a book percentage
|
||||
if (this.book.locations.length && core.isFloat(target)) {
|
||||
if (this.book.locations.length && isFloat(target)) {
|
||||
console.log("percentage", target);
|
||||
target = book.locations.cfiFromPercentage(target);
|
||||
console.log("cfi", target);
|
||||
|
@ -257,10 +257,10 @@ Rendition.prototype._display = function(target){
|
|||
// this.emit("displayed", section);
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Rendition.prototype.render = function(view, show) {
|
||||
/*
|
||||
render(view, show) {
|
||||
|
||||
// view.onLayout = this.layout.format.bind(this.layout);
|
||||
view.create();
|
||||
|
@ -301,25 +301,25 @@ Rendition.prototype.render = function(view, show) {
|
|||
this.trigger("loaderror", e);
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
*/
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Report what has been displayed
|
||||
* @private
|
||||
* @param {*} view
|
||||
*/
|
||||
Rendition.prototype.afterDisplayed = function(view){
|
||||
afterDisplayed(view){
|
||||
this.hooks.content.trigger(view, this);
|
||||
this.emit("rendered", view.section);
|
||||
this.reportLocation();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Report resize events and display the last seen location
|
||||
* @private
|
||||
*/
|
||||
Rendition.prototype.onResized = function(size){
|
||||
onResized(size){
|
||||
|
||||
if(this.location) {
|
||||
this.display(this.location.start);
|
||||
|
@ -330,43 +330,43 @@ Rendition.prototype.onResized = function(size){
|
|||
height: size.height
|
||||
});
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Move the Rendition to a specific offset
|
||||
* Usually you would be better off calling display()
|
||||
* @param {object} offset
|
||||
*/
|
||||
Rendition.prototype.moveTo = function(offset){
|
||||
moveTo(offset){
|
||||
this.manager.moveTo(offset);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Go to the next "page" in the rendition
|
||||
* @return {Promise}
|
||||
*/
|
||||
Rendition.prototype.next = function(){
|
||||
next(){
|
||||
return this.q.enqueue(this.manager.next.bind(this.manager))
|
||||
.then(this.reportLocation.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Go to the previous "page" in the rendition
|
||||
* @return {Promise}
|
||||
*/
|
||||
Rendition.prototype.prev = function(){
|
||||
prev(){
|
||||
return this.q.enqueue(this.manager.prev.bind(this.manager))
|
||||
.then(this.reportLocation.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
//-- http://www.idpf.org/epub/301/spec/epub-publications.html#meta-properties-rendering
|
||||
/**
|
||||
//-- http://www.idpf.org/epub/301/spec/epub-publications.html#meta-properties-rendering
|
||||
/**
|
||||
* Determine the Layout properties from metadata and settings
|
||||
* @private
|
||||
* @param {object} metadata
|
||||
* @return {object} properties
|
||||
*/
|
||||
Rendition.prototype.determineLayoutProperties = function(metadata){
|
||||
determineLayoutProperties(metadata){
|
||||
var properties;
|
||||
var layout = this.settings.layout || metadata.layout || "reflowable";
|
||||
var spread = this.settings.spread || metadata.spread || "auto";
|
||||
|
@ -389,23 +389,23 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
|
|||
};
|
||||
|
||||
return properties;
|
||||
};
|
||||
};
|
||||
|
||||
// Rendition.prototype.applyLayoutProperties = function(){
|
||||
// var settings = this.determineLayoutProperties(this.book.package.metadata);
|
||||
//
|
||||
// this.flow(settings.flow);
|
||||
//
|
||||
// this.layout(settings);
|
||||
// };
|
||||
// applyLayoutProperties(){
|
||||
// var settings = this.determineLayoutProperties(this.book.package.metadata);
|
||||
//
|
||||
// this.flow(settings.flow);
|
||||
//
|
||||
// this.layout(settings);
|
||||
// };
|
||||
|
||||
/**
|
||||
/**
|
||||
* Adjust the flow of the rendition to paginated or scrolled
|
||||
* (scrolled-continuous vs scrolled-doc are handled by different view managers)
|
||||
* @param {string} flow
|
||||
*/
|
||||
Rendition.prototype.flow = function(flow){
|
||||
var _flow;
|
||||
flow(flow){
|
||||
var _flow = flow;
|
||||
if (flow === "scrolled-doc" || flow === "scrolled-continuous") {
|
||||
_flow = "scrolled";
|
||||
}
|
||||
|
@ -421,13 +421,13 @@ Rendition.prototype.flow = function(flow){
|
|||
if (this.manager) {
|
||||
this.manager.updateFlow(_flow);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Adjust the layout of the rendition to reflowable or pre-paginated
|
||||
* @param {object} settings
|
||||
*/
|
||||
Rendition.prototype.layout = function(settings){
|
||||
layout(settings){
|
||||
if (settings) {
|
||||
this._layout = new Layout(settings);
|
||||
this._layout.spread(settings.spread, this.settings.minSpreadWidth);
|
||||
|
@ -440,27 +440,27 @@ Rendition.prototype.layout = function(settings){
|
|||
}
|
||||
|
||||
return this._layout;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Adjust if the rendition uses spreads
|
||||
* @param {string} spread none | auto (TODO: implement landscape, portrait, both)
|
||||
* @param {int} min min width to use spreads at
|
||||
*/
|
||||
Rendition.prototype.spread = function(spread, min){
|
||||
spread(spread, min){
|
||||
|
||||
this._layout.spread(spread, min);
|
||||
|
||||
if (this.manager.isRendered()) {
|
||||
this.manager.updateLayout();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Report the current location
|
||||
* @private
|
||||
*/
|
||||
Rendition.prototype.reportLocation = function(){
|
||||
reportLocation(){
|
||||
return this.q.enqueue(function(){
|
||||
var location = this.manager.currentLocation();
|
||||
if (location && location.then && typeof location.then === 'function') {
|
||||
|
@ -485,13 +485,13 @@ Rendition.prototype.reportLocation = function(){
|
|||
}
|
||||
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the Current Location CFI
|
||||
* @return {EpubCFI} location (may be a promise)
|
||||
*/
|
||||
Rendition.prototype.currentLocation = function(){
|
||||
currentLocation(){
|
||||
var location = this.manager.currentLocation();
|
||||
if (location && location.then && typeof location.then === 'function') {
|
||||
location.then(function(result) {
|
||||
|
@ -508,56 +508,56 @@ Rendition.prototype.currentLocation = function(){
|
|||
}
|
||||
return location;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Remove and Clean Up the Rendition
|
||||
*/
|
||||
Rendition.prototype.destroy = function(){
|
||||
destroy(){
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
|
||||
this.manager.destroy();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Pass the events from a view
|
||||
* @private
|
||||
* @param {View} view
|
||||
*/
|
||||
Rendition.prototype.passViewEvents = function(view){
|
||||
passViewEvents(view){
|
||||
view.contents.listenedEvents.forEach(function(e){
|
||||
view.on(e, this.triggerViewEvent.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
view.on("selected", this.triggerSelectedEvent.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Emit events passed by a view
|
||||
* @private
|
||||
* @param {event} e
|
||||
*/
|
||||
Rendition.prototype.triggerViewEvent = function(e){
|
||||
triggerViewEvent(e){
|
||||
this.emit(e.type, e);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Emit a selection event's CFI Range passed from a a view
|
||||
* @private
|
||||
* @param {EpubCFI} cfirange
|
||||
*/
|
||||
Rendition.prototype.triggerSelectedEvent = function(cfirange){
|
||||
triggerSelectedEvent(cfirange){
|
||||
this.emit("selected", cfirange);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a Range from a Visible CFI
|
||||
* @param {string} cfi EpubCfi String
|
||||
* @param {string} ignoreClass
|
||||
* @return {range}
|
||||
*/
|
||||
Rendition.prototype.range = function(cfi, ignoreClass){
|
||||
range(cfi, ignoreClass){
|
||||
var _cfi = new EpubCFI(cfi);
|
||||
var found = this.visible().filter(function (view) {
|
||||
if(_cfi.spinePos === view.index) return true;
|
||||
|
@ -567,13 +567,13 @@ Rendition.prototype.range = function(cfi, ignoreClass){
|
|||
if (found.length) {
|
||||
return found[0].range(_cfi, ignoreClass);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Hook to adjust images to fit in columns
|
||||
* @param {View} view
|
||||
*/
|
||||
Rendition.prototype.adjustImages = function(view) {
|
||||
adjustImages(view) {
|
||||
|
||||
view.addStylesheetRules([
|
||||
["img",
|
||||
|
@ -587,13 +587,14 @@ Rendition.prototype.adjustImages = function(view) {
|
|||
resolve();
|
||||
}, 1);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
Rendition.prototype.getContents = function () {
|
||||
getContents () {
|
||||
return this.manager ? this.manager.getContents() : [];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
//-- Enable binding events to Renderer
|
||||
EventEmitter(Rendition.prototype);
|
||||
|
||||
module.exports = Rendition;
|
||||
export default Rendition;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// var URI = require('urijs');
|
||||
var core = require('./core');
|
||||
var Url = require('./core').Url;
|
||||
// import URI from 'urijs';
|
||||
import { qs } from './utils/core';
|
||||
import Url from './utils/url';
|
||||
|
||||
function base(doc, section){
|
||||
export function replaceBase(doc, section){
|
||||
var base;
|
||||
var head;
|
||||
|
||||
|
@ -12,8 +12,8 @@ function base(doc, section){
|
|||
|
||||
// head = doc.querySelector("head");
|
||||
// base = head.querySelector("base");
|
||||
head = core.qs(doc, "head");
|
||||
base = core.qs(head, "base");
|
||||
head = qs(doc, "head");
|
||||
base = qs(head, "base");
|
||||
|
||||
if(!base) {
|
||||
base = doc.createElement("base");
|
||||
|
@ -23,7 +23,7 @@ function base(doc, section){
|
|||
base.setAttribute("href", section.url);
|
||||
}
|
||||
|
||||
function canonical(doc, section){
|
||||
export function replaceCanonical(doc, section){
|
||||
var head;
|
||||
var link;
|
||||
var url = section.url; // window.location.origin + window.location.pathname + "?loc=" + encodeURIComponent(section.url);
|
||||
|
@ -32,8 +32,8 @@ function canonical(doc, section){
|
|||
return;
|
||||
}
|
||||
|
||||
head = core.qs(doc, "head");
|
||||
link = core.qs(head, "link[rel='canonical']");
|
||||
head = qs(doc, "head");
|
||||
link = qs(head, "link[rel='canonical']");
|
||||
|
||||
if (link) {
|
||||
link.setAttribute("href", url);
|
||||
|
@ -45,10 +45,10 @@ function canonical(doc, section){
|
|||
}
|
||||
}
|
||||
|
||||
function links(view, renderer) {
|
||||
export function replaceLinks(view, renderer) {
|
||||
|
||||
var links = view.document.querySelectorAll("a[href]");
|
||||
var replaceLinks = function(link){
|
||||
var replaceLink = function(link){
|
||||
var href = link.getAttribute("href");
|
||||
|
||||
if(href.indexOf("mailto:") === 0){
|
||||
|
@ -92,13 +92,13 @@ function links(view, renderer) {
|
|||
}.bind(this);
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
replaceLinks(links[i]);
|
||||
replaceLink(links[i]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function substitute(content, urls, replacements) {
|
||||
export function substitute(content, urls, replacements) {
|
||||
urls.forEach(function(url, i){
|
||||
if (url && replacements[i]) {
|
||||
content = content.replace(new RegExp(url, 'g'), replacements[i]);
|
||||
|
@ -106,9 +106,3 @@ function substitute(content, urls, replacements) {
|
|||
});
|
||||
return content;
|
||||
}
|
||||
module.exports = {
|
||||
'base': base,
|
||||
'canonical' : canonical,
|
||||
'links': links,
|
||||
'substitute': substitute
|
||||
};
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
var core = require('./core');
|
||||
var Path = require('./core').Path;
|
||||
import {defer, isXml, parse} from './utils/core';
|
||||
import Path from './utils/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 BLOB_RESPONSE = supportsURL ? "blob" : "arraybuffer";
|
||||
var uri;
|
||||
|
||||
var deferred = new core.defer();
|
||||
var deferred = new defer();
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
|
@ -49,7 +49,7 @@ function request(url, type, withCredentials, headers) {
|
|||
}
|
||||
|
||||
|
||||
if(core.isXml(type)) {
|
||||
if(isXml(type)) {
|
||||
// xhr.responseType = "document";
|
||||
xhr.overrideMimeType('text/xml'); // for OPF parsing
|
||||
}
|
||||
|
@ -106,16 +106,16 @@ function request(url, type, withCredentials, headers) {
|
|||
if(responseXML){
|
||||
r = this.responseXML;
|
||||
} else
|
||||
if(core.isXml(type)){
|
||||
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 = core.parse(this.response, "text/xml");
|
||||
r = parse(this.response, "text/xml");
|
||||
}else
|
||||
if(type == 'xhtml'){
|
||||
r = core.parse(this.response, "application/xhtml+xml");
|
||||
r = parse(this.response, "application/xhtml+xml");
|
||||
}else
|
||||
if(type == 'html' || type == 'htm'){
|
||||
r = core.parse(this.response, "text/html");
|
||||
r = parse(this.response, "text/html");
|
||||
}else
|
||||
if(type == 'json'){
|
||||
r = JSON.parse(this.response);
|
||||
|
@ -149,4 +149,4 @@ function request(url, type, withCredentials, headers) {
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
module.exports = request;
|
||||
export default request;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var replace = require('./replacements');
|
||||
var core = require('./core');
|
||||
var Path = require('./core').Path;
|
||||
var path = require('path');
|
||||
import {substitute} from './replacements';
|
||||
import {createBase64Url, createBlobUrl} from './utils/core';
|
||||
import Path from './utils/path';
|
||||
import path from 'path-webpack';
|
||||
|
||||
/**
|
||||
* Handle Package Resources
|
||||
|
@ -12,7 +12,8 @@ var path = require('path');
|
|||
* @param {[Archive]} options.archive
|
||||
* @param {[method]} options.resolver
|
||||
*/
|
||||
function Resources(manifest, options) {
|
||||
class Resources {
|
||||
constructor(manifest, options) {
|
||||
this.settings = {
|
||||
replacements: (options && options.replacements) || 'base64',
|
||||
archive: (options && options.archive),
|
||||
|
@ -28,13 +29,13 @@ function Resources(manifest, options) {
|
|||
|
||||
this.split();
|
||||
this.splitUrls();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Split resources by type
|
||||
* @private
|
||||
*/
|
||||
Resources.prototype.split = function(){
|
||||
split(){
|
||||
|
||||
// HTML
|
||||
this.html = this.resources.
|
||||
|
@ -61,13 +62,13 @@ Resources.prototype.split = function(){
|
|||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Convert split resources into Urls
|
||||
* @private
|
||||
*/
|
||||
Resources.prototype.splitUrls = function(){
|
||||
splitUrls(){
|
||||
|
||||
// All Assets Urls
|
||||
this.urls = this.assets.
|
||||
|
@ -80,15 +81,15 @@ Resources.prototype.splitUrls = function(){
|
|||
return item.href;
|
||||
});
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create blob urls for all the assets
|
||||
* @param {Archive} archive
|
||||
* @param {resolver} resolver Url resolver
|
||||
* @return {Promise} returns replacement urls
|
||||
*/
|
||||
Resources.prototype.replacements = function(archive, resolver){
|
||||
replacements(archive, resolver){
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
|
||||
|
@ -110,16 +111,16 @@ Resources.prototype.replacements = function(archive, resolver){
|
|||
this.replacementUrls = replacementUrls;
|
||||
return replacementUrls;
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Replace URLs in CSS resources
|
||||
* @private
|
||||
* @param {[Archive]} archive
|
||||
* @param {[method]} resolver
|
||||
* @return {Promise}
|
||||
*/
|
||||
Resources.prototype.replaceCss = function(archive, resolver){
|
||||
replaceCss(archive, resolver){
|
||||
var replaced = [];
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
|
@ -136,9 +137,9 @@ Resources.prototype.replaceCss = function(archive, resolver){
|
|||
replaced.push(replacement);
|
||||
}.bind(this));
|
||||
return Promise.all(replaced);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a new CSS file with the replaced URLs
|
||||
* @private
|
||||
* @param {string} href the original css file
|
||||
|
@ -146,7 +147,7 @@ Resources.prototype.replaceCss = function(archive, resolver){
|
|||
* @param {[method]} resolver
|
||||
* @return {Promise} returns a BlobUrl to the new CSS file or a data url
|
||||
*/
|
||||
Resources.prototype.createCssFile = function(href, archive, resolver){
|
||||
createCssFile(href, archive, resolver){
|
||||
var newUrl;
|
||||
var indexInUrls;
|
||||
archive = archive || this.settings.archive;
|
||||
|
@ -172,27 +173,27 @@ Resources.prototype.createCssFile = function(href, archive, resolver){
|
|||
|
||||
return textResponse.then(function (text) {
|
||||
// Replacements in the css text
|
||||
text = replace.substitute(text, relUrls, this.replacementUrls);
|
||||
text = substitute(text, relUrls, this.replacementUrls);
|
||||
|
||||
// Get the new url
|
||||
if (this.settings.replacements === "base64") {
|
||||
newUrl = core.createBase64Url(text, 'text/css');
|
||||
newUrl = createBase64Url(text, 'text/css');
|
||||
} else {
|
||||
newUrl = core.createBlobUrl(text, 'text/css');
|
||||
newUrl = createBlobUrl(text, 'text/css');
|
||||
}
|
||||
|
||||
return newUrl;
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Resolve all resources URLs relative to an absolute URL
|
||||
* @param {string} absolute to be resolved to
|
||||
* @param {[resolver]} resolver
|
||||
* @return {string[]} array with relative Urls
|
||||
*/
|
||||
Resources.prototype.relativeTo = function(absolute, resolver){
|
||||
relativeTo(absolute, resolver){
|
||||
resolver = resolver || this.settings.resolver;
|
||||
|
||||
// Get Urls relative to current sections
|
||||
|
@ -202,14 +203,14 @@ Resources.prototype.relativeTo = function(absolute, resolver){
|
|||
var relative = new Path(absolute).relative(resolved);
|
||||
return relative;
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a URL for a resource
|
||||
* @param {string} path
|
||||
* @return {string} url
|
||||
*/
|
||||
Resources.prototype.get = function(path) {
|
||||
get(path) {
|
||||
var indexInUrls = this.urls.indexOf(path);
|
||||
if (indexInUrls === -1) {
|
||||
return;
|
||||
|
@ -222,24 +223,24 @@ Resources.prototype.get = function(path) {
|
|||
return archive.createUrl(absolute,
|
||||
{"base64": (this.settings.replacements === "base64")})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Substitute urls in content, with replacements,
|
||||
* relative to a url if provided
|
||||
* @param {string} content
|
||||
* @param {[string]} url url to resolve to
|
||||
* @return {string} content with urls substituted
|
||||
*/
|
||||
Resources.prototype.substitute = function(content, url) {
|
||||
substitute(content, url) {
|
||||
var relUrls;
|
||||
if (url) {
|
||||
relUrls = this.relativeTo(url);
|
||||
} else {
|
||||
relUrls = this.urls;
|
||||
}
|
||||
return replace.substitute(content, relUrls, this.replacementUrls);
|
||||
};
|
||||
return substitute(content, relUrls, this.replacementUrls);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
module.exports = Resources;
|
||||
export default Resources;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Hook = require('./hook');
|
||||
var Url = require('./core').Url;
|
||||
import { defer } from './utils/core';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Hook from './hook';
|
||||
import Url from './utils/url';
|
||||
|
||||
/**
|
||||
* Represents a Section of the Book
|
||||
|
@ -9,7 +9,8 @@ var Url = require('./core').Url;
|
|||
* @param {object} item The spine item representing the section
|
||||
* @param {object} hooks hooks for serialize and content
|
||||
*/
|
||||
function Section(item, hooks){
|
||||
class Section {
|
||||
constructor(item, hooks){
|
||||
this.idref = item.idref;
|
||||
this.linear = item.linear;
|
||||
this.properties = item.properties;
|
||||
|
@ -29,16 +30,16 @@ function Section(item, hooks){
|
|||
this.hooks.content = new Hook(this);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Load the section from its url
|
||||
* @param {method} _request a request method to use for loading
|
||||
* @return {document} a promise with the xml document
|
||||
*/
|
||||
Section.prototype.load = function(_request){
|
||||
load(_request){
|
||||
var request = _request || this.request || require('./request');
|
||||
var loading = new core.defer();
|
||||
var loading = new defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
if(this.contents) {
|
||||
|
@ -63,15 +64,15 @@ Section.prototype.load = function(_request){
|
|||
}
|
||||
|
||||
return loaded;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Adds a base tag for resolving urls in the section
|
||||
* @private
|
||||
* @param {document} _document
|
||||
*/
|
||||
Section.prototype.base = function(_document){
|
||||
var task = new core.defer();
|
||||
base(_document){
|
||||
var task = new defer();
|
||||
var base = _document.createElement("base"); // TODO: check if exists
|
||||
var head;
|
||||
|
||||
|
@ -89,15 +90,15 @@ Section.prototype.base = function(_document){
|
|||
|
||||
|
||||
return task.promise;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Render the contents of a section
|
||||
* @param {method} _request a request method to use for loading
|
||||
* @return {string} output a serialized XML Document
|
||||
*/
|
||||
Section.prototype.render = function(_request){
|
||||
var rendering = new core.defer();
|
||||
render(_request){
|
||||
var rendering = new defer();
|
||||
var rendered = rendering.promise;
|
||||
this.output; // TODO: better way to return this from hooks?
|
||||
|
||||
|
@ -123,25 +124,25 @@ Section.prototype.render = function(_request){
|
|||
});
|
||||
|
||||
return rendered;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Find a string in a section
|
||||
* TODO: need reimplementation from v0.2
|
||||
* @param {string} query [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
Section.prototype.find = function(query){
|
||||
find(query){
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Reconciles the current chapters layout properies with
|
||||
* the global layout properities.
|
||||
* @param {object} global The globa layout settings object, chapter properties string
|
||||
* @return {object} layoutProperties Object with layout properties
|
||||
*/
|
||||
Section.prototype.reconcileLayoutSettings = function(global){
|
||||
/**
|
||||
* Reconciles the current chapters layout properies with
|
||||
* the global layout properities.
|
||||
* @param {object} global The globa layout settings object, chapter properties string
|
||||
* @return {object} layoutProperties Object with layout properties
|
||||
*/
|
||||
reconcileLayoutSettings(global){
|
||||
//-- Get the global defaults
|
||||
var settings = {
|
||||
layout : global.layout,
|
||||
|
@ -163,24 +164,25 @@ Section.prototype.reconcileLayoutSettings = function(global){
|
|||
}
|
||||
});
|
||||
return settings;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a CFI from a Range in the Section
|
||||
* @param {range} _range
|
||||
* @return {string} cfi an EpubCFI string
|
||||
*/
|
||||
Section.prototype.cfiFromRange = function(_range) {
|
||||
cfiFromRange(_range) {
|
||||
return new EpubCFI(_range, this.cfiBase).toString();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get a CFI from an Element in the Section
|
||||
* @param {element} el
|
||||
* @return {string} cfi an EpubCFI string
|
||||
*/
|
||||
Section.prototype.cfiFromElement = function(el) {
|
||||
cfiFromElement(el) {
|
||||
return new EpubCFI(el, this.cfiBase).toString();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Section;
|
||||
export default Section;
|
||||
|
|
64
src/spine.js
64
src/spine.js
|
@ -1,13 +1,14 @@
|
|||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Hook = require('./hook');
|
||||
var Section = require('./section');
|
||||
var replacements = require('./replacements');
|
||||
import core from './utils/core';
|
||||
import EpubCFI from './epubcfi';
|
||||
import Hook from './hook';
|
||||
import Section from './section';
|
||||
import {replaceBase, replaceCanonical} from './replacements';
|
||||
|
||||
/**
|
||||
* A collection of Spine Items
|
||||
*/
|
||||
function Spine(){
|
||||
class Spine {
|
||||
constructor() {
|
||||
this.spineItems = [];
|
||||
this.spineByHref = {};
|
||||
this.spineById = {};
|
||||
|
@ -17,20 +18,20 @@ function Spine(){
|
|||
this.hooks.content = new Hook();
|
||||
|
||||
// Register replacements
|
||||
this.hooks.content.register(replacements.base);
|
||||
this.hooks.content.register(replacements.canonical);
|
||||
this.hooks.content.register(replaceBase);
|
||||
this.hooks.content.register(replaceCanonical);
|
||||
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.loaded = false;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Unpack items from a opf into spine items
|
||||
* @param {Package} _package
|
||||
* @param {method} resolver URL resolver
|
||||
*/
|
||||
Spine.prototype.unpack = function(_package, resolver) {
|
||||
unpack(_package, resolver) {
|
||||
|
||||
this.items = _package.spine;
|
||||
this.manifest = _package.manifest;
|
||||
|
@ -65,9 +66,9 @@ Spine.prototype.unpack = function(_package, resolver) {
|
|||
}.bind(this));
|
||||
|
||||
this.loaded = true;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get an item from the spine
|
||||
* @param {[string|int]} target
|
||||
* @return {Section} section
|
||||
|
@ -76,7 +77,7 @@ Spine.prototype.unpack = function(_package, resolver) {
|
|||
* @example spine.get("chap1.html");
|
||||
* @example spine.get("#id1234");
|
||||
*/
|
||||
Spine.prototype.get = function(target) {
|
||||
get(target) {
|
||||
var index = 0;
|
||||
|
||||
if(this.epubcfi.isCfiString(target)) {
|
||||
|
@ -93,14 +94,14 @@ Spine.prototype.get = function(target) {
|
|||
}
|
||||
|
||||
return this.spineItems[index] || null;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Append a Section to the Spine
|
||||
* @private
|
||||
* @param {Section} section
|
||||
*/
|
||||
Spine.prototype.append = function(section) {
|
||||
append(section) {
|
||||
var index = this.spineItems.length;
|
||||
section.index = index;
|
||||
|
||||
|
@ -110,14 +111,14 @@ Spine.prototype.append = function(section) {
|
|||
this.spineById[section.idref] = index;
|
||||
|
||||
return index;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Prepend a Section to the Spine
|
||||
* @private
|
||||
* @param {Section} section
|
||||
*/
|
||||
Spine.prototype.prepend = function(section) {
|
||||
prepend(section) {
|
||||
var index = this.spineItems.unshift(section);
|
||||
this.spineByHref[section.href] = 0;
|
||||
this.spineById[section.idref] = 0;
|
||||
|
@ -128,18 +129,18 @@ Spine.prototype.prepend = function(section) {
|
|||
});
|
||||
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
// Spine.prototype.insert = function(section, index) {
|
||||
//
|
||||
// };
|
||||
// insert(section, index) {
|
||||
//
|
||||
// };
|
||||
|
||||
/**
|
||||
/**
|
||||
* Remove a Section from the Spine
|
||||
* @private
|
||||
* @param {Section} section
|
||||
*/
|
||||
Spine.prototype.remove = function(section) {
|
||||
remove(section) {
|
||||
var index = this.spineItems.indexOf(section);
|
||||
|
||||
if(index > -1) {
|
||||
|
@ -148,14 +149,15 @@ Spine.prototype.remove = function(section) {
|
|||
|
||||
return this.spineItems.splice(index, 1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Loop over the Sections in the Spine
|
||||
* @return {method} forEach
|
||||
*/
|
||||
Spine.prototype.each = function() {
|
||||
each() {
|
||||
return this.spineItems.forEach.apply(this.spineItems, arguments);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = Spine;
|
||||
export default Spine;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
var Url = require('./core').Url;
|
||||
import Url from './utils/url';
|
||||
|
||||
function Themes(rendition) {
|
||||
class Themes {
|
||||
constructor(rendition) {
|
||||
this.rendition = rendition;
|
||||
this._themes = {
|
||||
"default" : {
|
||||
|
@ -15,9 +16,9 @@ function Themes(rendition) {
|
|||
this.rendition.hooks.content.register(this.inject.bind(this));
|
||||
this.rendition.hooks.content.register(this.overrides.bind(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Themes.prototype.register = function () {
|
||||
register () {
|
||||
if (arguments.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -33,9 +34,9 @@ Themes.prototype.register = function () {
|
|||
if (arguments.length === 2 && typeof(arguments[1]) === "object") {
|
||||
return this.registerRules(arguments[0], arguments[1]);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.default = function (theme) {
|
||||
default (theme) {
|
||||
if (!theme) {
|
||||
return;
|
||||
}
|
||||
|
@ -45,9 +46,9 @@ Themes.prototype.default = function (theme) {
|
|||
if (typeof(theme) === "object") {
|
||||
return this.registerRules("default", theme);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.registerThemes = function (themes) {
|
||||
registerThemes (themes) {
|
||||
for (var theme in themes) {
|
||||
if (themes.hasOwnProperty(theme)) {
|
||||
if (typeof(themes[theme]) === "string") {
|
||||
|
@ -57,19 +58,19 @@ Themes.prototype.registerThemes = function (themes) {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.registerUrl = function (name, input) {
|
||||
registerUrl (name, input) {
|
||||
var url = new Url(input);
|
||||
this._themes[name] = { "url": url.toString() };
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.registerRules = function (name, rules) {
|
||||
registerRules (name, rules) {
|
||||
this._themes[name] = { "rules": rules };
|
||||
// TODO: serialize css rules
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.apply = function (name) {
|
||||
apply (name) {
|
||||
var prev = this._current;
|
||||
var contents;
|
||||
|
||||
|
@ -81,16 +82,16 @@ Themes.prototype.apply = function (name) {
|
|||
content.removeClass(prev);
|
||||
content.addClass(name);
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.update = function (name) {
|
||||
update (name) {
|
||||
var contents = this.rendition.getContents();
|
||||
contents.forEach(function (content) {
|
||||
this.add(name, content);
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.inject = function (view) {
|
||||
inject (view) {
|
||||
var links = [];
|
||||
var themes = this._themes;
|
||||
var theme;
|
||||
|
@ -107,9 +108,9 @@ Themes.prototype.inject = function (view) {
|
|||
if(this._current) {
|
||||
view.contents.addClass(this._current);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.add = function (name, contents) {
|
||||
add (name, contents) {
|
||||
var theme = this._themes[name];
|
||||
|
||||
if (!theme) {
|
||||
|
@ -124,9 +125,9 @@ Themes.prototype.add = function (name, contents) {
|
|||
contents.addStylesheetRules(theme.rules);
|
||||
theme.injected = true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.override = function (name, value) {
|
||||
override (name, value) {
|
||||
var contents = this.rendition.getContents();
|
||||
|
||||
this._overrides[name] = value;
|
||||
|
@ -134,9 +135,9 @@ Themes.prototype.override = function (name, value) {
|
|||
contents.forEach(function (content) {
|
||||
content.css(name, this._overrides[name]);
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.overrides = function (view) {
|
||||
overrides (view) {
|
||||
var contents = view.contents;
|
||||
var overrides = this._overrides;
|
||||
var rules = [];
|
||||
|
@ -146,10 +147,12 @@ Themes.prototype.overrides = function (view) {
|
|||
contents.css(rule, overrides[rule]);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Themes.prototype.fontSize = function (size) {
|
||||
fontSize (size) {
|
||||
this.override("font-size", size);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Themes;
|
||||
}
|
||||
|
||||
export default Themes;
|
||||
|
|
|
@ -1,144 +1,11 @@
|
|||
var base64 = require('base64-js');
|
||||
var path = require('path');
|
||||
export const requestAnimationFrame = (typeof window != 'undefined') ? (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame) : false;
|
||||
|
||||
var requestAnimationFrame = (typeof window != 'undefined') ? (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame) : false;
|
||||
|
||||
/**
|
||||
* creates a uri object
|
||||
* @param {string} urlString a url string (relative or absolute)
|
||||
* @param {[string]} baseString optional base for the url,
|
||||
* default to window.location.href
|
||||
* @return {object} url
|
||||
*/
|
||||
function Url(urlString, baseString) {
|
||||
var absolute = (urlString.indexOf('://') > -1);
|
||||
var pathname = urlString;
|
||||
|
||||
this.Url = undefined;
|
||||
this.href = urlString;
|
||||
this.protocol = "";
|
||||
this.origin = "";
|
||||
this.fragment = "";
|
||||
this.search = "";
|
||||
this.base = baseString;
|
||||
|
||||
if (!absolute && (typeof(baseString) !== "string")) {
|
||||
this.base = window && window.location.href;
|
||||
}
|
||||
|
||||
// URL Polyfill doesn't throw an error if base is empty
|
||||
if (absolute || this.base) {
|
||||
try {
|
||||
this.Url = new URL(urlString, this.base);
|
||||
this.href = this.Url.href;
|
||||
|
||||
this.protocol = this.Url.protocol;
|
||||
this.origin = this.Url.origin;
|
||||
this.fragment = this.Url.fragment;
|
||||
this.search = this.Url.search;
|
||||
|
||||
pathname = this.Url.pathname;
|
||||
} catch (e) {
|
||||
// Skip URL parsing
|
||||
this.Url = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
this.Path = new Path(pathname);
|
||||
this.directory = this.Path.directory;
|
||||
this.filename = this.Path.filename;
|
||||
this.extension = this.Path.extension;
|
||||
|
||||
}
|
||||
|
||||
Url.prototype.path = function () {
|
||||
return this.Path;
|
||||
};
|
||||
|
||||
Url.prototype.resolve = function (what) {
|
||||
var isAbsolute = (what.indexOf('://') > -1);
|
||||
var fullpath;
|
||||
|
||||
if (isAbsolute) {
|
||||
return what;
|
||||
}
|
||||
|
||||
fullpath = path.resolve(this.directory, what);
|
||||
return this.origin + fullpath;
|
||||
};
|
||||
|
||||
Url.prototype.relative = function (what) {
|
||||
return path.relative(what, this.directory);
|
||||
};
|
||||
|
||||
Url.prototype.toString = function () {
|
||||
return this.href;
|
||||
};
|
||||
|
||||
function Path(pathString) {
|
||||
var protocol;
|
||||
var parsed;
|
||||
|
||||
protocol = pathString.indexOf('://');
|
||||
if (protocol > -1) {
|
||||
pathString = new URL(pathString).pathname;
|
||||
}
|
||||
|
||||
parsed = this.parse(pathString);
|
||||
|
||||
this.path = pathString;
|
||||
|
||||
if (this.isDirectory(pathString)) {
|
||||
this.directory = pathString;
|
||||
} else {
|
||||
this.directory = parsed.dir + "/";
|
||||
}
|
||||
|
||||
this.filename = parsed.base;
|
||||
this.extension = parsed.ext.slice(1);
|
||||
|
||||
}
|
||||
|
||||
Path.prototype.parse = function (what) {
|
||||
return path.parse(what);
|
||||
};
|
||||
|
||||
Path.prototype.isAbsolute = function (what) {
|
||||
return path.isAbsolute(what || this.path);
|
||||
};
|
||||
|
||||
Path.prototype.isDirectory = function (what) {
|
||||
return (what.charAt(what.length-1) === '/');
|
||||
};
|
||||
|
||||
Path.prototype.resolve = function (what) {
|
||||
return path.resolve(this.directory, what);
|
||||
};
|
||||
|
||||
Path.prototype.relative = function (what) {
|
||||
return path.relative(this.directory, what);
|
||||
};
|
||||
|
||||
Path.prototype.splitPath = function(filename) {
|
||||
return this.splitPathRe.exec(filename).slice(1);
|
||||
};
|
||||
|
||||
Path.prototype.toString = function () {
|
||||
return this.path;
|
||||
};
|
||||
|
||||
function assertPath(path) {
|
||||
if (typeof path !== 'string') {
|
||||
throw new TypeError('Path must be a string. Received ', path);
|
||||
}
|
||||
};
|
||||
|
||||
function isElement(obj) {
|
||||
export function isElement(obj) {
|
||||
return !!(obj && obj.nodeType == 1);
|
||||
};
|
||||
|
||||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
|
||||
function uuid() {
|
||||
export function uuid() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = (d + Math.random()*16)%16 | 0;
|
||||
|
@ -149,7 +16,7 @@ function uuid() {
|
|||
};
|
||||
|
||||
// From Lodash
|
||||
function values(object) {
|
||||
export function values(object) {
|
||||
var index = -1,
|
||||
props = Object.keys(object),
|
||||
length = props.length,
|
||||
|
@ -161,70 +28,7 @@ function values(object) {
|
|||
return result;
|
||||
};
|
||||
|
||||
function resolveUrl(base, path) {
|
||||
var url = [],
|
||||
segments = [],
|
||||
baseUri = uri(base),
|
||||
pathUri = uri(path),
|
||||
baseDirectory = baseUri.directory,
|
||||
pathDirectory = pathUri.directory,
|
||||
directories = [],
|
||||
// folders = base.split("/"),
|
||||
paths;
|
||||
|
||||
// if(uri.host) {
|
||||
// return path;
|
||||
// }
|
||||
|
||||
if(baseDirectory[0] === "/") {
|
||||
baseDirectory = baseDirectory.substring(1);
|
||||
}
|
||||
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
baseDirectory = baseDirectory.substring(0, baseDirectory.length-1);
|
||||
}
|
||||
|
||||
if(pathDirectory[0] === "/") {
|
||||
pathDirectory = pathDirectory.substring(1);
|
||||
}
|
||||
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
pathDirectory = pathDirectory.substring(0, pathDirectory.length-1);
|
||||
}
|
||||
|
||||
if(baseDirectory) {
|
||||
directories = baseDirectory.split("/");
|
||||
}
|
||||
|
||||
paths = pathDirectory.split("/");
|
||||
|
||||
paths.reverse().forEach(function(part, index){
|
||||
if(part === ".."){
|
||||
directories.pop();
|
||||
} else if(part === directories[directories.length-1]) {
|
||||
directories.pop();
|
||||
segments.unshift(part);
|
||||
} else {
|
||||
segments.unshift(part);
|
||||
}
|
||||
});
|
||||
|
||||
url = [baseUri.origin];
|
||||
|
||||
if(directories.length) {
|
||||
url = url.concat(directories);
|
||||
}
|
||||
|
||||
if(segments) {
|
||||
url = url.concat(segments);
|
||||
}
|
||||
|
||||
url = url.concat(pathUri.filename);
|
||||
|
||||
return url.join("/");
|
||||
};
|
||||
|
||||
function documentHeight() {
|
||||
export function documentHeight() {
|
||||
return Math.max(
|
||||
document.documentElement.clientHeight,
|
||||
document.body.scrollHeight,
|
||||
|
@ -234,15 +38,15 @@ function documentHeight() {
|
|||
);
|
||||
};
|
||||
|
||||
function isNumber(n) {
|
||||
export function isNumber(n) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
};
|
||||
|
||||
function isFloat(n) {
|
||||
export function isFloat(n) {
|
||||
return isNumber(n) && (Math.floor(n) !== n);
|
||||
}
|
||||
|
||||
function prefixed(unprefixed) {
|
||||
export function prefixed(unprefixed) {
|
||||
var vendors = ["Webkit", "Moz", "O", "ms" ],
|
||||
prefixes = ['-Webkit-', '-moz-', '-o-', '-ms-'],
|
||||
upper = unprefixed[0].toUpperCase() + unprefixed.slice(1),
|
||||
|
@ -261,7 +65,7 @@ function prefixed(unprefixed) {
|
|||
return unprefixed;
|
||||
};
|
||||
|
||||
function defaults(obj) {
|
||||
export function defaults(obj) {
|
||||
for (var i = 1, length = arguments.length; i < length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var prop in source) {
|
||||
|
@ -271,7 +75,7 @@ function defaults(obj) {
|
|||
return obj;
|
||||
};
|
||||
|
||||
function extend(target) {
|
||||
export function extend(target) {
|
||||
var sources = [].slice.call(arguments, 1);
|
||||
sources.forEach(function (source) {
|
||||
if(!source) return;
|
||||
|
@ -284,14 +88,14 @@ function extend(target) {
|
|||
|
||||
// Fast quicksort insert for sorted array -- based on:
|
||||
// http://stackoverflow.com/questions/1344500/efficient-way-to-insert-a-number-into-a-sorted-array-of-numbers
|
||||
function insert(item, array, compareFunction) {
|
||||
export function insert(item, array, compareFunction) {
|
||||
var location = locationOf(item, array, compareFunction);
|
||||
array.splice(location, 0, item);
|
||||
|
||||
return location;
|
||||
};
|
||||
// Returns where something would fit in
|
||||
function locationOf(item, array, compareFunction, _start, _end) {
|
||||
export function locationOf(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
|
@ -322,7 +126,7 @@ function locationOf(item, array, compareFunction, _start, _end) {
|
|||
}
|
||||
};
|
||||
// Returns -1 of mpt found
|
||||
function indexOfSorted(item, array, compareFunction, _start, _end) {
|
||||
export function indexOfSorted(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
|
@ -352,7 +156,7 @@ function indexOfSorted(item, array, compareFunction, _start, _end) {
|
|||
}
|
||||
};
|
||||
|
||||
function bounds(el) {
|
||||
export function bounds(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
|
@ -376,7 +180,7 @@ function bounds(el) {
|
|||
|
||||
};
|
||||
|
||||
function borders(el) {
|
||||
export function borders(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
|
@ -400,7 +204,7 @@ function borders(el) {
|
|||
|
||||
};
|
||||
|
||||
function windowBounds() {
|
||||
export function windowBounds() {
|
||||
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
|
@ -417,7 +221,7 @@ function windowBounds() {
|
|||
};
|
||||
|
||||
//https://stackoverflow.com/questions/13482352/xquery-looking-for-text-with-single-quote/13483496#13483496
|
||||
function cleanStringForXpath(str) {
|
||||
export function cleanStringForXpath(str) {
|
||||
var parts = str.match(/[^'"]+|['"]/g);
|
||||
parts = parts.map(function(part){
|
||||
if (part === "'") {
|
||||
|
@ -432,7 +236,7 @@ function cleanStringForXpath(str) {
|
|||
return "concat(\'\'," + parts.join(",") + ")";
|
||||
};
|
||||
|
||||
function indexOfTextNode(textNode){
|
||||
export function indexOfTextNode(textNode){
|
||||
var parent = textNode.parentNode;
|
||||
var children = parent.childNodes;
|
||||
var sib;
|
||||
|
@ -448,17 +252,17 @@ function indexOfTextNode(textNode){
|
|||
return index;
|
||||
};
|
||||
|
||||
function isXml(ext) {
|
||||
export function isXml(ext) {
|
||||
return ['xml', 'opf', 'ncx'].indexOf(ext) > -1;
|
||||
}
|
||||
|
||||
function createBlob(content, mime){
|
||||
export function createBlob(content, mime){
|
||||
var blob = new Blob([content], {type : mime });
|
||||
|
||||
return blob;
|
||||
};
|
||||
|
||||
function createBlobUrl(content, mime){
|
||||
export function createBlobUrl(content, mime){
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var tempUrl;
|
||||
var blob = this.createBlob(content, mime);
|
||||
|
@ -468,7 +272,7 @@ function createBlobUrl(content, mime){
|
|||
return tempUrl;
|
||||
};
|
||||
|
||||
function createBase64Url(content, mime){
|
||||
export function createBase64Url(content, mime){
|
||||
var string;
|
||||
var data;
|
||||
var datauri;
|
||||
|
@ -485,11 +289,11 @@ function createBase64Url(content, mime){
|
|||
return datauri;
|
||||
};
|
||||
|
||||
function type(obj){
|
||||
export function type(obj){
|
||||
return Object.prototype.toString.call(obj).slice(8, -1);
|
||||
}
|
||||
|
||||
function parse(markup, mime, forceXMLDom) {
|
||||
export function parse(markup, mime, forceXMLDom) {
|
||||
var doc;
|
||||
|
||||
if (typeof DOMParser === "undefined" || forceXMLDom) {
|
||||
|
@ -502,7 +306,7 @@ function parse(markup, mime, forceXMLDom) {
|
|||
return doc;
|
||||
}
|
||||
|
||||
function qs(el, sel) {
|
||||
export function qs(el, sel) {
|
||||
var elements;
|
||||
if (!el) {
|
||||
throw new Error('No Element Provided');
|
||||
|
@ -518,7 +322,7 @@ function qs(el, sel) {
|
|||
}
|
||||
}
|
||||
|
||||
function qsa(el, sel) {
|
||||
export function qsa(el, sel) {
|
||||
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelectorAll(sel);
|
||||
|
@ -527,7 +331,7 @@ function qsa(el, sel) {
|
|||
}
|
||||
}
|
||||
|
||||
function qsp(el, sel, props) {
|
||||
export function qsp(el, sel, props) {
|
||||
var q, filtered;
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
sel += '[';
|
||||
|
@ -558,7 +362,7 @@ function qsp(el, sel, props) {
|
|||
* @param {element} root element to start with
|
||||
* @param {function} func function to run on each element
|
||||
*/
|
||||
function sprint(root, func) {
|
||||
export function sprint(root, func) {
|
||||
var doc = root.ownerDocument || root;
|
||||
if (typeof(doc.createTreeWalker) !== "undefined") {
|
||||
treeWalker(root, func, NodeFilter.SHOW_TEXT);
|
||||
|
@ -571,14 +375,15 @@ function sprint(root, func) {
|
|||
}
|
||||
}
|
||||
|
||||
function treeWalker(root, func, filter) {
|
||||
export function treeWalker(root, func, filter) {
|
||||
var treeWalker = document.createTreeWalker(root, filter, null, false);
|
||||
let node;
|
||||
while ((node = treeWalker.nextNode())) {
|
||||
func(node);
|
||||
}
|
||||
}
|
||||
|
||||
// function walk(root, func, onlyText) {
|
||||
// export function walk(root, func, onlyText) {
|
||||
// var node = root;
|
||||
//
|
||||
// if (node && !onlyText || node.nodeType === 3) { // Node.TEXT_NODE
|
||||
|
@ -597,7 +402,7 @@ function treeWalker(root, func, filter) {
|
|||
* @param callback return false for continue,true for break
|
||||
* @return boolean true: break visit;
|
||||
*/
|
||||
function walk(node,callback){
|
||||
export function walk(node,callback){
|
||||
if(callback(node)){
|
||||
return true;
|
||||
}
|
||||
|
@ -608,7 +413,7 @@ function walk(node,callback){
|
|||
}
|
||||
}
|
||||
|
||||
function blob2base64(blob, cb) {
|
||||
export function blob2base64(blob, cb) {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onloadend = function() {
|
||||
|
@ -617,7 +422,7 @@ function blob2base64(blob, cb) {
|
|||
}
|
||||
|
||||
// From: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred#backwards_forwards_compatible
|
||||
function defer() {
|
||||
export function defer() {
|
||||
/* A method to resolve the associated Promise with the value passed.
|
||||
* If the promise is already settled it does nothing.
|
||||
*
|
||||
|
@ -648,14 +453,14 @@ function defer() {
|
|||
Object.freeze(this);
|
||||
}
|
||||
|
||||
function querySelectorByType(html, element, type){
|
||||
export function querySelectorByType(html, element, type){
|
||||
var query;
|
||||
if (typeof html.querySelector != "undefined") {
|
||||
query = html.querySelector(element+'[*|type="'+type+'"]');
|
||||
}
|
||||
// Handle IE not supporting namespaced epub:type in querySelector
|
||||
if(!query || query.length === 0) {
|
||||
query = this.qsa(html, element);
|
||||
query = qsa(html, element);
|
||||
for (var i = 0; i < query.length; i++) {
|
||||
if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type) {
|
||||
return query[i];
|
||||
|
@ -666,53 +471,14 @@ function defer() {
|
|||
}
|
||||
}
|
||||
|
||||
function children(el) {
|
||||
var children = [];
|
||||
export function findChildren(el) {
|
||||
var result = [];
|
||||
var childNodes = el.parentNode.childNodes;
|
||||
for (var i = 0; i < childNodes.length; i++) {
|
||||
node = childNodes[i];
|
||||
let node = childNodes[i];
|
||||
if (node.nodeType === 1) {
|
||||
children.push(node);
|
||||
result.push(node);
|
||||
}
|
||||
};
|
||||
return children;
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'isElement': isElement,
|
||||
'uuid': uuid,
|
||||
'values': values,
|
||||
'resolveUrl': resolveUrl,
|
||||
'indexOfSorted': indexOfSorted,
|
||||
'documentHeight': documentHeight,
|
||||
'isNumber': isNumber,
|
||||
'isFloat': isFloat,
|
||||
'prefixed': prefixed,
|
||||
'defaults': defaults,
|
||||
'extend': extend,
|
||||
'insert': insert,
|
||||
'locationOf': locationOf,
|
||||
'indexOfSorted': indexOfSorted,
|
||||
'requestAnimationFrame': requestAnimationFrame,
|
||||
'bounds': bounds,
|
||||
'borders': borders,
|
||||
'windowBounds': windowBounds,
|
||||
'cleanStringForXpath': cleanStringForXpath,
|
||||
'indexOfTextNode': indexOfTextNode,
|
||||
'isXml': isXml,
|
||||
'createBlob': createBlob,
|
||||
'createBlobUrl': createBlobUrl,
|
||||
'type': type,
|
||||
'parse' : parse,
|
||||
'qs' : qs,
|
||||
'qsa' : qsa,
|
||||
'qsp' : qsp,
|
||||
'blob2base64' : blob2base64,
|
||||
'createBase64Url': createBase64Url,
|
||||
'defer': defer,
|
||||
'Url': Url,
|
||||
'Path': Path,
|
||||
'querySelectorByType': querySelectorByType,
|
||||
'sprint' : sprint,
|
||||
'children' : children
|
||||
};
|
57
src/utils/path.js
Normal file
57
src/utils/path.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import path from 'path-webpack';
|
||||
|
||||
class Path {
|
||||
constructor(pathString) {
|
||||
var protocol;
|
||||
var parsed;
|
||||
|
||||
protocol = pathString.indexOf('://');
|
||||
if (protocol > -1) {
|
||||
pathString = new URL(pathString).pathname;
|
||||
}
|
||||
|
||||
parsed = this.parse(pathString);
|
||||
|
||||
this.path = pathString;
|
||||
|
||||
if (this.isDirectory(pathString)) {
|
||||
this.directory = pathString;
|
||||
} else {
|
||||
this.directory = parsed.dir + "/";
|
||||
}
|
||||
|
||||
this.filename = parsed.base;
|
||||
this.extension = parsed.ext.slice(1);
|
||||
|
||||
}
|
||||
|
||||
parse (what) {
|
||||
return path.parse(what);
|
||||
};
|
||||
|
||||
isAbsolute (what) {
|
||||
return path.isAbsolute(what || this.path);
|
||||
};
|
||||
|
||||
isDirectory (what) {
|
||||
return (what.charAt(what.length-1) === '/');
|
||||
};
|
||||
|
||||
resolve (what) {
|
||||
return path.resolve(this.directory, what);
|
||||
};
|
||||
|
||||
relative (what) {
|
||||
return path.relative(this.directory, what);
|
||||
};
|
||||
|
||||
splitPath(filename) {
|
||||
return this.splitPathRe.exec(filename).slice(1);
|
||||
};
|
||||
|
||||
toString () {
|
||||
return this.path;
|
||||
};
|
||||
}
|
||||
|
||||
export default Path
|
83
src/utils/url.js
Normal file
83
src/utils/url.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
import Path from './path'
|
||||
import path from 'path-webpack';
|
||||
|
||||
/**
|
||||
* creates a uri object
|
||||
* @param {string} urlString a url string (relative or absolute)
|
||||
* @param {[string]} baseString optional base for the url,
|
||||
* default to window.location.href
|
||||
* @return {object} url
|
||||
*/
|
||||
|
||||
class Url {
|
||||
constructor(urlString, baseString) {
|
||||
var absolute = (urlString.indexOf('://') > -1);
|
||||
var pathname = urlString;
|
||||
|
||||
this.Url = undefined;
|
||||
this.href = urlString;
|
||||
this.protocol = "";
|
||||
this.origin = "";
|
||||
this.fragment = "";
|
||||
this.search = "";
|
||||
this.base = baseString;
|
||||
|
||||
if (!absolute && (typeof(baseString) !== "string")) {
|
||||
this.base = window && 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
|
||||
this.Url = new URL(urlString, this.base);
|
||||
} else {
|
||||
this.Url = new URL(urlString);
|
||||
}
|
||||
this.href = this.Url.href;
|
||||
|
||||
this.protocol = this.Url.protocol;
|
||||
this.origin = this.Url.origin;
|
||||
this.fragment = this.Url.fragment;
|
||||
this.search = this.Url.search;
|
||||
|
||||
pathname = this.Url.pathname;
|
||||
} catch (e) {
|
||||
// Skip URL parsing
|
||||
this.Url = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
this.Path = new Path(pathname);
|
||||
this.directory = this.Path.directory;
|
||||
this.filename = this.Path.filename;
|
||||
this.extension = this.Path.extension;
|
||||
|
||||
}
|
||||
|
||||
path () {
|
||||
return this.Path;
|
||||
};
|
||||
|
||||
resolve (what) {
|
||||
var isAbsolute = (what.indexOf('://') > -1);
|
||||
var fullpath;
|
||||
|
||||
if (isAbsolute) {
|
||||
return what;
|
||||
}
|
||||
|
||||
fullpath = path.resolve(this.directory, what);
|
||||
return this.origin + fullpath;
|
||||
};
|
||||
|
||||
relative (what) {
|
||||
return path.relative(what, this.directory);
|
||||
};
|
||||
|
||||
toString () {
|
||||
return this.href;
|
||||
};
|
||||
}
|
||||
|
||||
export default Url
|
|
@ -9,7 +9,7 @@ describe('Core', function() {
|
|||
|
||||
describe('Url', function () {
|
||||
|
||||
var Url = require('../src/core').Url;
|
||||
var Url = require('../src/utils/url');
|
||||
|
||||
it("Url()", function() {
|
||||
var url = new Url("http://example.com/fred/chasen/derf.html");
|
||||
|
@ -61,7 +61,7 @@ describe('Core', function() {
|
|||
|
||||
describe('Path', function () {
|
||||
|
||||
var Path = require('../src/core').Path;
|
||||
var Path = require('../src/utils/path');
|
||||
|
||||
it("Path()", function() {
|
||||
var path = new Path("/fred/chasen/derf.html");
|
||||
|
|
|
@ -8,13 +8,13 @@ describe('EpubCFI', function() {
|
|||
var EpubCFI = require('../src/epubcfi.js');
|
||||
|
||||
it('parse a cfi on init', function() {
|
||||
var cfi = EpubCFI("epubcfi(/6/2[cover]!/6)");
|
||||
var cfi = new EpubCFI("epubcfi(/6/2[cover]!/6)");
|
||||
|
||||
assert.equal( cfi.spinePos, 0, "spinePos is parsed as the first item" );
|
||||
});
|
||||
|
||||
it('parse a cfi and ignore the base if present', function() {
|
||||
var cfi = EpubCFI("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
|
||||
var cfi = new EpubCFI("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
|
||||
|
||||
assert.equal( cfi.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
|
||||
});
|
||||
|
@ -56,9 +56,9 @@ describe('EpubCFI', function() {
|
|||
describe('#toString()', function() {
|
||||
it('parse a cfi and write it back', function() {
|
||||
|
||||
assert.equal(EpubCFI("epubcfi(/6/2[cover]!/6)").toString(), "epubcfi(/6/2[cover]!/6)", "output cfi string is same as input" );
|
||||
assert.equal(EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)", "output cfi string is same as input" );
|
||||
assert.equal(EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)", "output cfi string is same as input" );
|
||||
assert.equal(new EpubCFI("epubcfi(/6/2[cover]!/6)").toString(), "epubcfi(/6/2[cover]!/6)", "output cfi string is same as input" );
|
||||
assert.equal(new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)", "output cfi string is same as input" );
|
||||
assert.equal(new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)").toString(), "epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)", "output cfi string is same as input" );
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ describe('EpubCFI', function() {
|
|||
});
|
||||
|
||||
it('determine the type of a cfi', function() {
|
||||
var ogcfi = EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
|
||||
var ogcfi = new EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
|
||||
var cfi = new EpubCFI();
|
||||
|
||||
assert.equal( cfi.checkType(ogcfi), 'EpubCFI' );
|
||||
|
|
|
@ -2,12 +2,10 @@ var assert = require('assert');
|
|||
|
||||
describe('Locations', function() {
|
||||
var Locations = require('../src/locations');
|
||||
var core = require('../src/core');
|
||||
var chapter = require('raw-loader!./fixtures/locations.xhtml');
|
||||
var core = require('../src/utils/core');
|
||||
|
||||
describe('#parse', function() {
|
||||
var Locations = require('../src/locations');
|
||||
var core = require('../src/core');
|
||||
var chapter = require('raw-loader!./fixtures/locations.xhtml');
|
||||
|
||||
it('parse locations from a document', function() {
|
||||
|
@ -25,7 +23,6 @@ describe('Locations', function() {
|
|||
|
||||
var locations = new Locations();
|
||||
var result = locations.parse(contents, "/6/4[chap01ref]", 100);
|
||||
console.log(result);
|
||||
assert.equal(result.length, 15);
|
||||
|
||||
});
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
var webpack = require("webpack");
|
||||
var path = require('path');
|
||||
var BabiliPlugin = require("babili-webpack-plugin");
|
||||
var PROD = (process.env.NODE_ENV === 'production')
|
||||
var LEGACY = (process.env.LEGACY)
|
||||
var hostname = "localhost";
|
||||
var port = "8080";
|
||||
var enter = LEGACY ? {
|
||||
"epub.legacy": ["babel-polyfill", "./libs/url/url.js", "./src/epub.js"]
|
||||
} : {
|
||||
"epub": "./src/epub.js",
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
epub: "./src/epub.js",
|
||||
polyfills: ["./node_modules/es6-promise/dist/es6-promise.auto.js", "./libs/url/url.js"]
|
||||
},
|
||||
devtool: 'source-map',
|
||||
entry: enter,
|
||||
devtool: PROD ? false : 'source-map',
|
||||
output: {
|
||||
path: path.resolve("./dist"),
|
||||
// path: "./dist",
|
||||
filename: "[name].js",
|
||||
filename: PROD ? "[name].min.js" : "[name].js",
|
||||
sourceMapFilename: "[name].js.map",
|
||||
library: "ePub",
|
||||
libraryTarget: "umd",
|
||||
|
@ -23,9 +27,9 @@ module.exports = {
|
|||
"jszip": "JSZip",
|
||||
"xmldom": "xmldom"
|
||||
},
|
||||
plugins: [
|
||||
// new webpack.IgnorePlugin(/punycode|IPv6/),
|
||||
],
|
||||
plugins: PROD ? [
|
||||
new BabiliPlugin()
|
||||
] : [],
|
||||
resolve: {
|
||||
alias: {
|
||||
path: "path-webpack"
|
||||
|
@ -35,5 +39,24 @@ module.exports = {
|
|||
host: hostname,
|
||||
port: port,
|
||||
inline: true
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
LEGACY ? {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "babel-loader",
|
||||
query: {
|
||||
presets: ['es2015'],
|
||||
plugins: [
|
||||
"add-module-exports",
|
||||
]
|
||||
}
|
||||
} : {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "babel-loader"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue