1
0
Fork 0
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:
Fred Chasen 2016-12-06 15:04:16 +01:00
parent b0944bdff8
commit 353dfa62fd
46 changed files with 16839 additions and 18742 deletions

15
.babelrc Normal file
View file

@ -0,0 +1,15 @@
{
"presets": [
["env", {
"targets": {
"chrome": 54,
"safari" : 10,
"firefox" : 50,
"edge" : 14
}
}]
],
"plugins": [
"add-module-exports"
]
}

3
.gitignore vendored
View file

@ -5,3 +5,6 @@ components
node_modules
bower_components
books
lib
dist
documentation/html

View file

@ -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"
}
}

16366
dist/epub.js vendored

File diff suppressed because it is too large Load diff

2
dist/epub.js.map vendored

File diff suppressed because one or more lines are too long

5
dist/epub.min.js vendored

File diff suppressed because one or more lines are too long

2110
dist/polyfills.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -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"
]
}
}
]
}
},

View file

@ -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"
}
}

View file

@ -1,13 +1,14 @@
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 = {};
@ -18,7 +19,7 @@ function Archive() {
* Requires JSZip if it isn't there
* @private
*/
Archive.prototype.checkRequirements = function(){
checkRequirements(){
try {
if (typeof JSZip === 'undefined') {
JSZip = require('jszip');
@ -35,7 +36,7 @@ Archive.prototype.checkRequirements = function(){
* @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});
};
@ -45,7 +46,7 @@ Archive.prototype.open = function(input, isBase64){
* @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});
@ -58,8 +59,8 @@ Archive.prototype.openUrl = function(zipUrl, isBase64){
* @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 {
@ -96,23 +97,23 @@ Archive.prototype.request = function(url, type){
* @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;
}
@ -126,7 +127,7 @@ Archive.prototype.handleResponse = function(response, type){
* @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);
@ -144,7 +145,7 @@ Archive.prototype.getBlob = function(url, mimeType){
* @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);
@ -161,7 +162,7 @@ Archive.prototype.getText = function(url, encoding){
* @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);
@ -179,8 +180,8 @@ Archive.prototype.getBase64 = function(url, mimeType){
* @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;
@ -236,10 +237,11 @@ Archive.prototype.createUrl = function(url, options){
* 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;

View file

@ -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,12 +141,12 @@ 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));
});
}
};
@ -158,7 +157,7 @@ function Book(url, options){
* @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,7 +180,7 @@ Book.prototype.open = function(input, what){
}
return opening;
};
}
/**
* Open an archived epub
@ -190,15 +189,15 @@ Book.prototype.open = function(input, what){
* @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
@ -206,13 +205,13 @@ Book.prototype.openEpub = function(data, encoding){
* @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
@ -220,22 +219,22 @@ Book.prototype.openContainer = function(url){
* @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,7 +244,7 @@ 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
@ -253,7 +252,7 @@ Book.prototype.load = function (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);
@ -278,7 +277,7 @@ Book.prototype.resolve = function (path, absolute) {
* @param {string} input
* @return {string} binary | directory | epub | opf
*/
Book.prototype.determineType = function(input) {
determineType(input) {
var url;
var path;
var extension;
@ -310,7 +309,7 @@ Book.prototype.determineType = function(input) {
* @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,20 +362,20 @@ 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
@ -384,7 +383,7 @@ Book.prototype.section = function(target) {
* @param {[object]} options
* @return {Rendition}
*/
Book.prototype.renderTo = function(element, options) {
renderTo(element, options) {
// var renderMethod = (options && options.method) ?
// options.method :
// "single";
@ -399,7 +398,7 @@ Book.prototype.renderTo = function(element, options) {
* Set if request should use withCredentials
* @param {boolean} credentials
*/
Book.prototype.setRequestCredentials = function(credentials) {
setRequestCredentials(credentials) {
this.settings.requestCredentials = credentials;
};
@ -407,7 +406,7 @@ Book.prototype.setRequestCredentials = function(credentials) {
* Set headers request should use
* @param {object} headers
*/
Book.prototype.setRequestHeaders = function(headers) {
setRequestHeaders(headers) {
this.settings.requestHeaders = headers;
};
@ -418,53 +417,53 @@ Book.prototype.setRequestHeaders = function(headers) {
* @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;

View file

@ -1,13 +1,14 @@
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);
}
@ -17,7 +18,7 @@ function Container(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");
@ -37,5 +38,6 @@ Container.prototype.parse = function(containerDocument){
this.directory = path.dirname(this.packagePath);
this.encoding = containerDocument.xmlEncoding;
};
}
module.exports = Container;
export default Container;

View file

@ -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();
@ -25,11 +26,11 @@ function Contents(doc, content, 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";
}
@ -43,11 +44,11 @@ Contents.prototype.width = function(w) {
};
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";
}
@ -60,11 +61,11 @@ Contents.prototype.height = function(h) {
};
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";
}
@ -77,11 +78,11 @@ Contents.prototype.contentWidth = function(w) {
};
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";
}
@ -93,7 +94,7 @@ Contents.prototype.contentHeight = function(h) {
};
Contents.prototype.textWidth = function() {
textWidth() {
var width;
var range = this.document.createRange();
var content = this.content || this.document.body;
@ -108,7 +109,7 @@ Contents.prototype.textWidth = function() {
};
Contents.prototype.textHeight = function() {
textHeight() {
var height;
var range = this.document.createRange();
var content = this.content || this.document.body;
@ -120,19 +121,19 @@ Contents.prototype.textHeight = function() {
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;
@ -141,7 +142,7 @@ Contents.prototype.overflow = function(overflow) {
return this.window.getComputedStyle(this.documentElement)['overflow'];
};
Contents.prototype.overflowX = function(overflow) {
overflowX(overflow) {
if (overflow) {
this.documentElement.style.overflowX = overflow;
@ -150,7 +151,7 @@ Contents.prototype.overflowX = function(overflow) {
return this.window.getComputedStyle(this.documentElement)['overflowX'];
};
Contents.prototype.overflowY = function(overflow) {
overflowY(overflow) {
if (overflow) {
this.documentElement.style.overflowY = overflow;
@ -159,7 +160,7 @@ Contents.prototype.overflowY = function(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) {
@ -169,7 +170,7 @@ 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 = '';
@ -223,7 +224,7 @@ Contents.prototype.viewport = function(options) {
};
// Contents.prototype.layout = function(layoutFunc) {
// layout(layoutFunc) {
//
// this.iframe.style.display = "inline-block";
//
@ -240,15 +241,15 @@ Contents.prototype.viewport = function(options) {
//
// };
//
// Contents.prototype.onLayout = function(view) {
// onLayout(view) {
// // stub
// };
Contents.prototype.expand = function() {
expand() {
this.emit("expand");
};
Contents.prototype.listeners = function() {
listeners() {
this.imageLoadListeners();
@ -264,14 +265,14 @@ Contents.prototype.listeners = function() {
};
Contents.prototype.removeListeners = function() {
removeListeners() {
this.removeEventListeners();
this.removeSelectionListeners();
};
Contents.prototype.resizeListeners = function() {
resizeListeners() {
var width, height;
// Test size again
clearTimeout(this.expanding);
@ -293,7 +294,7 @@ Contents.prototype.resizeListeners = function() {
};
//https://github.com/tylergaw/media-query-events/blob/master/js/mq-events.js
Contents.prototype.mediaQueryListeners = function() {
mediaQueryListeners() {
var sheets = this.document.styleSheets;
var mediaChangeHandler = function(m){
if(m.matches && !this._expanding) {
@ -322,7 +323,7 @@ Contents.prototype.mediaQueryListeners = function() {
}
};
Contents.prototype.observe = function(target) {
observe(target) {
var renderer = this;
// create an observer instance
@ -344,7 +345,7 @@ Contents.prototype.observe = function(target) {
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++) {
@ -357,7 +358,7 @@ Contents.prototype.imageLoadListeners = function(target) {
}
};
Contents.prototype.fontLoadListeners = function(target) {
fontLoadListeners(target) {
if (!this.document || !this.document.fonts) {
return;
}
@ -368,12 +369,12 @@ Contents.prototype.fontLoadListeners = function(target) {
};
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};
@ -416,7 +417,7 @@ 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;
@ -453,7 +454,7 @@ Contents.prototype.addStylesheet = function(src) {
};
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule
Contents.prototype.addStylesheetRules = function(rules) {
addStylesheetRules(rules) {
var styleEl;
var styleSheet;
var key = "epubjs-inserted-css";
@ -491,7 +492,7 @@ Contents.prototype.addStylesheetRules = function(rules) {
}
};
Contents.prototype.addScript = function(src) {
addScript(src) {
return new Promise(function(resolve, reject){
var $script;
@ -520,7 +521,7 @@ Contents.prototype.addScript = function(src) {
}.bind(this));
};
Contents.prototype.addClass = function(className) {
addClass(className) {
var content;
if(!this.document) return;
@ -531,7 +532,7 @@ Contents.prototype.addClass = function(className) {
};
Contents.prototype.removeClass = function(className) {
removeClass(className) {
var content;
if(!this.document) return;
@ -542,7 +543,7 @@ Contents.prototype.removeClass = function(className) {
};
Contents.prototype.addEventListeners = function(){
addEventListeners(){
if(!this.document) {
return;
}
@ -552,7 +553,7 @@ Contents.prototype.addEventListeners = function(){
};
Contents.prototype.removeEventListeners = function(){
removeEventListeners(){
if(!this.document) {
return;
}
@ -563,25 +564,25 @@ Contents.prototype.removeEventListeners = function(){
};
// Pass browser events
Contents.prototype.triggerEvent = function(e){
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);
}
@ -591,7 +592,7 @@ Contents.prototype.onSelectionChange = function(e){
}.bind(this), 500);
};
Contents.prototype.triggerSelectedEvent = function(selection){
triggerSelectedEvent(selection){
var range, cfirange;
if (selection && selection.rangeCount > 0) {
@ -605,17 +606,17 @@ Contents.prototype.triggerSelectedEvent = function(selection){
}
};
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);
@ -630,11 +631,11 @@ Contents.prototype.size = function(width, height){
};
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);
@ -656,7 +657,7 @@ Contents.prototype.columns = function(width, height, columnWidth, gap){
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"));
@ -669,7 +670,7 @@ 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();
@ -705,7 +706,8 @@ Contents.prototype.destroy = function() {
this.removeListeners();
};
}
EventEmitter(Contents.prototype);
module.exports = Contents;
export default Contents;

View file

@ -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;

View file

@ -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) {
@ -64,12 +65,12 @@ function EpubCFI(cfiFrom, base, ignoreClass){
};
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';
@ -80,7 +81,7 @@ EpubCFI.prototype.checkType = function(cfi) {
}
};
EpubCFI.prototype.parse = function(cfiStr) {
parse(cfiStr) {
var cfi = {
spinePos: -1,
range: false,
@ -129,7 +130,7 @@ EpubCFI.prototype.parse = function(cfiStr) {
return cfi;
};
EpubCFI.prototype.parseComponent = function(componentStr){
parseComponent(componentStr){
var component = {
steps: [],
terminal: {
@ -157,7 +158,7 @@ EpubCFI.prototype.parseComponent = function(componentStr){
return component;
};
EpubCFI.prototype.parseStep = function(stepStr){
parseStep(stepStr){
var type, num, index, has_brackets, id;
has_brackets = stepStr.match(/\[(.*)\]/);
@ -187,7 +188,7 @@ EpubCFI.prototype.parseStep = function(stepStr){
};
};
EpubCFI.prototype.parseTerminal = function(termialStr){
parseTerminal(termialStr){
var characterOffset, textLocationAssertion;
var assertion = termialStr.match(/\[(.*)\]/);
@ -205,25 +206,25 @@ EpubCFI.prototype.parseTerminal = function(termialStr){
};
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(",");
@ -237,12 +238,12 @@ 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 "";
}
@ -268,7 +269,7 @@ EpubCFI.prototype.joinSteps = function(steps) {
};
EpubCFI.prototype.segmentString = function(segment) {
segmentString(segment) {
var segmentString = '/';
segmentString += this.joinSteps(segment.steps);
@ -284,7 +285,7 @@ EpubCFI.prototype.segmentString = function(segment) {
return segmentString;
};
EpubCFI.prototype.toString = function() {
toString() {
var cfiString = 'epubcfi(';
cfiString += this.segmentString(this.base);
@ -308,7 +309,7 @@ EpubCFI.prototype.toString = function() {
return cfiString;
};
EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
compare(cfiOne, cfiTwo) {
var stepsA, stepsB;
var terminalA, terminalB;
@ -376,7 +377,7 @@ EpubCFI.prototype.compare = function(cfiOne, cfiTwo) {
return 0;
};
EpubCFI.prototype.step = function(node) {
step(node) {
var nodeType = (node.nodeType === TEXT_NODE) ? 'text' : 'element';
return {
@ -387,7 +388,7 @@ EpubCFI.prototype.step = function(node) {
};
};
EpubCFI.prototype.filteredStep = function(node, ignoreClass) {
filteredStep(node, ignoreClass) {
var filteredNode = this.filter(node, ignoreClass);
var nodeType;
@ -407,7 +408,7 @@ EpubCFI.prototype.filteredStep = function(node, ignoreClass) {
};
};
EpubCFI.prototype.pathTo = function(node, offset, ignoreClass) {
pathTo(node, offset, ignoreClass) {
var segment = {
steps: [],
terminal: {
@ -453,7 +454,7 @@ EpubCFI.prototype.pathTo = function(node, offset, ignoreClass) {
return segment;
}
EpubCFI.prototype.equalStep = function(stepA, stepB) {
equalStep(stepA, stepB) {
if (!stepA || !stepB) {
return false;
}
@ -467,7 +468,7 @@ EpubCFI.prototype.equalStep = function(stepA, stepB) {
return false;
};
EpubCFI.prototype.fromRange = function(range, base, ignoreClass) {
fromRange(range, base, ignoreClass) {
var cfi = {
range: false,
base: {},
@ -554,7 +555,7 @@ 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: {},
@ -582,10 +583,10 @@ EpubCFI.prototype.fromNode = function(anchor, base, 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) {
@ -625,7 +626,7 @@ EpubCFI.prototype.filter = function(anchor, ignoreClass) {
};
EpubCFI.prototype.patchOffset = function(anchor, offset, ignoreClass) {
patchOffset(anchor, offset, ignoreClass) {
var needsIgnoring;
var sibling;
@ -662,7 +663,7 @@ EpubCFI.prototype.patchOffset = function(anchor, offset, ignoreClass) {
};
EpubCFI.prototype.normalizedMap = function(children, nodeType, ignoreClass) {
normalizedMap(children, nodeType, ignoreClass) {
var output = {};
var prevIndex = -1;
var i, len = children.length;
@ -696,13 +697,13 @@ 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 {
@ -713,7 +714,7 @@ 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) {
@ -735,7 +736,7 @@ EpubCFI.prototype.filteredPosition = function(anchor, ignoreClass) {
return map[index];
};
EpubCFI.prototype.stepsToXpath = function(steps) {
stepsToXpath(steps) {
var xpath = [".", "*"];
steps.forEach(function(step){
@ -769,7 +770,7 @@ if(startContainerParent && lastStep.type == "text") {
container = startContainerParent.childNodes[lastStep.index];
}
*/
EpubCFI.prototype.stepsToQuerySelector = function(steps) {
stepsToQuerySelector(steps) {
var query = ["html"];
steps.forEach(function(step){
@ -789,7 +790,7 @@ EpubCFI.prototype.stepsToQuerySelector = function(steps) {
};
EpubCFI.prototype.textNodes = function(container, ignoreClass) {
textNodes(container, ignoreClass) {
return Array.prototype.slice.call(container.childNodes).
filter(function (node) {
if (node.nodeType === TEXT_NODE) {
@ -801,7 +802,7 @@ EpubCFI.prototype.textNodes = function(container, ignoreClass) {
});
};
EpubCFI.prototype.walkToNode = function(steps, _doc, ignoreClass) {
walkToNode(steps, _doc, ignoreClass) {
var doc = _doc || document;
var container = doc.documentElement;
var step;
@ -822,7 +823,7 @@ 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;
@ -839,7 +840,7 @@ 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);
@ -875,7 +876,7 @@ EpubCFI.prototype.fixMiss = function(steps, offset, _doc, ignoreClass) {
};
EpubCFI.prototype.toRange = function(_doc, ignoreClass) {
toRange(_doc, ignoreClass) {
var doc = _doc || document;
var range = doc.createRange();
var start, end, startContainer, endContainer;
@ -936,7 +937,7 @@ EpubCFI.prototype.toRange = function(_doc, ignoreClass) {
};
// is a cfi string, should be wrapped with "epubcfi()"
EpubCFI.prototype.isCfiString = function(str) {
isCfiString(str) {
if(typeof str === 'string' &&
str.indexOf("epubcfi(") === 0 &&
str[str.length-1] === ")") {
@ -946,7 +947,7 @@ 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+'/';
@ -959,5 +960,6 @@ EpubCFI.prototype.generateChapterComponent = function(_spineNodeIndex, _pos, id)
return cfi;
};
}
module.exports = EpubCFI;
export default EpubCFI;

View file

@ -5,7 +5,8 @@
* @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 = [];
};
@ -14,7 +15,7 @@ function Hook(context){
* 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]);
@ -31,7 +32,7 @@ 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 = [];
@ -51,12 +52,12 @@ Hook.prototype.trigger = function(){
};
// Adds a function to be run before a hook completes
Hook.prototype.list = function(){
list(){
return this.hooks;
};
Hook.prototype.clear = function(){
clear(){
return this.hooks = [];
};
module.exports = Hook;
}
export default Hook;

15
src/index.js Normal file
View 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
};

View file

@ -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;
@ -37,7 +38,7 @@ function Layout(settings){
* 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";
}
@ -47,7 +48,7 @@ Layout.prototype.flow = function(flow) {
* @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;
@ -62,7 +63,7 @@ Layout.prototype.spread = function(spread, min) {
* @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;
@ -121,7 +122,7 @@ Layout.prototype.calculate = function(_width, _height, _gap){
* @param {Contents} contents
* @return {[Promise]}
*/
Layout.prototype.format = function(contents){
format(contents){
var formating;
if (this.name === "pre-paginated") {
@ -141,7 +142,7 @@ Layout.prototype.format = function(contents){
* @return {number} spreads
* @return {number} pages
*/
Layout.prototype.count = function(totalWidth) {
count(totalWidth) {
// var totalWidth = contents.scrollWidth();
var spreads = Math.ceil( totalWidth / this.spreadWidth);
@ -150,5 +151,6 @@ Layout.prototype.count = function(totalWidth) {
pages : spreads * this.divisor
};
};
}
module.exports = Layout;
export default Layout;

View file

@ -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;
@ -29,7 +30,7 @@ function Locations(spine, request) {
* @param {int} chars how many chars to split on
* @return {object} locations
*/
Locations.prototype.generate = function(chars) {
generate(chars) {
if (chars) {
this.break = chars;
@ -56,7 +57,7 @@ Locations.prototype.generate = function(chars) {
};
Locations.prototype.createRange = function () {
createRange () {
return {
startContainer: undefined,
startOffset: undefined,
@ -65,7 +66,7 @@ Locations.prototype.createRange = function () {
}
};
Locations.prototype.process = function(section) {
process(section) {
return section.load(this.request)
.then(function(contents) {
@ -75,11 +76,11 @@ Locations.prototype.process = function(section) {
};
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,14 +138,14 @@ 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;
}
@ -152,15 +153,15 @@ Locations.prototype.parse = function(contents, cfiBase, chars) {
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;
}
@ -170,14 +171,14 @@ Locations.prototype.percentageFromCfi = function(cfi) {
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"){
@ -191,28 +192,28 @@ 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"){
@ -239,19 +240,19 @@ Locations.prototype.setCurrent = function(curr){
});
};
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;

View file

@ -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) {
@ -37,19 +38,15 @@ function ContinuousViewManager(options) {
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) {
@ -62,7 +59,7 @@ ContinuousViewManager.prototype.fill = function(_full){
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,
@ -86,7 +83,7 @@ ContinuousViewManager.prototype.moveTo = function(offset){
};
/*
ContinuousViewManager.prototype.afterDisplayed = function(currView){
afterDisplayed(currView){
var next = currView.section.next();
var prev = currView.section.prev();
var index = this.views.indexOf(currView);
@ -109,7 +106,7 @@ ContinuousViewManager.prototype.afterDisplayed = function(currView){
};
*/
ContinuousViewManager.prototype.resize = function(width, height){
resize(width, height){
// Clear the queue
this.q.clear();
@ -139,7 +136,7 @@ ContinuousViewManager.prototype.resize = function(width, height){
};
ContinuousViewManager.prototype.onResized = function(e) {
onResized(e) {
// this.views.clear();
@ -149,12 +146,12 @@ ContinuousViewManager.prototype.onResized = function(e) {
}.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){
removeShownListeners(view){
// view.off("shown", this.afterDisplayed);
// view.off("shown", this.afterDisplayedAbove);
@ -163,7 +160,7 @@ ContinuousViewManager.prototype.removeShownListeners = function(view){
};
// ContinuousViewManager.prototype.append = function(section){
// append(section){
// return this.q.enqueue(function() {
//
// this._append(section);
@ -172,7 +169,7 @@ ContinuousViewManager.prototype.removeShownListeners = function(view){
// }.bind(this));
// };
//
// ContinuousViewManager.prototype.prepend = function(section){
// prepend(section){
// return this.q.enqueue(function() {
//
// this._prepend(section);
@ -181,13 +178,13 @@ ContinuousViewManager.prototype.removeShownListeners = function(view){
//
// };
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));
@ -196,7 +193,7 @@ ContinuousViewManager.prototype.prepend = function(section){
return view;
};
ContinuousViewManager.prototype.counter = function(bounds){
counter(bounds){
if(this.settings.axis === "vertical") {
this.scrollBy(0, bounds.heightDelta, true);
@ -206,7 +203,7 @@ ContinuousViewManager.prototype.counter = function(bounds){
};
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++) {
@ -250,10 +247,10 @@ ContinuousViewManager.prototype.update = function(_offset){
};
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");
@ -308,8 +305,8 @@ 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];
@ -332,7 +329,7 @@ ContinuousViewManager.prototype.trim = function(){
return task.promise;
};
ContinuousViewManager.prototype.erase = function(view, above){ //Trim
erase(view, above){ //Trim
var prevTop;
var prevLeft;
@ -360,7 +357,7 @@ ContinuousViewManager.prototype.erase = function(view, above){ //Trim
};
ContinuousViewManager.prototype.addEventListeners = function(stage){
addEventListeners(stage){
window.addEventListener('unload', function(e){
this.ignore = true;
@ -371,10 +368,10 @@ ContinuousViewManager.prototype.addEventListeners = function(stage){
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;
@ -405,7 +402,9 @@ ContinuousViewManager.prototype.addScrollListeners = function() {
};
ContinuousViewManager.prototype.onScroll = function(){
onScroll(){
let scrollTop;
let scrollLeft;
// if(!this.ignore) {
@ -475,7 +474,7 @@ ContinuousViewManager.prototype.onScroll = function(){
};
// ContinuousViewManager.prototype.resizeView = function(view) {
// resizeView(view) {
//
// if(this.settings.axis === "horizontal") {
// view.lock("height", this.stage.width, this.stage.height);
@ -485,7 +484,7 @@ ContinuousViewManager.prototype.onScroll = function(){
//
// };
ContinuousViewManager.prototype.currentLocation = function(){
currentLocation(){
if (this.settings.axis === "vertical") {
this.location = this.scrolledLocation();
@ -496,7 +495,7 @@ ContinuousViewManager.prototype.currentLocation = function(){
return this.location;
};
ContinuousViewManager.prototype.scrolledLocation = function(){
scrolledLocation(){
var visible = this.visible();
var startPage, endPage;
@ -520,7 +519,7 @@ ContinuousViewManager.prototype.scrolledLocation = function(){
};
ContinuousViewManager.prototype.paginatedLocation = function(){
paginatedLocation(){
var visible = this.visible();
var startA, startB, endA, endB;
var pageLeft, pageRight;
@ -554,7 +553,7 @@ ContinuousViewManager.prototype.paginatedLocation = function(){
};
/*
Continuous.prototype.current = function(what){
current(what){
var view, top;
var container = this.container.getBoundingClientRect();
var length = this.views.length - 1;
@ -599,7 +598,7 @@ Continuous.prototype.current = function(what){
};
*/
ContinuousViewManager.prototype.updateLayout = function() {
updateLayout() {
if (!this.stage) {
return;
@ -629,7 +628,7 @@ ContinuousViewManager.prototype.updateLayout = function() {
};
ContinuousViewManager.prototype.next = function(){
next(){
if(this.settings.axis === "horizontal") {
@ -648,7 +647,7 @@ ContinuousViewManager.prototype.next = function(){
}
};
ContinuousViewManager.prototype.prev = function(){
prev(){
if(this.settings.axis === "horizontal") {
this.scrollBy(-this.layout.delta, 0);
} else {
@ -656,7 +655,7 @@ ContinuousViewManager.prototype.prev = function(){
}
};
ContinuousViewManager.prototype.updateFlow = function(flow){
updateFlow(flow){
var axis = (flow === "paginated") ? "horizontal" : "vertical";
this.settings.axis = axis;
@ -676,4 +675,6 @@ ContinuousViewManager.prototype.updateFlow = function(flow){
}
};
module.exports = ContinuousViewManager;
}
export default ContinuousViewManager;

View file

@ -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,
@ -37,7 +38,7 @@ function DefaultViewManager(options) {
}
DefaultViewManager.prototype.render = function(element, size){
render(element, size){
// Save the stage
this.stage = new Stage({
@ -78,13 +79,13 @@ DefaultViewManager.prototype.render = function(element, size){
}
};
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();
// });
@ -100,14 +101,14 @@ DefaultViewManager.prototype.destroy = function(){
*/
};
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();
@ -133,13 +134,13 @@ DefaultViewManager.prototype.resize = function(width, 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
@ -194,19 +195,19 @@ DefaultViewManager.prototype.display = function(section, target){
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){
// moveTo(offset){
// this.scrollTo(offset.left, offset.top);
// };
DefaultViewManager.prototype.moveTo = function(offset){
moveTo(offset){
var distX = 0,
distY = 0;
@ -223,7 +224,7 @@ 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);
@ -236,19 +237,19 @@ DefaultViewManager.prototype.add = function(section){
};
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) {
// resizeView(view) {
//
// if(this.settings.globalLayoutProperties.layout === "pre-paginated") {
// view.lock("both", this.bounds.width, this.bounds.height);
@ -258,7 +259,7 @@ DefaultViewManager.prototype.prepend = function(section){
//
// };
DefaultViewManager.prototype.next = function(){
next(){
var next;
var view;
var left;
@ -307,7 +308,7 @@ DefaultViewManager.prototype.next = function(){
};
DefaultViewManager.prototype.prev = function(){
prev(){
var prev;
var view;
var left;
@ -355,7 +356,7 @@ DefaultViewManager.prototype.prev = function(){
}
};
DefaultViewManager.prototype.current = function(){
current(){
var visible = this.visible();
if(visible.length){
// Current is the last visible view
@ -364,7 +365,7 @@ DefaultViewManager.prototype.current = function(){
return null;
};
DefaultViewManager.prototype.currentLocation = function(){
currentLocation(){
if (this.settings.axis === "vertical") {
this.location = this.scrolledLocation();
@ -374,7 +375,7 @@ DefaultViewManager.prototype.currentLocation = function(){
return this.location;
};
DefaultViewManager.prototype.scrolledLocation = function(){
scrolledLocation(){
var view;
if(this.views.length) {
@ -384,7 +385,7 @@ DefaultViewManager.prototype.scrolledLocation = function(){
};
DefaultViewManager.prototype.paginatedLocation = function(){
paginatedLocation(){
var view;
var start, end;
@ -397,7 +398,7 @@ DefaultViewManager.prototype.paginatedLocation = function(){
};
DefaultViewManager.prototype.isVisible = function(view, offsetPrev, offsetNext, _container){
isVisible(view, offsetPrev, offsetNext, _container){
var position = view.position();
var container = _container || this.bounds();
@ -418,7 +419,7 @@ DefaultViewManager.prototype.isVisible = function(view, offsetPrev, offsetNext,
};
DefaultViewManager.prototype.visible = function(){
visible(){
// return this.views.displayed();
var container = this.bounds();
var views = this.views.displayed();
@ -439,7 +440,7 @@ DefaultViewManager.prototype.visible = function(){
return visible;
};
DefaultViewManager.prototype.scrollBy = function(x, y, silent){
scrollBy(x, y, silent){
if(silent) {
this.ignore = true;
}
@ -457,7 +458,7 @@ DefaultViewManager.prototype.scrollBy = function(x, y, silent){
this.onScroll();
};
DefaultViewManager.prototype.scrollTo = function(x, y, silent){
scrollTo(x, y, silent){
if(silent) {
this.ignore = true;
}
@ -479,11 +480,11 @@ DefaultViewManager.prototype.scrollTo = function(x, y, silent){
// };
};
DefaultViewManager.prototype.onScroll = function(){
onScroll(){
};
DefaultViewManager.prototype.bounds = function() {
bounds() {
var bounds;
bounds = this.stage.bounds();
@ -491,7 +492,7 @@ DefaultViewManager.prototype.bounds = function() {
return bounds;
};
DefaultViewManager.prototype.applyLayout = function(layout) {
applyLayout(layout) {
this.layout = layout;
this.updateLayout();
@ -500,7 +501,7 @@ DefaultViewManager.prototype.applyLayout = function(layout) {
// this.manager.layout(this.layout.format);
};
DefaultViewManager.prototype.updateLayout = function() {
updateLayout() {
if (!this.stage) {
return;
}
@ -531,7 +532,7 @@ DefaultViewManager.prototype.updateLayout = function() {
};
DefaultViewManager.prototype.setLayout = function(layout){
setLayout(layout){
this.viewSettings.layout = layout;
@ -545,7 +546,7 @@ DefaultViewManager.prototype.setLayout = function(layout){
};
DefaultViewManager.prototype.updateFlow = function(flow){
updateFlow(flow){
var axis = (flow === "paginated") ? "horizontal" : "vertical";
this.settings.axis = axis;
@ -559,15 +560,16 @@ DefaultViewManager.prototype.updateFlow = function(flow){
};
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;

View file

@ -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);
@ -16,22 +17,22 @@ function Stage(_options) {
* Creates an element to render to.
* Resizes to passed width and height or to the elements size
*/
Stage.prototype.create = function(options){
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");
@ -61,7 +62,7 @@ Stage.prototype.create = function(options){
return container;
};
Stage.wrap = function(container) {
wrap(container) {
var wrapper = document.createElement("div");
wrapper.style.visibility = "hidden";
@ -74,10 +75,10 @@ Stage.wrap = function(container) {
};
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);
@ -91,7 +92,7 @@ Stage.prototype.getElement = function(_element){
return element;
};
Stage.prototype.attachTo = function(what){
attachTo(what){
var element = this.getElement(what);
var base;
@ -114,21 +115,21 @@ Stage.prototype.attachTo = function(what){
};
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;
@ -186,17 +187,17 @@ Stage.prototype.size = function(width, height){
};
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
@ -207,7 +208,7 @@ Stage.prototype.getSheet = function(){
return style.sheet;
}
Stage.prototype.addStyleRules = function(selector, rulesArray){
addStyleRules(selector, rulesArray){
var scope = "#" + this.id + " ";
var rules = "";
@ -225,7 +226,6 @@ Stage.prototype.addStyleRules = function(selector, rulesArray){
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
}
}
module.exports = Stage;
export default Stage;

View file

@ -1,35 +1,36 @@
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);
@ -38,7 +39,7 @@ Views.prototype.append = function(view){
return view;
};
Views.prototype.prepend = function(view){
prepend(view){
this._views.unshift(view);
if(this.container){
this.container.insertBefore(view.element, this.container.firstChild);
@ -47,7 +48,7 @@ Views.prototype.prepend = function(view){
return view;
};
Views.prototype.insert = function(view, index) {
insert(view, index) {
this._views.splice(index, 0, view);
if(this.container){
@ -62,7 +63,7 @@ Views.prototype.insert = function(view, index) {
return view;
};
Views.prototype.remove = function(view) {
remove(view) {
var index = this._views.indexOf(view);
if(index > -1) {
@ -75,7 +76,7 @@ Views.prototype.remove = function(view) {
this.length--;
};
Views.prototype.destroy = function(view) {
destroy(view) {
if(view.displayed){
view.destroy();
}
@ -88,11 +89,11 @@ Views.prototype.destroy = function(view) {
// 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;
@ -108,7 +109,7 @@ Views.prototype.clear = function(){
this.length = 0;
};
Views.prototype.find = function(section){
find(section){
var view;
var len = this.length;
@ -122,7 +123,7 @@ Views.prototype.find = function(section){
};
Views.prototype.displayed = function(){
displayed(){
var displayed = [];
var view;
var len = this.length;
@ -136,7 +137,7 @@ Views.prototype.displayed = function(){
return displayed;
};
Views.prototype.show = function(){
show(){
var view;
var len = this.length;
@ -149,7 +150,7 @@ Views.prototype.show = function(){
this.hidden = false;
};
Views.prototype.hide = function(){
hide(){
var view;
var len = this.length;
@ -161,5 +162,6 @@ Views.prototype.hide = function(){
}
this.hidden = true;
};
}
module.exports = Views;
export default Views;

View file

@ -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;
@ -37,7 +38,7 @@ function IframeView(section, options) {
// 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");
@ -56,7 +57,7 @@ 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
@ -110,7 +111,7 @@ 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();
@ -169,7 +170,7 @@ IframeView.prototype.render = function(request, show) {
};
// Determine locks base on settings
IframeView.prototype.size = function(_width, _height) {
size(_width, _height) {
var width = _width || this.settings.width;
var height = _height || this.settings.height;
@ -184,29 +185,29 @@ IframeView.prototype.size = function(_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(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;
@ -226,7 +227,7 @@ IframeView.prototype.lock = function(what, width, height) {
};
// Resize a single axis based on content dimensions
IframeView.prototype.expand = function(force) {
expand(force) {
var width = this.lockedWidth;
var height = this.lockedHeight;
var columns;
@ -287,7 +288,7 @@ IframeView.prototype.expand = function(force) {
this._expanding = false;
};
IframeView.prototype.contentWidth = function(min) {
contentWidth(min) {
var prev;
var width;
@ -303,7 +304,7 @@ IframeView.prototype.contentWidth = function(min) {
return width;
};
IframeView.prototype.contentHeight = function(min) {
contentHeight(min) {
var prev;
var height;
@ -316,44 +317,44 @@ IframeView.prototype.contentHeight = function(min) {
};
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,
@ -369,8 +370,8 @@ IframeView.prototype.reframe = function(width, height) {
};
IframeView.prototype.load = function(contents) {
var loading = new core.defer();
load(contents) {
var loading = new defer();
var loaded = loading.promise;
if(!this.iframe) {
@ -404,7 +405,7 @@ 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;
@ -434,7 +435,7 @@ IframeView.prototype.onLoad = function(event, promise) {
// IframeView.prototype.layout = function(layoutFunc) {
// layout(layoutFunc) {
//
// this.iframe.style.display = "inline-block";
//
@ -451,34 +452,34 @@ IframeView.prototype.onLoad = function(event, promise) {
//
// };
//
// IframeView.prototype.onLayout = function(view) {
// 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) {
@ -500,7 +501,7 @@ IframeView.prototype.display = function(request) {
return displayed.promise;
};
IframeView.prototype.show = function() {
show() {
this.element.style.visibility = "visible";
@ -511,7 +512,7 @@ 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";
@ -520,11 +521,11 @@ IframeView.prototype.hide = function() {
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);
@ -534,22 +535,22 @@ IframeView.prototype.locationOf = function(target) {
};
};
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;
@ -569,7 +570,8 @@ IframeView.prototype.destroy = function() {
// this.element.style.height = "0px";
// this.element.style.width = "0px";
};
}
EventEmitter(IframeView.prototype);
module.exports = IframeView;
export default IframeView;

View file

@ -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;
@ -39,7 +40,7 @@ function InlineView(section, options) {
};
InlineView.prototype.container = function(axis) {
container(axis) {
var element = document.createElement('div');
element.classList.add("epub-view");
@ -63,7 +64,7 @@ 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();
@ -158,7 +159,7 @@ InlineView.prototype.render = function(request, show) {
};
// Determine locks base on settings
InlineView.prototype.size = function(_width, _height) {
size(_width, _height) {
var width = _width || this.settings.width;
var height = _height || this.settings.height;
@ -174,29 +175,29 @@ InlineView.prototype.size = function(_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(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;
@ -207,7 +208,7 @@ InlineView.prototype.lock = function(what, width, height) {
};
// Resize a single axis based on content dimensions
InlineView.prototype.expand = function(force) {
expand(force) {
var width = this.lockedWidth;
var height = this.lockedHeight;
@ -234,33 +235,33 @@ 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,
@ -276,11 +277,11 @@ InlineView.prototype.resize = function(width, height) {
};
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)
@ -311,27 +312,27 @@ 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) {
@ -354,7 +355,7 @@ InlineView.prototype.display = function(request) {
return displayed.promise;
};
InlineView.prototype.show = function() {
show() {
this.element.style.visibility = "visible";
@ -365,7 +366,7 @@ 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";
@ -374,11 +375,11 @@ InlineView.prototype.hide = function() {
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);
@ -388,22 +389,22 @@ InlineView.prototype.locationOf = function(target) {
};
};
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;
@ -423,7 +424,8 @@ InlineView.prototype.destroy = function() {
// this.element.style.height = "0px";
// this.element.style.width = "0px";
};
}
EventEmitter(InlineView.prototype);
module.exports = InlineView;
export default InlineView;

View file

@ -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) {
@ -24,7 +25,7 @@ Mapping.prototype.page = function(contents, cfiBase, 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) {
@ -45,7 +46,7 @@ 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);
@ -65,7 +66,7 @@ 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;
@ -112,7 +113,7 @@ Mapping.prototype.findStart = function(root, start, end){
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;
@ -163,7 +164,7 @@ Mapping.prototype.findEnd = function(root, start, end){
};
Mapping.prototype.findTextStartRange = function(node, start, end){
findTextStartRange(node, start, end){
var ranges = this.splitTextNodeIntoRanges(node);
var prev;
var range;
@ -185,7 +186,7 @@ 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;
@ -211,7 +212,7 @@ Mapping.prototype.findTextEndRange = function(node, start, end){
};
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();
@ -260,7 +261,7 @@ Mapping.prototype.splitTextNodeIntoRanges = function(node, _splitter){
Mapping.prototype.rangePairToCfiPair = function(cfiBase, rangePair){
rangePairToCfiPair(cfiBase, rangePair){
var startRange = rangePair.start;
var endRange = rangePair.end;
@ -270,8 +271,8 @@ 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,
@ -280,7 +281,7 @@ Mapping.prototype.rangePairToCfiPair = function(cfiBase, rangePair){
};
Mapping.prototype.rangeListToCfiList = function(cfiBase, columns){
rangeListToCfiList(cfiBase, columns){
var map = [];
var rangePair, cifPair;
@ -293,5 +294,6 @@ Mapping.prototype.rangeListToCfiList = function(cfiBase, columns){
return map;
};
}
module.exports = Mapping;
export default Mapping;

View file

@ -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 = {};
@ -19,9 +19,9 @@ function Navigation(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);
@ -37,7 +37,7 @@ Navigation.prototype.parse = function(xml) {
* @private
* @param {array} toc
*/
Navigation.prototype.unpack = function(toc) {
unpack(toc) {
var item;
for (var i = 0; i < toc.length; i++) {
@ -53,7 +53,7 @@ Navigation.prototype.unpack = function(toc) {
* @param {string} target
* @return {object} navItems
*/
Navigation.prototype.get = function(target) {
get(target) {
var index;
if(!target) {
@ -75,9 +75,9 @@ Navigation.prototype.get = function(target) {
* @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 = {};
@ -106,9 +106,9 @@ Navigation.prototype.parseNav = function(navHtml){
* @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 = [],
@ -134,8 +134,8 @@ Navigation.prototype.navItem = function(item){
* @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 = {};
@ -164,11 +164,11 @@ Navigation.prototype.parseNcx = function(tocXml){
* @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,
@ -193,8 +193,9 @@ Navigation.prototype.ncxItem = function(item){
* @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;

View file

@ -1,13 +1,13 @@
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);
}
@ -18,7 +18,7 @@ function Packaging(packageDocument) {
* @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;
@ -75,7 +75,7 @@ Packaging.prototype.parse = function(packageDocument){
* @param {document} xml
* @return {object} metadata
*/
Packaging.prototype.parseMetadata = function(xml){
parseMetadata(xml){
var metadata = {};
metadata.title = this.getElementText(xml, 'title');
@ -107,12 +107,12 @@ Packaging.prototype.parseMetadata = function(xml){
* @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
@ -141,7 +141,7 @@ Packaging.prototype.parseManifest = function(manifestXml){
* @param {Packaging.manifest} manifest
* @return {object} spine
*/
Packaging.prototype.parseSpine = function(spineXml, manifest){
parseSpine(spineXml, manifest){
var spine = [];
var selected = spineXml.getElementsByTagName("itemref"),
@ -177,11 +177,11 @@ Packaging.prototype.parseSpine = function(spineXml, manifest){
* 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;
};
@ -190,9 +190,9 @@ Packaging.prototype.findNavPath = function(manifestNode){
* 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
@ -216,12 +216,12 @@ Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
* @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,7 +234,7 @@ 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') : '';
}
};
@ -246,7 +246,7 @@ Packaging.prototype.findCoverPath = function(packageXml){
* @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;
@ -269,8 +269,8 @@ Packaging.prototype.getElementText = function(xml, tag){
* @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;
@ -278,5 +278,6 @@ Packaging.prototype.getPropertyText = function(xml, property){
return '';
};
}
module.exports = Packaging;
export default Packaging;

View file

@ -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();
@ -23,9 +30,9 @@ function PageList(xml) {
* 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);
@ -42,9 +49,9 @@ PageList.prototype.parse = function(xml) {
* @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 = {};
@ -67,9 +74,9 @@ PageList.prototype.parseNav = function(navHtml){
* @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),
@ -101,7 +108,7 @@ PageList.prototype.item = function(item){
* @private
* @param {array} pageList
*/
PageList.prototype.process = function(pageList){
process(pageList){
pageList.forEach(function(item){
this.pages.push(item.page);
if (item.cfi) {
@ -118,7 +125,7 @@ PageList.prototype.process = function(pageList){
* 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){
@ -130,7 +137,7 @@ 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;
@ -160,7 +167,7 @@ EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
* @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) {
@ -198,7 +205,7 @@ PageList.prototype.pageFromCfi = function(cfi){
* @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"){
@ -220,7 +227,7 @@ PageList.prototype.cfiFromPage = function(pg){
* @param {number} percent
* @return {string} page
*/
PageList.prototype.pageFromPercentage = function(percent){
pageFromPercentage(percent){
var pg = Math.round(this.totalPages * percent);
return pg;
};
@ -230,7 +237,7 @@ PageList.prototype.pageFromPercentage = function(percent){
* @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;
};
@ -240,10 +247,11 @@ PageList.prototype.percentageFromPage = function(pg){
* @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;

View file

@ -1,14 +1,15 @@
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;
};
@ -17,7 +18,7 @@ function Queue(context){
* 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 = {
@ -68,7 +69,7 @@ Queue.prototype.enqueue = function() {
* 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,7 +101,7 @@ Queue.prototype.dequeue = function(){
}
} else {
inwait = new core.defer();
inwait = new defer();
inwait.deferred.resolve();
return inwait.promise;
}
@ -108,7 +109,7 @@ Queue.prototype.dequeue = function(){
};
// Run All Immediately
Queue.prototype.dump = function(){
dump(){
while(this._q.length) {
this.dequeue();
}
@ -118,11 +119,11 @@ Queue.prototype.dump = function(){
* 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() {
@ -153,7 +154,7 @@ Queue.prototype.run = function(){
* Flush all, as quickly as possible
* @return {Promise}
*/
Queue.prototype.flush = function(){
flush(){
if(this.running){
return this.running;
@ -174,7 +175,7 @@ Queue.prototype.flush = function(){
/**
* Clear all items in wait
*/
Queue.prototype.clear = function(){
clear(){
this._q = [];
this.running = false;
};
@ -183,16 +184,18 @@ Queue.prototype.clear = function(){
* 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 || [];
@ -223,5 +227,7 @@ function Task(task, args, context){
};
};
}
module.exports = Queue;
export default Queue;

View file

@ -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,7 +81,7 @@ 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);
};
@ -90,7 +90,7 @@ function Rendition(book, options) {
* Set the manager function
* @param {function} manager
*/
Rendition.prototype.setManager = function(manager) {
setManager(manager) {
this.manager = manager;
};
@ -99,7 +99,7 @@ Rendition.prototype.setManager = function(manager) {
* @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,
@ -120,7 +120,7 @@ Rendition.prototype.requireManager = function(manager) {
* @param {string|function} view
* @return {view}
*/
Rendition.prototype.requireView = function(view) {
requireView(view) {
var View;
if (typeof view == "string") {
@ -137,7 +137,7 @@ Rendition.prototype.requireView = function(view) {
* Start the rendering
* @return {Promise} rendering has started
*/
Rendition.prototype.start = function(){
start(){
if(!this.manager) {
this.ViewManager = this.requireManager(this.settings.manager);
@ -183,7 +183,7 @@ Rendition.prototype.start = function(){
* @param {element} element to attach to
* @return {Promise}
*/
Rendition.prototype.attachTo = function(element){
attachTo(element){
return this.q.enqueue(function () {
@ -208,7 +208,7 @@ 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);
@ -220,15 +220,15 @@ Rendition.prototype.display = function(target){
* @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);
@ -260,7 +260,7 @@ Rendition.prototype._display = function(target){
};
/*
Rendition.prototype.render = function(view, show) {
render(view, show) {
// view.onLayout = this.layout.format.bind(this.layout);
view.create();
@ -309,7 +309,7 @@ Rendition.prototype.render = function(view, show) {
* @private
* @param {*} view
*/
Rendition.prototype.afterDisplayed = function(view){
afterDisplayed(view){
this.hooks.content.trigger(view, this);
this.emit("rendered", view.section);
this.reportLocation();
@ -319,7 +319,7 @@ Rendition.prototype.afterDisplayed = function(view){
* 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);
@ -337,7 +337,7 @@ Rendition.prototype.onResized = function(size){
* Usually you would be better off calling display()
* @param {object} offset
*/
Rendition.prototype.moveTo = function(offset){
moveTo(offset){
this.manager.moveTo(offset);
};
@ -345,7 +345,7 @@ Rendition.prototype.moveTo = function(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));
};
@ -354,7 +354,7 @@ Rendition.prototype.next = function(){
* 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));
};
@ -366,7 +366,7 @@ Rendition.prototype.prev = function(){
* @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";
@ -391,7 +391,7 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
return properties;
};
// Rendition.prototype.applyLayoutProperties = function(){
// applyLayoutProperties(){
// var settings = this.determineLayoutProperties(this.book.package.metadata);
//
// this.flow(settings.flow);
@ -404,8 +404,8 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
* (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";
}
@ -427,7 +427,7 @@ Rendition.prototype.flow = function(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);
@ -447,7 +447,7 @@ Rendition.prototype.layout = function(settings){
* @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);
@ -460,7 +460,7 @@ Rendition.prototype.spread = function(spread, min){
* 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') {
@ -491,7 +491,7 @@ Rendition.prototype.reportLocation = function(){
* 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) {
@ -513,7 +513,7 @@ Rendition.prototype.currentLocation = function(){
/**
* Remove and Clean Up the Rendition
*/
Rendition.prototype.destroy = function(){
destroy(){
// Clear the queue
this.q.clear();
@ -525,7 +525,7 @@ Rendition.prototype.destroy = function(){
* @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));
@ -538,7 +538,7 @@ Rendition.prototype.passViewEvents = function(view){
* @private
* @param {event} e
*/
Rendition.prototype.triggerViewEvent = function(e){
triggerViewEvent(e){
this.emit(e.type, e);
};
@ -547,7 +547,7 @@ Rendition.prototype.triggerViewEvent = function(e){
* @private
* @param {EpubCFI} cfirange
*/
Rendition.prototype.triggerSelectedEvent = function(cfirange){
triggerSelectedEvent(cfirange){
this.emit("selected", cfirange);
};
@ -557,7 +557,7 @@ Rendition.prototype.triggerSelectedEvent = function(cfirange){
* @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;
@ -573,7 +573,7 @@ Rendition.prototype.range = function(cfi, ignoreClass){
* Hook to adjust images to fit in columns
* @param {View} view
*/
Rendition.prototype.adjustImages = function(view) {
adjustImages(view) {
view.addStylesheetRules([
["img",
@ -589,11 +589,12 @@ Rendition.prototype.adjustImages = function(view) {
});
};
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;

View file

@ -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
};

View file

@ -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;

View file

@ -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),
@ -34,7 +35,7 @@ function Resources(manifest, options) {
* Split resources by type
* @private
*/
Resources.prototype.split = function(){
split(){
// HTML
this.html = this.resources.
@ -67,7 +68,7 @@ Resources.prototype.split = function(){
* Convert split resources into Urls
* @private
*/
Resources.prototype.splitUrls = function(){
splitUrls(){
// All Assets Urls
this.urls = this.assets.
@ -88,7 +89,7 @@ Resources.prototype.splitUrls = function(){
* @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;
@ -119,7 +120,7 @@ Resources.prototype.replacements = function(archive, resolver){
* @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;
@ -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,13 +173,13 @@ 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;
@ -192,7 +193,7 @@ Resources.prototype.createCssFile = function(href, archive, resolver){
* @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
@ -209,7 +210,7 @@ Resources.prototype.relativeTo = function(absolute, resolver){
* @param {string} path
* @return {string} url
*/
Resources.prototype.get = function(path) {
get(path) {
var indexInUrls = this.urls.indexOf(path);
if (indexInUrls === -1) {
return;
@ -231,15 +232,15 @@ Resources.prototype.get = function(path) {
* @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;

View file

@ -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;
@ -36,9 +37,9 @@ function Section(item, hooks){
* @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) {
@ -70,8 +71,8 @@ Section.prototype.load = function(_request){
* @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;
@ -96,8 +97,8 @@ Section.prototype.base = function(_document){
* @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?
@ -131,7 +132,7 @@ Section.prototype.render = function(_request){
* @param {string} query [description]
* @return {[type]} [description]
*/
Section.prototype.find = function(query){
find(query){
};
@ -141,7 +142,7 @@ Section.prototype.find = function(query){
* @param {object} global The globa layout settings object, chapter properties string
* @return {object} layoutProperties Object with layout properties
*/
Section.prototype.reconcileLayoutSettings = function(global){
reconcileLayoutSettings(global){
//-- Get the global defaults
var settings = {
layout : global.layout,
@ -170,7 +171,7 @@ Section.prototype.reconcileLayoutSettings = function(global){
* @param {range} _range
* @return {string} cfi an EpubCFI string
*/
Section.prototype.cfiFromRange = function(_range) {
cfiFromRange(_range) {
return new EpubCFI(_range, this.cfiBase).toString();
};
@ -179,8 +180,9 @@ Section.prototype.cfiFromRange = function(_range) {
* @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;

View file

@ -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,8 +18,8 @@ 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();
@ -30,7 +31,7 @@ function Spine(){
* @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;
@ -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)) {
@ -100,7 +101,7 @@ Spine.prototype.get = function(target) {
* @private
* @param {Section} section
*/
Spine.prototype.append = function(section) {
append(section) {
var index = this.spineItems.length;
section.index = index;
@ -117,7 +118,7 @@ Spine.prototype.append = function(section) {
* @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;
@ -130,7 +131,7 @@ Spine.prototype.prepend = function(section) {
return 0;
};
// Spine.prototype.insert = function(section, index) {
// insert(section, index) {
//
// };
@ -139,7 +140,7 @@ Spine.prototype.prepend = function(section) {
* @private
* @param {Section} section
*/
Spine.prototype.remove = function(section) {
remove(section) {
var index = this.spineItems.indexOf(section);
if(index > -1) {
@ -154,8 +155,9 @@ Spine.prototype.remove = function(section) {
* 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;

View file

@ -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" : {
@ -17,7 +18,7 @@ function Themes(rendition) {
}
Themes.prototype.register = function () {
register () {
if (arguments.length === 0) {
return;
}
@ -35,7 +36,7 @@ Themes.prototype.register = function () {
}
};
Themes.prototype.default = function (theme) {
default (theme) {
if (!theme) {
return;
}
@ -47,7 +48,7 @@ Themes.prototype.default = function (theme) {
}
};
Themes.prototype.registerThemes = function (themes) {
registerThemes (themes) {
for (var theme in themes) {
if (themes.hasOwnProperty(theme)) {
if (typeof(themes[theme]) === "string") {
@ -59,17 +60,17 @@ 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;
@ -83,14 +84,14 @@ Themes.prototype.apply = function (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;
@ -109,7 +110,7 @@ Themes.prototype.inject = function (view) {
}
};
Themes.prototype.add = function (name, contents) {
add (name, contents) {
var theme = this._themes[name];
if (!theme) {
@ -126,7 +127,7 @@ Themes.prototype.add = function (name, contents) {
}
};
Themes.prototype.override = function (name, value) {
override (name, value) {
var contents = this.rendition.getContents();
this._overrides[name] = value;
@ -136,7 +137,7 @@ Themes.prototype.override = function (name, value) {
}.bind(this));
};
Themes.prototype.overrides = function (view) {
overrides (view) {
var contents = view.contents;
var overrides = this._overrides;
var rules = [];
@ -148,8 +149,10 @@ Themes.prototype.overrides = function (view) {
}
};
Themes.prototype.fontSize = function (size) {
fontSize (size) {
this.override("font-size", size);
};
module.exports = Themes;
}
export default Themes;

View file

@ -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
View 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
View 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

View file

@ -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");

View file

@ -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' );

View file

@ -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);
});

View file

@ -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"
}
]
}
}