mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-03 14:59:18 +02:00
Merge pull request #485 from futurepress/tabify
Tabify epub.js src and tests
This commit is contained in:
commit
8dd67cc167
31 changed files with 7759 additions and 7758 deletions
7027
dist/epub.js
vendored
7027
dist/epub.js
vendored
File diff suppressed because it is too large
Load diff
2
dist/epub.js.map
vendored
2
dist/epub.js.map
vendored
File diff suppressed because one or more lines are too long
162
gulpfile.js
162
gulpfile.js
|
@ -6,7 +6,7 @@ var uglify = require('gulp-uglify');
|
|||
var gutil = require('gulp-util');
|
||||
var plumber = require('gulp-plumber');
|
||||
var onError = function (err) {
|
||||
gutil.log(gutil.colors.green(err));
|
||||
gutil.log(gutil.colors.green(err));
|
||||
};
|
||||
var server = require("./tools/serve.js");
|
||||
|
||||
|
@ -24,73 +24,73 @@ var mochify = require('mochify');
|
|||
|
||||
// Lint JS
|
||||
gulp.task('lint', function() {
|
||||
return gulp.src('src/*.js')
|
||||
.pipe(jshint())
|
||||
.pipe(jshint.reporter('default'));
|
||||
return gulp.src('src/*.js')
|
||||
.pipe(jshint())
|
||||
.pipe(jshint.reporter('default'));
|
||||
});
|
||||
|
||||
// set up the browserify instance on a task basis
|
||||
gulp.task('bundle', function () {
|
||||
return bundle('epub.js');
|
||||
return bundle('epub.js');
|
||||
});
|
||||
|
||||
// Minify JS
|
||||
gulp.task('minify', ['bundle'], function(){
|
||||
var uglifyOptions = {
|
||||
mangle: true,
|
||||
preserveComments : "license"
|
||||
};
|
||||
return gulp.src('dist/epub.js')
|
||||
.pipe(plumber({ errorHandler: onError }))
|
||||
.pipe(rename('epub.min.js'))
|
||||
// .pipe(sourcemaps.init({loadMaps: true}))
|
||||
.pipe(uglify(uglifyOptions))
|
||||
// .pipe(sourcemaps.write('./'))
|
||||
.pipe(size({ showFiles: true }))
|
||||
.pipe(gulp.dest('dist'));
|
||||
var uglifyOptions = {
|
||||
mangle: true,
|
||||
preserveComments : "license"
|
||||
};
|
||||
return gulp.src('dist/epub.js')
|
||||
.pipe(plumber({ errorHandler: onError }))
|
||||
.pipe(rename('epub.min.js'))
|
||||
// .pipe(sourcemaps.init({loadMaps: true}))
|
||||
.pipe(uglify(uglifyOptions))
|
||||
// .pipe(sourcemaps.write('./'))
|
||||
.pipe(size({ showFiles: true }))
|
||||
.pipe(gulp.dest('dist'));
|
||||
});
|
||||
|
||||
// Watch Our Files
|
||||
gulp.task('watch', function(cb) {
|
||||
bundle('epub.js', cb);
|
||||
bundle('epub.js', cb);
|
||||
});
|
||||
|
||||
gulp.task('serve', function(cb) {
|
||||
server();
|
||||
bundle('epub.js', cb);
|
||||
server();
|
||||
bundle('epub.js', cb);
|
||||
});
|
||||
|
||||
gulp.task('serve:no-watch', function(cb) {
|
||||
server();
|
||||
server();
|
||||
});
|
||||
|
||||
gulp.task('test', function(cb) {
|
||||
mochify('./test/*.js', {
|
||||
reporter: 'spec',
|
||||
transform: 'brfs',
|
||||
"web-security": false,
|
||||
"webSecurityEnabled": false,
|
||||
// "localUrlAccess": true,
|
||||
watch: true,
|
||||
wd: false,
|
||||
debug: false
|
||||
})
|
||||
.bundle();
|
||||
mochify('./test/*.js', {
|
||||
reporter: 'spec',
|
||||
transform: 'brfs',
|
||||
"web-security": false,
|
||||
"webSecurityEnabled": false,
|
||||
// "localUrlAccess": true,
|
||||
watch: true,
|
||||
wd: false,
|
||||
debug: false
|
||||
})
|
||||
.bundle();
|
||||
});
|
||||
|
||||
|
||||
gulp.task('test:once', function(cb) {
|
||||
mochify('./test/*.js', {
|
||||
reporter: 'spec',
|
||||
transform: 'brfs',
|
||||
"web-security": false,
|
||||
"webSecurityEnabled": false,
|
||||
// "localUrlAccess": true,
|
||||
watch: false,
|
||||
wd: false,
|
||||
debug: false
|
||||
})
|
||||
.bundle();
|
||||
mochify('./test/*.js', {
|
||||
reporter: 'spec',
|
||||
transform: 'brfs',
|
||||
"web-security": false,
|
||||
"webSecurityEnabled": false,
|
||||
// "localUrlAccess": true,
|
||||
watch: false,
|
||||
wd: false,
|
||||
debug: false
|
||||
})
|
||||
.bundle();
|
||||
});
|
||||
|
||||
// Default
|
||||
|
@ -98,51 +98,51 @@ gulp.task('default', ['lint', 'bundle']);
|
|||
|
||||
|
||||
function bundle(file, watch) {
|
||||
var opt = {
|
||||
entries: ['src/'+file],
|
||||
standalone: 'ePub',
|
||||
debug : true
|
||||
};
|
||||
var opt = {
|
||||
entries: ['src/'+file],
|
||||
standalone: 'ePub',
|
||||
debug : true
|
||||
};
|
||||
|
||||
var b = browserify(opt);
|
||||
var b = browserify(opt);
|
||||
|
||||
// Expose epub module for require
|
||||
b.require('./src/'+file, {expose: 'epub'});
|
||||
// Expose epub module for require
|
||||
b.require('./src/'+file, {expose: 'epub'});
|
||||
|
||||
// Keep JSZip library seperate,
|
||||
// must be loaded to use Unarchive or `require` will throw an error
|
||||
b.external('jszip');
|
||||
// Keep JSZip library seperate,
|
||||
// must be loaded to use Unarchive or `require` will throw an error
|
||||
b.external('jszip');
|
||||
|
||||
b.external('xmldom');
|
||||
b.external('xmldom');
|
||||
|
||||
// Ignore optional URI libraries
|
||||
var urijsPath = URI(require.resolve('urijs'));
|
||||
['./punycode.js', './IPv6.js'].forEach(function(lib) {
|
||||
var libPath = URI(lib).absoluteTo(urijsPath).toString();
|
||||
b.ignore(libPath);
|
||||
});
|
||||
// Ignore optional URI libraries
|
||||
var urijsPath = URI(require.resolve('urijs'));
|
||||
['./punycode.js', './IPv6.js'].forEach(function(lib) {
|
||||
var libPath = URI(lib).absoluteTo(urijsPath).toString();
|
||||
b.ignore(libPath);
|
||||
});
|
||||
|
||||
// watchify() if watch requested, otherwise run browserify() once
|
||||
var bundler = watch ? watchify(b) : b;
|
||||
// watchify() if watch requested, otherwise run browserify() once
|
||||
var bundler = watch ? watchify(b) : b;
|
||||
|
||||
function rebundle() {
|
||||
var stream = bundler.bundle();
|
||||
return stream
|
||||
.on('error', gutil.log)
|
||||
.pipe(source(file))
|
||||
.pipe(buffer())
|
||||
.pipe(sourcemaps.init({loadMaps: true}))
|
||||
.pipe(sourcemaps.write('./'))
|
||||
.pipe(size({ showFiles: true }))
|
||||
.pipe(gulp.dest('./dist/'));
|
||||
}
|
||||
function rebundle() {
|
||||
var stream = bundler.bundle();
|
||||
return stream
|
||||
.on('error', gutil.log)
|
||||
.pipe(source(file))
|
||||
.pipe(buffer())
|
||||
.pipe(sourcemaps.init({loadMaps: true}))
|
||||
.pipe(sourcemaps.write('./'))
|
||||
.pipe(size({ showFiles: true }))
|
||||
.pipe(gulp.dest('./dist/'));
|
||||
}
|
||||
|
||||
// listen for an update and run rebundle
|
||||
bundler.on('update', function() {
|
||||
rebundle();
|
||||
gutil.log('Rebundle...');
|
||||
});
|
||||
// listen for an update and run rebundle
|
||||
bundler.on('update', function() {
|
||||
rebundle();
|
||||
gutil.log('Rebundle...');
|
||||
});
|
||||
|
||||
// run it once the first time buildScript is called
|
||||
return rebundle();
|
||||
// run it once the first time buildScript is called
|
||||
return rebundle();
|
||||
}
|
||||
|
|
416
src/book.js
416
src/book.js
|
@ -12,264 +12,264 @@ var EpubCFI = require('./epubcfi');
|
|||
|
||||
function Book(_url, options){
|
||||
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
this.settings = core.extend(this.settings || {}, {
|
||||
requestMethod: this.requestMethod
|
||||
});
|
||||
|
||||
core.extend(this.settings, options);
|
||||
core.extend(this.settings, options);
|
||||
|
||||
|
||||
// Promises
|
||||
this.opening = new RSVP.defer();
|
||||
this.opened = this.opening.promise;
|
||||
this.isOpen = false;
|
||||
// Promises
|
||||
this.opening = new RSVP.defer();
|
||||
this.opened = this.opening.promise;
|
||||
this.isOpen = false;
|
||||
|
||||
this.url = undefined;
|
||||
this.url = undefined;
|
||||
|
||||
this.loading = {
|
||||
manifest: new RSVP.defer(),
|
||||
spine: new RSVP.defer(),
|
||||
metadata: new RSVP.defer(),
|
||||
cover: new RSVP.defer(),
|
||||
navigation: new RSVP.defer(),
|
||||
pageList: new RSVP.defer()
|
||||
};
|
||||
this.loading = {
|
||||
manifest: new RSVP.defer(),
|
||||
spine: new RSVP.defer(),
|
||||
metadata: new RSVP.defer(),
|
||||
cover: new RSVP.defer(),
|
||||
navigation: new RSVP.defer(),
|
||||
pageList: new RSVP.defer()
|
||||
};
|
||||
|
||||
this.loaded = {
|
||||
manifest: this.loading.manifest.promise,
|
||||
spine: this.loading.spine.promise,
|
||||
metadata: this.loading.metadata.promise,
|
||||
cover: this.loading.cover.promise,
|
||||
navigation: this.loading.navigation.promise,
|
||||
pageList: this.loading.pageList.promise
|
||||
};
|
||||
this.loaded = {
|
||||
manifest: this.loading.manifest.promise,
|
||||
spine: this.loading.spine.promise,
|
||||
metadata: this.loading.metadata.promise,
|
||||
cover: this.loading.cover.promise,
|
||||
navigation: this.loading.navigation.promise,
|
||||
pageList: this.loading.pageList.promise
|
||||
};
|
||||
|
||||
this.ready = RSVP.hash(this.loaded);
|
||||
this.ready = RSVP.hash(this.loaded);
|
||||
|
||||
// Queue for methods used before opening
|
||||
this.isRendered = false;
|
||||
// this._q = core.queue(this);
|
||||
// Queue for methods used before opening
|
||||
this.isRendered = false;
|
||||
// this._q = core.queue(this);
|
||||
|
||||
this.request = this.settings.requestMethod.bind(this);
|
||||
this.request = this.settings.requestMethod.bind(this);
|
||||
|
||||
this.spine = new Spine(this.request);
|
||||
this.locations = new Locations(this.spine, this.request);
|
||||
this.spine = new Spine(this.request);
|
||||
this.locations = new Locations(this.spine, this.request);
|
||||
|
||||
if(_url) {
|
||||
this.open(_url).catch(function (error) {
|
||||
var err = new Error("Cannot load book at "+ _url );
|
||||
console.error(err);
|
||||
if(_url) {
|
||||
this.open(_url).catch(function (error) {
|
||||
var err = new Error("Cannot load book at "+ _url );
|
||||
console.error(err);
|
||||
|
||||
this.trigger("loadFailed", error);
|
||||
}.bind(this));
|
||||
}
|
||||
this.trigger("loadFailed", error);
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
Book.prototype.open = function(_url, options){
|
||||
var uri;
|
||||
var parse = new Parser();
|
||||
var epubPackage;
|
||||
var epubContainer;
|
||||
var book = this;
|
||||
var containerPath = "META-INF/container.xml";
|
||||
var location;
|
||||
var absoluteUri;
|
||||
var isArrayBuffer = false;
|
||||
var isBase64 = options && options.base64;
|
||||
var uri;
|
||||
var parse = new Parser();
|
||||
var epubPackage;
|
||||
var epubContainer;
|
||||
var book = this;
|
||||
var containerPath = "META-INF/container.xml";
|
||||
var location;
|
||||
var absoluteUri;
|
||||
var isArrayBuffer = false;
|
||||
var isBase64 = options && options.base64;
|
||||
|
||||
if(!_url) {
|
||||
this.opening.resolve(this);
|
||||
return this.opened;
|
||||
}
|
||||
|
||||
// Reuse parsed url or create a new uri object
|
||||
// if(typeof(_url) === "object") {
|
||||
// uri = _url;
|
||||
// } else {
|
||||
// uri = core.uri(_url);
|
||||
// }
|
||||
if (_url instanceof ArrayBuffer || isBase64) {
|
||||
isArrayBuffer = true;
|
||||
this.url = '/';
|
||||
} else {
|
||||
uri = URI(_url);
|
||||
if(!_url) {
|
||||
this.opening.resolve(this);
|
||||
return this.opened;
|
||||
}
|
||||
|
||||
if (window && window.location && uri) {
|
||||
absoluteUri = uri.absoluteTo(window.location.href);
|
||||
this.url = absoluteUri.toString();
|
||||
} else if (window && window.location) {
|
||||
this.url = window.location.href;
|
||||
} else {
|
||||
this.url = _url;
|
||||
}
|
||||
// Reuse parsed url or create a new uri object
|
||||
// if(typeof(_url) === "object") {
|
||||
// uri = _url;
|
||||
// } else {
|
||||
// uri = core.uri(_url);
|
||||
// }
|
||||
if (_url instanceof ArrayBuffer || isBase64) {
|
||||
isArrayBuffer = true;
|
||||
this.url = '/';
|
||||
} else {
|
||||
uri = URI(_url);
|
||||
}
|
||||
|
||||
// Find path to the Container
|
||||
if(uri && uri.suffix() === "opf") {
|
||||
// Direct link to package, no container
|
||||
this.packageUrl = _url;
|
||||
this.containerUrl = '';
|
||||
if (window && window.location && uri) {
|
||||
absoluteUri = uri.absoluteTo(window.location.href);
|
||||
this.url = absoluteUri.toString();
|
||||
} else if (window && window.location) {
|
||||
this.url = window.location.href;
|
||||
} else {
|
||||
this.url = _url;
|
||||
}
|
||||
|
||||
if(uri.origin()) {
|
||||
this.baseUrl = uri.origin() + "/" + uri.directory() + "/";
|
||||
} else if(absoluteUri){
|
||||
this.baseUrl = absoluteUri.origin();
|
||||
this.baseUrl += absoluteUri.directory() + "/";
|
||||
} else {
|
||||
this.baseUrl = uri.directory() + "/";
|
||||
}
|
||||
// Find path to the Container
|
||||
if(uri && uri.suffix() === "opf") {
|
||||
// Direct link to package, no container
|
||||
this.packageUrl = _url;
|
||||
this.containerUrl = '';
|
||||
|
||||
epubPackage = this.request(this.packageUrl)
|
||||
.catch(function(error) {
|
||||
book.opening.reject(error);
|
||||
});
|
||||
if(uri.origin()) {
|
||||
this.baseUrl = uri.origin() + "/" + uri.directory() + "/";
|
||||
} else if(absoluteUri){
|
||||
this.baseUrl = absoluteUri.origin();
|
||||
this.baseUrl += absoluteUri.directory() + "/";
|
||||
} else {
|
||||
this.baseUrl = uri.directory() + "/";
|
||||
}
|
||||
|
||||
} else if(isArrayBuffer || isBase64 || this.isArchivedUrl(uri)) {
|
||||
// Book is archived
|
||||
this.url = '/';
|
||||
this.containerUrl = URI(containerPath).absoluteTo(this.url).toString();
|
||||
epubPackage = this.request(this.packageUrl)
|
||||
.catch(function(error) {
|
||||
book.opening.reject(error);
|
||||
});
|
||||
|
||||
epubContainer = this.unarchive(_url, isBase64).
|
||||
then(function() {
|
||||
return this.request(this.containerUrl);
|
||||
}.bind(this))
|
||||
.catch(function(error) {
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
// Find the path to the Package from the container
|
||||
else if (!uri.suffix()) {
|
||||
} else if(isArrayBuffer || isBase64 || this.isArchivedUrl(uri)) {
|
||||
// Book is archived
|
||||
this.url = '/';
|
||||
this.containerUrl = URI(containerPath).absoluteTo(this.url).toString();
|
||||
|
||||
this.containerUrl = this.url + containerPath;
|
||||
epubContainer = this.unarchive(_url, isBase64).
|
||||
then(function() {
|
||||
return this.request(this.containerUrl);
|
||||
}.bind(this))
|
||||
.catch(function(error) {
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
// Find the path to the Package from the container
|
||||
else if (!uri.suffix()) {
|
||||
|
||||
epubContainer = this.request(this.containerUrl)
|
||||
.catch(function(error) {
|
||||
// handle errors in loading container
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
this.containerUrl = this.url + containerPath;
|
||||
|
||||
if (epubContainer) {
|
||||
epubPackage = epubContainer.
|
||||
then(function(containerXml){
|
||||
return parse.container(containerXml); // Container has path to content
|
||||
}).
|
||||
then(function(paths){
|
||||
var packageUri = URI(paths.packagePath);
|
||||
var absPackageUri = packageUri.absoluteTo(book.url);
|
||||
var absWindowUri;
|
||||
epubContainer = this.request(this.containerUrl)
|
||||
.catch(function(error) {
|
||||
// handle errors in loading container
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
book.packageUrl = absPackageUri.toString();
|
||||
book.encoding = paths.encoding;
|
||||
if (epubContainer) {
|
||||
epubPackage = epubContainer.
|
||||
then(function(containerXml){
|
||||
return parse.container(containerXml); // Container has path to content
|
||||
}).
|
||||
then(function(paths){
|
||||
var packageUri = URI(paths.packagePath);
|
||||
var absPackageUri = packageUri.absoluteTo(book.url);
|
||||
var absWindowUri;
|
||||
|
||||
// Set Url relative to the content
|
||||
if(absPackageUri.origin()) {
|
||||
book.baseUrl = absPackageUri.origin() + absPackageUri.directory() + "/";
|
||||
} else {
|
||||
if(packageUri.directory()) {
|
||||
book.baseUrl = "/" + packageUri.directory() + "/";
|
||||
} else {
|
||||
book.baseUrl = "/"
|
||||
}
|
||||
}
|
||||
book.packageUrl = absPackageUri.toString();
|
||||
book.encoding = paths.encoding;
|
||||
|
||||
return book.request(book.packageUrl);
|
||||
}).catch(function(error) {
|
||||
// handle errors in either of the two requests
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
// Set Url relative to the content
|
||||
if(absPackageUri.origin()) {
|
||||
book.baseUrl = absPackageUri.origin() + absPackageUri.directory() + "/";
|
||||
} else {
|
||||
if(packageUri.directory()) {
|
||||
book.baseUrl = "/" + packageUri.directory() + "/";
|
||||
} else {
|
||||
book.baseUrl = "/"
|
||||
}
|
||||
}
|
||||
|
||||
epubPackage.then(function(packageXml) {
|
||||
return book.request(book.packageUrl);
|
||||
}).catch(function(error) {
|
||||
// handle errors in either of the two requests
|
||||
book.opening.reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
if (!packageXml) {
|
||||
return;
|
||||
}
|
||||
epubPackage.then(function(packageXml) {
|
||||
|
||||
// Get package information from epub opf
|
||||
book.unpack(packageXml);
|
||||
if (!packageXml) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve promises
|
||||
book.loading.manifest.resolve(book.package.manifest);
|
||||
book.loading.metadata.resolve(book.package.metadata);
|
||||
book.loading.spine.resolve(book.spine);
|
||||
book.loading.cover.resolve(book.cover);
|
||||
// Get package information from epub opf
|
||||
book.unpack(packageXml);
|
||||
|
||||
book.isOpen = true;
|
||||
// Resolve promises
|
||||
book.loading.manifest.resolve(book.package.manifest);
|
||||
book.loading.metadata.resolve(book.package.metadata);
|
||||
book.loading.spine.resolve(book.spine);
|
||||
book.loading.cover.resolve(book.cover);
|
||||
|
||||
// Clear queue of any waiting book request
|
||||
book.isOpen = true;
|
||||
|
||||
// Resolve book opened promise
|
||||
book.opening.resolve(book);
|
||||
// Clear queue of any waiting book request
|
||||
|
||||
}).catch(function(error) {
|
||||
// handle errors in parsing the book
|
||||
// console.error(error.message, error.stack);
|
||||
book.opening.reject(error);
|
||||
});
|
||||
// Resolve book opened promise
|
||||
book.opening.resolve(book);
|
||||
|
||||
return this.opened;
|
||||
}).catch(function(error) {
|
||||
// handle errors in parsing the book
|
||||
// console.error(error.message, error.stack);
|
||||
book.opening.reject(error);
|
||||
});
|
||||
|
||||
return this.opened;
|
||||
};
|
||||
|
||||
Book.prototype.unpack = function(packageXml){
|
||||
var book = this,
|
||||
parse = new Parser();
|
||||
var book = this,
|
||||
parse = new Parser();
|
||||
|
||||
book.package = parse.packageContents(packageXml); // Extract info from contents
|
||||
if(!book.package) {
|
||||
return;
|
||||
}
|
||||
book.package = parse.packageContents(packageXml); // Extract info from contents
|
||||
if(!book.package) {
|
||||
return;
|
||||
}
|
||||
|
||||
book.package.baseUrl = book.baseUrl; // Provides a url base for resolving paths
|
||||
book.package.baseUrl = book.baseUrl; // Provides a url base for resolving paths
|
||||
|
||||
this.spine.load(book.package);
|
||||
this.spine.load(book.package);
|
||||
|
||||
book.navigation = new Navigation(book.package, this.request);
|
||||
book.navigation.load().then(function(toc){
|
||||
book.toc = toc;
|
||||
book.loading.navigation.resolve(book.toc);
|
||||
});
|
||||
book.navigation = new Navigation(book.package, this.request);
|
||||
book.navigation.load().then(function(toc){
|
||||
book.toc = toc;
|
||||
book.loading.navigation.resolve(book.toc);
|
||||
});
|
||||
|
||||
// //-- Set Global Layout setting based on metadata
|
||||
// MOVE TO RENDER
|
||||
// book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata);
|
||||
// //-- Set Global Layout setting based on metadata
|
||||
// MOVE TO RENDER
|
||||
// book.globalLayoutProperties = book.parseLayoutProperties(book.package.metadata);
|
||||
|
||||
book.cover = URI(book.package.coverPath).absoluteTo(book.baseUrl).toString();
|
||||
book.cover = URI(book.package.coverPath).absoluteTo(book.baseUrl).toString();
|
||||
};
|
||||
|
||||
// Alias for book.spine.get
|
||||
Book.prototype.section = function(target) {
|
||||
return this.spine.get(target);
|
||||
return this.spine.get(target);
|
||||
};
|
||||
|
||||
// Sugar to render a book
|
||||
Book.prototype.renderTo = function(element, options) {
|
||||
// var renderMethod = (options && options.method) ?
|
||||
// options.method :
|
||||
// "single";
|
||||
// var renderMethod = (options && options.method) ?
|
||||
// options.method :
|
||||
// "single";
|
||||
|
||||
this.rendition = new Rendition(this, options);
|
||||
this.rendition.attachTo(element);
|
||||
this.rendition = new Rendition(this, options);
|
||||
this.rendition.attachTo(element);
|
||||
|
||||
return this.rendition;
|
||||
return this.rendition;
|
||||
};
|
||||
|
||||
Book.prototype.requestMethod = function(_url) {
|
||||
// Switch request methods
|
||||
if(this.unarchived) {
|
||||
return this.unarchived.request(_url);
|
||||
} else {
|
||||
return request(_url, null, this.requestCredentials, this.requestHeaders);
|
||||
}
|
||||
// Switch request methods
|
||||
if(this.unarchived) {
|
||||
return this.unarchived.request(_url);
|
||||
} else {
|
||||
return request(_url, null, this.requestCredentials, this.requestHeaders);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Book.prototype.setRequestCredentials = function(_credentials) {
|
||||
this.requestCredentials = _credentials;
|
||||
this.requestCredentials = _credentials;
|
||||
};
|
||||
|
||||
Book.prototype.setRequestHeaders = function(_headers) {
|
||||
this.requestHeaders = _headers;
|
||||
this.requestHeaders = _headers;
|
||||
};
|
||||
|
||||
Book.prototype.unarchive = function(bookUrl, isBase64){
|
||||
|
@ -279,21 +279,21 @@ Book.prototype.unarchive = function(bookUrl, isBase64){
|
|||
|
||||
//-- Checks if url has a .epub or .zip extension, or is ArrayBuffer (of zip/epub)
|
||||
Book.prototype.isArchivedUrl = function(bookUrl){
|
||||
var uri;
|
||||
var extension;
|
||||
var uri;
|
||||
var extension;
|
||||
|
||||
if (bookUrl instanceof ArrayBuffer) {
|
||||
if (bookUrl instanceof ArrayBuffer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reuse parsed url or create a new uri object
|
||||
// if(typeof(bookUrl) === "object") {
|
||||
// uri = bookUrl;
|
||||
// } else {
|
||||
// uri = core.uri(bookUrl);
|
||||
// }
|
||||
uri = URI(bookUrl);
|
||||
extension = uri.suffix();
|
||||
// Reuse parsed url or create a new uri object
|
||||
// if(typeof(bookUrl) === "object") {
|
||||
// uri = bookUrl;
|
||||
// } else {
|
||||
// uri = core.uri(bookUrl);
|
||||
// }
|
||||
uri = URI(bookUrl);
|
||||
extension = uri.suffix();
|
||||
|
||||
if(extension && (extension == "epub" || extension == "zip")){
|
||||
return true;
|
||||
|
@ -319,13 +319,13 @@ Book.prototype.coverUrl = function(){
|
|||
};
|
||||
|
||||
Book.prototype.range = function(cfiRange) {
|
||||
var cfi = new EpubCFI(cfiRange);
|
||||
var item = this.spine.get(cfi.spinePos);
|
||||
var cfi = new EpubCFI(cfiRange);
|
||||
var item = this.spine.get(cfi.spinePos);
|
||||
|
||||
return item.load().then(function (contents) {
|
||||
var range = cfi.toRange(item.document);
|
||||
return range;
|
||||
})
|
||||
return item.load().then(function (contents) {
|
||||
var range = cfi.toRange(item.document);
|
||||
return range;
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = Book;
|
||||
|
@ -335,7 +335,7 @@ RSVP.EventTarget.mixin(Book.prototype);
|
|||
|
||||
//-- Handle RSVP Errors
|
||||
RSVP.on('error', function(event) {
|
||||
console.error(event);
|
||||
console.error(event);
|
||||
});
|
||||
|
||||
RSVP.configure('instrument', false); //-- true | will logging out all RSVP rejections
|
||||
|
@ -343,5 +343,5 @@ RSVP.configure('instrument', false); //-- true | will logging out all RSVP rejec
|
|||
// RSVP.on('chained', listener);
|
||||
// RSVP.on('fulfilled', listener);
|
||||
RSVP.on('rejected', function(event){
|
||||
console.error(event.detail.message, event.detail.stack);
|
||||
console.error(event.detail.message, event.detail.stack);
|
||||
});
|
||||
|
|
776
src/contents.js
776
src/contents.js
File diff suppressed because it is too large
Load diff
740
src/core.js
740
src/core.js
|
@ -5,536 +5,536 @@ var requestAnimationFrame = (typeof window != 'undefined') ? (window.requestAnim
|
|||
/*
|
||||
//-- Parse the different parts of a url, returning a object
|
||||
function uri(url){
|
||||
var uri = {
|
||||
protocol : '',
|
||||
host : '',
|
||||
path : '',
|
||||
origin : '',
|
||||
directory : '',
|
||||
base : '',
|
||||
filename : '',
|
||||
extension : '',
|
||||
fragment : '',
|
||||
href : url
|
||||
},
|
||||
doubleSlash = url.indexOf('://'),
|
||||
search = url.indexOf('?'),
|
||||
fragment = url.indexOf("#"),
|
||||
withoutProtocol,
|
||||
dot,
|
||||
firstSlash;
|
||||
var uri = {
|
||||
protocol : '',
|
||||
host : '',
|
||||
path : '',
|
||||
origin : '',
|
||||
directory : '',
|
||||
base : '',
|
||||
filename : '',
|
||||
extension : '',
|
||||
fragment : '',
|
||||
href : url
|
||||
},
|
||||
doubleSlash = url.indexOf('://'),
|
||||
search = url.indexOf('?'),
|
||||
fragment = url.indexOf("#"),
|
||||
withoutProtocol,
|
||||
dot,
|
||||
firstSlash;
|
||||
|
||||
if(fragment != -1) {
|
||||
uri.fragment = url.slice(fragment + 1);
|
||||
url = url.slice(0, fragment);
|
||||
}
|
||||
if(fragment != -1) {
|
||||
uri.fragment = url.slice(fragment + 1);
|
||||
url = url.slice(0, fragment);
|
||||
}
|
||||
|
||||
if(search != -1) {
|
||||
uri.search = url.slice(search + 1);
|
||||
url = url.slice(0, search);
|
||||
href = url;
|
||||
}
|
||||
if(search != -1) {
|
||||
uri.search = url.slice(search + 1);
|
||||
url = url.slice(0, search);
|
||||
href = url;
|
||||
}
|
||||
|
||||
if(doubleSlash != -1) {
|
||||
uri.protocol = url.slice(0, doubleSlash);
|
||||
withoutProtocol = url.slice(doubleSlash+3);
|
||||
firstSlash = withoutProtocol.indexOf('/');
|
||||
if(doubleSlash != -1) {
|
||||
uri.protocol = url.slice(0, doubleSlash);
|
||||
withoutProtocol = url.slice(doubleSlash+3);
|
||||
firstSlash = withoutProtocol.indexOf('/');
|
||||
|
||||
if(firstSlash === -1) {
|
||||
uri.host = uri.path;
|
||||
uri.path = "";
|
||||
} else {
|
||||
uri.host = withoutProtocol.slice(0, firstSlash);
|
||||
uri.path = withoutProtocol.slice(firstSlash);
|
||||
}
|
||||
if(firstSlash === -1) {
|
||||
uri.host = uri.path;
|
||||
uri.path = "";
|
||||
} else {
|
||||
uri.host = withoutProtocol.slice(0, firstSlash);
|
||||
uri.path = withoutProtocol.slice(firstSlash);
|
||||
}
|
||||
|
||||
|
||||
uri.origin = uri.protocol + "://" + uri.host;
|
||||
uri.origin = uri.protocol + "://" + uri.host;
|
||||
|
||||
uri.directory = folder(uri.path);
|
||||
uri.directory = folder(uri.path);
|
||||
|
||||
uri.base = uri.origin + uri.directory;
|
||||
// return origin;
|
||||
} else {
|
||||
uri.path = url;
|
||||
uri.directory = folder(url);
|
||||
uri.base = uri.directory;
|
||||
}
|
||||
uri.base = uri.origin + uri.directory;
|
||||
// return origin;
|
||||
} else {
|
||||
uri.path = url;
|
||||
uri.directory = folder(url);
|
||||
uri.base = uri.directory;
|
||||
}
|
||||
|
||||
//-- Filename
|
||||
uri.filename = url.replace(uri.base, '');
|
||||
dot = uri.filename.lastIndexOf('.');
|
||||
if(dot != -1) {
|
||||
uri.extension = uri.filename.slice(dot+1);
|
||||
}
|
||||
return uri;
|
||||
//-- Filename
|
||||
uri.filename = url.replace(uri.base, '');
|
||||
dot = uri.filename.lastIndexOf('.');
|
||||
if(dot != -1) {
|
||||
uri.extension = uri.filename.slice(dot+1);
|
||||
}
|
||||
return uri;
|
||||
};
|
||||
|
||||
//-- Parse out the folder, will return everything before the last slash
|
||||
function folder(url){
|
||||
|
||||
var lastSlash = url.lastIndexOf('/');
|
||||
var lastSlash = url.lastIndexOf('/');
|
||||
|
||||
if(lastSlash == -1) var folder = '';
|
||||
if(lastSlash == -1) var folder = '';
|
||||
|
||||
folder = url.slice(0, lastSlash + 1);
|
||||
folder = url.slice(0, lastSlash + 1);
|
||||
|
||||
return folder;
|
||||
return folder;
|
||||
|
||||
};
|
||||
*/
|
||||
function isElement(obj) {
|
||||
return !!(obj && obj.nodeType == 1);
|
||||
return !!(obj && obj.nodeType == 1);
|
||||
};
|
||||
|
||||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
|
||||
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;
|
||||
d = Math.floor(d/16);
|
||||
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
|
||||
});
|
||||
return 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;
|
||||
d = Math.floor(d/16);
|
||||
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
};
|
||||
|
||||
// From Lodash
|
||||
function values(object) {
|
||||
var index = -1,
|
||||
props = Object.keys(object),
|
||||
length = props.length,
|
||||
result = Array(length);
|
||||
var index = -1,
|
||||
props = Object.keys(object),
|
||||
length = props.length,
|
||||
result = Array(length);
|
||||
|
||||
while (++index < length) {
|
||||
result[index] = object[props[index]];
|
||||
}
|
||||
return result;
|
||||
while (++index < length) {
|
||||
result[index] = object[props[index]];
|
||||
}
|
||||
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;
|
||||
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(uri.host) {
|
||||
// return path;
|
||||
// }
|
||||
|
||||
if(baseDirectory[0] === "/") {
|
||||
baseDirectory = baseDirectory.substring(1);
|
||||
}
|
||||
if(baseDirectory[0] === "/") {
|
||||
baseDirectory = baseDirectory.substring(1);
|
||||
}
|
||||
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
baseDirectory = baseDirectory.substring(0, baseDirectory.length-1);
|
||||
}
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
baseDirectory = baseDirectory.substring(0, baseDirectory.length-1);
|
||||
}
|
||||
|
||||
if(pathDirectory[0] === "/") {
|
||||
pathDirectory = pathDirectory.substring(1);
|
||||
}
|
||||
if(pathDirectory[0] === "/") {
|
||||
pathDirectory = pathDirectory.substring(1);
|
||||
}
|
||||
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
pathDirectory = pathDirectory.substring(0, pathDirectory.length-1);
|
||||
}
|
||||
if(pathDirectory[pathDirectory.length-1] === "/") {
|
||||
pathDirectory = pathDirectory.substring(0, pathDirectory.length-1);
|
||||
}
|
||||
|
||||
if(baseDirectory) {
|
||||
directories = baseDirectory.split("/");
|
||||
}
|
||||
if(baseDirectory) {
|
||||
directories = baseDirectory.split("/");
|
||||
}
|
||||
|
||||
paths = pathDirectory.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);
|
||||
}
|
||||
});
|
||||
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];
|
||||
url = [baseUri.origin];
|
||||
|
||||
if(directories.length) {
|
||||
url = url.concat(directories);
|
||||
}
|
||||
if(directories.length) {
|
||||
url = url.concat(directories);
|
||||
}
|
||||
|
||||
if(segments) {
|
||||
url = url.concat(segments);
|
||||
}
|
||||
if(segments) {
|
||||
url = url.concat(segments);
|
||||
}
|
||||
|
||||
url = url.concat(pathUri.filename);
|
||||
url = url.concat(pathUri.filename);
|
||||
|
||||
return url.join("/");
|
||||
return url.join("/");
|
||||
};
|
||||
|
||||
function documentHeight() {
|
||||
return Math.max(
|
||||
document.documentElement.clientHeight,
|
||||
document.body.scrollHeight,
|
||||
document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight,
|
||||
document.documentElement.offsetHeight
|
||||
);
|
||||
return Math.max(
|
||||
document.documentElement.clientHeight,
|
||||
document.body.scrollHeight,
|
||||
document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight,
|
||||
document.documentElement.offsetHeight
|
||||
);
|
||||
};
|
||||
|
||||
function isNumber(n) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
};
|
||||
|
||||
function prefixed(unprefixed) {
|
||||
var vendors = ["Webkit", "Moz", "O", "ms" ],
|
||||
prefixes = ['-Webkit-', '-moz-', '-o-', '-ms-'],
|
||||
upper = unprefixed[0].toUpperCase() + unprefixed.slice(1),
|
||||
length = vendors.length;
|
||||
var vendors = ["Webkit", "Moz", "O", "ms" ],
|
||||
prefixes = ['-Webkit-', '-moz-', '-o-', '-ms-'],
|
||||
upper = unprefixed[0].toUpperCase() + unprefixed.slice(1),
|
||||
length = vendors.length;
|
||||
|
||||
if (typeof(document) === 'undefined' || typeof(document.body.style[unprefixed]) != 'undefined') {
|
||||
return unprefixed;
|
||||
}
|
||||
if (typeof(document) === 'undefined' || typeof(document.body.style[unprefixed]) != 'undefined') {
|
||||
return unprefixed;
|
||||
}
|
||||
|
||||
for ( var i=0; i < length; i++ ) {
|
||||
if (typeof(document.body.style[vendors[i] + upper]) != 'undefined') {
|
||||
return vendors[i] + upper;
|
||||
}
|
||||
}
|
||||
for ( var i=0; i < length; i++ ) {
|
||||
if (typeof(document.body.style[vendors[i] + upper]) != 'undefined') {
|
||||
return vendors[i] + upper;
|
||||
}
|
||||
}
|
||||
|
||||
return unprefixed;
|
||||
return unprefixed;
|
||||
};
|
||||
|
||||
function defaults(obj) {
|
||||
for (var i = 1, length = arguments.length; i < length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var prop in source) {
|
||||
if (obj[prop] === void 0) obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
for (var i = 1, length = arguments.length; i < length; i++) {
|
||||
var source = arguments[i];
|
||||
for (var prop in source) {
|
||||
if (obj[prop] === void 0) obj[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
function extend(target) {
|
||||
var sources = [].slice.call(arguments, 1);
|
||||
sources.forEach(function (source) {
|
||||
if(!source) return;
|
||||
Object.getOwnPropertyNames(source).forEach(function(propName) {
|
||||
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
|
||||
});
|
||||
});
|
||||
return target;
|
||||
var sources = [].slice.call(arguments, 1);
|
||||
sources.forEach(function (source) {
|
||||
if(!source) return;
|
||||
Object.getOwnPropertyNames(source).forEach(function(propName) {
|
||||
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
|
||||
});
|
||||
});
|
||||
return 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) {
|
||||
var location = locationOf(item, array, compareFunction);
|
||||
array.splice(location, 0, item);
|
||||
var location = locationOf(item, array, compareFunction);
|
||||
array.splice(location, 0, item);
|
||||
|
||||
return location;
|
||||
return location;
|
||||
};
|
||||
// Returns where something would fit in
|
||||
function locationOf(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
if(a < b) return -1;
|
||||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 0) {
|
||||
return pivot;
|
||||
}
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
if(a < b) return -1;
|
||||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 0) {
|
||||
return pivot;
|
||||
}
|
||||
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared > 0 ? pivot : pivot + 1;
|
||||
}
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared > 0 ? pivot : pivot + 1;
|
||||
}
|
||||
|
||||
if(compared === 0) {
|
||||
return pivot;
|
||||
}
|
||||
if(compared === -1) {
|
||||
return locationOf(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return locationOf(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
if(compared === 0) {
|
||||
return pivot;
|
||||
}
|
||||
if(compared === -1) {
|
||||
return locationOf(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return locationOf(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
};
|
||||
// Returns -1 of mpt found
|
||||
function indexOfSorted(item, array, compareFunction, _start, _end) {
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
if(a < b) return -1;
|
||||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 0) {
|
||||
return -1; // Not found
|
||||
}
|
||||
var start = _start || 0;
|
||||
var end = _end || array.length;
|
||||
var pivot = parseInt(start + (end - start) / 2);
|
||||
var compared;
|
||||
if(!compareFunction){
|
||||
compareFunction = function(a, b) {
|
||||
if(a > b) return 1;
|
||||
if(a < b) return -1;
|
||||
if(a = b) return 0;
|
||||
};
|
||||
}
|
||||
if(end-start <= 0) {
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared === 0 ? pivot : -1;
|
||||
}
|
||||
if(compared === 0) {
|
||||
return pivot; // Found
|
||||
}
|
||||
if(compared === -1) {
|
||||
return indexOfSorted(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return indexOfSorted(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
compared = compareFunction(array[pivot], item);
|
||||
if(end-start === 1) {
|
||||
return compared === 0 ? pivot : -1;
|
||||
}
|
||||
if(compared === 0) {
|
||||
return pivot; // Found
|
||||
}
|
||||
if(compared === -1) {
|
||||
return indexOfSorted(item, array, compareFunction, pivot, end);
|
||||
} else{
|
||||
return indexOfSorted(item, array, compareFunction, start, pivot);
|
||||
}
|
||||
};
|
||||
|
||||
function bounds(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["width", "paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["height", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
|
||||
widthProps.forEach(function(prop){
|
||||
width += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
widthProps.forEach(function(prop){
|
||||
width += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
|
||||
heightProps.forEach(function(prop){
|
||||
height += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
heightProps.forEach(function(prop){
|
||||
height += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
};
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
function borders(el) {
|
||||
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
var style = window.getComputedStyle(el);
|
||||
var widthProps = ["paddingRight", "paddingLeft", "marginRight", "marginLeft", "borderRightWidth", "borderLeftWidth"];
|
||||
var heightProps = ["paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"];
|
||||
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
|
||||
widthProps.forEach(function(prop){
|
||||
width += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
widthProps.forEach(function(prop){
|
||||
width += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
|
||||
heightProps.forEach(function(prop){
|
||||
height += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
heightProps.forEach(function(prop){
|
||||
height += parseFloat(style[prop]) || 0;
|
||||
});
|
||||
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
};
|
||||
return {
|
||||
height: height,
|
||||
width: width
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
function windowBounds() {
|
||||
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
|
||||
return {
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: width,
|
||||
bottom: height,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
return {
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: width,
|
||||
bottom: height,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//https://stackoverflow.com/questions/13482352/xquery-looking-for-text-with-single-quote/13483496#13483496
|
||||
function cleanStringForXpath(str) {
|
||||
var parts = str.match(/[^'"]+|['"]/g);
|
||||
parts = parts.map(function(part){
|
||||
if (part === "'") {
|
||||
return '\"\'\"'; // output "'"
|
||||
}
|
||||
var parts = str.match(/[^'"]+|['"]/g);
|
||||
parts = parts.map(function(part){
|
||||
if (part === "'") {
|
||||
return '\"\'\"'; // output "'"
|
||||
}
|
||||
|
||||
if (part === '"') {
|
||||
return "\'\"\'"; // output '"'
|
||||
}
|
||||
return "\'" + part + "\'";
|
||||
});
|
||||
return "concat(\'\'," + parts.join(",") + ")";
|
||||
if (part === '"') {
|
||||
return "\'\"\'"; // output '"'
|
||||
}
|
||||
return "\'" + part + "\'";
|
||||
});
|
||||
return "concat(\'\'," + parts.join(",") + ")";
|
||||
};
|
||||
|
||||
function indexOfTextNode(textNode){
|
||||
var parent = textNode.parentNode;
|
||||
var children = parent.childNodes;
|
||||
var sib;
|
||||
var index = -1;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
sib = children[i];
|
||||
if(sib.nodeType === Node.TEXT_NODE){
|
||||
index++;
|
||||
}
|
||||
if(sib == textNode) break;
|
||||
}
|
||||
var parent = textNode.parentNode;
|
||||
var children = parent.childNodes;
|
||||
var sib;
|
||||
var index = -1;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
sib = children[i];
|
||||
if(sib.nodeType === Node.TEXT_NODE){
|
||||
index++;
|
||||
}
|
||||
if(sib == textNode) break;
|
||||
}
|
||||
|
||||
return index;
|
||||
return index;
|
||||
};
|
||||
|
||||
function isXml(ext) {
|
||||
return ['xml', 'opf', 'ncx'].indexOf(ext) > -1;
|
||||
return ['xml', 'opf', 'ncx'].indexOf(ext) > -1;
|
||||
}
|
||||
|
||||
function createBlob(content, mime){
|
||||
var blob = new Blob([content], {type : mime });
|
||||
|
||||
return blob;
|
||||
return blob;
|
||||
};
|
||||
|
||||
function createBlobUrl(content, mime){
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var tempUrl;
|
||||
var blob = this.createBlob(content, mime);
|
||||
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
|
||||
return tempUrl;
|
||||
return tempUrl;
|
||||
};
|
||||
|
||||
function createBase64Url(content, mime){
|
||||
var string;
|
||||
var data;
|
||||
var datauri;
|
||||
var string;
|
||||
var data;
|
||||
var datauri;
|
||||
|
||||
if (typeof(content) !== "string") {
|
||||
// Only handles strings
|
||||
return;
|
||||
}
|
||||
if (typeof(content) !== "string") {
|
||||
// Only handles strings
|
||||
return;
|
||||
}
|
||||
|
||||
data = btoa(content);
|
||||
data = btoa(content);
|
||||
|
||||
datauri = "data:" + mime + ";base64," + data;
|
||||
datauri = "data:" + mime + ";base64," + data;
|
||||
|
||||
return datauri;
|
||||
return datauri;
|
||||
};
|
||||
|
||||
function type(obj){
|
||||
return Object.prototype.toString.call(obj).slice(8, -1);
|
||||
return Object.prototype.toString.call(obj).slice(8, -1);
|
||||
}
|
||||
|
||||
function parse(markup, mime) {
|
||||
var doc;
|
||||
// console.log("parse", markup);
|
||||
var doc;
|
||||
// console.log("parse", markup);
|
||||
|
||||
if (typeof DOMParser === "undefined") {
|
||||
DOMParser = require('xmldom').DOMParser;
|
||||
}
|
||||
if (typeof DOMParser === "undefined") {
|
||||
DOMParser = require('xmldom').DOMParser;
|
||||
}
|
||||
|
||||
|
||||
doc = new DOMParser().parseFromString(markup, mime);
|
||||
doc = new DOMParser().parseFromString(markup, mime);
|
||||
|
||||
return doc;
|
||||
return doc;
|
||||
}
|
||||
|
||||
function qs(el, sel) {
|
||||
var elements;
|
||||
var elements;
|
||||
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelector(sel);
|
||||
} else {
|
||||
elements = el.getElementsByTagName(sel);
|
||||
if (elements.length) {
|
||||
return elements[0];
|
||||
}
|
||||
}
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelector(sel);
|
||||
} else {
|
||||
elements = el.getElementsByTagName(sel);
|
||||
if (elements.length) {
|
||||
return elements[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function qsa(el, sel) {
|
||||
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelectorAll(sel);
|
||||
} else {
|
||||
return el.getElementsByTagName(sel);
|
||||
}
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
return el.querySelectorAll(sel);
|
||||
} else {
|
||||
return el.getElementsByTagName(sel);
|
||||
}
|
||||
}
|
||||
|
||||
function qsp(el, sel, props) {
|
||||
var q, filtered;
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
sel += '[';
|
||||
for (var prop in props) {
|
||||
sel += prop + "='" + props[prop] + "'";
|
||||
}
|
||||
sel += ']';
|
||||
return el.querySelector(sel);
|
||||
} else {
|
||||
q = el.getElementsByTagName(sel);
|
||||
filtered = Array.prototype.slice.call(q, 0).filter(function(el) {
|
||||
for (var prop in props) {
|
||||
if(el.getAttribute(prop) === props[prop]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
var q, filtered;
|
||||
if (typeof el.querySelector != "undefined") {
|
||||
sel += '[';
|
||||
for (var prop in props) {
|
||||
sel += prop + "='" + props[prop] + "'";
|
||||
}
|
||||
sel += ']';
|
||||
return el.querySelector(sel);
|
||||
} else {
|
||||
q = el.getElementsByTagName(sel);
|
||||
filtered = Array.prototype.slice.call(q, 0).filter(function(el) {
|
||||
for (var prop in props) {
|
||||
if(el.getAttribute(prop) === props[prop]){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (filtered) {
|
||||
return filtered[0];
|
||||
}
|
||||
}
|
||||
if (filtered) {
|
||||
return filtered[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function blob2base64(blob, cb) {
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onloadend = function() {
|
||||
cb(reader.result);
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onloadend = function() {
|
||||
cb(reader.result);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// 'uri': uri,
|
||||
// 'folder': folder,
|
||||
'isElement': isElement,
|
||||
'uuid': uuid,
|
||||
'values': values,
|
||||
'resolveUrl': resolveUrl,
|
||||
'indexOfSorted': indexOfSorted,
|
||||
'documentHeight': documentHeight,
|
||||
'isNumber': isNumber,
|
||||
'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
|
||||
// 'uri': uri,
|
||||
// 'folder': folder,
|
||||
'isElement': isElement,
|
||||
'uuid': uuid,
|
||||
'values': values,
|
||||
'resolveUrl': resolveUrl,
|
||||
'indexOfSorted': indexOfSorted,
|
||||
'documentHeight': documentHeight,
|
||||
'isNumber': isNumber,
|
||||
'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
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ ePub.ViewManagers = {};
|
|||
ePub.Views = {};
|
||||
ePub.register = {
|
||||
manager : function(name, manager){
|
||||
return ePub.ViewManagers[name] = manager;
|
||||
return ePub.ViewManagers[name] = manager;
|
||||
},
|
||||
view : function(name, view){
|
||||
return ePub.Views[name] = view;
|
||||
|
|
1302
src/epubcfi.js
1302
src/epubcfi.js
File diff suppressed because it is too large
Load diff
52
src/hook.js
52
src/hook.js
|
@ -9,51 +9,51 @@ var RSVP = require('rsvp');
|
|||
// this.content.trigger(args).then(function(){});
|
||||
|
||||
function Hook(context){
|
||||
this.context = context || this;
|
||||
this.hooks = [];
|
||||
this.context = context || this;
|
||||
this.hooks = [];
|
||||
};
|
||||
|
||||
// Adds a function to be run before a hook completes
|
||||
Hook.prototype.register = function(){
|
||||
for(var i = 0; i < arguments.length; ++i) {
|
||||
if (typeof arguments[i] === "function") {
|
||||
this.hooks.push(arguments[i]);
|
||||
} else {
|
||||
// unpack array
|
||||
for(var j = 0; j < arguments[i].length; ++j) {
|
||||
this.hooks.push(arguments[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < arguments.length; ++i) {
|
||||
if (typeof arguments[i] === "function") {
|
||||
this.hooks.push(arguments[i]);
|
||||
} else {
|
||||
// unpack array
|
||||
for(var j = 0; j < arguments[i].length; ++j) {
|
||||
this.hooks.push(arguments[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Triggers a hook to run all functions
|
||||
Hook.prototype.trigger = function(){
|
||||
var args = arguments;
|
||||
var context = this.context;
|
||||
var promises = [];
|
||||
var args = arguments;
|
||||
var context = this.context;
|
||||
var promises = [];
|
||||
|
||||
this.hooks.forEach(function(task, i) {
|
||||
var executing = task.apply(context, args);
|
||||
this.hooks.forEach(function(task, i) {
|
||||
var executing = task.apply(context, args);
|
||||
|
||||
if(executing && typeof executing["then"] === "function") {
|
||||
// Task is a function that returns a promise
|
||||
promises.push(executing);
|
||||
}
|
||||
// Otherwise Task resolves immediately, continue
|
||||
});
|
||||
if(executing && typeof executing["then"] === "function") {
|
||||
// Task is a function that returns a promise
|
||||
promises.push(executing);
|
||||
}
|
||||
// Otherwise Task resolves immediately, continue
|
||||
});
|
||||
|
||||
|
||||
return RSVP.all(promises);
|
||||
return RSVP.all(promises);
|
||||
};
|
||||
|
||||
// Adds a function to be run before a hook completes
|
||||
Hook.prototype.list = function(){
|
||||
return this.hooks;
|
||||
return this.hooks;
|
||||
};
|
||||
|
||||
Hook.prototype.clear = function(){
|
||||
return this.hooks = [];
|
||||
return this.hooks = [];
|
||||
};
|
||||
|
||||
module.exports = Hook;
|
||||
|
|
150
src/layout.js
150
src/layout.js
|
@ -2,120 +2,120 @@ var core = require('./core');
|
|||
var RSVP = require('rsvp');
|
||||
|
||||
function Layout(settings){
|
||||
this.name = settings.layout || "reflowable";
|
||||
this._spread = (settings.spread === "none") ? false : true;
|
||||
this._minSpreadWidth = settings.spread || 800;
|
||||
this._evenSpreads = settings.evenSpreads || false;
|
||||
this.name = settings.layout || "reflowable";
|
||||
this._spread = (settings.spread === "none") ? false : true;
|
||||
this._minSpreadWidth = settings.spread || 800;
|
||||
this._evenSpreads = settings.evenSpreads || false;
|
||||
|
||||
if (settings.flow === "scrolled-continuous" ||
|
||||
settings.flow === "scrolled-doc") {
|
||||
this._flow = "scrolled";
|
||||
} else {
|
||||
this._flow = "paginated";
|
||||
}
|
||||
if (settings.flow === "scrolled-continuous" ||
|
||||
settings.flow === "scrolled-doc") {
|
||||
this._flow = "scrolled";
|
||||
} else {
|
||||
this._flow = "paginated";
|
||||
}
|
||||
|
||||
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.spreadWidth = 0;
|
||||
this.delta = 0;
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.spreadWidth = 0;
|
||||
this.delta = 0;
|
||||
|
||||
this.columnWidth = 0;
|
||||
this.gap = 0;
|
||||
this.divisor = 1;
|
||||
this.columnWidth = 0;
|
||||
this.gap = 0;
|
||||
this.divisor = 1;
|
||||
};
|
||||
|
||||
// paginated | scrolled
|
||||
Layout.prototype.flow = function(flow) {
|
||||
this._flow = (flow === "paginated") ? "paginated" : "scrolled";
|
||||
this._flow = (flow === "paginated") ? "paginated" : "scrolled";
|
||||
}
|
||||
|
||||
// true | false
|
||||
Layout.prototype.spread = function(spread, min) {
|
||||
|
||||
this._spread = (spread === "none") ? false : true;
|
||||
this._spread = (spread === "none") ? false : true;
|
||||
|
||||
if (min >= 0) {
|
||||
this._minSpreadWidth = min;
|
||||
}
|
||||
if (min >= 0) {
|
||||
this._minSpreadWidth = min;
|
||||
}
|
||||
}
|
||||
|
||||
Layout.prototype.calculate = function(_width, _height, _gap){
|
||||
|
||||
var divisor = 1;
|
||||
var gap = _gap || 0;
|
||||
var divisor = 1;
|
||||
var gap = _gap || 0;
|
||||
|
||||
//-- Check the width and create even width columns
|
||||
var fullWidth = Math.floor(_width);
|
||||
var width = _width;
|
||||
//-- Check the width and create even width columns
|
||||
var fullWidth = Math.floor(_width);
|
||||
var width = _width;
|
||||
|
||||
var section = Math.floor(width / 8);
|
||||
var section = Math.floor(width / 8);
|
||||
|
||||
var colWidth;
|
||||
var spreadWidth;
|
||||
var delta;
|
||||
var colWidth;
|
||||
var spreadWidth;
|
||||
var delta;
|
||||
|
||||
if (this._spread && width >= this._minSpreadWidth) {
|
||||
divisor = 2;
|
||||
} else {
|
||||
divisor = 1;
|
||||
}
|
||||
if (this._spread && width >= this._minSpreadWidth) {
|
||||
divisor = 2;
|
||||
} else {
|
||||
divisor = 1;
|
||||
}
|
||||
|
||||
if (this.name === "reflowable" && this._flow === "paginated" && !(_gap >= 0)) {
|
||||
gap = ((section % 2 === 0) ? section : section - 1);
|
||||
}
|
||||
if (this.name === "reflowable" && this._flow === "paginated" && !(_gap >= 0)) {
|
||||
gap = ((section % 2 === 0) ? section : section - 1);
|
||||
}
|
||||
|
||||
if (this.name === "pre-paginated" ) {
|
||||
gap = 0;
|
||||
}
|
||||
if (this.name === "pre-paginated" ) {
|
||||
gap = 0;
|
||||
}
|
||||
|
||||
//-- Double Page
|
||||
if(divisor > 1) {
|
||||
colWidth = Math.floor((width - gap) / divisor);
|
||||
} else {
|
||||
colWidth = width;
|
||||
}
|
||||
//-- Double Page
|
||||
if(divisor > 1) {
|
||||
colWidth = Math.floor((width - gap) / divisor);
|
||||
} else {
|
||||
colWidth = width;
|
||||
}
|
||||
|
||||
if (this.name === "pre-paginated" && divisor > 1) {
|
||||
width = colWidth;
|
||||
}
|
||||
if (this.name === "pre-paginated" && divisor > 1) {
|
||||
width = colWidth;
|
||||
}
|
||||
|
||||
spreadWidth = colWidth * divisor;
|
||||
spreadWidth = colWidth * divisor;
|
||||
|
||||
delta = (colWidth + gap) * divisor;
|
||||
delta = (colWidth + gap) * divisor;
|
||||
|
||||
this.width = width;
|
||||
this.height = _height;
|
||||
this.spreadWidth = spreadWidth;
|
||||
this.delta = delta;
|
||||
this.width = width;
|
||||
this.height = _height;
|
||||
this.spreadWidth = spreadWidth;
|
||||
this.delta = delta;
|
||||
|
||||
this.columnWidth = colWidth;
|
||||
this.gap = gap;
|
||||
this.divisor = divisor;
|
||||
this.columnWidth = colWidth;
|
||||
this.gap = gap;
|
||||
this.divisor = divisor;
|
||||
};
|
||||
|
||||
Layout.prototype.format = function(contents){
|
||||
var formating;
|
||||
var formating;
|
||||
|
||||
if (this.name === "pre-paginated") {
|
||||
formating = contents.fit(this.columnWidth, this.height);
|
||||
} else if (this._flow === "paginated") {
|
||||
formating = contents.columns(this.width, this.height, this.columnWidth, this.gap);
|
||||
} else { // scrolled
|
||||
formating = contents.size(this.width, null);
|
||||
}
|
||||
if (this.name === "pre-paginated") {
|
||||
formating = contents.fit(this.columnWidth, this.height);
|
||||
} else if (this._flow === "paginated") {
|
||||
formating = contents.columns(this.width, this.height, this.columnWidth, this.gap);
|
||||
} else { // scrolled
|
||||
formating = contents.size(this.width, null);
|
||||
}
|
||||
|
||||
return formating; // might be a promise in some View Managers
|
||||
return formating; // might be a promise in some View Managers
|
||||
};
|
||||
|
||||
Layout.prototype.count = function(totalWidth) {
|
||||
// var totalWidth = contents.scrollWidth();
|
||||
var spreads = Math.ceil( totalWidth / this.spreadWidth);
|
||||
// var totalWidth = contents.scrollWidth();
|
||||
var spreads = Math.ceil( totalWidth / this.spreadWidth);
|
||||
|
||||
return {
|
||||
spreads : spreads,
|
||||
pages : spreads * this.divisor
|
||||
};
|
||||
return {
|
||||
spreads : spreads,
|
||||
pages : spreads * this.divisor
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Layout;
|
||||
|
|
222
src/locations.js
222
src/locations.js
|
@ -4,114 +4,114 @@ var EpubCFI = require('./epubcfi');
|
|||
var RSVP = require('rsvp');
|
||||
|
||||
function Locations(spine, request) {
|
||||
this.spine = spine;
|
||||
this.request = request;
|
||||
this.spine = spine;
|
||||
this.request = request;
|
||||
|
||||
this.q = new Queue(this);
|
||||
this.epubcfi = new EpubCFI();
|
||||
this.q = new Queue(this);
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this._locations = [];
|
||||
this.total = 0;
|
||||
this._locations = [];
|
||||
this.total = 0;
|
||||
|
||||
this.break = 150;
|
||||
this.break = 150;
|
||||
|
||||
this._current = 0;
|
||||
this._current = 0;
|
||||
|
||||
};
|
||||
|
||||
// Load all of sections in the book
|
||||
Locations.prototype.generate = function(chars) {
|
||||
|
||||
if (chars) {
|
||||
this.break = chars;
|
||||
}
|
||||
if (chars) {
|
||||
this.break = chars;
|
||||
}
|
||||
|
||||
this.q.pause();
|
||||
this.q.pause();
|
||||
|
||||
this.spine.each(function(section) {
|
||||
this.spine.each(function(section) {
|
||||
|
||||
this.q.enqueue(this.process, section);
|
||||
this.q.enqueue(this.process, section);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
return this.q.run().then(function() {
|
||||
this.total = this._locations.length-1;
|
||||
return this.q.run().then(function() {
|
||||
this.total = this._locations.length-1;
|
||||
|
||||
if (this._currentCfi) {
|
||||
this.currentLocation = this._currentCfi;
|
||||
}
|
||||
if (this._currentCfi) {
|
||||
this.currentLocation = this._currentCfi;
|
||||
}
|
||||
|
||||
return this._locations;
|
||||
// console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end));
|
||||
}.bind(this));
|
||||
return this._locations;
|
||||
// console.log(this.precentage(this.book.rendition.location.start), this.precentage(this.book.rendition.location.end));
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
|
||||
Locations.prototype.process = function(section) {
|
||||
|
||||
return section.load(this.request)
|
||||
.then(function(contents) {
|
||||
return section.load(this.request)
|
||||
.then(function(contents) {
|
||||
|
||||
var range;
|
||||
var doc = contents.ownerDocument;
|
||||
var counter = 0;
|
||||
var range;
|
||||
var doc = contents.ownerDocument;
|
||||
var counter = 0;
|
||||
|
||||
this.sprint(contents, function(node) {
|
||||
var len = node.length;
|
||||
var dist;
|
||||
var pos = 0;
|
||||
this.sprint(contents, function(node) {
|
||||
var len = node.length;
|
||||
var dist;
|
||||
var pos = 0;
|
||||
|
||||
// Start range
|
||||
if (counter == 0) {
|
||||
range = doc.createRange();
|
||||
range.setStart(node, 0);
|
||||
}
|
||||
// Start range
|
||||
if (counter == 0) {
|
||||
range = doc.createRange();
|
||||
range.setStart(node, 0);
|
||||
}
|
||||
|
||||
dist = this.break - counter;
|
||||
dist = this.break - counter;
|
||||
|
||||
// Node is smaller than a break
|
||||
if(dist > len){
|
||||
counter += len;
|
||||
pos = len;
|
||||
}
|
||||
// Node is smaller than a break
|
||||
if(dist > len){
|
||||
counter += len;
|
||||
pos = len;
|
||||
}
|
||||
|
||||
while (pos < len) {
|
||||
counter = this.break;
|
||||
pos += this.break;
|
||||
while (pos < len) {
|
||||
counter = this.break;
|
||||
pos += this.break;
|
||||
|
||||
// Gone over
|
||||
if(pos >= len){
|
||||
// Continue counter for next node
|
||||
counter = len - (pos - this.break);
|
||||
// Gone over
|
||||
if(pos >= len){
|
||||
// Continue counter for next node
|
||||
counter = len - (pos - this.break);
|
||||
|
||||
// At End
|
||||
} else {
|
||||
// End the previous range
|
||||
range.setEnd(node, pos);
|
||||
cfi = section.cfiFromRange(range);
|
||||
this._locations.push(cfi);
|
||||
counter = 0;
|
||||
// At End
|
||||
} else {
|
||||
// End the previous range
|
||||
range.setEnd(node, pos);
|
||||
cfi = section.cfiFromRange(range);
|
||||
this._locations.push(cfi);
|
||||
counter = 0;
|
||||
|
||||
// Start new range
|
||||
pos += 1;
|
||||
range = doc.createRange();
|
||||
range.setStart(node, pos);
|
||||
}
|
||||
}
|
||||
// Start new range
|
||||
pos += 1;
|
||||
range = doc.createRange();
|
||||
range.setStart(node, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
// Close remaining
|
||||
if (range) {
|
||||
range.setEnd(prev, prev.length);
|
||||
cfi = section.cfiFromRange(range);
|
||||
this._locations.push(cfi)
|
||||
counter = 0;
|
||||
}
|
||||
// Close remaining
|
||||
if (range) {
|
||||
range.setEnd(prev, prev.length);
|
||||
cfi = section.cfiFromRange(range);
|
||||
this._locations.push(cfi)
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
|
||||
|
@ -125,26 +125,26 @@ Locations.prototype.sprint = function(root, func) {
|
|||
};
|
||||
|
||||
Locations.prototype.locationFromCfi = function(cfi){
|
||||
// Check if the location has not been set yet
|
||||
// Check if the location has not been set yet
|
||||
if(this._locations.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return core.locationOf(cfi, this._locations, this.epubcfi.compare);
|
||||
return core.locationOf(cfi, this._locations, this.epubcfi.compare);
|
||||
};
|
||||
|
||||
Locations.prototype.precentageFromCfi = function(cfi) {
|
||||
// Find closest cfi
|
||||
var loc = this.locationFromCfi(cfi);
|
||||
// Get percentage in total
|
||||
return this.precentageFromLocation(loc);
|
||||
// Find closest cfi
|
||||
var loc = this.locationFromCfi(cfi);
|
||||
// Get percentage in total
|
||||
return this.precentageFromLocation(loc);
|
||||
};
|
||||
|
||||
Locations.prototype.percentageFromLocation = function(loc) {
|
||||
if (!loc || !this.total) {
|
||||
return 0;
|
||||
}
|
||||
return (loc / this.total);
|
||||
if (!loc || !this.total) {
|
||||
return 0;
|
||||
}
|
||||
return (loc / this.total);
|
||||
};
|
||||
|
||||
Locations.prototype.cfiFromLocation = function(loc){
|
||||
|
@ -162,7 +162,7 @@ Locations.prototype.cfiFromLocation = function(loc){
|
|||
};
|
||||
|
||||
Locations.prototype.cfiFromPercentage = function(value){
|
||||
var percentage = (value > 1) ? value / 100 : value; // Normalize value to 0-1
|
||||
var percentage = (value > 1) ? value / 100 : value; // Normalize value to 0-1
|
||||
var loc = Math.ceil(this.total * percentage);
|
||||
|
||||
return this.cfiFromLocation(loc);
|
||||
|
@ -170,8 +170,8 @@ Locations.prototype.cfiFromPercentage = function(value){
|
|||
|
||||
Locations.prototype.load = function(locations){
|
||||
this._locations = JSON.parse(locations);
|
||||
this.total = this._locations.length-1;
|
||||
return this._locations;
|
||||
this.total = this._locations.length-1;
|
||||
return this._locations;
|
||||
};
|
||||
|
||||
Locations.prototype.save = function(json){
|
||||
|
@ -183,39 +183,39 @@ Locations.prototype.getCurrent = function(json){
|
|||
};
|
||||
|
||||
Locations.prototype.setCurrent = function(curr){
|
||||
var loc;
|
||||
var loc;
|
||||
|
||||
if(typeof curr == "string"){
|
||||
this._currentCfi = curr;
|
||||
} else if (typeof curr == "number") {
|
||||
this._current = curr;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._locations.length === 0) {
|
||||
return;
|
||||
if(typeof curr == "string"){
|
||||
this._currentCfi = curr;
|
||||
} else if (typeof curr == "number") {
|
||||
this._current = curr;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof curr == "string"){
|
||||
loc = this.locationFromCfi(curr);
|
||||
this._current = loc;
|
||||
} else {
|
||||
loc = curr;
|
||||
}
|
||||
if(this._locations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.trigger("changed", {
|
||||
percentage: this.precentageFromLocation(loc)
|
||||
});
|
||||
if(typeof curr == "string"){
|
||||
loc = this.locationFromCfi(curr);
|
||||
this._current = loc;
|
||||
} else {
|
||||
loc = curr;
|
||||
}
|
||||
|
||||
this.trigger("changed", {
|
||||
percentage: this.precentageFromLocation(loc)
|
||||
});
|
||||
};
|
||||
|
||||
Object.defineProperty(Locations.prototype, 'currentLocation', {
|
||||
get: function () {
|
||||
return this._current;
|
||||
},
|
||||
set: function (curr) {
|
||||
this.setCurrent(curr);
|
||||
}
|
||||
get: function () {
|
||||
return this._current;
|
||||
},
|
||||
set: function (curr) {
|
||||
this.setCurrent(curr);
|
||||
}
|
||||
});
|
||||
|
||||
RSVP.EventTarget.mixin(Locations.prototype);
|
||||
|
|
|
@ -21,9 +21,9 @@ function ContinuousViewManager(options) {
|
|||
core.extend(this.settings, options.settings || {});
|
||||
|
||||
// Gap can be 0, byt defaults doesn't handle that
|
||||
if (options.settings.gap != "undefined" && options.settings.gap === 0) {
|
||||
this.settings.gap = options.settings.gap;
|
||||
}
|
||||
if (options.settings.gap != "undefined" && options.settings.gap === 0) {
|
||||
this.settings.gap = options.settings.gap;
|
||||
}
|
||||
|
||||
// this.viewSettings.axis = this.settings.axis;
|
||||
this.viewSettings = {
|
||||
|
@ -43,7 +43,7 @@ ContinuousViewManager.prototype = Object.create(SingleViewManager.prototype);
|
|||
ContinuousViewManager.prototype.constructor = ContinuousViewManager;
|
||||
|
||||
ContinuousViewManager.prototype.display = function(section, target){
|
||||
return SingleViewManager.prototype.display.call(this, section, target)
|
||||
return SingleViewManager.prototype.display.call(this, section, target)
|
||||
.then(function () {
|
||||
return this.fill();
|
||||
}.bind(this));
|
||||
|
@ -64,8 +64,8 @@ ContinuousViewManager.prototype.fill = function(_full){
|
|||
}
|
||||
|
||||
ContinuousViewManager.prototype.moveTo = function(offset){
|
||||
// var bounds = this.stage.bounds();
|
||||
// var dist = Math.floor(offset.top / bounds.height) * bounds.height;
|
||||
// var bounds = this.stage.bounds();
|
||||
// var dist = Math.floor(offset.top / bounds.height) * bounds.height;
|
||||
var distX = 0,
|
||||
distY = 0;
|
||||
|
||||
|
@ -80,10 +80,10 @@ ContinuousViewManager.prototype.moveTo = function(offset){
|
|||
offsetX = distX+this.settings.offset;
|
||||
}
|
||||
|
||||
return this.check(offsetX, offsetY)
|
||||
return this.check(offsetX, offsetY)
|
||||
.then(function(){
|
||||
this.scrollBy(distX, distY);
|
||||
}.bind(this));
|
||||
this.scrollBy(distX, distY);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -113,7 +113,7 @@ ContinuousViewManager.prototype.afterDisplayed = function(currView){
|
|||
ContinuousViewManager.prototype.resize = function(width, height){
|
||||
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
this.q.clear();
|
||||
|
||||
this._stageSize = this.stage.size(width, height);
|
||||
this._bounds = this.bounds();
|
||||
|
@ -127,27 +127,27 @@ ContinuousViewManager.prototype.resize = function(width, height){
|
|||
view.size(this._stageSize.width, this._stageSize.height);
|
||||
}.bind(this));
|
||||
|
||||
this.updateLayout();
|
||||
this.updateLayout();
|
||||
|
||||
// if(this.location) {
|
||||
// this.rendition.display(this.location.start);
|
||||
// }
|
||||
// if(this.location) {
|
||||
// this.rendition.display(this.location.start);
|
||||
// }
|
||||
|
||||
this.trigger("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
});
|
||||
this.trigger("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.onResized = function(e) {
|
||||
|
||||
// this.views.clear();
|
||||
// this.views.clear();
|
||||
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.afterResized = function(view){
|
||||
|
@ -220,34 +220,34 @@ ContinuousViewManager.prototype.update = function(_offset){
|
|||
var promises = [];
|
||||
|
||||
for (var i = 0; i < viewsLength; i++) {
|
||||
view = views[i];
|
||||
view = views[i];
|
||||
|
||||
isVisible = this.isVisible(view, offset, offset, container);
|
||||
isVisible = this.isVisible(view, offset, offset, container);
|
||||
|
||||
if(isVisible === true) {
|
||||
if(isVisible === true) {
|
||||
if (!view.displayed) {
|
||||
promises.push(view.display(this.request).then(function (view) {
|
||||
view.show();
|
||||
}));
|
||||
}
|
||||
visible.push(view);
|
||||
} else {
|
||||
visible.push(view);
|
||||
} else {
|
||||
this.q.enqueue(view.destroy.bind(view));
|
||||
|
||||
clearTimeout(this.trimTimeout);
|
||||
this.trimTimeout = setTimeout(function(){
|
||||
this.q.enqueue(this.trim.bind(this));
|
||||
}.bind(this), 250);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(promises.length){
|
||||
return RSVP.all(promises);
|
||||
} else {
|
||||
updating.resolve();
|
||||
return updating.promise;
|
||||
}
|
||||
return RSVP.all(promises);
|
||||
} else {
|
||||
updating.resolve();
|
||||
return updating.promise;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -276,61 +276,61 @@ ContinuousViewManager.prototype.check = function(_offsetLeft, _offsetTop){
|
|||
|
||||
if (offset + visibleLength + delta >= contentLength) {
|
||||
last = this.views.last();
|
||||
next = last && last.section.next();
|
||||
if(next) {
|
||||
newViews.push(this.append(next));
|
||||
}
|
||||
}
|
||||
next = last && last.section.next();
|
||||
if(next) {
|
||||
newViews.push(this.append(next));
|
||||
}
|
||||
}
|
||||
|
||||
if (offset - delta < 0 ) {
|
||||
if (offset - delta < 0 ) {
|
||||
first = this.views.first();
|
||||
prev = first && first.section.prev();
|
||||
if(prev) {
|
||||
newViews.push(this.prepend(prev));
|
||||
}
|
||||
}
|
||||
prev = first && first.section.prev();
|
||||
if(prev) {
|
||||
newViews.push(this.prepend(prev));
|
||||
}
|
||||
}
|
||||
|
||||
if(newViews.length){
|
||||
// RSVP.all(promises)
|
||||
// .then(function() {
|
||||
// Check to see if anything new is on screen after rendering
|
||||
return this.q.enqueue(function(){
|
||||
if(newViews.length){
|
||||
// RSVP.all(promises)
|
||||
// .then(function() {
|
||||
// Check to see if anything new is on screen after rendering
|
||||
return this.q.enqueue(function(){
|
||||
return this.update(delta);
|
||||
}.bind(this));
|
||||
|
||||
|
||||
// }.bind(this));
|
||||
// }.bind(this));
|
||||
|
||||
} else {
|
||||
checking.resolve(false);
|
||||
} else {
|
||||
checking.resolve(false);
|
||||
return checking.promise;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.trim = function(){
|
||||
var task = new RSVP.defer();
|
||||
var displayed = this.views.displayed();
|
||||
var first = displayed[0];
|
||||
var last = displayed[displayed.length-1];
|
||||
var firstIndex = this.views.indexOf(first);
|
||||
var lastIndex = this.views.indexOf(last);
|
||||
var above = this.views.slice(0, firstIndex);
|
||||
var below = this.views.slice(lastIndex+1);
|
||||
var task = new RSVP.defer();
|
||||
var displayed = this.views.displayed();
|
||||
var first = displayed[0];
|
||||
var last = displayed[displayed.length-1];
|
||||
var firstIndex = this.views.indexOf(first);
|
||||
var lastIndex = this.views.indexOf(last);
|
||||
var above = this.views.slice(0, firstIndex);
|
||||
var below = this.views.slice(lastIndex+1);
|
||||
|
||||
// Erase all but last above
|
||||
for (var i = 0; i < above.length-1; i++) {
|
||||
this.erase(above[i], above);
|
||||
}
|
||||
// Erase all but last above
|
||||
for (var i = 0; i < above.length-1; i++) {
|
||||
this.erase(above[i], above);
|
||||
}
|
||||
|
||||
// Erase all except first below
|
||||
for (var j = 1; j < below.length; j++) {
|
||||
this.erase(below[j]);
|
||||
}
|
||||
// Erase all except first below
|
||||
for (var j = 1; j < below.length; j++) {
|
||||
this.erase(below[j]);
|
||||
}
|
||||
|
||||
task.resolve();
|
||||
return task.promise;
|
||||
task.resolve();
|
||||
return task.promise;
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.erase = function(view, above){ //Trim
|
||||
|
@ -339,12 +339,12 @@ ContinuousViewManager.prototype.erase = function(view, above){ //Trim
|
|||
var prevLeft;
|
||||
|
||||
if(this.settings.height) {
|
||||
prevTop = this.container.scrollTop;
|
||||
prevTop = this.container.scrollTop;
|
||||
prevLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
prevTop = window.scrollY;
|
||||
} else {
|
||||
prevTop = window.scrollY;
|
||||
prevLeft = window.scrollX;
|
||||
}
|
||||
}
|
||||
|
||||
var bounds = view.bounds();
|
||||
|
||||
|
@ -373,60 +373,60 @@ ContinuousViewManager.prototype.addEventListeners = function(stage){
|
|||
};
|
||||
|
||||
ContinuousViewManager.prototype.addScrollListeners = function() {
|
||||
var scroller;
|
||||
var scroller;
|
||||
|
||||
this.tick = core.requestAnimationFrame;
|
||||
this.tick = core.requestAnimationFrame;
|
||||
|
||||
if(this.settings.height) {
|
||||
this.prevScrollTop = this.container.scrollTop;
|
||||
this.prevScrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
this.prevScrollTop = window.scrollY;
|
||||
if(this.settings.height) {
|
||||
this.prevScrollTop = this.container.scrollTop;
|
||||
this.prevScrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
this.prevScrollTop = window.scrollY;
|
||||
this.prevScrollLeft = window.scrollX;
|
||||
}
|
||||
}
|
||||
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
|
||||
if(this.settings.height) {
|
||||
scroller = this.container;
|
||||
if(this.settings.height) {
|
||||
scroller = this.container;
|
||||
this.scrollTop = this.container.scrollTop;
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
scroller = window;
|
||||
} else {
|
||||
scroller = window;
|
||||
this.scrollTop = window.scrollY;
|
||||
this.scrollLeft = window.scrollX;
|
||||
}
|
||||
}
|
||||
|
||||
scroller.addEventListener("scroll", this.onScroll.bind(this));
|
||||
scroller.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
|
||||
this.scrolled = false;
|
||||
this.scrolled = false;
|
||||
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.onScroll = function(){
|
||||
|
||||
// if(!this.ignore) {
|
||||
// if(!this.ignore) {
|
||||
|
||||
if(this.settings.height) {
|
||||
scrollTop = this.container.scrollTop;
|
||||
scrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
scrollTop = window.scrollY;
|
||||
if(this.settings.height) {
|
||||
scrollTop = this.container.scrollTop;
|
||||
scrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
scrollTop = window.scrollY;
|
||||
scrollLeft = window.scrollX;
|
||||
}
|
||||
}
|
||||
|
||||
this.scrollTop = scrollTop;
|
||||
this.scrollLeft = scrollLeft;
|
||||
|
||||
if(!this.ignore) {
|
||||
if(!this.ignore) {
|
||||
|
||||
if((this.scrollDeltaVert === 0 &&
|
||||
this.scrollDeltaHorz === 0) ||
|
||||
this.scrollDeltaVert > this.settings.offsetDelta ||
|
||||
this.scrollDeltaHorz > this.settings.offsetDelta) {
|
||||
if((this.scrollDeltaVert === 0 &&
|
||||
this.scrollDeltaHorz === 0) ||
|
||||
this.scrollDeltaVert > this.settings.offsetDelta ||
|
||||
this.scrollDeltaHorz > this.settings.offsetDelta) {
|
||||
|
||||
this.q.enqueue(function() {
|
||||
this.check();
|
||||
|
@ -434,44 +434,44 @@ ContinuousViewManager.prototype.onScroll = function(){
|
|||
// this.check();
|
||||
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
|
||||
this.trigger("scroll", {
|
||||
top: scrollTop,
|
||||
left: scrollLeft
|
||||
});
|
||||
top: scrollTop,
|
||||
left: scrollLeft
|
||||
});
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
this.afterScrolled = setTimeout(function () {
|
||||
this.trigger("scrolled", {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
});
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
this.ignore = false;
|
||||
this.ignore = false;
|
||||
}
|
||||
|
||||
this.scrollDeltaVert += Math.abs(scrollTop-this.prevScrollTop);
|
||||
this.scrollDeltaHorz += Math.abs(scrollLeft-this.prevScrollLeft);
|
||||
this.scrollDeltaVert += Math.abs(scrollTop-this.prevScrollTop);
|
||||
this.scrollDeltaHorz += Math.abs(scrollLeft-this.prevScrollLeft);
|
||||
|
||||
this.prevScrollTop = scrollTop;
|
||||
this.prevScrollLeft = scrollLeft;
|
||||
|
||||
clearTimeout(this.scrollTimeout);
|
||||
clearTimeout(this.scrollTimeout);
|
||||
this.scrollTimeout = setTimeout(function(){
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
}.bind(this), 150);
|
||||
|
||||
|
||||
this.scrolled = false;
|
||||
// }
|
||||
this.scrolled = false;
|
||||
// }
|
||||
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
|
||||
};
|
||||
|
||||
|
@ -488,9 +488,9 @@ ContinuousViewManager.prototype.onScroll = function(){
|
|||
|
||||
ContinuousViewManager.prototype.currentLocation = function(){
|
||||
|
||||
if (this.settings.axis === "vertical") {
|
||||
this.location = this.scrolledLocation();
|
||||
} else {
|
||||
if (this.settings.axis === "vertical") {
|
||||
this.location = this.scrolledLocation();
|
||||
} else {
|
||||
this.location = this.paginatedLocation();
|
||||
}
|
||||
|
||||
|
@ -499,104 +499,104 @@ ContinuousViewManager.prototype.currentLocation = function(){
|
|||
|
||||
ContinuousViewManager.prototype.scrolledLocation = function(){
|
||||
|
||||
var visible = this.visible();
|
||||
var startPage, endPage;
|
||||
var visible = this.visible();
|
||||
var startPage, endPage;
|
||||
|
||||
var container = this.container.getBoundingClientRect();
|
||||
var container = this.container.getBoundingClientRect();
|
||||
|
||||
if(visible.length === 1) {
|
||||
return this.mapping.page(visible[0].contents, visible[0].section.cfiBase);
|
||||
}
|
||||
if(visible.length === 1) {
|
||||
return this.mapping.page(visible[0].contents, visible[0].section.cfiBase);
|
||||
}
|
||||
|
||||
if(visible.length > 1) {
|
||||
if(visible.length > 1) {
|
||||
|
||||
startPage = this.mapping.page(visible[0].contents, visible[0].section.cfiBase);
|
||||
endPage = this.mapping.page(visible[visible.length-1].contents, visible[visible.length-1].section.cfiBase);
|
||||
startPage = this.mapping.page(visible[0].contents, visible[0].section.cfiBase);
|
||||
endPage = this.mapping.page(visible[visible.length-1].contents, visible[visible.length-1].section.cfiBase);
|
||||
|
||||
return {
|
||||
start: startPage.start,
|
||||
end: endPage.end
|
||||
};
|
||||
}
|
||||
return {
|
||||
start: startPage.start,
|
||||
end: endPage.end
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ContinuousViewManager.prototype.paginatedLocation = function(){
|
||||
var visible = this.visible();
|
||||
var startA, startB, endA, endB;
|
||||
var pageLeft, pageRight;
|
||||
var container = this.container.getBoundingClientRect();
|
||||
var visible = this.visible();
|
||||
var startA, startB, endA, endB;
|
||||
var pageLeft, pageRight;
|
||||
var container = this.container.getBoundingClientRect();
|
||||
|
||||
if(visible.length === 1) {
|
||||
startA = container.left - visible[0].position().left;
|
||||
endA = startA + this.layout.spreadWidth;
|
||||
if(visible.length === 1) {
|
||||
startA = container.left - visible[0].position().left;
|
||||
endA = startA + this.layout.spreadWidth;
|
||||
|
||||
return this.mapping.page(visible[0].contents, visible[0].section.cfiBase, startA, endA);
|
||||
}
|
||||
return this.mapping.page(visible[0].contents, visible[0].section.cfiBase, startA, endA);
|
||||
}
|
||||
|
||||
if(visible.length > 1) {
|
||||
if(visible.length > 1) {
|
||||
|
||||
// Left Col
|
||||
startA = container.left - visible[0].position().left;
|
||||
endA = startA + this.layout.columnWidth;
|
||||
// Left Col
|
||||
startA = container.left - visible[0].position().left;
|
||||
endA = startA + this.layout.columnWidth;
|
||||
|
||||
// Right Col
|
||||
startB = container.left + this.layout.spreadWidth - visible[visible.length-1].position().left;
|
||||
endB = startB + this.layout.columnWidth;
|
||||
// Right Col
|
||||
startB = container.left + this.layout.spreadWidth - visible[visible.length-1].position().left;
|
||||
endB = startB + this.layout.columnWidth;
|
||||
|
||||
pageLeft = this.mapping.page(visible[0].contents, visible[0].section.cfiBase, startA, endA);
|
||||
pageRight = this.mapping.page(visible[visible.length-1].contents, visible[visible.length-1].section.cfiBase, startB, endB);
|
||||
pageLeft = this.mapping.page(visible[0].contents, visible[0].section.cfiBase, startA, endA);
|
||||
pageRight = this.mapping.page(visible[visible.length-1].contents, visible[visible.length-1].section.cfiBase, startB, endB);
|
||||
|
||||
return {
|
||||
start: pageLeft.start,
|
||||
end: pageRight.end
|
||||
};
|
||||
}
|
||||
return {
|
||||
start: pageLeft.start,
|
||||
end: pageRight.end
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Continuous.prototype.current = function(what){
|
||||
var view, top;
|
||||
var container = this.container.getBoundingClientRect();
|
||||
var length = this.views.length - 1;
|
||||
var view, top;
|
||||
var container = this.container.getBoundingClientRect();
|
||||
var length = this.views.length - 1;
|
||||
|
||||
if(this.settings.axis === "horizontal") {
|
||||
if(this.settings.axis === "horizontal") {
|
||||
|
||||
for (var i = length; i >= 0; i--) {
|
||||
view = this.views[i];
|
||||
left = view.position().left;
|
||||
for (var i = length; i >= 0; i--) {
|
||||
view = this.views[i];
|
||||
left = view.position().left;
|
||||
|
||||
if(left < container.right) {
|
||||
if(left < container.right) {
|
||||
|
||||
if(this._current == view) {
|
||||
break;
|
||||
}
|
||||
if(this._current == view) {
|
||||
break;
|
||||
}
|
||||
|
||||
this._current = view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this._current = view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
for (var i = length; i >= 0; i--) {
|
||||
view = this.views[i];
|
||||
top = view.bounds().top;
|
||||
if(top < container.bottom) {
|
||||
for (var i = length; i >= 0; i--) {
|
||||
view = this.views[i];
|
||||
top = view.bounds().top;
|
||||
if(top < container.bottom) {
|
||||
|
||||
if(this._current == view) {
|
||||
break;
|
||||
}
|
||||
if(this._current == view) {
|
||||
break;
|
||||
}
|
||||
|
||||
this._current = view;
|
||||
this._current = view;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return this._current;
|
||||
return this._current;
|
||||
};
|
||||
*/
|
||||
|
||||
|
@ -626,7 +626,7 @@ ContinuousViewManager.prototype.updateLayout = function() {
|
|||
this.viewSettings.width = this.layout.width;
|
||||
this.viewSettings.height = this.layout.height;
|
||||
|
||||
this.setLayout(this.layout);
|
||||
this.setLayout(this.layout);
|
||||
|
||||
};
|
||||
|
||||
|
@ -634,15 +634,15 @@ ContinuousViewManager.prototype.next = function(){
|
|||
|
||||
if(this.settings.axis === "horizontal") {
|
||||
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
this.scrollLeft = this.container.scrollLeft;
|
||||
|
||||
if(this.container.scrollLeft +
|
||||
this.container.offsetWidth +
|
||||
this.layout.delta < this.container.scrollWidth) {
|
||||
this.scrollBy(this.layout.delta, 0);
|
||||
} else {
|
||||
this.scrollTo(this.container.scrollWidth - this.layout.delta, 0);
|
||||
}
|
||||
if(this.container.scrollLeft +
|
||||
this.container.offsetWidth +
|
||||
this.layout.delta < this.container.scrollWidth) {
|
||||
this.scrollBy(this.layout.delta, 0);
|
||||
} else {
|
||||
this.scrollTo(this.container.scrollWidth - this.layout.delta, 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
this.scrollBy(0, this.layout.height);
|
||||
|
@ -651,7 +651,7 @@ ContinuousViewManager.prototype.next = function(){
|
|||
|
||||
ContinuousViewManager.prototype.prev = function(){
|
||||
if(this.settings.axis === "horizontal") {
|
||||
this.scrollBy(-this.layout.delta, 0);
|
||||
this.scrollBy(-this.layout.delta, 0);
|
||||
} else {
|
||||
this.scrollBy(0, -this.layout.height);
|
||||
}
|
||||
|
@ -672,7 +672,7 @@ ContinuousViewManager.prototype.updateFlow = function(flow){
|
|||
|
||||
if (this.settings.axis === "vertical") {
|
||||
this.settings.infinite = true;
|
||||
} else {
|
||||
} else {
|
||||
this.settings.infinite = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,15 +93,15 @@ SingleViewManager.prototype.destroy = function(){
|
|||
|
||||
SingleViewManager.prototype.onResized = function(e) {
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
this.resize();
|
||||
}.bind(this), 150);
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.resize = function(width, height){
|
||||
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
this.q.clear();
|
||||
|
||||
this._stageSize = this.stage.size(width, height);
|
||||
this._bounds = this.bounds();
|
||||
|
@ -115,12 +115,12 @@ SingleViewManager.prototype.resize = function(width, height){
|
|||
view.size(this._stageSize.width, this._stageSize.height);
|
||||
}.bind(this));
|
||||
|
||||
this.updateLayout();
|
||||
this.updateLayout();
|
||||
|
||||
this.trigger("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
});
|
||||
this.trigger("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
@ -208,7 +208,7 @@ SingleViewManager.prototype.moveTo = function(offset){
|
|||
}
|
||||
}
|
||||
|
||||
this.scrollTo(distX, distY);
|
||||
this.scrollTo(distX, distY);
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.add = function(section){
|
||||
|
@ -349,20 +349,20 @@ SingleViewManager.prototype.current = function(){
|
|||
// Current is the last visible view
|
||||
return visible[visible.length-1];
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.currentLocation = function(){
|
||||
var view;
|
||||
var start, end;
|
||||
var view;
|
||||
var start, end;
|
||||
|
||||
if(this.views.length) {
|
||||
view = this.views.first();
|
||||
start = container.left - view.position().left;
|
||||
end = start + this.layout.spread;
|
||||
if(this.views.length) {
|
||||
view = this.views.first();
|
||||
start = container.left - view.position().left;
|
||||
end = start + this.layout.spread;
|
||||
|
||||
return this.mapping.page(view, view.section.cfiBase);
|
||||
}
|
||||
return this.mapping.page(view, view.section.cfiBase);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -376,12 +376,12 @@ SingleViewManager.prototype.isVisible = function(view, offsetPrev, offsetNext, _
|
|||
|
||||
return true;
|
||||
|
||||
} else if(this.settings.axis === "vertical" &&
|
||||
position.bottom > container.top - offsetPrev &&
|
||||
} else if(this.settings.axis === "vertical" &&
|
||||
position.bottom > container.top - offsetPrev &&
|
||||
position.top < container.bottom + offsetNext) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
@ -392,60 +392,60 @@ SingleViewManager.prototype.visible = function(){
|
|||
var container = this.bounds();
|
||||
var views = this.views.displayed();
|
||||
var viewsLength = views.length;
|
||||
var visible = [];
|
||||
var isVisible;
|
||||
var view;
|
||||
var visible = [];
|
||||
var isVisible;
|
||||
var view;
|
||||
|
||||
for (var i = 0; i < viewsLength; i++) {
|
||||
view = views[i];
|
||||
isVisible = this.isVisible(view, 0, 0, container);
|
||||
for (var i = 0; i < viewsLength; i++) {
|
||||
view = views[i];
|
||||
isVisible = this.isVisible(view, 0, 0, container);
|
||||
|
||||
if(isVisible === true) {
|
||||
visible.push(view);
|
||||
}
|
||||
if(isVisible === true) {
|
||||
visible.push(view);
|
||||
}
|
||||
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
return visible;
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.scrollBy = function(x, y, silent){
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
|
||||
if(this.settings.height) {
|
||||
if(this.settings.height) {
|
||||
|
||||
if(x) this.container.scrollLeft += x;
|
||||
if(y) this.container.scrollTop += y;
|
||||
if(x) this.container.scrollLeft += x;
|
||||
if(y) this.container.scrollTop += y;
|
||||
|
||||
} else {
|
||||
window.scrollBy(x,y);
|
||||
}
|
||||
// console.log("scrollBy", x, y);
|
||||
this.scrolled = true;
|
||||
} else {
|
||||
window.scrollBy(x,y);
|
||||
}
|
||||
// console.log("scrollBy", x, y);
|
||||
this.scrolled = true;
|
||||
this.onScroll();
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.scrollTo = function(x, y, silent){
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
if(silent) {
|
||||
this.ignore = true;
|
||||
}
|
||||
|
||||
if(this.settings.height) {
|
||||
this.container.scrollLeft = x;
|
||||
this.container.scrollTop = y;
|
||||
} else {
|
||||
window.scrollTo(x,y);
|
||||
}
|
||||
// console.log("scrollTo", x, y);
|
||||
this.scrolled = true;
|
||||
if(this.settings.height) {
|
||||
this.container.scrollLeft = x;
|
||||
this.container.scrollTop = y;
|
||||
} else {
|
||||
window.scrollTo(x,y);
|
||||
}
|
||||
// console.log("scrollTo", x, y);
|
||||
this.scrolled = true;
|
||||
this.onScroll();
|
||||
// if(this.container.scrollLeft != x){
|
||||
// setTimeout(function() {
|
||||
// this.scrollTo(x, y, silent);
|
||||
// }.bind(this), 10);
|
||||
// return;
|
||||
// };
|
||||
// if(this.container.scrollLeft != x){
|
||||
// setTimeout(function() {
|
||||
// this.scrollTo(x, y, silent);
|
||||
// }.bind(this), 10);
|
||||
// return;
|
||||
// };
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.onScroll = function(){
|
||||
|
@ -466,7 +466,7 @@ SingleViewManager.prototype.applyLayout = function(layout) {
|
|||
this.updateLayout();
|
||||
|
||||
this.mapping = new Mapping(this.layout);
|
||||
// this.manager.layout(this.layout.format);
|
||||
// this.manager.layout(this.layout.format);
|
||||
};
|
||||
|
||||
SingleViewManager.prototype.updateLayout = function() {
|
||||
|
|
390
src/mapping.js
390
src/mapping.js
|
@ -1,297 +1,297 @@
|
|||
var EpubCFI = require('./epubcfi');
|
||||
|
||||
function Mapping(layout){
|
||||
this.layout = layout;
|
||||
this.layout = layout;
|
||||
};
|
||||
|
||||
Mapping.prototype.section = function(view) {
|
||||
var ranges = this.findRanges(view);
|
||||
var map = this.rangeListToCfiList(view.section.cfiBase, ranges);
|
||||
var ranges = this.findRanges(view);
|
||||
var map = this.rangeListToCfiList(view.section.cfiBase, ranges);
|
||||
|
||||
return map;
|
||||
return map;
|
||||
};
|
||||
|
||||
Mapping.prototype.page = function(contents, cfiBase, start, end) {
|
||||
var root = contents && contents.document ? contents.document.body : false;
|
||||
var root = contents && contents.document ? contents.document.body : false;
|
||||
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.rangePairToCfiPair(cfiBase, {
|
||||
start: this.findStart(root, start, end),
|
||||
end: this.findEnd(root, start, end)
|
||||
});
|
||||
return this.rangePairToCfiPair(cfiBase, {
|
||||
start: this.findStart(root, start, end),
|
||||
end: this.findEnd(root, start, end)
|
||||
});
|
||||
};
|
||||
|
||||
Mapping.prototype.walk = function(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) {
|
||||
if ( node.data.trim().length > 0 ) {
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
} else {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
var node;
|
||||
var result;
|
||||
while ((node = treeWalker.nextNode())) {
|
||||
result = func(node);
|
||||
if(result) break;
|
||||
}
|
||||
//var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, null, false);
|
||||
var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
||||
acceptNode: function (node) {
|
||||
if ( node.data.trim().length > 0 ) {
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
} else {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
var node;
|
||||
var result;
|
||||
while ((node = treeWalker.nextNode())) {
|
||||
result = func(node);
|
||||
if(result) break;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
};
|
||||
|
||||
Mapping.prototype.findRanges = function(view){
|
||||
var columns = [];
|
||||
var scrollWidth = view.contents.scrollWidth();
|
||||
var count = this.layout.count(scrollWidth);
|
||||
var column = this.layout.column;
|
||||
var gap = this.layout.gap;
|
||||
var start, end;
|
||||
var columns = [];
|
||||
var scrollWidth = view.contents.scrollWidth();
|
||||
var count = this.layout.count(scrollWidth);
|
||||
var column = this.layout.column;
|
||||
var gap = this.layout.gap;
|
||||
var start, end;
|
||||
|
||||
for (var i = 0; i < count.pages; i++) {
|
||||
start = (column + gap) * i;
|
||||
end = (column * (i+1)) + (gap * i);
|
||||
columns.push({
|
||||
start: this.findStart(view.document.body, start, end),
|
||||
end: this.findEnd(view.document.body, start, end)
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < count.pages; i++) {
|
||||
start = (column + gap) * i;
|
||||
end = (column * (i+1)) + (gap * i);
|
||||
columns.push({
|
||||
start: this.findStart(view.document.body, start, end),
|
||||
end: this.findEnd(view.document.body, start, end)
|
||||
});
|
||||
}
|
||||
|
||||
return columns;
|
||||
return columns;
|
||||
};
|
||||
|
||||
Mapping.prototype.findStart = function(root, start, end){
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var found;
|
||||
var $prev = root;
|
||||
while (stack.length) {
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var found;
|
||||
var $prev = root;
|
||||
while (stack.length) {
|
||||
|
||||
$el = stack.shift();
|
||||
$el = stack.shift();
|
||||
|
||||
found = this.walk($el, function(node){
|
||||
var left, right;
|
||||
var elPos;
|
||||
var elRange;
|
||||
found = this.walk($el, function(node){
|
||||
var left, right;
|
||||
var elPos;
|
||||
var elRange;
|
||||
|
||||
|
||||
if(node.nodeType == Node.TEXT_NODE){
|
||||
elRange = document.createRange();
|
||||
elRange.selectNodeContents(node);
|
||||
elPos = elRange.getBoundingClientRect();
|
||||
} else {
|
||||
elPos = node.getBoundingClientRect();
|
||||
}
|
||||
if(node.nodeType == Node.TEXT_NODE){
|
||||
elRange = document.createRange();
|
||||
elRange.selectNodeContents(node);
|
||||
elPos = elRange.getBoundingClientRect();
|
||||
} else {
|
||||
elPos = node.getBoundingClientRect();
|
||||
}
|
||||
|
||||
left = elPos.left;
|
||||
right = elPos.right;
|
||||
left = elPos.left;
|
||||
right = elPos.right;
|
||||
|
||||
if( left >= start && left <= end ) {
|
||||
return node;
|
||||
} else if (right > start) {
|
||||
return node;
|
||||
} else {
|
||||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
if( left >= start && left <= end ) {
|
||||
return node;
|
||||
} else if (right > start) {
|
||||
return node;
|
||||
} else {
|
||||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
if(found) {
|
||||
return this.findTextStartRange(found, start, end);
|
||||
}
|
||||
if(found) {
|
||||
return this.findTextStartRange(found, start, end);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Return last element
|
||||
return this.findTextStartRange($prev, start, end);
|
||||
// Return last element
|
||||
return this.findTextStartRange($prev, start, end);
|
||||
};
|
||||
|
||||
Mapping.prototype.findEnd = function(root, start, end){
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var $prev = root;
|
||||
var found;
|
||||
var stack = [root];
|
||||
var $el;
|
||||
var $prev = root;
|
||||
var found;
|
||||
|
||||
while (stack.length) {
|
||||
while (stack.length) {
|
||||
|
||||
$el = stack.shift();
|
||||
$el = stack.shift();
|
||||
|
||||
found = this.walk($el, function(node){
|
||||
found = this.walk($el, function(node){
|
||||
|
||||
var left, right;
|
||||
var elPos;
|
||||
var elRange;
|
||||
var left, right;
|
||||
var elPos;
|
||||
var elRange;
|
||||
|
||||
|
||||
if(node.nodeType == Node.TEXT_NODE){
|
||||
elRange = document.createRange();
|
||||
elRange.selectNodeContents(node);
|
||||
elPos = elRange.getBoundingClientRect();
|
||||
} else {
|
||||
elPos = node.getBoundingClientRect();
|
||||
}
|
||||
if(node.nodeType == Node.TEXT_NODE){
|
||||
elRange = document.createRange();
|
||||
elRange.selectNodeContents(node);
|
||||
elPos = elRange.getBoundingClientRect();
|
||||
} else {
|
||||
elPos = node.getBoundingClientRect();
|
||||
}
|
||||
|
||||
left = elPos.left;
|
||||
right = elPos.right;
|
||||
left = elPos.left;
|
||||
right = elPos.right;
|
||||
|
||||
if(left > end && $prev) {
|
||||
return $prev;
|
||||
} else if(right > end) {
|
||||
return node;
|
||||
} else {
|
||||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
if(left > end && $prev) {
|
||||
return $prev;
|
||||
} else if(right > end) {
|
||||
return node;
|
||||
} else {
|
||||
$prev = node;
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if(found){
|
||||
return this.findTextEndRange(found, start, end);
|
||||
}
|
||||
if(found){
|
||||
return this.findTextEndRange(found, start, end);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// end of chapter
|
||||
return this.findTextEndRange($prev, start, end);
|
||||
// end of chapter
|
||||
return this.findTextEndRange($prev, start, end);
|
||||
};
|
||||
|
||||
|
||||
Mapping.prototype.findTextStartRange = function(node, start, end){
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
var pos;
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
var pos;
|
||||
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
range = ranges[i];
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
range = ranges[i];
|
||||
|
||||
pos = range.getBoundingClientRect();
|
||||
pos = range.getBoundingClientRect();
|
||||
|
||||
if( pos.left >= start ) {
|
||||
return range;
|
||||
}
|
||||
if( pos.left >= start ) {
|
||||
return range;
|
||||
}
|
||||
|
||||
prev = range;
|
||||
prev = range;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ranges[0];
|
||||
return ranges[0];
|
||||
};
|
||||
|
||||
Mapping.prototype.findTextEndRange = function(node, start, end){
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
var pos;
|
||||
var ranges = this.splitTextNodeIntoRanges(node);
|
||||
var prev;
|
||||
var range;
|
||||
var pos;
|
||||
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
range = ranges[i];
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
range = ranges[i];
|
||||
|
||||
pos = range.getBoundingClientRect();
|
||||
pos = range.getBoundingClientRect();
|
||||
|
||||
if(pos.left > end && prev) {
|
||||
return prev;
|
||||
} else if(pos.right > end) {
|
||||
return range;
|
||||
}
|
||||
if(pos.left > end && prev) {
|
||||
return prev;
|
||||
} else if(pos.right > end) {
|
||||
return range;
|
||||
}
|
||||
|
||||
prev = range;
|
||||
prev = range;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Ends before limit
|
||||
return ranges[ranges.length-1];
|
||||
// Ends before limit
|
||||
return ranges[ranges.length-1];
|
||||
|
||||
};
|
||||
|
||||
Mapping.prototype.splitTextNodeIntoRanges = function(node, _splitter){
|
||||
var ranges = [];
|
||||
var textContent = node.textContent || "";
|
||||
var text = textContent.trim();
|
||||
var range;
|
||||
var rect;
|
||||
var list;
|
||||
var doc = node.ownerDocument;
|
||||
var splitter = _splitter || " ";
|
||||
var ranges = [];
|
||||
var textContent = node.textContent || "";
|
||||
var text = textContent.trim();
|
||||
var range;
|
||||
var rect;
|
||||
var list;
|
||||
var doc = node.ownerDocument;
|
||||
var splitter = _splitter || " ";
|
||||
|
||||
pos = text.indexOf(splitter);
|
||||
pos = text.indexOf(splitter);
|
||||
|
||||
if(pos === -1 || node.nodeType != Node.TEXT_NODE) {
|
||||
range = doc.createRange();
|
||||
range.selectNodeContents(node);
|
||||
return [range];
|
||||
}
|
||||
if(pos === -1 || node.nodeType != Node.TEXT_NODE) {
|
||||
range = doc.createRange();
|
||||
range.selectNodeContents(node);
|
||||
return [range];
|
||||
}
|
||||
|
||||
range = doc.createRange();
|
||||
range.setStart(node, 0);
|
||||
range.setEnd(node, pos);
|
||||
ranges.push(range);
|
||||
range = false;
|
||||
range = doc.createRange();
|
||||
range.setStart(node, 0);
|
||||
range.setEnd(node, pos);
|
||||
ranges.push(range);
|
||||
range = false;
|
||||
|
||||
while ( pos != -1 ) {
|
||||
while ( pos != -1 ) {
|
||||
|
||||
pos = text.indexOf(splitter, pos + 1);
|
||||
if(pos > 0) {
|
||||
pos = text.indexOf(splitter, pos + 1);
|
||||
if(pos > 0) {
|
||||
|
||||
if(range) {
|
||||
range.setEnd(node, pos);
|
||||
ranges.push(range);
|
||||
}
|
||||
if(range) {
|
||||
range.setEnd(node, pos);
|
||||
ranges.push(range);
|
||||
}
|
||||
|
||||
range = doc.createRange();
|
||||
range.setStart(node, pos+1);
|
||||
}
|
||||
}
|
||||
range = doc.createRange();
|
||||
range.setStart(node, pos+1);
|
||||
}
|
||||
}
|
||||
|
||||
if(range) {
|
||||
range.setEnd(node, text.length);
|
||||
ranges.push(range);
|
||||
}
|
||||
if(range) {
|
||||
range.setEnd(node, text.length);
|
||||
ranges.push(range);
|
||||
}
|
||||
|
||||
return ranges;
|
||||
return ranges;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Mapping.prototype.rangePairToCfiPair = function(cfiBase, rangePair){
|
||||
|
||||
var startRange = rangePair.start;
|
||||
var endRange = rangePair.end;
|
||||
var startRange = rangePair.start;
|
||||
var endRange = rangePair.end;
|
||||
|
||||
startRange.collapse(true);
|
||||
endRange.collapse(true);
|
||||
startRange.collapse(true);
|
||||
endRange.collapse(true);
|
||||
|
||||
// startCfi = section.cfiFromRange(startRange);
|
||||
// endCfi = section.cfiFromRange(endRange);
|
||||
startCfi = new EpubCFI(startRange, cfiBase).toString();
|
||||
endCfi = new EpubCFI(endRange, cfiBase).toString();
|
||||
// startCfi = section.cfiFromRange(startRange);
|
||||
// endCfi = section.cfiFromRange(endRange);
|
||||
startCfi = new EpubCFI(startRange, cfiBase).toString();
|
||||
endCfi = new EpubCFI(endRange, cfiBase).toString();
|
||||
|
||||
return {
|
||||
start: startCfi,
|
||||
end: endCfi
|
||||
};
|
||||
return {
|
||||
start: startCfi,
|
||||
end: endCfi
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Mapping.prototype.rangeListToCfiList = function(cfiBase, columns){
|
||||
var map = [];
|
||||
var rangePair, cifPair;
|
||||
var map = [];
|
||||
var rangePair, cifPair;
|
||||
|
||||
for (var i = 0; i < columns.length; i++) {
|
||||
cifPair = this.rangePairToCfiPair(cfiBase, columns[i]);
|
||||
for (var i = 0; i < columns.length; i++) {
|
||||
cifPair = this.rangePairToCfiPair(cfiBase, columns[i]);
|
||||
|
||||
map.push(cifPair);
|
||||
map.push(cifPair);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
return map;
|
||||
};
|
||||
|
||||
module.exports = Mapping;
|
||||
|
|
|
@ -4,99 +4,99 @@ var RSVP = require('rsvp');
|
|||
var URI = require('urijs');
|
||||
|
||||
function Navigation(_package, _request){
|
||||
var navigation = this;
|
||||
var parse = new Parser();
|
||||
var request = _request || require('./request');
|
||||
var navigation = this;
|
||||
var parse = new Parser();
|
||||
var request = _request || require('./request');
|
||||
|
||||
this.package = _package;
|
||||
this.toc = [];
|
||||
this.tocByHref = {};
|
||||
this.tocById = {};
|
||||
this.package = _package;
|
||||
this.toc = [];
|
||||
this.tocByHref = {};
|
||||
this.tocById = {};
|
||||
|
||||
if(_package.navPath) {
|
||||
this.navUrl = URI(_package.navPath).absoluteTo(_package.baseUrl).toString();
|
||||
this.nav = {};
|
||||
if(_package.navPath) {
|
||||
this.navUrl = URI(_package.navPath).absoluteTo(_package.baseUrl).toString();
|
||||
this.nav = {};
|
||||
|
||||
this.nav.load = function(_request){
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
this.nav.load = function(_request){
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
request(navigation.navUrl, 'xml').then(function(xml){
|
||||
navigation.toc = parse.nav(xml);
|
||||
navigation.loaded(navigation.toc);
|
||||
loading.resolve(navigation.toc);
|
||||
});
|
||||
request(navigation.navUrl, 'xml').then(function(xml){
|
||||
navigation.toc = parse.nav(xml);
|
||||
navigation.loaded(navigation.toc);
|
||||
loading.resolve(navigation.toc);
|
||||
});
|
||||
|
||||
return loaded;
|
||||
};
|
||||
return loaded;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(_package.ncxPath) {
|
||||
this.ncxUrl = URI(_package.ncxPath).absoluteTo(_package.baseUrl).toString();
|
||||
this.ncx = {};
|
||||
if(_package.ncxPath) {
|
||||
this.ncxUrl = URI(_package.ncxPath).absoluteTo(_package.baseUrl).toString();
|
||||
this.ncx = {};
|
||||
|
||||
this.ncx.load = function(_request){
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
this.ncx.load = function(_request){
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
request(navigation.ncxUrl, 'xml').then(function(xml){
|
||||
navigation.toc = parse.toc(xml);
|
||||
navigation.loaded(navigation.toc);
|
||||
loading.resolve(navigation.toc);
|
||||
});
|
||||
request(navigation.ncxUrl, 'xml').then(function(xml){
|
||||
navigation.toc = parse.toc(xml);
|
||||
navigation.loaded(navigation.toc);
|
||||
loading.resolve(navigation.toc);
|
||||
});
|
||||
|
||||
return loaded;
|
||||
};
|
||||
return loaded;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Load the navigation
|
||||
Navigation.prototype.load = function(_request) {
|
||||
var request = _request || require('./request');
|
||||
var loading, loaded;
|
||||
var request = _request || require('./request');
|
||||
var loading, loaded;
|
||||
|
||||
if(this.nav) {
|
||||
loading = this.nav.load();
|
||||
} else if(this.ncx) {
|
||||
loading = this.ncx.load();
|
||||
} else {
|
||||
loaded = new RSVP.defer();
|
||||
loaded.resolve([]);
|
||||
loading = loaded.promise;
|
||||
}
|
||||
if(this.nav) {
|
||||
loading = this.nav.load();
|
||||
} else if(this.ncx) {
|
||||
loading = this.ncx.load();
|
||||
} else {
|
||||
loaded = new RSVP.defer();
|
||||
loaded.resolve([]);
|
||||
loading = loaded.promise;
|
||||
}
|
||||
|
||||
return loading;
|
||||
return loading;
|
||||
|
||||
};
|
||||
|
||||
Navigation.prototype.loaded = function(toc) {
|
||||
var item;
|
||||
var item;
|
||||
|
||||
for (var i = 0; i < toc.length; i++) {
|
||||
item = toc[i];
|
||||
this.tocByHref[item.href] = i;
|
||||
this.tocById[item.id] = i;
|
||||
}
|
||||
for (var i = 0; i < toc.length; i++) {
|
||||
item = toc[i];
|
||||
this.tocByHref[item.href] = i;
|
||||
this.tocById[item.id] = i;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Get an item from the navigation
|
||||
Navigation.prototype.get = function(target) {
|
||||
var index;
|
||||
var index;
|
||||
|
||||
if(!target) {
|
||||
return this.toc;
|
||||
}
|
||||
if(!target) {
|
||||
return this.toc;
|
||||
}
|
||||
|
||||
if(target.indexOf("#") === 0) {
|
||||
index = this.tocById[target.substring(1)];
|
||||
} else if(target in this.tocByHref){
|
||||
index = this.tocByHref[target];
|
||||
}
|
||||
if(target.indexOf("#") === 0) {
|
||||
index = this.tocById[target.substring(1)];
|
||||
} else if(target in this.tocByHref){
|
||||
index = this.tocByHref[target];
|
||||
}
|
||||
|
||||
return this.toc[index];
|
||||
return this.toc[index];
|
||||
};
|
||||
|
||||
module.exports = Navigation;
|
||||
|
|
350
src/parser.js
350
src/parser.js
|
@ -6,120 +6,120 @@ var EpubCFI = require('./epubcfi');
|
|||
function Parser(){};
|
||||
|
||||
Parser.prototype.container = function(containerXml){
|
||||
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
||||
var rootfile, fullpath, folder, encoding;
|
||||
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
||||
var rootfile, fullpath, folder, encoding;
|
||||
|
||||
if(!containerXml) {
|
||||
console.error("Container File Not Found");
|
||||
return;
|
||||
}
|
||||
if(!containerXml) {
|
||||
console.error("Container File Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
rootfile = core.qs(containerXml, "rootfile");
|
||||
rootfile = core.qs(containerXml, "rootfile");
|
||||
|
||||
if(!rootfile) {
|
||||
console.error("No RootFile Found");
|
||||
return;
|
||||
}
|
||||
if(!rootfile) {
|
||||
console.error("No RootFile Found");
|
||||
return;
|
||||
}
|
||||
|
||||
fullpath = rootfile.getAttribute('full-path');
|
||||
folder = URI(fullpath).directory();
|
||||
encoding = containerXml.xmlEncoding;
|
||||
fullpath = rootfile.getAttribute('full-path');
|
||||
folder = URI(fullpath).directory();
|
||||
encoding = containerXml.xmlEncoding;
|
||||
|
||||
//-- Now that we have the path we can parse the contents
|
||||
return {
|
||||
'packagePath' : fullpath,
|
||||
'basePath' : folder,
|
||||
'encoding' : encoding
|
||||
};
|
||||
//-- Now that we have the path we can parse the contents
|
||||
return {
|
||||
'packagePath' : fullpath,
|
||||
'basePath' : folder,
|
||||
'encoding' : encoding
|
||||
};
|
||||
};
|
||||
|
||||
Parser.prototype.identifier = function(packageXml){
|
||||
var metadataNode;
|
||||
var metadataNode;
|
||||
|
||||
if(!packageXml) {
|
||||
console.error("Package File Not Found");
|
||||
return;
|
||||
}
|
||||
if(!packageXml) {
|
||||
console.error("Package File Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
metadataNode = core.qs(packageXml, "metadata");
|
||||
metadataNode = core.qs(packageXml, "metadata");
|
||||
|
||||
if(!metadataNode) {
|
||||
console.error("No Metadata Found");
|
||||
return;
|
||||
}
|
||||
if(!metadataNode) {
|
||||
console.error("No Metadata Found");
|
||||
return;
|
||||
}
|
||||
|
||||
return this.getElementText(metadataNode, "identifier");
|
||||
return this.getElementText(metadataNode, "identifier");
|
||||
};
|
||||
|
||||
Parser.prototype.packageContents = function(packageXml){
|
||||
var parse = this;
|
||||
var metadataNode, manifestNode, spineNode;
|
||||
var manifest, navPath, ncxPath, coverPath;
|
||||
var spineNodeIndex;
|
||||
var spine;
|
||||
var spineIndexByURL;
|
||||
var metadata;
|
||||
var parse = this;
|
||||
var metadataNode, manifestNode, spineNode;
|
||||
var manifest, navPath, ncxPath, coverPath;
|
||||
var spineNodeIndex;
|
||||
var spine;
|
||||
var spineIndexByURL;
|
||||
var metadata;
|
||||
|
||||
if(!packageXml) {
|
||||
console.error("Package File Not Found");
|
||||
return;
|
||||
}
|
||||
if(!packageXml) {
|
||||
console.error("Package File Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
metadataNode = core.qs(packageXml, "metadata");
|
||||
if(!metadataNode) {
|
||||
console.error("No Metadata Found");
|
||||
return;
|
||||
}
|
||||
metadataNode = core.qs(packageXml, "metadata");
|
||||
if(!metadataNode) {
|
||||
console.error("No Metadata Found");
|
||||
return;
|
||||
}
|
||||
|
||||
manifestNode = core.qs(packageXml, "manifest");
|
||||
if(!manifestNode) {
|
||||
console.error("No Manifest Found");
|
||||
return;
|
||||
}
|
||||
manifestNode = core.qs(packageXml, "manifest");
|
||||
if(!manifestNode) {
|
||||
console.error("No Manifest Found");
|
||||
return;
|
||||
}
|
||||
|
||||
spineNode = core.qs(packageXml, "spine");
|
||||
if(!spineNode) {
|
||||
console.error("No Spine Found");
|
||||
return;
|
||||
}
|
||||
spineNode = core.qs(packageXml, "spine");
|
||||
if(!spineNode) {
|
||||
console.error("No Spine Found");
|
||||
return;
|
||||
}
|
||||
|
||||
manifest = parse.manifest(manifestNode);
|
||||
navPath = parse.findNavPath(manifestNode);
|
||||
ncxPath = parse.findNcxPath(manifestNode, spineNode);
|
||||
coverPath = parse.findCoverPath(packageXml);
|
||||
manifest = parse.manifest(manifestNode);
|
||||
navPath = parse.findNavPath(manifestNode);
|
||||
ncxPath = parse.findNcxPath(manifestNode, spineNode);
|
||||
coverPath = parse.findCoverPath(packageXml);
|
||||
|
||||
spineNodeIndex = Array.prototype.indexOf.call(spineNode.parentNode.childNodes, spineNode);
|
||||
spineNodeIndex = Array.prototype.indexOf.call(spineNode.parentNode.childNodes, spineNode);
|
||||
|
||||
spine = parse.spine(spineNode, manifest);
|
||||
spine = parse.spine(spineNode, manifest);
|
||||
|
||||
metadata = parse.metadata(metadataNode);
|
||||
metadata = parse.metadata(metadataNode);
|
||||
|
||||
metadata.direction = spineNode.getAttribute("page-progression-direction");
|
||||
|
||||
return {
|
||||
'metadata' : metadata,
|
||||
'spine' : spine,
|
||||
'manifest' : manifest,
|
||||
'navPath' : navPath,
|
||||
'ncxPath' : ncxPath,
|
||||
'coverPath': coverPath,
|
||||
'spineNodeIndex' : spineNodeIndex
|
||||
};
|
||||
return {
|
||||
'metadata' : metadata,
|
||||
'spine' : spine,
|
||||
'manifest' : manifest,
|
||||
'navPath' : navPath,
|
||||
'ncxPath' : ncxPath,
|
||||
'coverPath': coverPath,
|
||||
'spineNodeIndex' : spineNodeIndex
|
||||
};
|
||||
};
|
||||
|
||||
//-- Find TOC NAV
|
||||
Parser.prototype.findNavPath = function(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"});
|
||||
return node ? node.getAttribute('href') : false;
|
||||
// var node = manifestNode.querySelector("item[properties$='nav'], item[properties^='nav '], item[properties*=' nav ']");
|
||||
var node = core.qsp(manifestNode, "item", {"properties":"nav"});
|
||||
return node ? node.getAttribute('href') : false;
|
||||
};
|
||||
|
||||
//-- Find TOC NCX: media-type="application/x-dtbncx+xml" href="toc.ncx"
|
||||
Parser.prototype.findNcxPath = function(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 = core.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
|
||||
|
@ -129,7 +129,7 @@ Parser.prototype.findNcxPath = function(manifestNode, spineNode){
|
|||
tocId = spineNode.getAttribute("toc");
|
||||
if(tocId) {
|
||||
// node = manifestNode.querySelector("item[id='" + tocId + "']");
|
||||
node = manifestNode.getElementById(tocId);
|
||||
node = manifestNode.getElementById(tocId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,36 +138,36 @@ Parser.prototype.findNcxPath = function(manifestNode, spineNode){
|
|||
|
||||
//-- Expanded to match Readium web components
|
||||
Parser.prototype.metadata = function(xml){
|
||||
var metadata = {},
|
||||
p = this;
|
||||
var metadata = {},
|
||||
p = this;
|
||||
|
||||
metadata.title = p.getElementText(xml, 'title');
|
||||
metadata.creator = p.getElementText(xml, 'creator');
|
||||
metadata.description = p.getElementText(xml, 'description');
|
||||
metadata.title = p.getElementText(xml, 'title');
|
||||
metadata.creator = p.getElementText(xml, 'creator');
|
||||
metadata.description = p.getElementText(xml, 'description');
|
||||
|
||||
metadata.pubdate = p.getElementText(xml, 'date');
|
||||
metadata.pubdate = p.getElementText(xml, 'date');
|
||||
|
||||
metadata.publisher = p.getElementText(xml, 'publisher');
|
||||
metadata.publisher = p.getElementText(xml, 'publisher');
|
||||
|
||||
metadata.identifier = p.getElementText(xml, "identifier");
|
||||
metadata.language = p.getElementText(xml, "language");
|
||||
metadata.rights = p.getElementText(xml, "rights");
|
||||
metadata.identifier = p.getElementText(xml, "identifier");
|
||||
metadata.language = p.getElementText(xml, "language");
|
||||
metadata.rights = p.getElementText(xml, "rights");
|
||||
|
||||
metadata.modified_date = p.getPropertyText(xml, 'dcterms:modified');
|
||||
metadata.modified_date = p.getPropertyText(xml, 'dcterms:modified');
|
||||
|
||||
metadata.layout = p.getPropertyText(xml, "rendition:layout");
|
||||
metadata.orientation = p.getPropertyText(xml, 'rendition:orientation');
|
||||
metadata.flow = p.getPropertyText(xml, 'rendition:flow');
|
||||
metadata.viewport = p.getPropertyText(xml, 'rendition:viewport');
|
||||
// metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
|
||||
metadata.layout = p.getPropertyText(xml, "rendition:layout");
|
||||
metadata.orientation = p.getPropertyText(xml, 'rendition:orientation');
|
||||
metadata.flow = p.getPropertyText(xml, 'rendition:flow');
|
||||
metadata.viewport = p.getPropertyText(xml, 'rendition:viewport');
|
||||
// metadata.page_prog_dir = packageXml.querySelector("spine").getAttribute("page-progression-direction");
|
||||
|
||||
return metadata;
|
||||
return metadata;
|
||||
};
|
||||
|
||||
//-- Find Cover: <item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />
|
||||
//-- Fallback for Epub 2.0
|
||||
Parser.prototype.findCoverPath = function(packageXml){
|
||||
var pkg = core.qs(packageXml, "package");
|
||||
var pkg = core.qs(packageXml, "package");
|
||||
var epubVersion = pkg.getAttribute('version');
|
||||
|
||||
if (epubVersion === '2.0') {
|
||||
|
@ -175,7 +175,7 @@ Parser.prototype.findCoverPath = function(packageXml){
|
|||
if (metaCover) {
|
||||
var coverId = metaCover.getAttribute('content');
|
||||
// var cover = packageXml.querySelector("item[id='" + coverId + "']");
|
||||
var cover = packageXml.getElementById(coverId);
|
||||
var cover = packageXml.getElementById(coverId);
|
||||
return cover ? cover.getAttribute('href') : false;
|
||||
}
|
||||
else {
|
||||
|
@ -183,113 +183,113 @@ Parser.prototype.findCoverPath = function(packageXml){
|
|||
}
|
||||
}
|
||||
else {
|
||||
// var node = packageXml.querySelector("item[properties='cover-image']");
|
||||
var node = core.qsp(packageXml, 'item', {'properties':'cover-image'});
|
||||
// var node = packageXml.querySelector("item[properties='cover-image']");
|
||||
var node = core.qsp(packageXml, 'item', {'properties':'cover-image'});
|
||||
return node ? node.getAttribute('href') : false;
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.getElementText = function(xml, tag){
|
||||
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
|
||||
el;
|
||||
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
|
||||
el;
|
||||
|
||||
if(!found || found.length === 0) return '';
|
||||
if(!found || found.length === 0) return '';
|
||||
|
||||
el = found[0];
|
||||
el = found[0];
|
||||
|
||||
if(el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
if(el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
return '';
|
||||
return '';
|
||||
|
||||
};
|
||||
|
||||
Parser.prototype.getPropertyText = function(xml, property){
|
||||
var el = core.qsp(xml, "meta", {"property":property});
|
||||
var el = core.qsp(xml, "meta", {"property":property});
|
||||
|
||||
if(el && el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
if(el && el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
return '';
|
||||
return '';
|
||||
};
|
||||
|
||||
Parser.prototype.querySelectorText = function(xml, q){
|
||||
var el = xml.querySelector(q);
|
||||
var el = xml.querySelector(q);
|
||||
|
||||
if(el && el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
if(el && el.childNodes.length){
|
||||
return el.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
return '';
|
||||
return '';
|
||||
};
|
||||
|
||||
Parser.prototype.manifest = function(manifestXml){
|
||||
var manifest = {};
|
||||
var manifest = {};
|
||||
|
||||
//-- Turn items into an array
|
||||
// var selected = manifestXml.querySelectorAll("item");
|
||||
var selected = core.qsa(manifestXml, "item");
|
||||
var items = Array.prototype.slice.call(selected);
|
||||
//-- Turn items into an array
|
||||
// var selected = manifestXml.querySelectorAll("item");
|
||||
var selected = core.qsa(manifestXml, "item");
|
||||
var items = Array.prototype.slice.call(selected);
|
||||
|
||||
//-- Create an object with the id as key
|
||||
items.forEach(function(item){
|
||||
var id = item.getAttribute('id'),
|
||||
href = item.getAttribute('href') || '',
|
||||
type = item.getAttribute('media-type') || '',
|
||||
properties = item.getAttribute('properties') || '';
|
||||
//-- Create an object with the id as key
|
||||
items.forEach(function(item){
|
||||
var id = item.getAttribute('id'),
|
||||
href = item.getAttribute('href') || '',
|
||||
type = item.getAttribute('media-type') || '',
|
||||
properties = item.getAttribute('properties') || '';
|
||||
|
||||
manifest[id] = {
|
||||
'href' : href,
|
||||
// 'url' : href,
|
||||
'type' : type,
|
||||
'properties' : properties.length ? properties.split(' ') : []
|
||||
};
|
||||
manifest[id] = {
|
||||
'href' : href,
|
||||
// 'url' : href,
|
||||
'type' : type,
|
||||
'properties' : properties.length ? properties.split(' ') : []
|
||||
};
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
return manifest;
|
||||
return manifest;
|
||||
|
||||
};
|
||||
|
||||
Parser.prototype.spine = function(spineXml, manifest){
|
||||
var spine = [];
|
||||
var spine = [];
|
||||
|
||||
var selected = spineXml.getElementsByTagName("itemref"),
|
||||
items = Array.prototype.slice.call(selected);
|
||||
var selected = spineXml.getElementsByTagName("itemref"),
|
||||
items = Array.prototype.slice.call(selected);
|
||||
|
||||
var epubcfi = new EpubCFI();
|
||||
var epubcfi = new EpubCFI();
|
||||
|
||||
//-- Add to array to mantain ordering and cross reference with manifest
|
||||
items.forEach(function(item, index){
|
||||
var idref = item.getAttribute('idref');
|
||||
// var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
|
||||
var props = item.getAttribute('properties') || '';
|
||||
var propArray = props.length ? props.split(' ') : [];
|
||||
// var manifestProps = manifest[Id].properties;
|
||||
// var manifestPropArray = manifestProps.length ? manifestProps.split(' ') : [];
|
||||
//-- Add to array to mantain ordering and cross reference with manifest
|
||||
items.forEach(function(item, index){
|
||||
var idref = item.getAttribute('idref');
|
||||
// var cfiBase = epubcfi.generateChapterComponent(spineNodeIndex, index, Id);
|
||||
var props = item.getAttribute('properties') || '';
|
||||
var propArray = props.length ? props.split(' ') : [];
|
||||
// var manifestProps = manifest[Id].properties;
|
||||
// var manifestPropArray = manifestProps.length ? manifestProps.split(' ') : [];
|
||||
|
||||
var itemref = {
|
||||
'idref' : idref,
|
||||
'linear' : item.getAttribute('linear') || '',
|
||||
'properties' : propArray,
|
||||
// 'href' : manifest[Id].href,
|
||||
// 'url' : manifest[Id].url,
|
||||
'index' : index
|
||||
// 'cfiBase' : cfiBase
|
||||
};
|
||||
spine.push(itemref);
|
||||
});
|
||||
var itemref = {
|
||||
'idref' : idref,
|
||||
'linear' : item.getAttribute('linear') || '',
|
||||
'properties' : propArray,
|
||||
// 'href' : manifest[Id].href,
|
||||
// 'url' : manifest[Id].url,
|
||||
'index' : index
|
||||
// 'cfiBase' : cfiBase
|
||||
};
|
||||
spine.push(itemref);
|
||||
});
|
||||
|
||||
return spine;
|
||||
return spine;
|
||||
};
|
||||
|
||||
Parser.prototype.querySelectorByType = function(html, element, type){
|
||||
var query;
|
||||
if (typeof html.querySelector != "undefined") {
|
||||
query = html.querySelector(element+'[*|type="'+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 = core.qsa(html, element);
|
||||
|
@ -305,7 +305,7 @@ Parser.prototype.querySelectorByType = function(html, element, type){
|
|||
|
||||
Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
|
||||
var navElement = this.querySelectorByType(navHtml, "nav", "toc");
|
||||
// var navItems = navElement ? navElement.querySelectorAll("ol li") : [];
|
||||
// var navItems = navElement ? navElement.querySelectorAll("ol li") : [];
|
||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
|
@ -332,7 +332,7 @@ Parser.prototype.nav = function(navHtml, spineIndexByURL, bookSpine){
|
|||
Parser.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
||||
var id = item.getAttribute('id') || false,
|
||||
// content = item.querySelector("a, span"),
|
||||
content = core.qs(item, "a"),
|
||||
content = core.qs(item, "a"),
|
||||
src = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
// split = src.split("#"),
|
||||
|
@ -348,7 +348,7 @@ Parser.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
|||
parent = parentNode.getAttribute('id');
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
if(!id) {
|
||||
if(spinePos) {
|
||||
spineItem = bookSpine[spinePos];
|
||||
|
@ -359,7 +359,7 @@ Parser.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
|||
item.setAttribute('id', id);
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
return {
|
||||
"id": id,
|
||||
|
@ -372,7 +372,7 @@ Parser.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
|||
|
||||
Parser.prototype.ncx = function(tocXml, spineIndexByURL, bookSpine){
|
||||
// var navPoints = tocXml.querySelectorAll("navMap navPoint");
|
||||
var navPoints = core.qsa(tocXml, "navPoint");
|
||||
var navPoints = core.qsa(tocXml, "navPoint");
|
||||
var length = navPoints.length;
|
||||
var i;
|
||||
var toc = {};
|
||||
|
@ -400,8 +400,8 @@ Parser.prototype.ncxItem = function(item, spineIndexByURL, bookSpine){
|
|||
// content = item.querySelector("content"),
|
||||
content = core.qs(item, "content"),
|
||||
src = content.getAttribute('src'),
|
||||
// navLabel = item.querySelector("navLabel"),
|
||||
navLabel = core.qs(item, "navLabel"),
|
||||
// navLabel = item.querySelector("navLabel"),
|
||||
navLabel = core.qs(item, "navLabel"),
|
||||
text = navLabel.textContent ? navLabel.textContent : "",
|
||||
// split = src.split("#"),
|
||||
// baseUrl = split[0],
|
||||
|
@ -416,7 +416,7 @@ Parser.prototype.ncxItem = function(item, spineIndexByURL, bookSpine){
|
|||
parent = parentNode.getAttribute('id');
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
if(!id) {
|
||||
if(spinePos) {
|
||||
spineItem = bookSpine[spinePos];
|
||||
|
@ -427,7 +427,7 @@ Parser.prototype.ncxItem = function(item, spineIndexByURL, bookSpine){
|
|||
item.setAttribute('id', id);
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
return {
|
||||
"id": id,
|
||||
|
@ -440,7 +440,7 @@ Parser.prototype.ncxItem = function(item, spineIndexByURL, bookSpine){
|
|||
|
||||
Parser.prototype.pageList = function(navHtml, spineIndexByURL, bookSpine){
|
||||
var navElement = this.querySelectorByType(navHtml, "nav", "page-list");
|
||||
// var navItems = navElement ? navElement.querySelectorAll("ol li") : [];
|
||||
// var navItems = navElement ? navElement.querySelectorAll("ol li") : [];
|
||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||
var length = navItems.length;
|
||||
var i;
|
||||
|
@ -461,7 +461,7 @@ Parser.prototype.pageList = function(navHtml, spineIndexByURL, bookSpine){
|
|||
Parser.prototype.pageListItem = function(item, spineIndexByURL, bookSpine){
|
||||
var id = item.getAttribute('id') || false,
|
||||
// content = item.querySelector("a"),
|
||||
content = core.qs(item, "a"),
|
||||
content = core.qs(item, "a"),
|
||||
href = content.getAttribute('href') || '',
|
||||
text = content.textContent || "",
|
||||
page = parseInt(text),
|
||||
|
|
232
src/queue.js
232
src/queue.js
|
@ -2,191 +2,191 @@ var RSVP = require('rsvp');
|
|||
var core = require('./core');
|
||||
|
||||
function Queue(_context){
|
||||
this._q = [];
|
||||
this.context = _context;
|
||||
this.tick = core.requestAnimationFrame;
|
||||
this.running = false;
|
||||
this.paused = false;
|
||||
this._q = [];
|
||||
this.context = _context;
|
||||
this.tick = core.requestAnimationFrame;
|
||||
this.running = false;
|
||||
this.paused = false;
|
||||
};
|
||||
|
||||
// Add an item to the queue
|
||||
Queue.prototype.enqueue = function() {
|
||||
var deferred, promise;
|
||||
var queued;
|
||||
var task = [].shift.call(arguments);
|
||||
var args = arguments;
|
||||
var deferred, promise;
|
||||
var queued;
|
||||
var task = [].shift.call(arguments);
|
||||
var args = arguments;
|
||||
|
||||
// Handle single args without context
|
||||
// if(args && !Array.isArray(args)) {
|
||||
// args = [args];
|
||||
// }
|
||||
if(!task) {
|
||||
return console.error("No Task Provided");
|
||||
}
|
||||
// Handle single args without context
|
||||
// if(args && !Array.isArray(args)) {
|
||||
// args = [args];
|
||||
// }
|
||||
if(!task) {
|
||||
return console.error("No Task Provided");
|
||||
}
|
||||
|
||||
if(typeof task === "function"){
|
||||
if(typeof task === "function"){
|
||||
|
||||
deferred = new RSVP.defer();
|
||||
promise = deferred.promise;
|
||||
deferred = new RSVP.defer();
|
||||
promise = deferred.promise;
|
||||
|
||||
queued = {
|
||||
"task" : task,
|
||||
"args" : args,
|
||||
//"context" : context,
|
||||
"deferred" : deferred,
|
||||
"promise" : promise
|
||||
};
|
||||
queued = {
|
||||
"task" : task,
|
||||
"args" : args,
|
||||
//"context" : context,
|
||||
"deferred" : deferred,
|
||||
"promise" : promise
|
||||
};
|
||||
|
||||
} else {
|
||||
// Task is a promise
|
||||
queued = {
|
||||
"promise" : task
|
||||
};
|
||||
} else {
|
||||
// Task is a promise
|
||||
queued = {
|
||||
"promise" : task
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this._q.push(queued);
|
||||
this._q.push(queued);
|
||||
|
||||
// Wait to start queue flush
|
||||
if (this.paused == false && !this.running) {
|
||||
// setTimeout(this.flush.bind(this), 0);
|
||||
// this.tick.call(window, this.run.bind(this));
|
||||
this.run();
|
||||
}
|
||||
// Wait to start queue flush
|
||||
if (this.paused == false && !this.running) {
|
||||
// setTimeout(this.flush.bind(this), 0);
|
||||
// this.tick.call(window, this.run.bind(this));
|
||||
this.run();
|
||||
}
|
||||
|
||||
return queued.promise;
|
||||
return queued.promise;
|
||||
};
|
||||
|
||||
// Run one item
|
||||
Queue.prototype.dequeue = function(){
|
||||
var inwait, task, result;
|
||||
var inwait, task, result;
|
||||
|
||||
if(this._q.length) {
|
||||
inwait = this._q.shift();
|
||||
task = inwait.task;
|
||||
if(task){
|
||||
// console.log(task)
|
||||
if(this._q.length) {
|
||||
inwait = this._q.shift();
|
||||
task = inwait.task;
|
||||
if(task){
|
||||
// console.log(task)
|
||||
|
||||
result = task.apply(this.context, inwait.args);
|
||||
result = task.apply(this.context, inwait.args);
|
||||
|
||||
if(result && typeof result["then"] === "function") {
|
||||
// Task is a function that returns a promise
|
||||
return result.then(function(){
|
||||
inwait.deferred.resolve.apply(this.context, arguments);
|
||||
}.bind(this));
|
||||
} else {
|
||||
// Task resolves immediately
|
||||
inwait.deferred.resolve.apply(this.context, result);
|
||||
return inwait.promise;
|
||||
}
|
||||
if(result && typeof result["then"] === "function") {
|
||||
// Task is a function that returns a promise
|
||||
return result.then(function(){
|
||||
inwait.deferred.resolve.apply(this.context, arguments);
|
||||
}.bind(this));
|
||||
} else {
|
||||
// Task resolves immediately
|
||||
inwait.deferred.resolve.apply(this.context, result);
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if(inwait.promise) {
|
||||
// Task is a promise
|
||||
return inwait.promise;
|
||||
}
|
||||
} else if(inwait.promise) {
|
||||
// Task is a promise
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
} else {
|
||||
inwait = new RSVP.defer();
|
||||
inwait.deferred.resolve();
|
||||
return inwait.promise;
|
||||
}
|
||||
} else {
|
||||
inwait = new RSVP.defer();
|
||||
inwait.deferred.resolve();
|
||||
return inwait.promise;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Run All Immediately
|
||||
Queue.prototype.dump = function(){
|
||||
while(this._q.length) {
|
||||
this.dequeue();
|
||||
}
|
||||
while(this._q.length) {
|
||||
this.dequeue();
|
||||
}
|
||||
};
|
||||
|
||||
// Run all sequentially, at convince
|
||||
|
||||
Queue.prototype.run = function(){
|
||||
|
||||
if(!this.running){
|
||||
this.running = true;
|
||||
this.defered = new RSVP.defer();
|
||||
}
|
||||
if(!this.running){
|
||||
this.running = true;
|
||||
this.defered = new RSVP.defer();
|
||||
}
|
||||
|
||||
this.tick.call(window, function() {
|
||||
this.tick.call(window, function() {
|
||||
|
||||
if(this._q.length) {
|
||||
if(this._q.length) {
|
||||
|
||||
this.dequeue()
|
||||
.then(function(){
|
||||
this.run();
|
||||
}.bind(this));
|
||||
this.dequeue()
|
||||
.then(function(){
|
||||
this.run();
|
||||
}.bind(this));
|
||||
|
||||
} else {
|
||||
this.defered.resolve();
|
||||
this.running = undefined;
|
||||
}
|
||||
} else {
|
||||
this.defered.resolve();
|
||||
this.running = undefined;
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
// Unpause
|
||||
if(this.paused == true) {
|
||||
this.paused = false;
|
||||
}
|
||||
// Unpause
|
||||
if(this.paused == true) {
|
||||
this.paused = false;
|
||||
}
|
||||
|
||||
return this.defered.promise;
|
||||
return this.defered.promise;
|
||||
};
|
||||
|
||||
// Flush all, as quickly as possible
|
||||
Queue.prototype.flush = function(){
|
||||
|
||||
if(this.running){
|
||||
return this.running;
|
||||
}
|
||||
if(this.running){
|
||||
return this.running;
|
||||
}
|
||||
|
||||
if(this._q.length) {
|
||||
this.running = this.dequeue()
|
||||
.then(function(){
|
||||
this.running = undefined;
|
||||
return this.flush();
|
||||
}.bind(this));
|
||||
if(this._q.length) {
|
||||
this.running = this.dequeue()
|
||||
.then(function(){
|
||||
this.running = undefined;
|
||||
return this.flush();
|
||||
}.bind(this));
|
||||
|
||||
return this.running;
|
||||
}
|
||||
return this.running;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Clear all items in wait
|
||||
Queue.prototype.clear = function(){
|
||||
this._q = [];
|
||||
this.running = false;
|
||||
this._q = [];
|
||||
this.running = false;
|
||||
};
|
||||
|
||||
Queue.prototype.length = function(){
|
||||
return this._q.length;
|
||||
return this._q.length;
|
||||
};
|
||||
|
||||
Queue.prototype.pause = function(){
|
||||
this.paused = true;
|
||||
this.paused = true;
|
||||
};
|
||||
|
||||
// Create a new task from a callback
|
||||
function Task(task, args, context){
|
||||
|
||||
return function(){
|
||||
var toApply = arguments || [];
|
||||
return function(){
|
||||
var toApply = arguments || [];
|
||||
|
||||
return new RSVP.Promise(function(resolve, reject) {
|
||||
var callback = function(value){
|
||||
resolve(value);
|
||||
};
|
||||
// Add the callback to the arguments list
|
||||
toApply.push(callback);
|
||||
return new RSVP.Promise(function(resolve, reject) {
|
||||
var callback = function(value){
|
||||
resolve(value);
|
||||
};
|
||||
// Add the callback to the arguments list
|
||||
toApply.push(callback);
|
||||
|
||||
// Apply all arguments to the functions
|
||||
task.apply(this, toApply);
|
||||
// Apply all arguments to the functions
|
||||
task.apply(this, toApply);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
120
src/rendition.js
120
src/rendition.js
|
@ -49,7 +49,7 @@ function Rendition(book, options) {
|
|||
|
||||
// this.hooks.display.register(this.afterDisplay.bind(this));
|
||||
|
||||
this.epubcfi = new EpubCFI();
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.q = new Queue(this);
|
||||
|
||||
|
@ -83,7 +83,7 @@ Rendition.prototype.requireManager = function(manager) {
|
|||
viewManager = manager
|
||||
}
|
||||
|
||||
return viewManager;
|
||||
return viewManager;
|
||||
};
|
||||
|
||||
Rendition.prototype.requireView = function(view) {
|
||||
|
@ -96,7 +96,7 @@ Rendition.prototype.requireView = function(view) {
|
|||
View = view
|
||||
}
|
||||
|
||||
return View;
|
||||
return View;
|
||||
};
|
||||
|
||||
Rendition.prototype.start = function(){
|
||||
|
@ -362,24 +362,24 @@ Rendition.prototype.spread = function(spread, min){
|
|||
|
||||
|
||||
Rendition.prototype.reportLocation = function(){
|
||||
return this.q.enqueue(function(){
|
||||
var location = this.manager.currentLocation();
|
||||
return this.q.enqueue(function(){
|
||||
var location = this.manager.currentLocation();
|
||||
if (location && location.then && typeof location.then === 'function') {
|
||||
location.then(function(result) {
|
||||
this.location = result;
|
||||
this.trigger("locationChanged", this.location);
|
||||
this.trigger("locationChanged", this.location);
|
||||
}.bind(this));
|
||||
} else if (location) {
|
||||
this.location = location;
|
||||
this.trigger("locationChanged", this.location);
|
||||
this.trigger("locationChanged", this.location);
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
||||
Rendition.prototype.destroy = function(){
|
||||
// Clear the queue
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
|
||||
this.views.clear();
|
||||
|
@ -394,7 +394,7 @@ Rendition.prototype.destroy = function(){
|
|||
};
|
||||
|
||||
Rendition.prototype.passViewEvents = function(view){
|
||||
view.contents.listenedEvents.forEach(function(e){
|
||||
view.contents.listenedEvents.forEach(function(e){
|
||||
view.on(e, this.triggerViewEvent.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
|
@ -402,11 +402,11 @@ Rendition.prototype.passViewEvents = function(view){
|
|||
};
|
||||
|
||||
Rendition.prototype.triggerViewEvent = function(e){
|
||||
this.trigger(e.type, e);
|
||||
this.trigger(e.type, e);
|
||||
};
|
||||
|
||||
Rendition.prototype.triggerSelectedEvent = function(cfirange){
|
||||
this.trigger("selected", cfirange);
|
||||
this.trigger("selected", cfirange);
|
||||
};
|
||||
|
||||
Rendition.prototype.replacements = function(){
|
||||
|
@ -414,27 +414,27 @@ Rendition.prototype.replacements = function(){
|
|||
// return this.q.enqueue(function () {
|
||||
// Get thes books manifest
|
||||
var manifest = this.book.package.manifest;
|
||||
var manifestArray = Object.keys(manifest).
|
||||
map(function (key){
|
||||
return manifest[key];
|
||||
});
|
||||
var manifestArray = Object.keys(manifest).
|
||||
map(function (key){
|
||||
return manifest[key];
|
||||
});
|
||||
|
||||
// Exclude HTML
|
||||
var items = manifestArray.
|
||||
filter(function (item){
|
||||
if (item.type != "application/xhtml+xml" &&
|
||||
item.type != "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// Exclude HTML
|
||||
var items = manifestArray.
|
||||
filter(function (item){
|
||||
if (item.type != "application/xhtml+xml" &&
|
||||
item.type != "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Only CSS
|
||||
var css = items.
|
||||
filter(function (item){
|
||||
if (item.type === "text/css") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// Only CSS
|
||||
var css = items.
|
||||
filter(function (item){
|
||||
if (item.type === "text/css") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Css Urls
|
||||
var cssUrls = css.map(function(item) {
|
||||
|
@ -442,18 +442,18 @@ Rendition.prototype.replacements = function(){
|
|||
});
|
||||
|
||||
// All Assets Urls
|
||||
var urls = items.
|
||||
map(function(item) {
|
||||
return item.href;
|
||||
}.bind(this));
|
||||
var urls = items.
|
||||
map(function(item) {
|
||||
return item.href;
|
||||
}.bind(this));
|
||||
|
||||
// Create blob urls for all the assets
|
||||
var processing = urls.
|
||||
map(function(url) {
|
||||
var processing = urls.
|
||||
map(function(url) {
|
||||
var absolute = URI(url).absoluteTo(this.book.baseUrl).toString();
|
||||
// Full url from archive base
|
||||
return this.book.unarchived.createUrl(absolute, {"base64": this.settings.useBase64});
|
||||
}.bind(this));
|
||||
return this.book.unarchived.createUrl(absolute, {"base64": this.settings.useBase64});
|
||||
}.bind(this));
|
||||
|
||||
var replacementUrls;
|
||||
|
||||
|
@ -467,11 +467,11 @@ Rendition.prototype.replacements = function(){
|
|||
// Replace Asset Urls in the text of all css files
|
||||
cssUrls.forEach(function(href) {
|
||||
replaced.push(this.replaceCss(href, urls, replacementUrls));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
return RSVP.all(replaced);
|
||||
|
||||
}.bind(this))
|
||||
}.bind(this))
|
||||
.then(function () {
|
||||
// Replace Asset Urls in chapters
|
||||
// by registering a hook after the sections contents has been serialized
|
||||
|
@ -483,8 +483,8 @@ Rendition.prototype.replacements = function(){
|
|||
|
||||
}.bind(this))
|
||||
.catch(function(reason){
|
||||
console.error(reason);
|
||||
});
|
||||
console.error(reason);
|
||||
});
|
||||
// }.bind(this));
|
||||
};
|
||||
|
||||
|
@ -545,31 +545,31 @@ Rendition.prototype.replaceAssets = function(section, urls, replacementUrls){
|
|||
};
|
||||
|
||||
Rendition.prototype.range = function(_cfi, ignoreClass){
|
||||
var cfi = new EpubCFI(_cfi);
|
||||
var found = this.visible().filter(function (view) {
|
||||
var cfi = new EpubCFI(_cfi);
|
||||
var found = this.visible().filter(function (view) {
|
||||
if(cfi.spinePos === view.index) return true;
|
||||
});
|
||||
|
||||
// Should only every return 1 item
|
||||
if (found.length) {
|
||||
return found[0].range(cfi, ignoreClass);
|
||||
}
|
||||
if (found.length) {
|
||||
return found[0].range(cfi, ignoreClass);
|
||||
}
|
||||
};
|
||||
|
||||
Rendition.prototype.adjustImages = function(view) {
|
||||
|
||||
view.addStylesheetRules([
|
||||
["img",
|
||||
["max-width", (view.layout.spreadWidth) + "px"],
|
||||
["max-height", (view.layout.height) + "px"]
|
||||
]
|
||||
]);
|
||||
return new RSVP.Promise(function(resolve, reject){
|
||||
// Wait to apply
|
||||
setTimeout(function() {
|
||||
resolve();
|
||||
}, 1);
|
||||
});
|
||||
view.addStylesheetRules([
|
||||
["img",
|
||||
["max-width", (view.layout.spreadWidth) + "px"],
|
||||
["max-height", (view.layout.height) + "px"]
|
||||
]
|
||||
]);
|
||||
return new RSVP.Promise(function(resolve, reject){
|
||||
// Wait to apply
|
||||
setTimeout(function() {
|
||||
resolve();
|
||||
}, 1);
|
||||
});
|
||||
};
|
||||
|
||||
//-- Enable binding events to Renderer
|
||||
|
|
|
@ -2,69 +2,69 @@ var URI = require('urijs');
|
|||
var core = require('./core');
|
||||
|
||||
function base(doc, section){
|
||||
var base;
|
||||
var head;
|
||||
var base;
|
||||
var head;
|
||||
|
||||
if(!doc){
|
||||
return;
|
||||
}
|
||||
if(!doc){
|
||||
return;
|
||||
}
|
||||
|
||||
// head = doc.querySelector("head");
|
||||
// base = head.querySelector("base");
|
||||
head = core.qs(doc, "head");
|
||||
base = core.qs(head, "base");
|
||||
// head = doc.querySelector("head");
|
||||
// base = head.querySelector("base");
|
||||
head = core.qs(doc, "head");
|
||||
base = core.qs(head, "base");
|
||||
|
||||
if(!base) {
|
||||
base = doc.createElement("base");
|
||||
head.insertBefore(base, head.firstChild);
|
||||
}
|
||||
if(!base) {
|
||||
base = doc.createElement("base");
|
||||
head.insertBefore(base, head.firstChild);
|
||||
}
|
||||
|
||||
base.setAttribute("href", section.url);
|
||||
base.setAttribute("href", section.url);
|
||||
}
|
||||
|
||||
function canonical(doc, section){
|
||||
var head;
|
||||
var link;
|
||||
var url = section.url; // window.location.origin + window.location.pathname + "?loc=" + encodeURIComponent(section.url);
|
||||
var head;
|
||||
var link;
|
||||
var url = section.url; // window.location.origin + window.location.pathname + "?loc=" + encodeURIComponent(section.url);
|
||||
|
||||
if(!doc){
|
||||
return;
|
||||
}
|
||||
if(!doc){
|
||||
return;
|
||||
}
|
||||
|
||||
head = core.qs(doc, "head");
|
||||
link = core.qs(head, "link[rel='canonical']");
|
||||
head = core.qs(doc, "head");
|
||||
link = core.qs(head, "link[rel='canonical']");
|
||||
|
||||
if (link) {
|
||||
link.setAttribute("href", url);
|
||||
} else {
|
||||
link = doc.createElement("link");
|
||||
link.setAttribute("rel", "canonical");
|
||||
link.setAttribute("href", url);
|
||||
head.appendChild(link);
|
||||
}
|
||||
if (link) {
|
||||
link.setAttribute("href", url);
|
||||
} else {
|
||||
link = doc.createElement("link");
|
||||
link.setAttribute("rel", "canonical");
|
||||
link.setAttribute("href", url);
|
||||
head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
function links(view, renderer) {
|
||||
|
||||
var links = view.document.querySelectorAll("a[href]");
|
||||
var replaceLinks = function(link){
|
||||
var href = link.getAttribute("href");
|
||||
var links = view.document.querySelectorAll("a[href]");
|
||||
var replaceLinks = function(link){
|
||||
var href = link.getAttribute("href");
|
||||
|
||||
if(href.indexOf("mailto:") === 0){
|
||||
return;
|
||||
}
|
||||
if(href.indexOf("mailto:") === 0){
|
||||
return;
|
||||
}
|
||||
|
||||
var linkUri = URI(href);
|
||||
var absolute = linkUri.absoluteTo(view.section.url);
|
||||
var relative = absolute.relativeTo(this.book.baseUrl).toString();
|
||||
var linkUri = URI(href);
|
||||
var absolute = linkUri.absoluteTo(view.section.url);
|
||||
var relative = absolute.relativeTo(this.book.baseUrl).toString();
|
||||
|
||||
if(linkUri.protocol()){
|
||||
if(linkUri.protocol()){
|
||||
|
||||
link.setAttribute("target", "_blank");
|
||||
link.setAttribute("target", "_blank");
|
||||
|
||||
}else{
|
||||
/*
|
||||
if(baseDirectory) {
|
||||
}else{
|
||||
/*
|
||||
if(baseDirectory) {
|
||||
// We must ensure that the file:// protocol is preserved for
|
||||
// local file links, as in certain contexts (such as under
|
||||
// Titanium), file links without the file:// protocol will not
|
||||
|
@ -77,38 +77,38 @@ function links(view, renderer) {
|
|||
} else {
|
||||
relative = href;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
if(linkUri.fragment()) {
|
||||
// do nothing with fragment yet
|
||||
} else {
|
||||
link.onclick = function(){
|
||||
renderer.display(relative);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
if(linkUri.fragment()) {
|
||||
// do nothing with fragment yet
|
||||
} else {
|
||||
link.onclick = function(){
|
||||
renderer.display(relative);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}.bind(this);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
replaceLinks(links[i]);
|
||||
}
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
replaceLinks(links[i]);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function substitute(content, urls, replacements) {
|
||||
urls.forEach(function(url, i){
|
||||
if (url && replacements[i]) {
|
||||
content = content.replace(new RegExp(url, 'g'), replacements[i]);
|
||||
}
|
||||
});
|
||||
return content;
|
||||
urls.forEach(function(url, i){
|
||||
if (url && replacements[i]) {
|
||||
content = content.replace(new RegExp(url, 'g'), replacements[i]);
|
||||
}
|
||||
});
|
||||
return content;
|
||||
}
|
||||
module.exports = {
|
||||
'base': base,
|
||||
'canonical' : canonical,
|
||||
'links': links,
|
||||
'substitute': substitute
|
||||
'base': base,
|
||||
'canonical' : canonical,
|
||||
'links': links,
|
||||
'substitute': substitute
|
||||
};
|
||||
|
|
202
src/request.js
202
src/request.js
|
@ -3,55 +3,55 @@ var URI = require('urijs');
|
|||
var core = require('./core');
|
||||
|
||||
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 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 RSVP.defer();
|
||||
var deferred = new RSVP.defer();
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
//-- Check from PDF.js:
|
||||
// https://github.com/mozilla/pdf.js/blob/master/web/compatibility.js
|
||||
var xhrPrototype = XMLHttpRequest.prototype;
|
||||
//-- Check from PDF.js:
|
||||
// https://github.com/mozilla/pdf.js/blob/master/web/compatibility.js
|
||||
var xhrPrototype = XMLHttpRequest.prototype;
|
||||
|
||||
var header;
|
||||
var header;
|
||||
|
||||
if (!('overrideMimeType' in xhrPrototype)) {
|
||||
// IE10 might have response, but not overrideMimeType
|
||||
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
|
||||
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
|
||||
});
|
||||
}
|
||||
if(withCredentials) {
|
||||
xhr.withCredentials = true;
|
||||
}
|
||||
if (!('overrideMimeType' in xhrPrototype)) {
|
||||
// IE10 might have response, but not overrideMimeType
|
||||
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
|
||||
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
|
||||
});
|
||||
}
|
||||
if(withCredentials) {
|
||||
xhr.withCredentials = true;
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = handler;
|
||||
xhr.onerror = err;
|
||||
xhr.onreadystatechange = handler;
|
||||
xhr.onerror = err;
|
||||
|
||||
xhr.open("GET", url, true);
|
||||
xhr.open("GET", url, true);
|
||||
|
||||
for(header in headers) {
|
||||
xhr.setRequestHeader(header, headers[header]);
|
||||
}
|
||||
for(header in headers) {
|
||||
xhr.setRequestHeader(header, headers[header]);
|
||||
}
|
||||
|
||||
if(type == "json") {
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
}
|
||||
if(type == "json") {
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
}
|
||||
|
||||
// If type isn't set, determine it from the file extension
|
||||
// If type isn't set, determine it from the file extension
|
||||
if(!type) {
|
||||
uri = URI(url);
|
||||
type = uri.suffix();
|
||||
}
|
||||
|
||||
if(type == 'blob'){
|
||||
xhr.responseType = BLOB_RESPONSE;
|
||||
}
|
||||
if(type == 'blob'){
|
||||
xhr.responseType = BLOB_RESPONSE;
|
||||
}
|
||||
|
||||
|
||||
if(core.isXml(type)) {
|
||||
if(core.isXml(type)) {
|
||||
// xhr.responseType = "document";
|
||||
xhr.overrideMimeType('text/xml'); // for OPF parsing
|
||||
}
|
||||
|
@ -62,89 +62,89 @@ function request(url, type, withCredentials, headers) {
|
|||
|
||||
if(type == 'html' || type == 'htm') {
|
||||
// xhr.responseType = "document";
|
||||
}
|
||||
}
|
||||
|
||||
if(type == "binary") {
|
||||
xhr.responseType = "arraybuffer";
|
||||
}
|
||||
if(type == "binary") {
|
||||
xhr.responseType = "arraybuffer";
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
xhr.send();
|
||||
|
||||
function err(e) {
|
||||
console.error(e);
|
||||
deferred.reject(e);
|
||||
}
|
||||
function err(e) {
|
||||
console.error(e);
|
||||
deferred.reject(e);
|
||||
}
|
||||
|
||||
function handler() {
|
||||
if (this.readyState === XMLHttpRequest.DONE) {
|
||||
function handler() {
|
||||
if (this.readyState === XMLHttpRequest.DONE) {
|
||||
|
||||
if (this.status === 200 || this.responseXML ) { //-- Firefox is reporting 0 for blob urls
|
||||
var r;
|
||||
if (this.status === 200 || this.responseXML ) { //-- Firefox is reporting 0 for blob urls
|
||||
var r;
|
||||
|
||||
if (!this.response && !this.responseXML) {
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message : "Empty Response",
|
||||
stack : new Error().stack
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
if (!this.response && !this.responseXML) {
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message : "Empty Response",
|
||||
stack : new Error().stack
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
if (this.status === 403) {
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
response: this.response,
|
||||
message : "Forbidden",
|
||||
stack : new Error().stack
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
if (this.status === 403) {
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
response: this.response,
|
||||
message : "Forbidden",
|
||||
stack : new Error().stack
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
if((this.responseType == '' || this.responseType == 'document')
|
||||
&& this.responseXML){
|
||||
r = this.responseXML;
|
||||
} else
|
||||
if(core.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");
|
||||
}else
|
||||
if(type == 'xhtml'){
|
||||
r = core.parse(this.response, "application/xhtml+xml");
|
||||
}else
|
||||
if(type == 'html' || type == 'htm'){
|
||||
r = core.parse(this.response, "text/html");
|
||||
}else
|
||||
if(type == 'json'){
|
||||
r = JSON.parse(this.response);
|
||||
}else
|
||||
if(type == 'blob'){
|
||||
if((this.responseType == '' || this.responseType == 'document')
|
||||
&& this.responseXML){
|
||||
r = this.responseXML;
|
||||
} else
|
||||
if(core.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");
|
||||
}else
|
||||
if(type == 'xhtml'){
|
||||
r = core.parse(this.response, "application/xhtml+xml");
|
||||
}else
|
||||
if(type == 'html' || type == 'htm'){
|
||||
r = core.parse(this.response, "text/html");
|
||||
}else
|
||||
if(type == 'json'){
|
||||
r = JSON.parse(this.response);
|
||||
}else
|
||||
if(type == 'blob'){
|
||||
|
||||
if(supportsURL) {
|
||||
r = this.response;
|
||||
} else {
|
||||
//-- Safari doesn't support responseType blob, so create a blob from arraybuffer
|
||||
r = new Blob([this.response]);
|
||||
}
|
||||
if(supportsURL) {
|
||||
r = this.response;
|
||||
} else {
|
||||
//-- Safari doesn't support responseType blob, so create a blob from arraybuffer
|
||||
r = new Blob([this.response]);
|
||||
}
|
||||
|
||||
}else{
|
||||
r = this.response;
|
||||
}
|
||||
}else{
|
||||
r = this.response;
|
||||
}
|
||||
|
||||
deferred.resolve(r);
|
||||
} else {
|
||||
deferred.resolve(r);
|
||||
} else {
|
||||
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message : this.response,
|
||||
stack : new Error().stack
|
||||
});
|
||||
deferred.reject({
|
||||
status: this.status,
|
||||
message : this.response,
|
||||
stack : new Error().stack
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
module.exports = request;
|
||||
|
|
192
src/section.js
192
src/section.js
|
@ -5,110 +5,110 @@ var EpubCFI = require('./epubcfi');
|
|||
var Hook = require('./hook');
|
||||
|
||||
function Section(item, hooks){
|
||||
this.idref = item.idref;
|
||||
this.linear = item.linear;
|
||||
this.properties = item.properties;
|
||||
this.index = item.index;
|
||||
this.href = item.href;
|
||||
this.url = item.url;
|
||||
this.next = item.next;
|
||||
this.prev = item.prev;
|
||||
this.idref = item.idref;
|
||||
this.linear = item.linear;
|
||||
this.properties = item.properties;
|
||||
this.index = item.index;
|
||||
this.href = item.href;
|
||||
this.url = item.url;
|
||||
this.next = item.next;
|
||||
this.prev = item.prev;
|
||||
|
||||
this.cfiBase = item.cfiBase;
|
||||
this.cfiBase = item.cfiBase;
|
||||
|
||||
if (hooks) {
|
||||
this.hooks = hooks;
|
||||
} else {
|
||||
this.hooks = {};
|
||||
this.hooks.serialize = new Hook(this);
|
||||
this.hooks.content = new Hook(this);
|
||||
}
|
||||
if (hooks) {
|
||||
this.hooks = hooks;
|
||||
} else {
|
||||
this.hooks = {};
|
||||
this.hooks.serialize = new Hook(this);
|
||||
this.hooks.content = new Hook(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Section.prototype.load = function(_request){
|
||||
var request = _request || this.request || require('./request');
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
var request = _request || this.request || require('./request');
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
if(this.contents) {
|
||||
loading.resolve(this.contents);
|
||||
} else {
|
||||
request(this.url)
|
||||
.then(function(xml){
|
||||
var base;
|
||||
var directory = URI(this.url).directory();
|
||||
if(this.contents) {
|
||||
loading.resolve(this.contents);
|
||||
} else {
|
||||
request(this.url)
|
||||
.then(function(xml){
|
||||
var base;
|
||||
var directory = URI(this.url).directory();
|
||||
|
||||
this.document = xml;
|
||||
this.contents = xml.documentElement;
|
||||
this.document = xml;
|
||||
this.contents = xml.documentElement;
|
||||
|
||||
return this.hooks.content.trigger(this.document, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
loading.resolve(this.contents);
|
||||
}.bind(this))
|
||||
.catch(function(error){
|
||||
loading.reject(error);
|
||||
});
|
||||
}
|
||||
return this.hooks.content.trigger(this.document, this);
|
||||
}.bind(this))
|
||||
.then(function(){
|
||||
loading.resolve(this.contents);
|
||||
}.bind(this))
|
||||
.catch(function(error){
|
||||
loading.reject(error);
|
||||
});
|
||||
}
|
||||
|
||||
return loaded;
|
||||
return loaded;
|
||||
};
|
||||
|
||||
Section.prototype.base = function(_document){
|
||||
var task = new RSVP.defer();
|
||||
var base = _document.createElement("base"); // TODO: check if exists
|
||||
var head;
|
||||
console.log(window.location.origin + "/" +this.url);
|
||||
var task = new RSVP.defer();
|
||||
var base = _document.createElement("base"); // TODO: check if exists
|
||||
var head;
|
||||
console.log(window.location.origin + "/" +this.url);
|
||||
|
||||
base.setAttribute("href", window.location.origin + "/" +this.url);
|
||||
base.setAttribute("href", window.location.origin + "/" +this.url);
|
||||
|
||||
if(_document) {
|
||||
head = _document.querySelector("head");
|
||||
}
|
||||
if(head) {
|
||||
head.insertBefore(base, head.firstChild);
|
||||
task.resolve();
|
||||
} else {
|
||||
task.reject(new Error("No head to insert into"));
|
||||
}
|
||||
if(_document) {
|
||||
head = _document.querySelector("head");
|
||||
}
|
||||
if(head) {
|
||||
head.insertBefore(base, head.firstChild);
|
||||
task.resolve();
|
||||
} else {
|
||||
task.reject(new Error("No head to insert into"));
|
||||
}
|
||||
|
||||
|
||||
return task.promise;
|
||||
return task.promise;
|
||||
};
|
||||
|
||||
Section.prototype.beforeSectionLoad = function(){
|
||||
// Stub for a hook - replace me for now
|
||||
// Stub for a hook - replace me for now
|
||||
};
|
||||
|
||||
Section.prototype.render = function(_request){
|
||||
var rendering = new RSVP.defer();
|
||||
var rendered = rendering.promise;
|
||||
this.output; // TODO: better way to return this from hooks?
|
||||
var rendering = new RSVP.defer();
|
||||
var rendered = rendering.promise;
|
||||
this.output; // TODO: better way to return this from hooks?
|
||||
|
||||
this.load(_request).
|
||||
then(function(contents){
|
||||
var serializer;
|
||||
this.load(_request).
|
||||
then(function(contents){
|
||||
var serializer;
|
||||
|
||||
if (typeof XMLSerializer === "undefined") {
|
||||
XMLSerializer = require('xmldom').XMLSerializer;
|
||||
}
|
||||
serializer = new XMLSerializer();
|
||||
this.output = serializer.serializeToString(contents);
|
||||
return this.output;
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
return this.hooks.serialize.trigger(this.output, this);
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
rendering.resolve(this.output);
|
||||
}.bind(this))
|
||||
.catch(function(error){
|
||||
rendering.reject(error);
|
||||
});
|
||||
if (typeof XMLSerializer === "undefined") {
|
||||
XMLSerializer = require('xmldom').XMLSerializer;
|
||||
}
|
||||
serializer = new XMLSerializer();
|
||||
this.output = serializer.serializeToString(contents);
|
||||
return this.output;
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
return this.hooks.serialize.trigger(this.output, this);
|
||||
}.bind(this)).
|
||||
then(function(){
|
||||
rendering.resolve(this.output);
|
||||
}.bind(this))
|
||||
.catch(function(error){
|
||||
rendering.reject(error);
|
||||
});
|
||||
|
||||
return rendered;
|
||||
return rendered;
|
||||
};
|
||||
|
||||
Section.prototype.find = function(_query){
|
||||
|
@ -122,35 +122,35 @@ Section.prototype.find = function(_query){
|
|||
* Returns: Object with layout properties
|
||||
*/
|
||||
Section.prototype.reconcileLayoutSettings = function(global){
|
||||
//-- Get the global defaults
|
||||
var settings = {
|
||||
layout : global.layout,
|
||||
spread : global.spread,
|
||||
orientation : global.orientation
|
||||
};
|
||||
//-- Get the global defaults
|
||||
var settings = {
|
||||
layout : global.layout,
|
||||
spread : global.spread,
|
||||
orientation : global.orientation
|
||||
};
|
||||
|
||||
//-- Get the chapter's display type
|
||||
this.properties.forEach(function(prop){
|
||||
var rendition = prop.replace("rendition:", '');
|
||||
var split = rendition.indexOf("-");
|
||||
var property, value;
|
||||
//-- Get the chapter's display type
|
||||
this.properties.forEach(function(prop){
|
||||
var rendition = prop.replace("rendition:", '');
|
||||
var split = rendition.indexOf("-");
|
||||
var property, value;
|
||||
|
||||
if(split != -1){
|
||||
property = rendition.slice(0, split);
|
||||
value = rendition.slice(split+1);
|
||||
if(split != -1){
|
||||
property = rendition.slice(0, split);
|
||||
value = rendition.slice(split+1);
|
||||
|
||||
settings[property] = value;
|
||||
}
|
||||
});
|
||||
settings[property] = value;
|
||||
}
|
||||
});
|
||||
return settings;
|
||||
};
|
||||
|
||||
Section.prototype.cfiFromRange = function(_range) {
|
||||
return new EpubCFI(_range, this.cfiBase).toString();
|
||||
return new EpubCFI(_range, this.cfiBase).toString();
|
||||
};
|
||||
|
||||
Section.prototype.cfiFromElement = function(el) {
|
||||
return new EpubCFI(el, this.cfiBase).toString();
|
||||
return new EpubCFI(el, this.cfiBase).toString();
|
||||
};
|
||||
|
||||
module.exports = Section;
|
||||
|
|
146
src/spine.js
146
src/spine.js
|
@ -6,64 +6,64 @@ var Section = require('./section');
|
|||
var replacements = require('./replacements');
|
||||
|
||||
function Spine(_request){
|
||||
this.request = _request;
|
||||
this.spineItems = [];
|
||||
this.spineByHref = {};
|
||||
this.spineById = {};
|
||||
this.request = _request;
|
||||
this.spineItems = [];
|
||||
this.spineByHref = {};
|
||||
this.spineById = {};
|
||||
|
||||
this.hooks = {};
|
||||
this.hooks.serialize = new Hook();
|
||||
this.hooks.content = new Hook();
|
||||
this.hooks = {};
|
||||
this.hooks.serialize = new Hook();
|
||||
this.hooks.content = new Hook();
|
||||
|
||||
// Register replacements
|
||||
this.hooks.content.register(replacements.base);
|
||||
this.hooks.content.register(replacements.canonical);
|
||||
// Register replacements
|
||||
this.hooks.content.register(replacements.base);
|
||||
this.hooks.content.register(replacements.canonical);
|
||||
|
||||
this.epubcfi = new EpubCFI();
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.loaded = false;
|
||||
this.loaded = false;
|
||||
};
|
||||
|
||||
Spine.prototype.load = function(_package) {
|
||||
|
||||
this.items = _package.spine;
|
||||
this.manifest = _package.manifest;
|
||||
this.spineNodeIndex = _package.spineNodeIndex;
|
||||
this.baseUrl = _package.baseUrl || '';
|
||||
this.length = this.items.length;
|
||||
this.items = _package.spine;
|
||||
this.manifest = _package.manifest;
|
||||
this.spineNodeIndex = _package.spineNodeIndex;
|
||||
this.baseUrl = _package.baseUrl || '';
|
||||
this.length = this.items.length;
|
||||
|
||||
this.items.forEach(function(item, index){
|
||||
var href, url;
|
||||
var manifestItem = this.manifest[item.idref];
|
||||
var spineItem;
|
||||
this.items.forEach(function(item, index){
|
||||
var href, url;
|
||||
var manifestItem = this.manifest[item.idref];
|
||||
var spineItem;
|
||||
|
||||
item.cfiBase = this.epubcfi.generateChapterComponent(this.spineNodeIndex, item.index, item.idref);
|
||||
item.cfiBase = this.epubcfi.generateChapterComponent(this.spineNodeIndex, item.index, item.idref);
|
||||
|
||||
if(manifestItem) {
|
||||
item.href = manifestItem.href;
|
||||
item.url = this.baseUrl + item.href;
|
||||
if(manifestItem) {
|
||||
item.href = manifestItem.href;
|
||||
item.url = this.baseUrl + item.href;
|
||||
|
||||
if(manifestItem.properties.length){
|
||||
item.properties.push.apply(item.properties, manifestItem.properties);
|
||||
}
|
||||
}
|
||||
if(manifestItem.properties.length){
|
||||
item.properties.push.apply(item.properties, manifestItem.properties);
|
||||
}
|
||||
}
|
||||
|
||||
// if(index > 0) {
|
||||
item.prev = function(){ return this.get(index-1); }.bind(this);
|
||||
// }
|
||||
// if(index > 0) {
|
||||
item.prev = function(){ return this.get(index-1); }.bind(this);
|
||||
// }
|
||||
|
||||
// if(index+1 < this.items.length) {
|
||||
item.next = function(){ return this.get(index+1); }.bind(this);
|
||||
// }
|
||||
// if(index+1 < this.items.length) {
|
||||
item.next = function(){ return this.get(index+1); }.bind(this);
|
||||
// }
|
||||
|
||||
spineItem = new Section(item, this.hooks);
|
||||
spineItem = new Section(item, this.hooks);
|
||||
|
||||
this.append(spineItem);
|
||||
this.append(spineItem);
|
||||
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
this.loaded = true;
|
||||
this.loaded = true;
|
||||
};
|
||||
|
||||
// book.spine.get();
|
||||
|
@ -71,47 +71,47 @@ Spine.prototype.load = function(_package) {
|
|||
// book.spine.get("chap1.html");
|
||||
// book.spine.get("#id1234");
|
||||
Spine.prototype.get = function(target) {
|
||||
var index = 0;
|
||||
var index = 0;
|
||||
|
||||
if(this.epubcfi.isCfiString(target)) {
|
||||
cfi = new EpubCFI(target);
|
||||
index = cfi.spinePos;
|
||||
} else if(target && (typeof target === "number" || isNaN(target) === false)){
|
||||
index = target;
|
||||
} else if(target && target.indexOf("#") === 0) {
|
||||
index = this.spineById[target.substring(1)];
|
||||
} else if(target) {
|
||||
// Remove fragments
|
||||
target = target.split("#")[0];
|
||||
index = this.spineByHref[target];
|
||||
}
|
||||
if(this.epubcfi.isCfiString(target)) {
|
||||
cfi = new EpubCFI(target);
|
||||
index = cfi.spinePos;
|
||||
} else if(target && (typeof target === "number" || isNaN(target) === false)){
|
||||
index = target;
|
||||
} else if(target && target.indexOf("#") === 0) {
|
||||
index = this.spineById[target.substring(1)];
|
||||
} else if(target) {
|
||||
// Remove fragments
|
||||
target = target.split("#")[0];
|
||||
index = this.spineByHref[target];
|
||||
}
|
||||
|
||||
return this.spineItems[index] || null;
|
||||
return this.spineItems[index] || null;
|
||||
};
|
||||
|
||||
Spine.prototype.append = function(section) {
|
||||
var index = this.spineItems.length;
|
||||
section.index = index;
|
||||
var index = this.spineItems.length;
|
||||
section.index = index;
|
||||
|
||||
this.spineItems.push(section);
|
||||
this.spineItems.push(section);
|
||||
|
||||
this.spineByHref[section.href] = index;
|
||||
this.spineById[section.idref] = index;
|
||||
this.spineByHref[section.href] = index;
|
||||
this.spineById[section.idref] = index;
|
||||
|
||||
return index;
|
||||
return index;
|
||||
};
|
||||
|
||||
Spine.prototype.prepend = function(section) {
|
||||
var index = this.spineItems.unshift(section);
|
||||
this.spineByHref[section.href] = 0;
|
||||
this.spineById[section.idref] = 0;
|
||||
var index = this.spineItems.unshift(section);
|
||||
this.spineByHref[section.href] = 0;
|
||||
this.spineById[section.idref] = 0;
|
||||
|
||||
// Re-index
|
||||
this.spineItems.forEach(function(item, index){
|
||||
item.index = index;
|
||||
});
|
||||
// Re-index
|
||||
this.spineItems.forEach(function(item, index){
|
||||
item.index = index;
|
||||
});
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
};
|
||||
|
||||
Spine.prototype.insert = function(section, index) {
|
||||
|
@ -119,14 +119,14 @@ Spine.prototype.insert = function(section, index) {
|
|||
};
|
||||
|
||||
Spine.prototype.remove = function(section) {
|
||||
var index = this.spineItems.indexOf(section);
|
||||
var index = this.spineItems.indexOf(section);
|
||||
|
||||
if(index > -1) {
|
||||
delete this.spineByHref[section.href];
|
||||
delete this.spineById[section.idref];
|
||||
if(index > -1) {
|
||||
delete this.spineByHref[section.href];
|
||||
delete this.spineById[section.idref];
|
||||
|
||||
return this.spineItems.splice(index, 1);
|
||||
}
|
||||
return this.spineItems.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
Spine.prototype.each = function() {
|
||||
|
|
|
@ -20,7 +20,7 @@ Stage.prototype.create = function(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";
|
||||
var axis = options.axis || "vertical";
|
||||
|
||||
if(options.height && core.isNumber(options.height)) {
|
||||
height = options.height + "px";
|
||||
|
@ -223,7 +223,7 @@ Stage.prototype.addStyleRules = function(selector, rulesArray){
|
|||
}
|
||||
})
|
||||
|
||||
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
|
||||
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
182
src/unarchive.js
182
src/unarchive.js
|
@ -6,100 +6,100 @@ var mime = require('../libs/mime/mime');
|
|||
|
||||
function Unarchive() {
|
||||
|
||||
this.checkRequirements();
|
||||
this.urlCache = {};
|
||||
this.checkRequirements();
|
||||
this.urlCache = {};
|
||||
|
||||
}
|
||||
|
||||
Unarchive.prototype.checkRequirements = function(callback){
|
||||
try {
|
||||
if (typeof JSZip !== 'undefined') {
|
||||
this.zip = new JSZip();
|
||||
} else {
|
||||
JSZip = require('jszip');
|
||||
this.zip = new JSZip();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("JSZip lib not loaded");
|
||||
}
|
||||
try {
|
||||
if (typeof JSZip !== 'undefined') {
|
||||
this.zip = new JSZip();
|
||||
} else {
|
||||
JSZip = require('jszip');
|
||||
this.zip = new JSZip();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("JSZip lib not loaded");
|
||||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.open = function(zipUrl, isBase64){
|
||||
if (zipUrl instanceof ArrayBuffer || isBase64) {
|
||||
return this.zip.loadAsync(zipUrl, {"base64": isBase64});
|
||||
return this.zip.loadAsync(zipUrl, {"base64": isBase64});
|
||||
} else {
|
||||
return request(zipUrl, "binary")
|
||||
.then(function(data){
|
||||
return this.zip.loadAsync(data);
|
||||
}.bind(this));
|
||||
.then(function(data){
|
||||
return this.zip.loadAsync(data);
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.request = function(url, type){
|
||||
var deferred = new RSVP.defer();
|
||||
var response;
|
||||
var r;
|
||||
var deferred = new RSVP.defer();
|
||||
var response;
|
||||
var r;
|
||||
|
||||
// If type isn't set, determine it from the file extension
|
||||
// If type isn't set, determine it from the file extension
|
||||
if(!type) {
|
||||
uri = URI(url);
|
||||
type = uri.suffix();
|
||||
}
|
||||
|
||||
if(type == 'blob'){
|
||||
response = this.getBlob(url);
|
||||
} else {
|
||||
response = this.getText(url);
|
||||
}
|
||||
if(type == 'blob'){
|
||||
response = this.getBlob(url);
|
||||
} else {
|
||||
response = this.getText(url);
|
||||
}
|
||||
|
||||
if (response) {
|
||||
response.then(function (r) {
|
||||
result = this.handleResponse(r, type);
|
||||
deferred.resolve(result);
|
||||
}.bind(this));
|
||||
} else {
|
||||
deferred.reject({
|
||||
message : "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
if (response) {
|
||||
response.then(function (r) {
|
||||
result = this.handleResponse(r, type);
|
||||
deferred.resolve(result);
|
||||
}.bind(this));
|
||||
} else {
|
||||
deferred.reject({
|
||||
message : "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
});
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
Unarchive.prototype.handleResponse = function(response, type){
|
||||
var r;
|
||||
var r;
|
||||
|
||||
if(type == "json") {
|
||||
r = JSON.parse(response);
|
||||
}
|
||||
else
|
||||
if(core.isXml(type)) {
|
||||
r = core.parse(response, "text/xml");
|
||||
if(type == "json") {
|
||||
r = JSON.parse(response);
|
||||
}
|
||||
else
|
||||
else
|
||||
if(core.isXml(type)) {
|
||||
r = core.parse(response, "text/xml");
|
||||
}
|
||||
else
|
||||
if(type == 'xhtml') {
|
||||
r = core.parse(response, "application/xhtml+xml");
|
||||
r = core.parse(response, "application/xhtml+xml");
|
||||
}
|
||||
else
|
||||
else
|
||||
if(type == 'html' || type == 'htm') {
|
||||
r = core.parse(response, "text/html");
|
||||
} else {
|
||||
r = response;
|
||||
}
|
||||
r = core.parse(response, "text/html");
|
||||
} else {
|
||||
r = response;
|
||||
}
|
||||
|
||||
return r;
|
||||
return r;
|
||||
};
|
||||
|
||||
Unarchive.prototype.getBlob = function(url, _mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
var mimeType;
|
||||
var mimeType;
|
||||
|
||||
if(entry) {
|
||||
mimeType = _mimeType || mime.lookup(entry.name);
|
||||
return entry.async("uint8array").then(function(uint8array) {
|
||||
return new Blob([uint8array], {type : mimeType});
|
||||
});
|
||||
mimeType = _mimeType || mime.lookup(entry.name);
|
||||
return entry.async("uint8array").then(function(uint8array) {
|
||||
return new Blob([uint8array], {type : mimeType});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -108,22 +108,22 @@ Unarchive.prototype.getText = function(url, encoding){
|
|||
var entry = this.zip.file(decodededUrl);
|
||||
|
||||
if(entry) {
|
||||
return entry.async("string").then(function(text) {
|
||||
return text;
|
||||
});
|
||||
return entry.async("string").then(function(text) {
|
||||
return text;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.getBase64 = function(url, _mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
var mimeType;
|
||||
var mimeType;
|
||||
|
||||
if(entry) {
|
||||
mimeType = _mimeType || mime.lookup(entry.name);
|
||||
return entry.async("base64").then(function(data) {
|
||||
return "data:" + mimeType + ";base64," + data;
|
||||
});
|
||||
mimeType = _mimeType || mime.lookup(entry.name);
|
||||
return entry.async("base64").then(function(data) {
|
||||
return "data:" + mimeType + ";base64," + data;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -131,51 +131,51 @@ Unarchive.prototype.createUrl = function(url, options){
|
|||
var deferred = new RSVP.defer();
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var tempUrl;
|
||||
var blob;
|
||||
var blob;
|
||||
var response;
|
||||
var useBase64 = options && options.base64;
|
||||
var useBase64 = options && options.base64;
|
||||
|
||||
if(url in this.urlCache) {
|
||||
deferred.resolve(this.urlCache[url]);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
if (useBase64) {
|
||||
response = this.getBase64(url);
|
||||
if (useBase64) {
|
||||
response = this.getBase64(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(tempUrl) {
|
||||
if (response) {
|
||||
response.then(function(tempUrl) {
|
||||
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
response = this.getBlob(url);
|
||||
response = this.getBlob(url);
|
||||
|
||||
if (response) {
|
||||
response.then(function(blob) {
|
||||
if (response) {
|
||||
response.then(function(blob) {
|
||||
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
tempUrl = _URL.createObjectURL(blob);
|
||||
this.urlCache[url] = tempUrl;
|
||||
deferred.resolve(tempUrl);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!response) {
|
||||
deferred.reject({
|
||||
message : "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
});
|
||||
}
|
||||
if (!response) {
|
||||
deferred.reject({
|
||||
message : "File not found in the epub: " + url,
|
||||
stack : new Error().stack
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
|
136
src/views.js
136
src/views.js
|
@ -1,8 +1,8 @@
|
|||
function Views(container) {
|
||||
this.container = container;
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
this.hidden = false;
|
||||
this.container = container;
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
this.hidden = false;
|
||||
};
|
||||
|
||||
Views.prototype.all = function() {
|
||||
|
@ -31,35 +31,35 @@ Views.prototype.get = function(i) {
|
|||
|
||||
Views.prototype.append = function(view){
|
||||
this._views.push(view);
|
||||
if(this.container){
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
if(this.container){
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
|
||||
Views.prototype.prepend = function(view){
|
||||
this._views.unshift(view);
|
||||
if(this.container){
|
||||
this.container.insertBefore(view.element, this.container.firstChild);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
if(this.container){
|
||||
this.container.insertBefore(view.element, this.container.firstChild);
|
||||
}
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
|
||||
Views.prototype.insert = function(view, index) {
|
||||
this._views.splice(index, 0, view);
|
||||
|
||||
if(this.container){
|
||||
if(index < this.container.children.length){
|
||||
this.container.insertBefore(view.element, this.container.children[index]);
|
||||
} else {
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
}
|
||||
if(this.container){
|
||||
if(index < this.container.children.length){
|
||||
this.container.insertBefore(view.element, this.container.children[index]);
|
||||
} else {
|
||||
this.container.appendChild(view.element);
|
||||
}
|
||||
}
|
||||
|
||||
this.length++;
|
||||
return view;
|
||||
this.length++;
|
||||
return view;
|
||||
};
|
||||
|
||||
Views.prototype.remove = function(view) {
|
||||
|
@ -72,7 +72,7 @@ Views.prototype.remove = function(view) {
|
|||
|
||||
this.destroy(view);
|
||||
|
||||
this.length--;
|
||||
this.length--;
|
||||
};
|
||||
|
||||
Views.prototype.destroy = function(view) {
|
||||
|
@ -82,9 +82,9 @@ Views.prototype.destroy = function(view) {
|
|||
view.destroy();
|
||||
}
|
||||
|
||||
if(this.container){
|
||||
this.container.removeChild(view.element);
|
||||
}
|
||||
if(this.container){
|
||||
this.container.removeChild(view.element);
|
||||
}
|
||||
view = null;
|
||||
};
|
||||
|
||||
|
@ -96,72 +96,72 @@ Views.prototype.each = function() {
|
|||
|
||||
Views.prototype.clear = function(){
|
||||
// Remove all views
|
||||
var view;
|
||||
var len = this.length;
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
if(!this.length) return;
|
||||
if(!this.length) return;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
this.destroy(view);
|
||||
}
|
||||
}
|
||||
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
this._views = [];
|
||||
this.length = 0;
|
||||
};
|
||||
|
||||
Views.prototype.find = function(section){
|
||||
|
||||
var view;
|
||||
var len = this.length;
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed && view.section.index == section.index) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Views.prototype.displayed = function(){
|
||||
var displayed = [];
|
||||
var view;
|
||||
var len = this.length;
|
||||
var displayed = [];
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
displayed.push(view);
|
||||
}
|
||||
}
|
||||
return displayed;
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
displayed.push(view);
|
||||
}
|
||||
}
|
||||
return displayed;
|
||||
};
|
||||
|
||||
Views.prototype.show = function(){
|
||||
var view;
|
||||
var len = this.length;
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
view.show();
|
||||
}
|
||||
}
|
||||
this.hidden = false;
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
view.show();
|
||||
}
|
||||
}
|
||||
this.hidden = false;
|
||||
};
|
||||
|
||||
Views.prototype.hide = function(){
|
||||
var view;
|
||||
var len = this.length;
|
||||
var view;
|
||||
var len = this.length;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
view.hide();
|
||||
}
|
||||
}
|
||||
this.hidden = true;
|
||||
for (var i = 0; i < len; i++) {
|
||||
view = this._views[i];
|
||||
if(view.displayed){
|
||||
view.hide();
|
||||
}
|
||||
}
|
||||
this.hidden = true;
|
||||
};
|
||||
|
||||
module.exports = Views;
|
||||
|
|
|
@ -4,110 +4,110 @@ var EpubCFI = require('../epubcfi');
|
|||
var Contents = require('../contents');
|
||||
|
||||
function IframeView(section, options) {
|
||||
this.settings = core.extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
height: 0,
|
||||
layout: undefined,
|
||||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
this.settings = core.extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
height: 0,
|
||||
layout: undefined,
|
||||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
|
||||
this.id = "epubjs-view-" + core.uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
this.id = "epubjs-view-" + core.uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
|
||||
this.element = this.container(this.settings.axis);
|
||||
this.element = this.container(this.settings.axis);
|
||||
|
||||
this.added = false;
|
||||
this.displayed = false;
|
||||
this.rendered = false;
|
||||
this.added = false;
|
||||
this.displayed = false;
|
||||
this.rendered = false;
|
||||
|
||||
this.width = this.settings.width;
|
||||
this.height = this.settings.height;
|
||||
this.width = this.settings.width;
|
||||
this.height = this.settings.height;
|
||||
|
||||
this.fixedWidth = 0;
|
||||
this.fixedHeight = 0;
|
||||
this.fixedWidth = 0;
|
||||
this.fixedHeight = 0;
|
||||
|
||||
// Blank Cfi for Parsing
|
||||
this.epubcfi = new EpubCFI();
|
||||
// Blank Cfi for Parsing
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
};
|
||||
|
||||
IframeView.prototype.container = function(axis) {
|
||||
var element = document.createElement('div');
|
||||
var element = document.createElement('div');
|
||||
|
||||
element.classList.add("epub-view");
|
||||
element.classList.add("epub-view");
|
||||
|
||||
// this.element.style.minHeight = "100px";
|
||||
element.style.height = "0px";
|
||||
element.style.width = "0px";
|
||||
element.style.overflow = "hidden";
|
||||
// this.element.style.minHeight = "100px";
|
||||
element.style.height = "0px";
|
||||
element.style.width = "0px";
|
||||
element.style.overflow = "hidden";
|
||||
|
||||
if(axis && axis == "horizontal"){
|
||||
element.style.display = "inline-block";
|
||||
} else {
|
||||
element.style.display = "block";
|
||||
}
|
||||
if(axis && axis == "horizontal"){
|
||||
element.style.display = "inline-block";
|
||||
} else {
|
||||
element.style.display = "block";
|
||||
}
|
||||
|
||||
return element;
|
||||
return element;
|
||||
};
|
||||
|
||||
IframeView.prototype.create = function() {
|
||||
|
||||
if(this.iframe) {
|
||||
return this.iframe;
|
||||
}
|
||||
if(this.iframe) {
|
||||
return this.iframe;
|
||||
}
|
||||
|
||||
if(!this.element) {
|
||||
this.element = this.createContainer();
|
||||
}
|
||||
if(!this.element) {
|
||||
this.element = this.createContainer();
|
||||
}
|
||||
|
||||
this.iframe = document.createElement('iframe');
|
||||
this.iframe.id = this.id;
|
||||
this.iframe.scrolling = "no"; // Might need to be removed: breaks ios width calculations
|
||||
this.iframe.style.overflow = "hidden";
|
||||
this.iframe.seamless = "seamless";
|
||||
// Back up if seamless isn't supported
|
||||
this.iframe.style.border = "none";
|
||||
this.iframe = document.createElement('iframe');
|
||||
this.iframe.id = this.id;
|
||||
this.iframe.scrolling = "no"; // Might need to be removed: breaks ios width calculations
|
||||
this.iframe.style.overflow = "hidden";
|
||||
this.iframe.seamless = "seamless";
|
||||
// Back up if seamless isn't supported
|
||||
this.iframe.style.border = "none";
|
||||
|
||||
this.resizing = true;
|
||||
this.resizing = true;
|
||||
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
|
||||
this.iframe.style.width = "0";
|
||||
this.iframe.style.height = "0";
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this.iframe.style.width = "0";
|
||||
this.iframe.style.height = "0";
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
|
||||
this.element.appendChild(this.iframe);
|
||||
this.added = true;
|
||||
this.element.appendChild(this.iframe);
|
||||
this.added = true;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = core.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);
|
||||
// }
|
||||
// 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);
|
||||
// }
|
||||
|
||||
// Firefox has trouble with baseURI and srcdoc
|
||||
// TODO: Disable for now in firefox
|
||||
// Firefox has trouble with baseURI and srcdoc
|
||||
// TODO: Disable for now in firefox
|
||||
|
||||
if(!!("srcdoc" in this.iframe)) {
|
||||
this.supportsSrcdoc = true;
|
||||
} else {
|
||||
this.supportsSrcdoc = false;
|
||||
}
|
||||
if(!!("srcdoc" in this.iframe)) {
|
||||
this.supportsSrcdoc = true;
|
||||
} else {
|
||||
this.supportsSrcdoc = false;
|
||||
}
|
||||
|
||||
return this.iframe;
|
||||
return this.iframe;
|
||||
};
|
||||
|
||||
IframeView.prototype.render = function(request, show) {
|
||||
|
@ -116,11 +116,11 @@ IframeView.prototype.render = function(request, show) {
|
|||
this.create();
|
||||
|
||||
// Fit to size of the container, apply padding
|
||||
this.size();
|
||||
this.size();
|
||||
|
||||
if(!this.sectionRender) {
|
||||
this.sectionRender = this.section.render(request);
|
||||
}
|
||||
if(!this.sectionRender) {
|
||||
this.sectionRender = this.section.render(request);
|
||||
}
|
||||
|
||||
// Render Chain
|
||||
return this.sectionRender
|
||||
|
@ -142,14 +142,14 @@ IframeView.prototype.render = function(request, show) {
|
|||
// }.bind(this))
|
||||
.then(function(){
|
||||
|
||||
// apply the layout function to the contents
|
||||
this.settings.layout.format(this.contents);
|
||||
// apply the layout function to the contents
|
||||
this.settings.layout.format(this.contents);
|
||||
|
||||
// Expand the iframe to the full size of the content
|
||||
this.expand();
|
||||
// Expand the iframe to the full size of the content
|
||||
this.expand();
|
||||
|
||||
// Listen for events that require an expansion of the iframe
|
||||
this.addListeners();
|
||||
// Listen for events that require an expansion of the iframe
|
||||
this.addListeners();
|
||||
|
||||
if(show !== false) {
|
||||
//this.q.enqueue(function(view){
|
||||
|
@ -169,12 +169,12 @@ IframeView.prototype.render = function(request, show) {
|
|||
|
||||
// Determine locks base on settings
|
||||
IframeView.prototype.size = function(_width, _height) {
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
|
||||
if(this.layout.name === "pre-paginated") {
|
||||
this.lock("both", width, height);
|
||||
} else if(this.settings.axis === "horizontal") {
|
||||
if(this.layout.name === "pre-paginated") {
|
||||
this.lock("both", width, height);
|
||||
} else if(this.settings.axis === "horizontal") {
|
||||
this.lock("height", width, height);
|
||||
} else {
|
||||
this.lock("width", width, height);
|
||||
|
@ -184,41 +184,41 @@ 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);
|
||||
var iframeBorders;
|
||||
var elBorders = core.borders(this.element);
|
||||
var iframeBorders;
|
||||
|
||||
if(this.iframe) {
|
||||
iframeBorders = core.borders(this.iframe);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
if(this.iframe) {
|
||||
iframeBorders = core.borders(this.iframe);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
}
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(width, this.lockedHeight);
|
||||
}
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(width, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(this.displayed && this.iframe) {
|
||||
if(this.displayed && this.iframe) {
|
||||
|
||||
// this.contents.layout();
|
||||
this.expand();
|
||||
// this.contents.layout();
|
||||
this.expand();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -226,209 +226,209 @@ IframeView.prototype.lock = function(what, width, height) {
|
|||
|
||||
// Resize a single axis based on content dimensions
|
||||
IframeView.prototype.expand = function(force) {
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
var columns;
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
var columns;
|
||||
|
||||
var textWidth, textHeight;
|
||||
var textWidth, textHeight;
|
||||
|
||||
if(!this.iframe || this._expanding) return;
|
||||
if(!this.iframe || this._expanding) return;
|
||||
|
||||
this._expanding = true;
|
||||
this._expanding = true;
|
||||
|
||||
// Expand Horizontally
|
||||
// if(height && !width) {
|
||||
if(this.settings.axis === "horizontal") {
|
||||
// Get the width of the text
|
||||
textWidth = this.contents.textWidth();
|
||||
// Check if the textWidth has changed
|
||||
if(textWidth != this._textWidth){
|
||||
// Get the contentWidth by resizing the iframe
|
||||
// Check with a min reset of the textWidth
|
||||
width = this.contentWidth(textWidth);
|
||||
// Expand Horizontally
|
||||
// if(height && !width) {
|
||||
if(this.settings.axis === "horizontal") {
|
||||
// Get the width of the text
|
||||
textWidth = this.contents.textWidth();
|
||||
// Check if the textWidth has changed
|
||||
if(textWidth != this._textWidth){
|
||||
// Get the contentWidth by resizing the iframe
|
||||
// Check with a min reset of the textWidth
|
||||
width = this.contentWidth(textWidth);
|
||||
|
||||
columns = Math.ceil(width / (this.settings.layout.columnWidth + this.settings.layout.gap));
|
||||
columns = Math.ceil(width / (this.settings.layout.columnWidth + this.settings.layout.gap));
|
||||
|
||||
if ( this.settings.layout.divisor > 1 &&
|
||||
this.settings.layout.name === "reflowable" &&
|
||||
(columns % 2 > 0)) {
|
||||
// add a blank page
|
||||
width += this.settings.layout.gap + this.settings.layout.columnWidth;
|
||||
}
|
||||
if ( this.settings.layout.divisor > 1 &&
|
||||
this.settings.layout.name === "reflowable" &&
|
||||
(columns % 2 > 0)) {
|
||||
// add a blank page
|
||||
width += this.settings.layout.gap + this.settings.layout.columnWidth;
|
||||
}
|
||||
|
||||
// Save the textWdith
|
||||
this._textWidth = textWidth;
|
||||
// Save the contentWidth
|
||||
this._contentWidth = width;
|
||||
} else {
|
||||
// Otherwise assume content height hasn't changed
|
||||
width = this._contentWidth;
|
||||
}
|
||||
} // Expand Vertically
|
||||
else if(this.settings.axis === "vertical") {
|
||||
textHeight = this.contents.textHeight();
|
||||
if(textHeight != this._textHeight){
|
||||
height = this.contentHeight(textHeight);
|
||||
this._textHeight = textHeight;
|
||||
this._contentHeight = height;
|
||||
} else {
|
||||
height = this._contentHeight;
|
||||
}
|
||||
// Save the textWdith
|
||||
this._textWidth = textWidth;
|
||||
// Save the contentWidth
|
||||
this._contentWidth = width;
|
||||
} else {
|
||||
// Otherwise assume content height hasn't changed
|
||||
width = this._contentWidth;
|
||||
}
|
||||
} // Expand Vertically
|
||||
else if(this.settings.axis === "vertical") {
|
||||
textHeight = this.contents.textHeight();
|
||||
if(textHeight != this._textHeight){
|
||||
height = this.contentHeight(textHeight);
|
||||
this._textHeight = textHeight;
|
||||
this._contentHeight = height;
|
||||
} else {
|
||||
height = this._contentHeight;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Only Resize if dimensions have changed or
|
||||
// if Frame is still hidden, so needs reframing
|
||||
if(this._needsReframe || width != this._width || height != this._height){
|
||||
this.resize(width, height);
|
||||
}
|
||||
// Only Resize if dimensions have changed or
|
||||
// if Frame is still hidden, so needs reframing
|
||||
if(this._needsReframe || width != this._width || height != this._height){
|
||||
this.resize(width, height);
|
||||
}
|
||||
|
||||
this._expanding = false;
|
||||
this._expanding = false;
|
||||
};
|
||||
|
||||
IframeView.prototype.contentWidth = function(min) {
|
||||
var prev;
|
||||
var width;
|
||||
var prev;
|
||||
var width;
|
||||
|
||||
// Save previous width
|
||||
prev = this.iframe.style.width;
|
||||
// Set the iframe size to min, width will only ever be greater
|
||||
// Will preserve the aspect ratio
|
||||
this.iframe.style.width = (min || 0) + "px";
|
||||
// Get the scroll overflow width
|
||||
width = this.contents.scrollWidth();
|
||||
// Reset iframe size back
|
||||
this.iframe.style.width = prev;
|
||||
return width;
|
||||
// Save previous width
|
||||
prev = this.iframe.style.width;
|
||||
// Set the iframe size to min, width will only ever be greater
|
||||
// Will preserve the aspect ratio
|
||||
this.iframe.style.width = (min || 0) + "px";
|
||||
// Get the scroll overflow width
|
||||
width = this.contents.scrollWidth();
|
||||
// Reset iframe size back
|
||||
this.iframe.style.width = prev;
|
||||
return width;
|
||||
};
|
||||
|
||||
IframeView.prototype.contentHeight = function(min) {
|
||||
var prev;
|
||||
var height;
|
||||
var prev;
|
||||
var height;
|
||||
|
||||
prev = this.iframe.style.height;
|
||||
this.iframe.style.height = (min || 0) + "px";
|
||||
height = this.contents.scrollHeight();
|
||||
prev = this.iframe.style.height;
|
||||
this.iframe.style.height = (min || 0) + "px";
|
||||
height = this.contents.scrollHeight();
|
||||
|
||||
this.iframe.style.height = prev;
|
||||
return height;
|
||||
this.iframe.style.height = prev;
|
||||
return height;
|
||||
};
|
||||
|
||||
|
||||
IframeView.prototype.resize = function(width, height) {
|
||||
|
||||
if(!this.iframe) return;
|
||||
if(!this.iframe) return;
|
||||
|
||||
if(core.isNumber(width)){
|
||||
this.iframe.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
if(core.isNumber(width)){
|
||||
this.iframe.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
this.iframe.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
if(core.isNumber(height)){
|
||||
this.iframe.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
|
||||
this.iframeBounds = core.bounds(this.iframe);
|
||||
this.iframeBounds = core.bounds(this.iframe);
|
||||
|
||||
this.reframe(this.iframeBounds.width, this.iframeBounds.height);
|
||||
this.reframe(this.iframeBounds.width, this.iframeBounds.height);
|
||||
|
||||
};
|
||||
|
||||
IframeView.prototype.reframe = function(width, height) {
|
||||
var size;
|
||||
var size;
|
||||
|
||||
// if(!this.displayed) {
|
||||
// this._needsReframe = true;
|
||||
// return;
|
||||
// }
|
||||
if(core.isNumber(width)){
|
||||
this.element.style.width = width + "px";
|
||||
}
|
||||
// if(!this.displayed) {
|
||||
// this._needsReframe = true;
|
||||
// return;
|
||||
// }
|
||||
if(core.isNumber(width)){
|
||||
this.element.style.width = width + "px";
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
this.element.style.height = height + "px";
|
||||
}
|
||||
if(core.isNumber(height)){
|
||||
this.element.style.height = height + "px";
|
||||
}
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
height: this.elementBounds.height,
|
||||
widthDelta: this.elementBounds.width - this.prevBounds.width,
|
||||
heightDelta: this.elementBounds.height - this.prevBounds.height,
|
||||
};
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
height: this.elementBounds.height,
|
||||
widthDelta: this.elementBounds.width - this.prevBounds.width,
|
||||
heightDelta: this.elementBounds.height - this.prevBounds.height,
|
||||
};
|
||||
|
||||
this.onResize(this, size);
|
||||
this.onResize(this, size);
|
||||
|
||||
this.trigger("resized", size);
|
||||
this.trigger("resized", size);
|
||||
|
||||
};
|
||||
|
||||
|
||||
IframeView.prototype.load = function(contents) {
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
|
||||
if(!this.iframe) {
|
||||
loading.reject(new Error("No Iframe Available"));
|
||||
return loaded;
|
||||
}
|
||||
if(!this.iframe) {
|
||||
loading.reject(new Error("No Iframe Available"));
|
||||
return loaded;
|
||||
}
|
||||
|
||||
this.iframe.onload = function(event) {
|
||||
this.iframe.onload = function(event) {
|
||||
|
||||
this.onLoad(event, loading);
|
||||
this.onLoad(event, loading);
|
||||
|
||||
}.bind(this);
|
||||
}.bind(this);
|
||||
|
||||
if(this.supportsSrcdoc){
|
||||
this.iframe.srcdoc = contents;
|
||||
} else {
|
||||
if(this.supportsSrcdoc){
|
||||
this.iframe.srcdoc = contents;
|
||||
} else {
|
||||
|
||||
this.document = this.iframe.contentDocument;
|
||||
this.document = this.iframe.contentDocument;
|
||||
|
||||
if(!this.document) {
|
||||
loading.reject(new Error("No Document Available"));
|
||||
return loaded;
|
||||
}
|
||||
if(!this.document) {
|
||||
loading.reject(new Error("No Document Available"));
|
||||
return loaded;
|
||||
}
|
||||
|
||||
this.iframe.contentDocument.open();
|
||||
this.iframe.contentDocument.write(contents);
|
||||
this.iframe.contentDocument.close();
|
||||
this.iframe.contentDocument.open();
|
||||
this.iframe.contentDocument.write(contents);
|
||||
this.iframe.contentDocument.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return loaded;
|
||||
return loaded;
|
||||
};
|
||||
|
||||
IframeView.prototype.onLoad = function(event, promise) {
|
||||
|
||||
this.window = this.iframe.contentWindow;
|
||||
this.document = this.iframe.contentDocument;
|
||||
this.window = this.iframe.contentWindow;
|
||||
this.document = this.iframe.contentDocument;
|
||||
|
||||
this.contents = new Contents(this.document, this.document.body, this.section.cfiBase);
|
||||
this.contents = new Contents(this.document, this.document.body, this.section.cfiBase);
|
||||
|
||||
this.rendering = false;
|
||||
this.rendering = false;
|
||||
|
||||
var link = this.document.querySelector("link[rel='canonical']");
|
||||
if (link) {
|
||||
link.setAttribute("href", this.section.url);
|
||||
} else {
|
||||
link = this.document.createElement("link");
|
||||
link.setAttribute("rel", "canonical");
|
||||
link.setAttribute("href", this.section.url);
|
||||
this.document.querySelector("head").appendChild(link);
|
||||
}
|
||||
var link = this.document.querySelector("link[rel='canonical']");
|
||||
if (link) {
|
||||
link.setAttribute("href", this.section.url);
|
||||
} else {
|
||||
link = this.document.createElement("link");
|
||||
link.setAttribute("rel", "canonical");
|
||||
link.setAttribute("href", this.section.url);
|
||||
this.document.querySelector("head").appendChild(link);
|
||||
}
|
||||
|
||||
this.contents.on("expand", function () {
|
||||
if(this.displayed && this.iframe) {
|
||||
this.expand();
|
||||
}
|
||||
});
|
||||
this.contents.on("expand", function () {
|
||||
if(this.displayed && this.iframe) {
|
||||
this.expand();
|
||||
}
|
||||
});
|
||||
|
||||
promise.resolve(this.contents);
|
||||
promise.resolve(this.contents);
|
||||
};
|
||||
|
||||
|
||||
|
@ -455,118 +455,118 @@ IframeView.prototype.onLoad = function(event, promise) {
|
|||
// };
|
||||
|
||||
IframeView.prototype.setLayout = function(layout) {
|
||||
this.layout = layout;
|
||||
this.layout = layout;
|
||||
};
|
||||
|
||||
IframeView.prototype.setAxis = function(axis) {
|
||||
this.settings.axis = axis;
|
||||
this.settings.axis = axis;
|
||||
};
|
||||
|
||||
IframeView.prototype.resizeListenters = function() {
|
||||
// Test size again
|
||||
clearTimeout(this.expanding);
|
||||
this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
// Test size again
|
||||
clearTimeout(this.expanding);
|
||||
this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
};
|
||||
|
||||
IframeView.prototype.addListeners = function() {
|
||||
//TODO: Add content listeners for expanding
|
||||
//TODO: Add content listeners for expanding
|
||||
};
|
||||
|
||||
IframeView.prototype.removeListeners = function(layoutFunc) {
|
||||
//TODO: remove content listeners for expanding
|
||||
//TODO: remove content listeners for expanding
|
||||
};
|
||||
|
||||
IframeView.prototype.display = function(request) {
|
||||
var displayed = new RSVP.defer();
|
||||
var displayed = new RSVP.defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
if (!this.displayed) {
|
||||
|
||||
this.render(request).then(function () {
|
||||
this.render(request).then(function () {
|
||||
|
||||
this.trigger("displayed", this);
|
||||
this.onDisplayed(this);
|
||||
this.trigger("displayed", this);
|
||||
this.onDisplayed(this);
|
||||
|
||||
this.displayed = true;
|
||||
displayed.resolve(this);
|
||||
this.displayed = true;
|
||||
displayed.resolve(this);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
|
||||
|
||||
return displayed.promise;
|
||||
return displayed.promise;
|
||||
};
|
||||
|
||||
IframeView.prototype.show = function() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
if(this.iframe){
|
||||
this.iframe.style.visibility = "visible";
|
||||
}
|
||||
if(this.iframe){
|
||||
this.iframe.style.visibility = "visible";
|
||||
}
|
||||
|
||||
this.trigger("shown", this);
|
||||
this.trigger("shown", this);
|
||||
};
|
||||
|
||||
IframeView.prototype.hide = function() {
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
// this.iframe.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.iframe.style.visibility = "hidden";
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.trigger("hidden", this);
|
||||
this.stopExpanding = true;
|
||||
this.trigger("hidden", this);
|
||||
};
|
||||
|
||||
IframeView.prototype.position = function() {
|
||||
return this.element.getBoundingClientRect();
|
||||
return this.element.getBoundingClientRect();
|
||||
};
|
||||
|
||||
IframeView.prototype.locationOf = function(target) {
|
||||
var parentPos = this.iframe.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
var parentPos = this.iframe.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
return {
|
||||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
return {
|
||||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
};
|
||||
|
||||
IframeView.prototype.onDisplayed = function(view) {
|
||||
// Stub, override with a custom functions
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
|
||||
IframeView.prototype.onResize = function(view, e) {
|
||||
// Stub, override with a custom functions
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
|
||||
IframeView.prototype.bounds = function() {
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
};
|
||||
|
||||
IframeView.prototype.destroy = function() {
|
||||
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
|
||||
this.removeListeners();
|
||||
this.removeListeners();
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.element.removeChild(this.iframe);
|
||||
this.displayed = false;
|
||||
this.iframe = null;
|
||||
this.stopExpanding = true;
|
||||
this.element.removeChild(this.iframe);
|
||||
this.displayed = false;
|
||||
this.iframe = null;
|
||||
|
||||
this._textWidth = null;
|
||||
this._textHeight = null;
|
||||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
this._textWidth = null;
|
||||
this._textHeight = null;
|
||||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
};
|
||||
|
||||
RSVP.EventTarget.mixin(IframeView.prototype);
|
||||
|
|
|
@ -5,103 +5,103 @@ var Contents = require('../contents');
|
|||
var URI = require('urijs');
|
||||
|
||||
function InlineView(section, options) {
|
||||
this.settings = core.extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
height: 0,
|
||||
layout: undefined,
|
||||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
this.settings = core.extend({
|
||||
ignoreClass : '',
|
||||
axis: 'vertical',
|
||||
width: 0,
|
||||
height: 0,
|
||||
layout: undefined,
|
||||
globalLayoutProperties: {},
|
||||
}, options || {});
|
||||
|
||||
this.id = "epubjs-view:" + core.uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
this.id = "epubjs-view:" + core.uuid();
|
||||
this.section = section;
|
||||
this.index = section.index;
|
||||
|
||||
this.element = this.container(this.settings.axis);
|
||||
this.element = this.container(this.settings.axis);
|
||||
|
||||
this.added = false;
|
||||
this.displayed = false;
|
||||
this.rendered = false;
|
||||
this.added = false;
|
||||
this.displayed = false;
|
||||
this.rendered = false;
|
||||
|
||||
this.width = this.settings.width;
|
||||
this.height = this.settings.height;
|
||||
this.width = this.settings.width;
|
||||
this.height = this.settings.height;
|
||||
|
||||
this.fixedWidth = 0;
|
||||
this.fixedHeight = 0;
|
||||
this.fixedWidth = 0;
|
||||
this.fixedHeight = 0;
|
||||
|
||||
// Blank Cfi for Parsing
|
||||
this.epubcfi = new EpubCFI();
|
||||
// Blank Cfi for Parsing
|
||||
this.epubcfi = new EpubCFI();
|
||||
|
||||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
this.layout = this.settings.layout;
|
||||
// Dom events to listen for
|
||||
// this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart"];
|
||||
|
||||
};
|
||||
|
||||
InlineView.prototype.container = function(axis) {
|
||||
var element = document.createElement('div');
|
||||
var element = document.createElement('div');
|
||||
|
||||
element.classList.add("epub-view");
|
||||
element.classList.add("epub-view");
|
||||
|
||||
// if(this.settings.axis === "horizontal") {
|
||||
// element.style.width = "auto";
|
||||
// element.style.height = "0";
|
||||
// if(this.settings.axis === "horizontal") {
|
||||
// element.style.width = "auto";
|
||||
// element.style.height = "0";
|
||||
// } else {
|
||||
// element.style.width = "0";
|
||||
// element.style.height = "auto";
|
||||
// element.style.width = "0";
|
||||
// element.style.height = "auto";
|
||||
// }
|
||||
|
||||
element.style.overflow = "hidden";
|
||||
element.style.overflow = "hidden";
|
||||
|
||||
if(axis && axis == "horizontal"){
|
||||
element.style.display = "inline-block";
|
||||
} else {
|
||||
element.style.display = "block";
|
||||
}
|
||||
if(axis && axis == "horizontal"){
|
||||
element.style.display = "inline-block";
|
||||
} else {
|
||||
element.style.display = "block";
|
||||
}
|
||||
|
||||
return element;
|
||||
return element;
|
||||
};
|
||||
|
||||
InlineView.prototype.create = function() {
|
||||
|
||||
if(this.frame) {
|
||||
return this.frame;
|
||||
}
|
||||
|
||||
if(!this.element) {
|
||||
this.element = this.createContainer();
|
||||
}
|
||||
|
||||
this.frame = document.createElement('div');
|
||||
this.frame.id = this.id;
|
||||
this.frame.style.overflow = "hidden";
|
||||
this.frame.style.wordSpacing = "initial";
|
||||
this.frame.style.lineHeight = "initial";
|
||||
|
||||
this.resizing = true;
|
||||
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
if(this.settings.axis === "horizontal") {
|
||||
this.frame.style.width = "auto";
|
||||
this.frame.style.height = "0";
|
||||
} else {
|
||||
this.frame.style.width = "0";
|
||||
this.frame.style.height = "auto";
|
||||
if(this.frame) {
|
||||
return this.frame;
|
||||
}
|
||||
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
if(!this.element) {
|
||||
this.element = this.createContainer();
|
||||
}
|
||||
|
||||
this.element.appendChild(this.frame);
|
||||
this.added = true;
|
||||
this.frame = document.createElement('div');
|
||||
this.frame.id = this.id;
|
||||
this.frame.style.overflow = "hidden";
|
||||
this.frame.style.wordSpacing = "initial";
|
||||
this.frame.style.lineHeight = "initial";
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.resizing = true;
|
||||
|
||||
return this.frame;
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
if(this.settings.axis === "horizontal") {
|
||||
this.frame.style.width = "auto";
|
||||
this.frame.style.height = "0";
|
||||
} else {
|
||||
this.frame.style.width = "0";
|
||||
this.frame.style.height = "auto";
|
||||
}
|
||||
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
|
||||
this.element.appendChild(this.frame);
|
||||
this.added = true;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
|
||||
return this.frame;
|
||||
};
|
||||
|
||||
InlineView.prototype.render = function(request, show) {
|
||||
|
@ -110,7 +110,7 @@ InlineView.prototype.render = function(request, show) {
|
|||
this.create();
|
||||
|
||||
// Fit to size of the container, apply padding
|
||||
this.size();
|
||||
this.size();
|
||||
|
||||
// Render Chain
|
||||
return this.section.render(request)
|
||||
|
@ -132,14 +132,14 @@ InlineView.prototype.render = function(request, show) {
|
|||
// }.bind(this))
|
||||
.then(function(){
|
||||
|
||||
// apply the layout function to the contents
|
||||
this.settings.layout.format(this.contents);
|
||||
// apply the layout function to the contents
|
||||
this.settings.layout.format(this.contents);
|
||||
|
||||
// Expand the iframe to the full size of the content
|
||||
// this.expand();
|
||||
// Expand the iframe to the full size of the content
|
||||
// this.expand();
|
||||
|
||||
// Listen for events that require an expansion of the iframe
|
||||
this.addListeners();
|
||||
// Listen for events that require an expansion of the iframe
|
||||
this.addListeners();
|
||||
|
||||
if(show !== false) {
|
||||
//this.q.enqueue(function(view){
|
||||
|
@ -159,13 +159,13 @@ InlineView.prototype.render = function(request, show) {
|
|||
|
||||
// Determine locks base on settings
|
||||
InlineView.prototype.size = function(_width, _height) {
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
var width = _width || this.settings.width;
|
||||
var height = _height || this.settings.height;
|
||||
|
||||
if(this.layout.name === "pre-paginated") {
|
||||
// TODO: check if these are different than the size set in chapter
|
||||
this.lock("both", width, height);
|
||||
} else if(this.settings.axis === "horizontal") {
|
||||
if(this.layout.name === "pre-paginated") {
|
||||
// TODO: check if these are different than the size set in chapter
|
||||
this.lock("both", width, height);
|
||||
} else if(this.settings.axis === "horizontal") {
|
||||
this.lock("height", width, height);
|
||||
} else {
|
||||
this.lock("width", width, height);
|
||||
|
@ -175,253 +175,253 @@ 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);
|
||||
var iframeBorders;
|
||||
var elBorders = core.borders(this.element);
|
||||
var iframeBorders;
|
||||
|
||||
if(this.frame) {
|
||||
iframeBorders = core.borders(this.frame);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
if(this.frame) {
|
||||
iframeBorders = core.borders(this.frame);
|
||||
} else {
|
||||
iframeBorders = {width: 0, height: 0};
|
||||
}
|
||||
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, false); // width keeps ratio correct
|
||||
}
|
||||
if(what == "width" && core.isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, false); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(false, this.lockedHeight);
|
||||
}
|
||||
if(what == "height" && core.isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(false, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
if(what === "both" &&
|
||||
core.isNumber(width) &&
|
||||
core.isNumber(height)){
|
||||
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Resize a single axis based on content dimensions
|
||||
InlineView.prototype.expand = function(force) {
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
var width = this.lockedWidth;
|
||||
var height = this.lockedHeight;
|
||||
|
||||
var textWidth, textHeight;
|
||||
var textWidth, textHeight;
|
||||
|
||||
if(!this.frame || this._expanding) return;
|
||||
if(!this.frame || this._expanding) return;
|
||||
|
||||
this._expanding = true;
|
||||
this._expanding = true;
|
||||
|
||||
// Expand Horizontally
|
||||
if(this.settings.axis === "horizontal") {
|
||||
width = this.contentWidth(textWidth);
|
||||
} // Expand Vertically
|
||||
else if(this.settings.axis === "vertical") {
|
||||
height = this.contentHeight(textHeight);
|
||||
}
|
||||
// Expand Horizontally
|
||||
if(this.settings.axis === "horizontal") {
|
||||
width = this.contentWidth(textWidth);
|
||||
} // Expand Vertically
|
||||
else if(this.settings.axis === "vertical") {
|
||||
height = this.contentHeight(textHeight);
|
||||
}
|
||||
|
||||
// Only Resize if dimensions have changed or
|
||||
// if Frame is still hidden, so needs reframing
|
||||
if(this._needsReframe || width != this._width || height != this._height){
|
||||
this.resize(width, height);
|
||||
}
|
||||
// Only Resize if dimensions have changed or
|
||||
// if Frame is still hidden, so needs reframing
|
||||
if(this._needsReframe || width != this._width || height != this._height){
|
||||
this.resize(width, height);
|
||||
}
|
||||
|
||||
this._expanding = false;
|
||||
this._expanding = false;
|
||||
};
|
||||
|
||||
InlineView.prototype.contentWidth = function(min) {
|
||||
return this.frame.scrollWidth;
|
||||
return this.frame.scrollWidth;
|
||||
};
|
||||
|
||||
InlineView.prototype.contentHeight = function(min) {
|
||||
console.log(this.frame.scrollHeight);
|
||||
return this.frame.scrollHeight;
|
||||
console.log(this.frame.scrollHeight);
|
||||
return this.frame.scrollHeight;
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.resize = function(width, height) {
|
||||
|
||||
if(!this.frame) return;
|
||||
if(!this.frame) return;
|
||||
|
||||
if(core.isNumber(width)){
|
||||
this.frame.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
if(core.isNumber(width)){
|
||||
this.frame.style.width = width + "px";
|
||||
this._width = width;
|
||||
}
|
||||
|
||||
if(core.isNumber(height)){
|
||||
this.frame.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
if(core.isNumber(height)){
|
||||
this.frame.style.height = height + "px";
|
||||
this._height = height;
|
||||
}
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
height: this.elementBounds.height,
|
||||
widthDelta: this.elementBounds.width - this.prevBounds.width,
|
||||
heightDelta: this.elementBounds.height - this.prevBounds.height,
|
||||
};
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
height: this.elementBounds.height,
|
||||
widthDelta: this.elementBounds.width - this.prevBounds.width,
|
||||
heightDelta: this.elementBounds.height - this.prevBounds.height,
|
||||
};
|
||||
|
||||
this.onResize(this, size);
|
||||
this.onResize(this, size);
|
||||
|
||||
this.trigger("resized", size);
|
||||
this.trigger("resized", size);
|
||||
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.load = function(contents) {
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
var doc = core.parse(contents, "text/html");
|
||||
var body = core.qs(doc, "body");
|
||||
var loading = new RSVP.defer();
|
||||
var loaded = loading.promise;
|
||||
var doc = core.parse(contents, "text/html");
|
||||
var body = core.qs(doc, "body");
|
||||
|
||||
var srcs = doc.querySelectorAll("[src]");
|
||||
Array.prototype.slice.call(srcs)
|
||||
.forEach(function(item) {
|
||||
var src = item.getAttribute('src');
|
||||
var assetUri = URI(src);
|
||||
var origin = assetUri.origin();
|
||||
var absoluteUri;
|
||||
var srcs = doc.querySelectorAll("[src]");
|
||||
Array.prototype.slice.call(srcs)
|
||||
.forEach(function(item) {
|
||||
var src = item.getAttribute('src');
|
||||
var assetUri = URI(src);
|
||||
var origin = assetUri.origin();
|
||||
var absoluteUri;
|
||||
|
||||
if (!origin) {
|
||||
absoluteUri = assetUri.absoluteTo(this.section.url);
|
||||
item.src = absoluteUri;
|
||||
}
|
||||
}.bind(this));
|
||||
if (!origin) {
|
||||
absoluteUri = assetUri.absoluteTo(this.section.url);
|
||||
item.src = absoluteUri;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
this.frame.innerHTML = body.innerHTML;
|
||||
this.frame.innerHTML = body.innerHTML;
|
||||
|
||||
this.document = this.frame.ownerDocument;
|
||||
this.window = this.document.defaultView;
|
||||
this.document = this.frame.ownerDocument;
|
||||
this.window = this.document.defaultView;
|
||||
|
||||
this.contents = new Contents(this.document, this.frame);
|
||||
this.contents = new Contents(this.document, this.frame);
|
||||
|
||||
this.rendering = false;
|
||||
this.rendering = false;
|
||||
|
||||
loading.resolve(this.contents);
|
||||
loading.resolve(this.contents);
|
||||
|
||||
|
||||
return loaded;
|
||||
return loaded;
|
||||
};
|
||||
|
||||
InlineView.prototype.setLayout = function(layout) {
|
||||
this.layout = layout;
|
||||
this.layout = layout;
|
||||
};
|
||||
|
||||
|
||||
InlineView.prototype.resizeListenters = function() {
|
||||
// Test size again
|
||||
// clearTimeout(this.expanding);
|
||||
// this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
// Test size again
|
||||
// clearTimeout(this.expanding);
|
||||
// this.expanding = setTimeout(this.expand.bind(this), 350);
|
||||
};
|
||||
|
||||
InlineView.prototype.addListeners = function() {
|
||||
//TODO: Add content listeners for expanding
|
||||
//TODO: Add content listeners for expanding
|
||||
};
|
||||
|
||||
InlineView.prototype.removeListeners = function(layoutFunc) {
|
||||
//TODO: remove content listeners for expanding
|
||||
//TODO: remove content listeners for expanding
|
||||
};
|
||||
|
||||
InlineView.prototype.display = function(request) {
|
||||
var displayed = new RSVP.defer();
|
||||
var displayed = new RSVP.defer();
|
||||
|
||||
if (!this.displayed) {
|
||||
if (!this.displayed) {
|
||||
|
||||
this.render(request).then(function () {
|
||||
this.render(request).then(function () {
|
||||
|
||||
this.trigger("displayed", this);
|
||||
this.onDisplayed(this);
|
||||
this.trigger("displayed", this);
|
||||
this.onDisplayed(this);
|
||||
|
||||
this.displayed = true;
|
||||
this.displayed = true;
|
||||
|
||||
displayed.resolve(this);
|
||||
displayed.resolve(this);
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
} else {
|
||||
displayed.resolve(this);
|
||||
}
|
||||
|
||||
|
||||
return displayed.promise;
|
||||
return displayed.promise;
|
||||
};
|
||||
|
||||
InlineView.prototype.show = function() {
|
||||
|
||||
this.element.style.visibility = "visible";
|
||||
this.element.style.visibility = "visible";
|
||||
|
||||
if(this.frame){
|
||||
this.frame.style.visibility = "visible";
|
||||
}
|
||||
if(this.frame){
|
||||
this.frame.style.visibility = "visible";
|
||||
}
|
||||
|
||||
this.trigger("shown", this);
|
||||
this.trigger("shown", this);
|
||||
};
|
||||
|
||||
InlineView.prototype.hide = function() {
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
// this.frame.style.display = "none";
|
||||
this.element.style.visibility = "hidden";
|
||||
this.frame.style.visibility = "hidden";
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.trigger("hidden", this);
|
||||
this.stopExpanding = true;
|
||||
this.trigger("hidden", this);
|
||||
};
|
||||
|
||||
InlineView.prototype.position = function() {
|
||||
return this.element.getBoundingClientRect();
|
||||
return this.element.getBoundingClientRect();
|
||||
};
|
||||
|
||||
InlineView.prototype.locationOf = function(target) {
|
||||
var parentPos = this.frame.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
var parentPos = this.frame.getBoundingClientRect();
|
||||
var targetPos = this.contents.locationOf(target, this.settings.ignoreClass);
|
||||
|
||||
return {
|
||||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
return {
|
||||
"left": window.scrollX + parentPos.left + targetPos.left,
|
||||
"top": window.scrollY + parentPos.top + targetPos.top
|
||||
};
|
||||
};
|
||||
|
||||
InlineView.prototype.onDisplayed = function(view) {
|
||||
// Stub, override with a custom functions
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
|
||||
InlineView.prototype.onResize = function(view, e) {
|
||||
// Stub, override with a custom functions
|
||||
// Stub, override with a custom functions
|
||||
};
|
||||
|
||||
InlineView.prototype.bounds = function() {
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
if(!this.elementBounds) {
|
||||
this.elementBounds = core.bounds(this.element);
|
||||
}
|
||||
return this.elementBounds;
|
||||
};
|
||||
|
||||
InlineView.prototype.destroy = function() {
|
||||
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
if(this.displayed){
|
||||
this.displayed = false;
|
||||
|
||||
this.removeListeners();
|
||||
this.removeListeners();
|
||||
|
||||
this.stopExpanding = true;
|
||||
this.element.removeChild(this.frame);
|
||||
this.displayed = false;
|
||||
this.frame = null;
|
||||
this.stopExpanding = true;
|
||||
this.element.removeChild(this.frame);
|
||||
this.displayed = false;
|
||||
this.frame = null;
|
||||
|
||||
this._textWidth = null;
|
||||
this._textHeight = null;
|
||||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
this._textWidth = null;
|
||||
this._textHeight = null;
|
||||
this._width = null;
|
||||
this._height = null;
|
||||
}
|
||||
// this.element.style.height = "0px";
|
||||
// this.element.style.width = "0px";
|
||||
};
|
||||
|
||||
RSVP.EventTarget.mixin(InlineView.prototype);
|
||||
|
|
50
test/epub.js
50
test/epub.js
|
@ -4,36 +4,36 @@ var fs = require('fs');
|
|||
|
||||
|
||||
describe('ePub', function() {
|
||||
var ePub = require('../src/epub');
|
||||
var server;
|
||||
before(function(){
|
||||
var packageContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/package.opf', 'utf8');
|
||||
var tocContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/toc.xhtml', 'utf8');
|
||||
var ePub = require('../src/epub');
|
||||
var server;
|
||||
before(function(){
|
||||
var packageContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/package.opf', 'utf8');
|
||||
var tocContents = fs.readFileSync(__dirname + '/../books/moby-dick/OPS/toc.xhtml', 'utf8');
|
||||
|
||||
server = sinon.fakeServer.create();
|
||||
server.autoRespond = true;
|
||||
server = sinon.fakeServer.create();
|
||||
server.autoRespond = true;
|
||||
|
||||
server.respondWith("moby-dick/OPS/package.opf", [200, {
|
||||
"Content-Type": "text/xml"
|
||||
}, packageContents]);
|
||||
server.respondWith("moby-dick/OPS/package.opf", [200, {
|
||||
"Content-Type": "text/xml"
|
||||
}, packageContents]);
|
||||
|
||||
server.respondWith("moby-dick/OPS/toc.xhtml", [200, {
|
||||
"Content-Type": "application/xhtml+xml"
|
||||
}, tocContents]);
|
||||
server.respondWith("moby-dick/OPS/toc.xhtml", [200, {
|
||||
"Content-Type": "application/xhtml+xml"
|
||||
}, tocContents]);
|
||||
|
||||
|
||||
});
|
||||
after(function(){
|
||||
server.restore();
|
||||
});
|
||||
});
|
||||
after(function(){
|
||||
server.restore();
|
||||
});
|
||||
|
||||
it('should open a epub', function(done) {
|
||||
var book = ePub("moby-dick/OPS/package.opf");
|
||||
it('should open a epub', function(done) {
|
||||
var book = ePub("moby-dick/OPS/package.opf");
|
||||
|
||||
book.opened.then(function(){
|
||||
assert.equal( book.isOpen, true, "book is opened" );
|
||||
assert.equal( book.url, "moby-dick/OPS/package.opf", "book url is passed to new Book" );
|
||||
done();
|
||||
});
|
||||
});
|
||||
book.opened.then(function(){
|
||||
assert.equal( book.isOpen, true, "book is opened" );
|
||||
assert.equal( book.url, "moby-dick/OPS/package.opf", "book url is passed to new Book" );
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
402
test/epubcfi.js
402
test/epubcfi.js
|
@ -1,11 +1,11 @@
|
|||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
if (typeof DOMParser === "undefined") {
|
||||
global.DOMParser = require('xmldom').DOMParser;
|
||||
global.DOMParser = require('xmldom').DOMParser;
|
||||
}
|
||||
|
||||
describe('EpubCFI', function() {
|
||||
var EpubCFI = require('../src/epubcfi.js');
|
||||
var EpubCFI = require('../src/epubcfi.js');
|
||||
|
||||
it('parse a cfi on init', function() {
|
||||
var cfi = EpubCFI("epubcfi(/6/2[cover]!/6)");
|
||||
|
@ -19,58 +19,58 @@ describe('EpubCFI', function() {
|
|||
assert.equal( cfi.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
|
||||
});
|
||||
|
||||
describe('#parse()', function() {
|
||||
describe('#parse()', function() {
|
||||
var cfi = new EpubCFI();
|
||||
|
||||
it('parse a cfi on init', function() {
|
||||
var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)");
|
||||
var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)");
|
||||
|
||||
assert.equal( parsed.spinePos, 0, "spinePos is parsed as the first item" );
|
||||
});
|
||||
assert.equal( parsed.spinePos, 0, "spinePos is parsed as the first item" );
|
||||
});
|
||||
|
||||
it('parse a cfi and ignore the base if present', function() {
|
||||
var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
|
||||
var parsed = cfi.parse("epubcfi(/6/2[cover]!/6)", "/6/6[end]");
|
||||
|
||||
assert.equal( parsed.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
|
||||
});
|
||||
assert.equal( parsed.spinePos, 0, "base is ignored and spinePos is parsed as the first item" );
|
||||
});
|
||||
|
||||
it('parse a cfi with a charecter offset', function() {
|
||||
var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
|
||||
var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
|
||||
|
||||
assert.equal( parsed.path.terminal.offset, 3, "Path has a terminal offset of 3" );
|
||||
});
|
||||
assert.equal( parsed.path.terminal.offset, 3, "Path has a terminal offset of 3" );
|
||||
});
|
||||
|
||||
it('parse a cfi with a range', function() {
|
||||
var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)");
|
||||
var parsed = cfi.parse("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)");
|
||||
|
||||
assert.equal( parsed.range, true, "Range is true" );
|
||||
assert.equal( parsed.start.steps.length, 2, "Start steps are present" );
|
||||
assert.equal( parsed.end.steps.length, 1, "End steps are present" );
|
||||
assert.equal( parsed.end.steps.length, 1, "End steps are present" );
|
||||
assert.equal( parsed.start.terminal.offset, 1, "Start has a terminal offset of 1" );
|
||||
assert.equal( parsed.end.terminal.offset, 4, "End has a terminal offset of 4" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('#toString()', function() {
|
||||
it('parse a cfi and write it back', 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/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" );
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#checkType()', function() {
|
||||
it('determine the type of a cfi string', function() {
|
||||
it('determine the type of a cfi string', function() {
|
||||
var cfi = new EpubCFI();
|
||||
|
||||
assert.equal( cfi.checkType('epubcfi(/6/2[cover]!/6)'), 'string' );
|
||||
assert.equal( cfi.checkType('/6/2[cover]!/6'), false );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('determine the type of a cfi', function() {
|
||||
var ogcfi = EpubCFI("epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)");
|
||||
|
@ -96,10 +96,10 @@ describe('EpubCFI', function() {
|
|||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('#compare()', function() {
|
||||
it('compare CFIs', function() {
|
||||
it('compare CFIs', function() {
|
||||
var epubcfi = new EpubCFI();
|
||||
|
||||
// Spines
|
||||
|
@ -131,272 +131,272 @@ describe('EpubCFI', function() {
|
|||
assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/5:1)", "epubcfi(/6/2[cover]!/4/6/15:2)"), 1, "First Element is greater");
|
||||
assert.equal(epubcfi.compare("epubcfi(/6/2[cover]!/4/8/1:0)", "epubcfi(/6/2[cover]!/4/8/1:0)"), 0, "All Equal");
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#fromNode()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
// var serializer = new XMLSerializer();
|
||||
// var doc = serializer.serializeToString(contents);
|
||||
var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
|
||||
describe('#fromNode()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
// var serializer = new XMLSerializer();
|
||||
// var doc = serializer.serializeToString(contents);
|
||||
var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
|
||||
|
||||
it('get a cfi from a p node', function() {
|
||||
var span = doc.getElementById('c001p0004');
|
||||
var cfi = new EpubCFI(span, base);
|
||||
it('get a cfi from a p node', function() {
|
||||
var span = doc.getElementById('c001p0004');
|
||||
var cfi = new EpubCFI(span, base);
|
||||
|
||||
assert.equal(span.nodeType, Node.ELEMENT_NODE, "provided a element node");
|
||||
assert.equal(span.nodeType, Node.ELEMENT_NODE, "provided a element node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004])" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a text node', function() {
|
||||
var t = doc.getElementById('c001p0004').childNodes[0];
|
||||
var cfi = new EpubCFI(t, base);
|
||||
it('get a cfi from a text node', function() {
|
||||
var t = doc.getElementById('c001p0004').childNodes[0];
|
||||
var cfi = new EpubCFI(t, base);
|
||||
|
||||
assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1)" );
|
||||
assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1)" );
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a text node inside a highlight', function() {
|
||||
var t = doc.getElementById('highlight-1').childNodes[0];
|
||||
var cfi = new EpubCFI(t, base, 'annotator-hl');
|
||||
it('get a cfi from a text node inside a highlight', function() {
|
||||
var t = doc.getElementById('highlight-1').childNodes[0];
|
||||
var cfi = new EpubCFI(t, base, 'annotator-hl');
|
||||
|
||||
assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1)" );
|
||||
assert.equal(t.nodeType, Node.TEXT_NODE, "provided a text node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a highlight node', function() {
|
||||
var t = doc.getElementById('highlight-1');
|
||||
var cfi = new EpubCFI(t, base, 'annotator-hl');
|
||||
it('get a cfi from a highlight node', function() {
|
||||
var t = doc.getElementById('highlight-1');
|
||||
var cfi = new EpubCFI(t, base, 'annotator-hl');
|
||||
|
||||
assert.equal(t.nodeType, Node.ELEMENT_NODE, "provided a highlight node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017])" );
|
||||
assert.equal(t.nodeType, Node.ELEMENT_NODE, "provided a highlight node");
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017])" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('#fromRange()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
describe('#fromRange()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
|
||||
var contentsClean = fs.readFileSync(__dirname + '/fixtures/chapter1.xhtml', 'utf8');
|
||||
var doc = new DOMParser().parseFromString(contentsClean, "application/xhtml+xml");
|
||||
var contentsClean = fs.readFileSync(__dirname + '/fixtures/chapter1.xhtml', 'utf8');
|
||||
var doc = new DOMParser().parseFromString(contentsClean, "application/xhtml+xml");
|
||||
|
||||
var contentsHighlights = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
var docHighlights = new DOMParser().parseFromString(contentsHighlights, "application/xhtml+xml");
|
||||
var contentsHighlights = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
var docHighlights = new DOMParser().parseFromString(contentsHighlights, "application/xhtml+xml");
|
||||
|
||||
var highlightContents = fs.readFileSync(__dirname + '/fixtures/highlight.xhtml', 'utf8');
|
||||
var docHighlightsAlice = new DOMParser().parseFromString(highlightContents, "application/xhtml+xml");
|
||||
var highlightContents = fs.readFileSync(__dirname + '/fixtures/highlight.xhtml', 'utf8');
|
||||
var docHighlightsAlice = new DOMParser().parseFromString(highlightContents, "application/xhtml+xml");
|
||||
|
||||
it('get a cfi from a collapsed range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
it('get a cfi from a collapsed range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 6);
|
||||
range.setStart(t1, 6);
|
||||
|
||||
cfi = new EpubCFI(range, base);
|
||||
cfi = new EpubCFI(range, base);
|
||||
|
||||
assert.equal( cfi.range, false);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
|
||||
assert.equal( cfi.range, false);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
it('get a cfi from a range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 6);
|
||||
range.setEnd(t2, 27);
|
||||
range.setStart(t1, 6);
|
||||
range.setEnd(t2, 27);
|
||||
|
||||
cfi = new EpubCFI(range, base);
|
||||
cfi = new EpubCFI(range, base);
|
||||
|
||||
assert.equal( cfi.range, true);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
|
||||
assert.equal( cfi.range, true);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range with offset 0', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
it('get a cfi from a range with offset 0', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var range = doc.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 0);
|
||||
range.setEnd(t1, 1);
|
||||
range.setStart(t1, 0);
|
||||
range.setEnd(t1, 1);
|
||||
|
||||
cfi = new EpubCFI(range, base);
|
||||
cfi = new EpubCFI(range, base);
|
||||
|
||||
assert.equal( cfi.range, true);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004],/1:0,/1:1)" );
|
||||
assert.equal( cfi.range, true);
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004],/1:0,/1:1)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range inside a highlight', function() {
|
||||
var t1 = docHighlights.getElementById('highlight-1').childNodes[0];
|
||||
var range = docHighlights.createRange();
|
||||
var cfi;
|
||||
it('get a cfi from a range inside a highlight', function() {
|
||||
var t1 = docHighlights.getElementById('highlight-1').childNodes[0];
|
||||
var range = docHighlights.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 6);
|
||||
range.setStart(t1, 6);
|
||||
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
|
||||
|
||||
});
|
||||
// TODO: might need to have double ranges in front
|
||||
it('get a cfi from a range past a highlight', function() {
|
||||
var t1 = docHighlights.getElementById('c001s0001').childNodes[1];
|
||||
var range = docHighlights.createRange();
|
||||
var cfi;
|
||||
});
|
||||
// TODO: might need to have double ranges in front
|
||||
it('get a cfi from a range past a highlight', function() {
|
||||
var t1 = docHighlights.getElementById('c001s0001').childNodes[1];
|
||||
var range = docHighlights.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 25);
|
||||
range.setStart(t1, 25);
|
||||
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001]/1:41)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001]/1:41)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range inbetween two highlights', function() {
|
||||
var t1 = docHighlightsAlice.getElementById('p2').childNodes[1];
|
||||
var range = docHighlightsAlice.createRange();
|
||||
var cfi;
|
||||
it('get a cfi from a range inbetween two highlights', function() {
|
||||
var t1 = docHighlightsAlice.getElementById('p2').childNodes[1];
|
||||
var range = docHighlightsAlice.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 4);
|
||||
range.setStart(t1, 4);
|
||||
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
cfi = new EpubCFI(range, base, 'annotator-hl');
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/4[p2]/1:123)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/4[p2]/1:123)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly count text nodes, independent of any elements present inbetween', function() {
|
||||
var t1 = docHighlightsAlice.getElementById('p3').childNodes[2];
|
||||
var range = docHighlightsAlice.createRange();
|
||||
var cfi;
|
||||
it('correctly count text nodes, independent of any elements present inbetween', function() {
|
||||
var t1 = docHighlightsAlice.getElementById('p3').childNodes[2];
|
||||
var range = docHighlightsAlice.createRange();
|
||||
var cfi;
|
||||
|
||||
range.setStart(t1, 4);
|
||||
range.setStart(t1, 4);
|
||||
|
||||
cfi = new EpubCFI(range, base);
|
||||
cfi = new EpubCFI(range, base);
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/6[p3]/3:4)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/6[p3]/3:4)" );
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#toRange()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
|
||||
describe('#toRange()', function() {
|
||||
var base = "/6/4[chap01ref]";
|
||||
var contents = fs.readFileSync(__dirname + '/fixtures/chapter1-highlights.xhtml', 'utf8');
|
||||
var doc = new DOMParser().parseFromString(contents, "application/xhtml+xml");
|
||||
|
||||
// var serializer = new XMLSerializer();
|
||||
// console.log(serializer.serializeToString(doc));
|
||||
// var serializer = new XMLSerializer();
|
||||
// console.log(serializer.serializeToString(doc));
|
||||
|
||||
it('get a range from a cfi', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
it('get a range from a cfi', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
|
||||
ogRange.setStart(t1, 6);
|
||||
ogRange.setStart(t1, 6);
|
||||
|
||||
cfi = new EpubCFI(ogRange, base);
|
||||
cfi = new EpubCFI(ogRange, base);
|
||||
|
||||
// Check it was parse correctly
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
|
||||
// Check it was parse correctly
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/10/2[c001p0004]/1:6)" );
|
||||
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc);
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc);
|
||||
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
assert.equal( newRange.collapsed, true);
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
assert.equal( newRange.collapsed, true);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a range from a cfi with a range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
it('get a range from a cfi with a range', function() {
|
||||
var t1 = doc.getElementById('c001p0004').childNodes[0];
|
||||
var t2 = doc.getElementById('c001p0007').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
|
||||
ogRange.setStart(t1, 6);
|
||||
ogRange.setEnd(t2, 27);
|
||||
ogRange.setStart(t1, 6);
|
||||
ogRange.setEnd(t2, 27);
|
||||
|
||||
cfi = new EpubCFI(ogRange, base);
|
||||
cfi = new EpubCFI(ogRange, base);
|
||||
|
||||
// Check it was parse correctly
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
|
||||
// Check it was parse correctly
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2,/10/2[c001p0004]/1:6,/16/2[c001p0007]/1:27)" );
|
||||
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc);
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc);
|
||||
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
|
||||
assert.equal( newRange.endContainer, t2);
|
||||
assert.equal( newRange.endOffset, 27);
|
||||
assert.equal( newRange.endContainer, t2);
|
||||
assert.equal( newRange.endOffset, 27);
|
||||
|
||||
assert.equal( newRange.collapsed, false);
|
||||
assert.equal( newRange.collapsed, false);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range inside a highlight', function() {
|
||||
var t1 = doc.getElementById('highlight-1').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
it('get a cfi from a range inside a highlight', function() {
|
||||
var t1 = doc.getElementById('highlight-1').childNodes[0];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
|
||||
ogRange.setStart(t1, 6);
|
||||
ogRange.setStart(t1, 6);
|
||||
|
||||
cfi = new EpubCFI(ogRange, base, 'annotator-hl');
|
||||
cfi = new EpubCFI(ogRange, base, 'annotator-hl');
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/32/2[c001p0017]/1:43)" );
|
||||
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc, 'annotator-hl');
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc, 'annotator-hl');
|
||||
|
||||
assert.ok(newRange.startContainer);
|
||||
assert.ok(newRange.startContainer);
|
||||
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
assert.equal( newRange.startContainer, t1);
|
||||
assert.equal( newRange.startOffset, 6);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('get a cfi from a range inside a highlight range', function() {
|
||||
var t1 = doc.getElementById('highlight-2').childNodes[0];
|
||||
var t2 = doc.getElementById('c001s0001').childNodes[1];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
it('get a cfi from a range inside a highlight range', function() {
|
||||
var t1 = doc.getElementById('highlight-2').childNodes[0];
|
||||
var t2 = doc.getElementById('c001s0001').childNodes[1];
|
||||
var ogRange = doc.createRange();
|
||||
var cfi;
|
||||
var newRange;
|
||||
|
||||
ogRange.setStart(t1, 5);
|
||||
ogRange.setEnd(t2, 25);
|
||||
ogRange.setStart(t1, 5);
|
||||
ogRange.setEnd(t2, 25);
|
||||
|
||||
cfi = new EpubCFI(ogRange, base, 'annotator-hl');
|
||||
cfi = new EpubCFI(ogRange, base, 'annotator-hl');
|
||||
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001],/1:5,/1:41)" );
|
||||
assert.equal( cfi.toString(), "epubcfi(/6/4[chap01ref]!/4/2/4/2[c001s0001],/1:5,/1:41)" );
|
||||
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc, 'annotator-hl');
|
||||
// Check the range
|
||||
newRange = cfi.toRange(doc, 'annotator-hl');
|
||||
|
||||
assert.strictEqual( newRange.startContainer.textContent, t1.textContent);
|
||||
// assert.strictEqual( newRange.startContainer, t1);
|
||||
// assert.equal( newRange.startOffset, 5);
|
||||
assert.strictEqual( newRange.startContainer.textContent, t1.textContent);
|
||||
// assert.strictEqual( newRange.startContainer, t1);
|
||||
// assert.equal( newRange.startOffset, 5);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -3,102 +3,102 @@ var domain = window.location.origin;
|
|||
module('Core');
|
||||
|
||||
test("EPUBJS.core.resolveUrl", 1, function() {
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "/chasen/derf.html";
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "/chasen/derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "http://example.com/fred/chasen/derf.html", "resolved" );
|
||||
equal( resolved, "http://example.com/fred/chasen/derf.html", "resolved" );
|
||||
|
||||
});
|
||||
|
||||
test("EPUBJS.core.resolveUrl ../", 1, function() {
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "../derf.html";
|
||||
var a = "http://example.com/fred/chasen/";
|
||||
var b = "../derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "http://example.com/fred/derf.html", "resolved" );
|
||||
equal( resolved, "http://example.com/fred/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
|
||||
test("EPUBJS.core.resolveUrl folders", 1, function() {
|
||||
var a = "/fred/chasen/";
|
||||
var b = "/fred/chasen/derf.html";
|
||||
var a = "/fred/chasen/";
|
||||
var b = "/fred/chasen/derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "/fred/chasen/derf.html", "resolved" );
|
||||
equal( resolved, "/fred/chasen/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
test("EPUBJS.core.resolveUrl ../folders", 1, function() {
|
||||
var a = "/fred/chasen/";
|
||||
var b = "../../derf.html";
|
||||
var a = "/fred/chasen/";
|
||||
var b = "../../derf.html";
|
||||
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
var resolved = EPUBJS.core.resolveUrl(a, b);
|
||||
|
||||
equal( resolved, "/derf.html", "resolved" );
|
||||
equal( resolved, "/derf.html", "resolved" );
|
||||
});
|
||||
|
||||
module('Create');
|
||||
|
||||
asyncTest("Create new ePub(/path/to/epub/)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, "../books/moby-dick/OPS/", "book url is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, "../books/moby-dick/OPS/", "book url is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Create new ePub(/path/to/epub/package.opf)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, domain + "/books/moby-dick/OPS/", "bookPath is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.url, domain + "/books/moby-dick/OPS/", "bookPath is passed to new EPUBJS.Book" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open using ePub(/path/to/epub/package.opf)", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open Remote ePub", 1, function() {
|
||||
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Open Remote ePub from Package", 1, function() {
|
||||
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("https://s3.amazonaws.com/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "https://s3.amazonaws.com/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Epub Package", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.packageUrl, "../books/moby-dick/OPS/package.opf", "packageUrl is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -108,43 +108,43 @@ module('Parse');
|
|||
|
||||
asyncTest("Manifest", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( Object.keys(book.package.manifest).length, 152, "Manifest is parsed" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( Object.keys(book.package.manifest).length, 152, "Manifest is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Metadata", 3, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.metadata.creator, "Herman Melville", "Creator metadata is parsed" );
|
||||
equal( book.package.metadata.title, "Moby-Dick", "Title metadata is parsed" );
|
||||
equal( book.package.metadata.identifier, "code.google.com.epub-samples.moby-dick-basic", "Identifier metadata is parsed" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.metadata.creator, "Herman Melville", "Creator metadata is parsed" );
|
||||
equal( book.package.metadata.title, "Moby-Dick", "Title metadata is parsed" );
|
||||
equal( book.package.metadata.identifier, "code.google.com.epub-samples.moby-dick-basic", "Identifier metadata is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Spine", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.spine.length, 144, "Spine is parsed" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.package.spine.length, 144, "Spine is parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Cover", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.cover, "../books/moby-dick/OPS/images/9780316000000.jpg", "Cover is set" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.cover, "../books/moby-dick/OPS/images/9780316000000.jpg", "Cover is set" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -152,74 +152,74 @@ module('Spine');
|
|||
|
||||
asyncTest("Length", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.length, 144, "All spine items present" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.length, 144, "All spine items present" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Items", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.spineItems.length, 144, "All spine items added" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
equal( book.spine.spineItems.length, 144, "All spine items added" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("First Item", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get(0);
|
||||
equal( section.href, "cover.xhtml", "First spine item href found" );
|
||||
equal( section.cfiBase, "/6/2[cover]", "First spine item cfi found" );
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get(0);
|
||||
equal( section.href, "cover.xhtml", "First spine item href found" );
|
||||
equal( section.cfiBase, "/6/2[cover]", "First spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Item by Href", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("chapter_001.xhtml");
|
||||
equal( section.href, "chapter_001.xhtml", "chap 1 spine item href found" );
|
||||
equal( section.cfiBase, "/6/14[xchapter_001]", "chap 1 spine item cfi found" );
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("chapter_001.xhtml");
|
||||
equal( section.href, "chapter_001.xhtml", "chap 1 spine item href found" );
|
||||
equal( section.cfiBase, "/6/14[xchapter_001]", "chap 1 spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Find Item by ID", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
equal( section.href, "chapter_050.xhtml", "chap 50 spine item href found" );
|
||||
equal( section.cfiBase, "/6/112[xchapter_050]", "chap 50 spine item cfi found" );
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
equal( section.href, "chapter_050.xhtml", "chap 50 spine item href found" );
|
||||
equal( section.cfiBase, "/6/112[xchapter_050]", "chap 50 spine item cfi found" );
|
||||
|
||||
start();
|
||||
});
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Render Spine Item", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
section.render().then(function(content){
|
||||
equal( content.substring(377, 429), "<h1>Chapter 50. Ahab’s Boat and Crew. Fedallah.</h1>", "Chapter text rendered as string" );
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var section = book.spine.get("#xchapter_050");
|
||||
section.render().then(function(content){
|
||||
equal( content.substring(377, 429), "<h1>Chapter 50. Ahab’s Boat and Crew. Fedallah.</h1>", "Chapter text rendered as string" );
|
||||
});
|
||||
|
||||
start();
|
||||
});
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -227,84 +227,84 @@ module('Navigation');
|
|||
|
||||
asyncTest("NCX & Nav", 2, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.navigation.navUrl, "../books/moby-dick/OPS/toc.xhtml", "Nav URL found" );
|
||||
equal( book.navigation.ncxUrl, "../books/moby-dick/OPS/toc.ncx", "NCX URL found" );
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
equal( book.navigation.navUrl, "../books/moby-dick/OPS/toc.xhtml", "Nav URL found" );
|
||||
equal( book.navigation.ncxUrl, "../books/moby-dick/OPS/toc.ncx", "NCX URL found" );
|
||||
|
||||
start();
|
||||
});
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
asyncTest("Load TOC Auto Pick", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
book.navigation.load().then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
var book = ePub("../books/moby-dick/");
|
||||
book.opened.then(function(){
|
||||
book.navigation.load().then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Load TOC from Nav", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var nav = book.navigation.nav.load();
|
||||
nav.then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var nav = book.navigation.nav.load();
|
||||
nav.then(function(toc){
|
||||
equal( toc.length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Load TOC from NCX", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var ncx = book.navigation.ncx.load();
|
||||
ncx.then(function(toc){
|
||||
equal( toc.length, 14, "Full NCX toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.opened.then(function(){
|
||||
var ncx = book.navigation.ncx.load();
|
||||
ncx.then(function(toc){
|
||||
equal( toc.length, 14, "Full NCX toc parsed" );
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get all TOC", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
equal( book.navigation.get().length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
equal( book.navigation.get().length, 141, "Full Nav toc parsed" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get TOC item by href", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("chapter_001.xhtml");
|
||||
equal( item.id, "toc-chapter_001", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("chapter_001.xhtml");
|
||||
equal( item.id, "toc-chapter_001", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
asyncTest("Get TOC item by ID", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("#toc-chapter_001");
|
||||
equal( item.href, "chapter_001.xhtml", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
book.loaded.navigation.then(function(){
|
||||
var item = book.navigation.get("#toc-chapter_001");
|
||||
equal( item.href, "chapter_001.xhtml", "Found TOC item" );
|
||||
start();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -312,15 +312,15 @@ module('Hooks');
|
|||
|
||||
asyncTest("Register a new hook", 1, function() {
|
||||
|
||||
var beforeDisplay = new EPUBJS.Hook();
|
||||
beforeDisplay.register(function(args){
|
||||
var defer = new RSVP.defer();
|
||||
console.log("ran", 1);
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
equal( beforeDisplay.hooks.length, 1, "Registered a hook" );
|
||||
start();
|
||||
var beforeDisplay = new EPUBJS.Hook();
|
||||
beforeDisplay.register(function(args){
|
||||
var defer = new RSVP.defer();
|
||||
console.log("ran", 1);
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
equal( beforeDisplay.hooks.length, 1, "Registered a hook" );
|
||||
start();
|
||||
|
||||
// this.beforeDisplay.trigger(args).then(function(){});
|
||||
|
||||
|
@ -328,44 +328,44 @@ asyncTest("Register a new hook", 1, function() {
|
|||
|
||||
asyncTest("Trigger all new hook", 4, function() {
|
||||
|
||||
var beforeDisplay = new EPUBJS.Hook(this);
|
||||
this.testerObject = {tester: 1};
|
||||
var beforeDisplay = new EPUBJS.Hook(this);
|
||||
this.testerObject = {tester: 1};
|
||||
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
|
||||
start();
|
||||
equal( testerObject.tester, 1, "tester is 1" );
|
||||
stop();
|
||||
start();
|
||||
equal( testerObject.tester, 1, "tester is 1" );
|
||||
stop();
|
||||
|
||||
testerObject.tester += 1;
|
||||
testerObject.tester += 1;
|
||||
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
beforeDisplay.register(function(testerObject){
|
||||
var defer = new RSVP.defer();
|
||||
|
||||
start();
|
||||
equal(testerObject.tester, 2, "tester is 2" );
|
||||
stop();
|
||||
start();
|
||||
equal(testerObject.tester, 2, "tester is 2" );
|
||||
stop();
|
||||
|
||||
testerObject.tester += 1;
|
||||
testerObject.tester += 1;
|
||||
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
defer.resolve();
|
||||
return defer.promise;
|
||||
});
|
||||
|
||||
start();
|
||||
equal( beforeDisplay.hooks.length, 2, "Added two hooks" );
|
||||
stop();
|
||||
start();
|
||||
equal( beforeDisplay.hooks.length, 2, "Added two hooks" );
|
||||
stop();
|
||||
|
||||
beforeDisplay.trigger(this.testerObject).then(function(){
|
||||
|
||||
start();
|
||||
equal( this.testerObject.tester, 3, "tester is 3" );
|
||||
beforeDisplay.trigger(this.testerObject).then(function(){
|
||||
|
||||
}.bind(this));
|
||||
start();
|
||||
equal( this.testerObject.tester, 3, "tester is 3" );
|
||||
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
});
|
||||
|
|
|
@ -2,15 +2,15 @@ module('Rendering');
|
|||
/*
|
||||
asyncTest("Render To", 1, function() {
|
||||
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
var rendition = book.renderTo("qunit-fixture", {width:400, height:600});
|
||||
var displayed = rendition.display(0);
|
||||
var book = ePub("../books/moby-dick/OPS/package.opf");
|
||||
var rendition = book.renderTo("qunit-fixture", {width:400, height:600});
|
||||
var displayed = rendition.display(0);
|
||||
|
||||
displayed.then(function(){
|
||||
equal( $( "iframe", "#qunit-fixture" ).length, 1, "iframe added successfully" );
|
||||
start();
|
||||
});
|
||||
displayed.then(function(){
|
||||
equal( $( "iframe", "#qunit-fixture" ).length, 1, "iframe added successfully" );
|
||||
start();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
*/
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue