mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-04 15:09:16 +02:00
Added resources, renamed unarchive -> archive, moved replacements to Book
This commit is contained in:
parent
47787678f7
commit
b5cfc74e12
8 changed files with 252 additions and 260 deletions
|
@ -1,15 +1,16 @@
|
|||
var core = require('./core');
|
||||
var request = require('./request');
|
||||
var mime = require('../libs/mime/mime');
|
||||
var Path = require('./core').Path;
|
||||
|
||||
function Unarchive() {
|
||||
function Archive() {
|
||||
|
||||
this.checkRequirements();
|
||||
this.urlCache = {};
|
||||
|
||||
}
|
||||
|
||||
Unarchive.prototype.checkRequirements = function(callback){
|
||||
Archive.prototype.checkRequirements = function(callback){
|
||||
try {
|
||||
if (typeof JSZip === 'undefined') {
|
||||
JSZip = require('jszip');
|
||||
|
@ -20,25 +21,26 @@ Unarchive.prototype.checkRequirements = function(callback){
|
|||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.open = function(input, isBase64){
|
||||
Archive.prototype.open = function(input, isBase64){
|
||||
return this.zip.loadAsync(input, {"base64": isBase64});
|
||||
};
|
||||
|
||||
Unarchive.prototype.openUrl = function(zipUrl, isBase64){
|
||||
Archive.prototype.openUrl = function(zipUrl, isBase64){
|
||||
return request(zipUrl, "binary")
|
||||
.then(function(data){
|
||||
return this.zip.loadAsync(data, {"base64": isBase64});
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Unarchive.prototype.request = function(url, type){
|
||||
Archive.prototype.request = function(url, type){
|
||||
var deferred = new core.defer();
|
||||
var response;
|
||||
var r;
|
||||
var path = new Path(url);
|
||||
|
||||
// If type isn't set, determine it from the file extension
|
||||
if(!type) {
|
||||
type = core.extension(url);
|
||||
type = path.extension;
|
||||
}
|
||||
|
||||
if(type == 'blob'){
|
||||
|
@ -61,7 +63,7 @@ Unarchive.prototype.request = function(url, type){
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
Unarchive.prototype.handleResponse = function(response, type){
|
||||
Archive.prototype.handleResponse = function(response, type){
|
||||
var r;
|
||||
|
||||
if(type == "json") {
|
||||
|
@ -85,7 +87,7 @@ Unarchive.prototype.handleResponse = function(response, type){
|
|||
return r;
|
||||
};
|
||||
|
||||
Unarchive.prototype.getBlob = function(url, _mimeType){
|
||||
Archive.prototype.getBlob = function(url, _mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
var mimeType;
|
||||
|
@ -98,7 +100,7 @@ Unarchive.prototype.getBlob = function(url, _mimeType){
|
|||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.getText = function(url, encoding){
|
||||
Archive.prototype.getText = function(url, encoding){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
|
||||
|
@ -109,7 +111,7 @@ Unarchive.prototype.getText = function(url, encoding){
|
|||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.getBase64 = function(url, _mimeType){
|
||||
Archive.prototype.getBase64 = function(url, _mimeType){
|
||||
var decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
|
||||
var entry = this.zip.file(decodededUrl);
|
||||
var mimeType;
|
||||
|
@ -122,7 +124,7 @@ Unarchive.prototype.getBase64 = function(url, _mimeType){
|
|||
}
|
||||
};
|
||||
|
||||
Unarchive.prototype.createUrl = function(url, options){
|
||||
Archive.prototype.createUrl = function(url, options){
|
||||
var deferred = new core.defer();
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var tempUrl;
|
||||
|
@ -175,10 +177,10 @@ Unarchive.prototype.createUrl = function(url, options){
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
Unarchive.prototype.revokeUrl = function(url){
|
||||
Archive.prototype.revokeUrl = function(url){
|
||||
var _URL = window.URL || window.webkitURL || window.mozURL;
|
||||
var fromCache = this.urlCache[url];
|
||||
if(fromCache) _URL.revokeObjectURL(fromCache);
|
||||
};
|
||||
|
||||
module.exports = Unarchive;
|
||||
module.exports = Archive;
|
98
src/book.js
98
src/book.js
|
@ -9,8 +9,9 @@ var Parser = require('./parser');
|
|||
var Container = require('./container');
|
||||
var Packaging = require('./packaging');
|
||||
var Navigation = require('./navigation');
|
||||
var Resources = require('./resources');
|
||||
var Rendition = require('./rendition');
|
||||
var Unarchive = require('./unarchive');
|
||||
var Archive = require('./archive');
|
||||
var request = require('./request');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
|
||||
|
@ -31,7 +32,8 @@ function Book(url, options){
|
|||
this.settings = core.extend(this.settings || {}, {
|
||||
requestMethod: this.requestMethod,
|
||||
requestCredentials: undefined,
|
||||
encoding: undefined // optional to pass 'binary' or base64' for archived Epubs
|
||||
encoding: undefined, // optional to pass 'binary' or base64' for archived Epubs
|
||||
base64: true
|
||||
});
|
||||
|
||||
core.extend(this.settings, options);
|
||||
|
@ -51,7 +53,8 @@ function Book(url, options){
|
|||
metadata: new core.defer(),
|
||||
cover: new core.defer(),
|
||||
navigation: new core.defer(),
|
||||
pageList: new core.defer()
|
||||
pageList: new core.defer(),
|
||||
resources: new core.defer()
|
||||
};
|
||||
|
||||
this.loaded = {
|
||||
|
@ -60,7 +63,8 @@ function Book(url, options){
|
|||
metadata: this.loading.metadata.promise,
|
||||
cover: this.loading.cover.promise,
|
||||
navigation: this.loading.navigation.promise,
|
||||
pageList: this.loading.pageList.promise
|
||||
pageList: this.loading.pageList.promise,
|
||||
resources: this.loading.resources.promise
|
||||
};
|
||||
|
||||
// this.ready = RSVP.hash(this.loaded);
|
||||
|
@ -72,7 +76,7 @@ function Book(url, options){
|
|||
this.loaded.metadata,
|
||||
this.loaded.cover,
|
||||
this.loaded.navigation,
|
||||
this.loaded.pageList ]);
|
||||
this.loaded.resources ]);
|
||||
|
||||
|
||||
// Queue for methods used before opening
|
||||
|
@ -128,22 +132,20 @@ Book.prototype.open = function(input, what){
|
|||
|
||||
if (type === "binary") {
|
||||
this.archived = true;
|
||||
this.url = new Url("/", "");
|
||||
opening = this.openEpub(input);
|
||||
} else if (type === "epub") {
|
||||
this.archived = true;
|
||||
this.url = new Url("/", "");
|
||||
opening = this.request(input, 'binary')
|
||||
.then(function(epubData) {
|
||||
return this.openEpub(epubData);
|
||||
}.bind(this));
|
||||
.then(this.openEpub.bind(this));
|
||||
} else if(type == "opf") {
|
||||
this.url = new Url(input);
|
||||
opening = this.openPackaging(input);
|
||||
} else {
|
||||
this.url = new Url(input);
|
||||
opening = this.openContainer(CONTAINER_PATH)
|
||||
.then(function(packagePath) {
|
||||
return this.openPackaging(packagePath);
|
||||
}.bind(this))
|
||||
.then(this.openPackaging.bind(this));
|
||||
}
|
||||
|
||||
return opening;
|
||||
|
@ -152,10 +154,10 @@ Book.prototype.open = function(input, what){
|
|||
Book.prototype.openEpub = function(data, encoding){
|
||||
return this.unarchive(data, encoding || this.settings.encoding)
|
||||
.then(function() {
|
||||
return this.openContainer("/" + CONTAINER_PATH);
|
||||
return this.openContainer(CONTAINER_PATH);
|
||||
}.bind(this))
|
||||
.then(function(packagePath) {
|
||||
return this.openPackaging("/" + packagePath);
|
||||
return this.openPackaging(packagePath);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
@ -163,7 +165,7 @@ Book.prototype.openContainer = function(url){
|
|||
return this.load(url)
|
||||
.then(function(xml) {
|
||||
this.container = new Container(xml);
|
||||
return this.container.packagePath;
|
||||
return this.resolve(this.container.packagePath);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
@ -180,9 +182,9 @@ Book.prototype.openPackaging = function(url){
|
|||
|
||||
Book.prototype.load = function (path) {
|
||||
var resolved;
|
||||
if(this.unarchived) {
|
||||
if(this.archived) {
|
||||
resolved = this.resolve(path);
|
||||
return this.unarchived.request(resolved);
|
||||
return this.archive.request(resolved);
|
||||
} else {
|
||||
resolved = this.resolve(path);
|
||||
return this.request(resolved, null, this.requestCredentials, this.requestHeaders);
|
||||
|
@ -244,6 +246,12 @@ Book.prototype.unpack = function(opf){
|
|||
|
||||
this.spine.unpack(this.package, this.resolve.bind(this));
|
||||
|
||||
this.resources = new Resources(this.package.manifest, {
|
||||
archive: this.archive,
|
||||
resolver: this.resolve.bind(this),
|
||||
base64: this.settings.base64
|
||||
});
|
||||
|
||||
this.loadNavigation(this.package).then(function(toc){
|
||||
this.toc = toc;
|
||||
this.loading.navigation.resolve(this.toc);
|
||||
|
@ -256,11 +264,20 @@ Book.prototype.unpack = function(opf){
|
|||
this.loading.metadata.resolve(this.package.metadata);
|
||||
this.loading.spine.resolve(this.spine);
|
||||
this.loading.cover.resolve(this.cover);
|
||||
this.loading.resources.resolve(this.resources);
|
||||
|
||||
|
||||
this.isOpen = true;
|
||||
|
||||
// Resolve book opened promise
|
||||
this.opening.resolve(this);
|
||||
if(this.archived) {
|
||||
this.replacements().then(function() {
|
||||
this.opening.resolve(this);
|
||||
}.bind(this));
|
||||
} else {
|
||||
// Resolve book opened promise
|
||||
this.opening.resolve(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Book.prototype.loadNavigation = function(opf){
|
||||
|
@ -311,34 +328,8 @@ Book.prototype.setRequestHeaders = function(_headers) {
|
|||
* Unarchive a zipped epub
|
||||
*/
|
||||
Book.prototype.unarchive = function(bookUrl, encoding){
|
||||
this.unarchived = new Unarchive();
|
||||
return this.unarchived.open(bookUrl, encoding);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if url has a .epub or .zip extension, or is ArrayBuffer (of zip/epub)
|
||||
*/
|
||||
Book.prototype.isArchivedUrl = function(bookUrl){
|
||||
var extension;
|
||||
|
||||
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 = core.extension(bookUrl);
|
||||
|
||||
if(extension && (extension == "epub" || extension == "zip")){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
this.archive = new Archive();
|
||||
return this.archive.open(bookUrl, encoding);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -347,8 +338,8 @@ Book.prototype.isArchivedUrl = function(bookUrl){
|
|||
Book.prototype.coverUrl = function(){
|
||||
var retrieved = this.loaded.cover.
|
||||
then(function(url) {
|
||||
if(this.unarchived) {
|
||||
return this.unarchived.createUrl(this.cover);
|
||||
if(this.archived) {
|
||||
return this.archive.createUrl(this.cover);
|
||||
}else{
|
||||
return this.cover;
|
||||
}
|
||||
|
@ -359,6 +350,17 @@ Book.prototype.coverUrl = function(){
|
|||
return retrieved;
|
||||
};
|
||||
|
||||
Book.prototype.replacements = function(){
|
||||
this.spine.hooks.serialize.register(function(output, section) {
|
||||
section.output = this.resources.substitute(output, section.url);
|
||||
}.bind(this));
|
||||
|
||||
return this.resources.replacements().
|
||||
then(function() {
|
||||
return this.resources.replaceCss();
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a DOM Range for a given CFI Range
|
||||
*/
|
||||
|
|
49
src/core.js
49
src/core.js
|
@ -12,6 +12,7 @@ var requestAnimationFrame = (typeof window != 'undefined') ? (window.requestAnim
|
|||
*/
|
||||
function Url(urlString, baseString) {
|
||||
var absolute = (urlString.indexOf('://') > -1);
|
||||
var pathname;
|
||||
|
||||
this.href = urlString;
|
||||
this.protocol = "";
|
||||
|
@ -20,7 +21,7 @@ function Url(urlString, baseString) {
|
|||
this.search = "";
|
||||
this.base = baseString || undefined;
|
||||
|
||||
if (!absolute && !baseString) {
|
||||
if (!absolute && typeof(baseString) !== "string") {
|
||||
this.base = window && window.location.href;
|
||||
}
|
||||
|
||||
|
@ -32,12 +33,15 @@ function Url(urlString, baseString) {
|
|||
this.origin = this.Url.origin;
|
||||
this.fragment = this.Url.fragment;
|
||||
this.search = this.Url.search;
|
||||
|
||||
pathname = this.Url.pathname;
|
||||
} catch (e) {
|
||||
// console.error(e);
|
||||
this.Url = undefined;
|
||||
pathname = urlString;
|
||||
}
|
||||
|
||||
this.Path = new Path(this.Url.pathname);
|
||||
this.Path = new Path(pathname);
|
||||
this.directory = this.Path.directory;
|
||||
this.filename = this.Path.filename;
|
||||
this.extension = this.Path.extension;
|
||||
|
@ -96,6 +100,10 @@ Path.prototype.parse = function (what) {
|
|||
return path.parse(what);
|
||||
};
|
||||
|
||||
Path.prototype.isAbsolute = function (what) {
|
||||
return path.isAbsolute(what || this.path);
|
||||
};
|
||||
|
||||
Path.prototype.isDirectory = function (what) {
|
||||
return (what.charAt(what.length-1) === '/');
|
||||
};
|
||||
|
@ -122,41 +130,6 @@ function assertPath(path) {
|
|||
}
|
||||
};
|
||||
|
||||
function extension(_url) {
|
||||
var url;
|
||||
var pathname;
|
||||
var ext;
|
||||
|
||||
try {
|
||||
url = new Url(url);
|
||||
pathname = url.pathname;
|
||||
} catch (e) {
|
||||
pathname = _url;
|
||||
}
|
||||
|
||||
ext = path.extname(pathname);
|
||||
if (ext) {
|
||||
return ext.slice(1);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function directory(_url) {
|
||||
var url;
|
||||
var pathname;
|
||||
var ext;
|
||||
|
||||
try {
|
||||
url = new Url(url);
|
||||
pathname = url.pathname;
|
||||
} catch (e) {
|
||||
pathname = _url;
|
||||
}
|
||||
|
||||
return path.dirname(pathname);
|
||||
}
|
||||
|
||||
function isElement(obj) {
|
||||
return !!(obj && obj.nodeType == 1);
|
||||
};
|
||||
|
@ -630,8 +603,6 @@ function defer() {
|
|||
|
||||
|
||||
module.exports = {
|
||||
'extension' : extension,
|
||||
'directory' : directory,
|
||||
'isElement': isElement,
|
||||
'uuid': uuid,
|
||||
'values': values,
|
||||
|
|
155
src/rendition.js
155
src/rendition.js
|
@ -58,11 +58,6 @@ function Rendition(book, options) {
|
|||
// this.starting = new core.defer();
|
||||
// this.started = this.starting.promise;
|
||||
this.q.enqueue(this.start);
|
||||
|
||||
if(this.book.archived) {
|
||||
this.q.enqueue(this.replacements.bind(this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Rendition.prototype.setManager = function(manager) {
|
||||
|
@ -400,156 +395,6 @@ Rendition.prototype.triggerSelectedEvent = function(cfirange){
|
|||
this.emit("selected", cfirange);
|
||||
};
|
||||
|
||||
Rendition.prototype.replacements = function(){
|
||||
// Wait for loading
|
||||
// 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];
|
||||
});
|
||||
|
||||
// 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;
|
||||
}
|
||||
});
|
||||
|
||||
// Css Urls
|
||||
var cssUrls = css.map(function(item) {
|
||||
return item.href;
|
||||
});
|
||||
|
||||
// All Assets Urls
|
||||
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 absolute = new URL(url, this.book.baseUrl).toString();
|
||||
var absolute = this.book.resolve(url);
|
||||
// Full url from archive base
|
||||
return this.book.unarchived.createUrl(absolute, {"base64": this.settings.useBase64});
|
||||
}.bind(this));
|
||||
|
||||
var replacementUrls;
|
||||
|
||||
// After all the urls are created
|
||||
return Promise.all(processing)
|
||||
.then(function(_replacementUrls) {
|
||||
var replaced = [];
|
||||
|
||||
replacementUrls = _replacementUrls;
|
||||
|
||||
// Replace Asset Urls in the text of all css files
|
||||
cssUrls.forEach(function(href) {
|
||||
replaced.push(this.replaceCss(href, urls, replacementUrls));
|
||||
}.bind(this));
|
||||
|
||||
return Promise.all(replaced);
|
||||
|
||||
}.bind(this))
|
||||
.then(function () {
|
||||
// Replace Asset Urls in chapters
|
||||
// by registering a hook after the sections contents has been serialized
|
||||
this.book.spine.hooks.serialize.register(function(output, section) {
|
||||
|
||||
this.replaceAssets(section, urls, replacementUrls);
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}.bind(this))
|
||||
.catch(function(reason){
|
||||
console.error(reason);
|
||||
});
|
||||
// }.bind(this));
|
||||
};
|
||||
|
||||
Rendition.prototype.replaceCss = function(href, urls, replacementUrls){
|
||||
var newUrl;
|
||||
var indexInUrls;
|
||||
|
||||
// Find the absolute url of the css file
|
||||
// var fileUri = URI(href);
|
||||
// var absolute = fileUri.absoluteTo(this.book.baseUrl).toString();
|
||||
|
||||
if (path.isAbsolute(href)) {
|
||||
return new Promise(function(resolve, reject){
|
||||
resolve(urls, replacementUrls);
|
||||
});
|
||||
}
|
||||
|
||||
var fileUri;
|
||||
var absolute = this.book.resolve(href);
|
||||
|
||||
// Get the text of the css file from the archive
|
||||
var textResponse = this.book.unarchived.getText(absolute);
|
||||
// Get asset links relative to css file
|
||||
var relUrls = urls.
|
||||
map(function(assetHref) {
|
||||
var resolved = this.book.resolve(assetHref);
|
||||
var relative = new Path(absolute).relative(resolved);
|
||||
|
||||
return relative;
|
||||
}.bind(this));
|
||||
|
||||
return textResponse.then(function (text) {
|
||||
// Replacements in the css text
|
||||
text = replace.substitute(text, relUrls, replacementUrls);
|
||||
|
||||
// Get the new url
|
||||
if (this.settings.useBase64) {
|
||||
newUrl = core.createBase64Url(text, 'text/css');
|
||||
} else {
|
||||
newUrl = core.createBlobUrl(text, 'text/css');
|
||||
}
|
||||
|
||||
// switch the url in the replacementUrls
|
||||
indexInUrls = urls.indexOf(href);
|
||||
if (indexInUrls > -1) {
|
||||
replacementUrls[indexInUrls] = newUrl;
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject){
|
||||
resolve(urls, replacementUrls);
|
||||
});
|
||||
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
|
||||
Rendition.prototype.replaceAssets = function(section, urls, replacementUrls){
|
||||
// var fileUri = URI(section.url);
|
||||
var fileUri;
|
||||
var absolute = section.url;
|
||||
|
||||
// Get Urls relative to current sections
|
||||
var relUrls = urls.
|
||||
map(function(href) {
|
||||
var resolved = this.book.resolve(href);
|
||||
var relative = new Path(absolute).relative(resolved);
|
||||
|
||||
return relative;
|
||||
}.bind(this));
|
||||
|
||||
section.output = replace.substitute(section.output, relUrls, replacementUrls);
|
||||
};
|
||||
|
||||
Rendition.prototype.range = function(_cfi, ignoreClass){
|
||||
var cfi = new EpubCFI(_cfi);
|
||||
var found = this.visible().filter(function (view) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var core = require('./core');
|
||||
var Path = require('./core').Path;
|
||||
|
||||
function request(url, type, withCredentials, headers) {
|
||||
var supportsURL = (typeof window != "undefined") ? window.URL : false; // TODO: fallback for url if window isn't defined
|
||||
|
@ -40,9 +41,7 @@ function request(url, type, withCredentials, headers) {
|
|||
|
||||
// If type isn't set, determine it from the file extension
|
||||
if(!type) {
|
||||
// uri = new URI(url);
|
||||
// type = uri.suffix();
|
||||
type = core.extension(url);
|
||||
type = new Path(url).extension;
|
||||
}
|
||||
|
||||
if(type == 'blob'){
|
||||
|
|
172
src/resources.js
Normal file
172
src/resources.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
var replace = require('./replacements');
|
||||
var core = require('./core');
|
||||
var Path = require('./core').Path;
|
||||
var path = require('path');
|
||||
|
||||
function Resources(manifest, options) {
|
||||
this.settings = {
|
||||
base64: (options && options.base64) || true,
|
||||
archive: (options && options.archive),
|
||||
resolver: (options && options.resolver)
|
||||
};
|
||||
this.manifest = manifest;
|
||||
this.resources = Object.keys(manifest).
|
||||
map(function (key){
|
||||
return manifest[key];
|
||||
});
|
||||
|
||||
this.replacementUrls = undefined;
|
||||
|
||||
this.split();
|
||||
this.urls();
|
||||
}
|
||||
|
||||
Resources.prototype.split = function(){
|
||||
|
||||
// HTML
|
||||
this.html = this.resources.
|
||||
filter(function (item){
|
||||
if (item.type === "application/xhtml+xml" ||
|
||||
item.type === "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Exclude HTML
|
||||
this.assets = this.resources.
|
||||
filter(function (item){
|
||||
if (item.type !== "application/xhtml+xml" &&
|
||||
item.type !== "text/html") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Only CSS
|
||||
this.css = this.resources.
|
||||
filter(function (item){
|
||||
if (item.type === "text/css") {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Resources.prototype.urls = function(){
|
||||
|
||||
// All Assets Urls
|
||||
this.urls = this.assets.
|
||||
map(function(item) {
|
||||
return item.href;
|
||||
}.bind(this));
|
||||
|
||||
// Css Urls
|
||||
this.cssUrls = this.css.map(function(item) {
|
||||
return item.href;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create blob urls for all the assets
|
||||
* @param {Archive} archive
|
||||
* @param {resolver} resolver Url resolver
|
||||
* @return {Promise} returns replacement urls
|
||||
*/
|
||||
Resources.prototype.replacements = function(archive, resolver){
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
var replacements = this.urls.
|
||||
map(function(url) {
|
||||
var absolute = resolver(url);
|
||||
|
||||
return archive.createUrl(absolute, {"base64": this.settings.base64});
|
||||
}.bind(this))
|
||||
|
||||
return Promise.all(replacements)
|
||||
.then(function(replacementUrls) {
|
||||
this.replacementUrls = replacementUrls;
|
||||
return replacementUrls;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Resources.prototype.replaceCss = function(archive, resolver){
|
||||
var replaced = [];
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
this.cssUrls.forEach(function(href) {
|
||||
var replacment = this.createCssFile(href, archive, resolver)
|
||||
.then(function (replacementUrl) {
|
||||
// switch the url in the replacementUrls
|
||||
var indexInUrls = this.urls.indexOf(href);
|
||||
if (indexInUrls > -1) {
|
||||
this.replacementUrls[indexInUrls] = replacementUrl;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
replaced.push(replacment);
|
||||
}.bind(this));
|
||||
return Promise.all(replaced);
|
||||
};
|
||||
|
||||
Resources.prototype.createCssFile = function(href, archive, resolver){
|
||||
var newUrl;
|
||||
var indexInUrls;
|
||||
archive = archive || this.settings.archive;
|
||||
resolver = resolver || this.settings.resolver;
|
||||
|
||||
if (path.isAbsolute(href)) {
|
||||
return new Promise(function(resolve, reject){
|
||||
resolve(urls, replacementUrls);
|
||||
});
|
||||
}
|
||||
|
||||
var absolute = resolver(href);
|
||||
|
||||
// Get the text of the css file from the archive
|
||||
var textResponse = archive.getText(absolute);
|
||||
// Get asset links relative to css file
|
||||
var relUrls = this.urls.map(function(assetHref) {
|
||||
var resolved = resolver(assetHref);
|
||||
var relative = new Path(absolute).relative(resolved);
|
||||
|
||||
return relative;
|
||||
}.bind(this));
|
||||
|
||||
return textResponse.then(function (text) {
|
||||
// Replacements in the css text
|
||||
text = replace.substitute(text, relUrls, this.replacementUrls);
|
||||
|
||||
// Get the new url
|
||||
if (this.settings.base64) {
|
||||
newUrl = core.createBase64Url(text, 'text/css');
|
||||
} else {
|
||||
newUrl = core.createBlobUrl(text, 'text/css');
|
||||
}
|
||||
|
||||
return newUrl;
|
||||
}.bind(this));
|
||||
|
||||
};
|
||||
|
||||
Resources.prototype.relativeTo = function(absolute, resolver){
|
||||
resolver = resolver || this.settings.resolver;
|
||||
|
||||
// Get Urls relative to current sections
|
||||
return this.urls.
|
||||
map(function(href) {
|
||||
var resolved = resolver(href);
|
||||
var relative = new Path(absolute).relative(resolved);
|
||||
return relative;
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Resources.prototype.substitute = function(content, url) {
|
||||
var relUrls;
|
||||
if (url) {
|
||||
relUrls = this.relativeTo(url);
|
||||
} else {
|
||||
relUrls = this.urls;
|
||||
}
|
||||
return replace.substitute(content, relUrls, this.replacementUrls);
|
||||
};
|
||||
|
||||
module.exports = Resources;
|
|
@ -1,6 +1,7 @@
|
|||
var core = require('./core');
|
||||
var EpubCFI = require('./epubcfi');
|
||||
var Hook = require('./hook');
|
||||
var Url = require('./core').Url;
|
||||
|
||||
function Section(item, hooks){
|
||||
this.idref = item.idref;
|
||||
|
@ -36,7 +37,7 @@ Section.prototype.load = function(_request){
|
|||
request(this.url)
|
||||
.then(function(xml){
|
||||
var base;
|
||||
var directory = core.directory(this.url);
|
||||
var directory = new Url(this.url).directory;
|
||||
|
||||
this.document = xml;
|
||||
this.contents = xml.documentElement;
|
||||
|
|
|
@ -45,7 +45,7 @@ describe('ePub', function() {
|
|||
|
||||
return book.opened.then(function(){
|
||||
assert.equal( book.isOpen, true, "book is opened" );
|
||||
assert( book.unarchived, "book is unarchived" );
|
||||
assert( book.archive, "book is unarchived" );
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue