1
0
Fork 0
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:
Fred Chasen 2016-11-08 16:05:47 +01:00
parent 47787678f7
commit b5cfc74e12
8 changed files with 252 additions and 260 deletions

View file

@ -1,15 +1,16 @@
var core = require('./core'); var core = require('./core');
var request = require('./request'); var request = require('./request');
var mime = require('../libs/mime/mime'); var mime = require('../libs/mime/mime');
var Path = require('./core').Path;
function Unarchive() { function Archive() {
this.checkRequirements(); this.checkRequirements();
this.urlCache = {}; this.urlCache = {};
} }
Unarchive.prototype.checkRequirements = function(callback){ Archive.prototype.checkRequirements = function(callback){
try { try {
if (typeof JSZip === 'undefined') { if (typeof JSZip === 'undefined') {
JSZip = require('jszip'); 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}); return this.zip.loadAsync(input, {"base64": isBase64});
}; };
Unarchive.prototype.openUrl = function(zipUrl, isBase64){ Archive.prototype.openUrl = function(zipUrl, isBase64){
return request(zipUrl, "binary") return request(zipUrl, "binary")
.then(function(data){ .then(function(data){
return this.zip.loadAsync(data, {"base64": isBase64}); return this.zip.loadAsync(data, {"base64": isBase64});
}.bind(this)); }.bind(this));
}; };
Unarchive.prototype.request = function(url, type){ Archive.prototype.request = function(url, type){
var deferred = new core.defer(); var deferred = new core.defer();
var response; var response;
var r; var r;
var path = new Path(url);
// If type isn't set, determine it from the file extension // If type isn't set, determine it from the file extension
if(!type) { if(!type) {
type = core.extension(url); type = path.extension;
} }
if(type == 'blob'){ if(type == 'blob'){
@ -61,7 +63,7 @@ Unarchive.prototype.request = function(url, type){
return deferred.promise; return deferred.promise;
}; };
Unarchive.prototype.handleResponse = function(response, type){ Archive.prototype.handleResponse = function(response, type){
var r; var r;
if(type == "json") { if(type == "json") {
@ -85,7 +87,7 @@ Unarchive.prototype.handleResponse = function(response, type){
return r; 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 decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
var entry = this.zip.file(decodededUrl); var entry = this.zip.file(decodededUrl);
var mimeType; 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 decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
var entry = this.zip.file(decodededUrl); 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 decodededUrl = window.decodeURIComponent(url.substr(1)); // Remove first slash
var entry = this.zip.file(decodededUrl); var entry = this.zip.file(decodededUrl);
var mimeType; 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 deferred = new core.defer();
var _URL = window.URL || window.webkitURL || window.mozURL; var _URL = window.URL || window.webkitURL || window.mozURL;
var tempUrl; var tempUrl;
@ -175,10 +177,10 @@ Unarchive.prototype.createUrl = function(url, options){
return deferred.promise; return deferred.promise;
}; };
Unarchive.prototype.revokeUrl = function(url){ Archive.prototype.revokeUrl = function(url){
var _URL = window.URL || window.webkitURL || window.mozURL; var _URL = window.URL || window.webkitURL || window.mozURL;
var fromCache = this.urlCache[url]; var fromCache = this.urlCache[url];
if(fromCache) _URL.revokeObjectURL(fromCache); if(fromCache) _URL.revokeObjectURL(fromCache);
}; };
module.exports = Unarchive; module.exports = Archive;

View file

@ -9,8 +9,9 @@ var Parser = require('./parser');
var Container = require('./container'); var Container = require('./container');
var Packaging = require('./packaging'); var Packaging = require('./packaging');
var Navigation = require('./navigation'); var Navigation = require('./navigation');
var Resources = require('./resources');
var Rendition = require('./rendition'); var Rendition = require('./rendition');
var Unarchive = require('./unarchive'); var Archive = require('./archive');
var request = require('./request'); var request = require('./request');
var EpubCFI = require('./epubcfi'); var EpubCFI = require('./epubcfi');
@ -31,7 +32,8 @@ function Book(url, options){
this.settings = core.extend(this.settings || {}, { this.settings = core.extend(this.settings || {}, {
requestMethod: this.requestMethod, requestMethod: this.requestMethod,
requestCredentials: undefined, 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); core.extend(this.settings, options);
@ -51,7 +53,8 @@ function Book(url, options){
metadata: new core.defer(), metadata: new core.defer(),
cover: new core.defer(), cover: new core.defer(),
navigation: new core.defer(), navigation: new core.defer(),
pageList: new core.defer() pageList: new core.defer(),
resources: new core.defer()
}; };
this.loaded = { this.loaded = {
@ -60,7 +63,8 @@ function Book(url, options){
metadata: this.loading.metadata.promise, metadata: this.loading.metadata.promise,
cover: this.loading.cover.promise, cover: this.loading.cover.promise,
navigation: this.loading.navigation.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); // this.ready = RSVP.hash(this.loaded);
@ -72,7 +76,7 @@ function Book(url, options){
this.loaded.metadata, this.loaded.metadata,
this.loaded.cover, this.loaded.cover,
this.loaded.navigation, this.loaded.navigation,
this.loaded.pageList ]); this.loaded.resources ]);
// Queue for methods used before opening // Queue for methods used before opening
@ -128,22 +132,20 @@ Book.prototype.open = function(input, what){
if (type === "binary") { if (type === "binary") {
this.archived = true; this.archived = true;
this.url = new Url("/", "");
opening = this.openEpub(input); opening = this.openEpub(input);
} else if (type === "epub") { } else if (type === "epub") {
this.archived = true; this.archived = true;
this.url = new Url("/", "");
opening = this.request(input, 'binary') opening = this.request(input, 'binary')
.then(function(epubData) { .then(this.openEpub.bind(this));
return this.openEpub(epubData);
}.bind(this));
} else if(type == "opf") { } else if(type == "opf") {
this.url = new Url(input); this.url = new Url(input);
opening = this.openPackaging(input); opening = this.openPackaging(input);
} else { } else {
this.url = new Url(input); this.url = new Url(input);
opening = this.openContainer(CONTAINER_PATH) opening = this.openContainer(CONTAINER_PATH)
.then(function(packagePath) { .then(this.openPackaging.bind(this));
return this.openPackaging(packagePath);
}.bind(this))
} }
return opening; return opening;
@ -152,10 +154,10 @@ Book.prototype.open = function(input, what){
Book.prototype.openEpub = function(data, encoding){ Book.prototype.openEpub = function(data, encoding){
return this.unarchive(data, encoding || this.settings.encoding) return this.unarchive(data, encoding || this.settings.encoding)
.then(function() { .then(function() {
return this.openContainer("/" + CONTAINER_PATH); return this.openContainer(CONTAINER_PATH);
}.bind(this)) }.bind(this))
.then(function(packagePath) { .then(function(packagePath) {
return this.openPackaging("/" + packagePath); return this.openPackaging(packagePath);
}.bind(this)); }.bind(this));
}; };
@ -163,7 +165,7 @@ Book.prototype.openContainer = function(url){
return this.load(url) return this.load(url)
.then(function(xml) { .then(function(xml) {
this.container = new Container(xml); this.container = new Container(xml);
return this.container.packagePath; return this.resolve(this.container.packagePath);
}.bind(this)); }.bind(this));
}; };
@ -180,9 +182,9 @@ Book.prototype.openPackaging = function(url){
Book.prototype.load = function (path) { Book.prototype.load = function (path) {
var resolved; var resolved;
if(this.unarchived) { if(this.archived) {
resolved = this.resolve(path); resolved = this.resolve(path);
return this.unarchived.request(resolved); return this.archive.request(resolved);
} else { } else {
resolved = this.resolve(path); resolved = this.resolve(path);
return this.request(resolved, null, this.requestCredentials, this.requestHeaders); 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.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.loadNavigation(this.package).then(function(toc){
this.toc = toc; this.toc = toc;
this.loading.navigation.resolve(this.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.metadata.resolve(this.package.metadata);
this.loading.spine.resolve(this.spine); this.loading.spine.resolve(this.spine);
this.loading.cover.resolve(this.cover); this.loading.cover.resolve(this.cover);
this.loading.resources.resolve(this.resources);
this.isOpen = true; this.isOpen = true;
// Resolve book opened promise if(this.archived) {
this.opening.resolve(this); this.replacements().then(function() {
this.opening.resolve(this);
}.bind(this));
} else {
// Resolve book opened promise
this.opening.resolve(this);
}
}; };
Book.prototype.loadNavigation = function(opf){ Book.prototype.loadNavigation = function(opf){
@ -311,34 +328,8 @@ Book.prototype.setRequestHeaders = function(_headers) {
* Unarchive a zipped epub * Unarchive a zipped epub
*/ */
Book.prototype.unarchive = function(bookUrl, encoding){ Book.prototype.unarchive = function(bookUrl, encoding){
this.unarchived = new Unarchive(); this.archive = new Archive();
return this.unarchived.open(bookUrl, encoding); return this.archive.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;
}; };
/** /**
@ -347,8 +338,8 @@ Book.prototype.isArchivedUrl = function(bookUrl){
Book.prototype.coverUrl = function(){ Book.prototype.coverUrl = function(){
var retrieved = this.loaded.cover. var retrieved = this.loaded.cover.
then(function(url) { then(function(url) {
if(this.unarchived) { if(this.archived) {
return this.unarchived.createUrl(this.cover); return this.archive.createUrl(this.cover);
}else{ }else{
return this.cover; return this.cover;
} }
@ -359,6 +350,17 @@ Book.prototype.coverUrl = function(){
return retrieved; 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 * Find a DOM Range for a given CFI Range
*/ */

View file

@ -12,6 +12,7 @@ var requestAnimationFrame = (typeof window != 'undefined') ? (window.requestAnim
*/ */
function Url(urlString, baseString) { function Url(urlString, baseString) {
var absolute = (urlString.indexOf('://') > -1); var absolute = (urlString.indexOf('://') > -1);
var pathname;
this.href = urlString; this.href = urlString;
this.protocol = ""; this.protocol = "";
@ -20,7 +21,7 @@ function Url(urlString, baseString) {
this.search = ""; this.search = "";
this.base = baseString || undefined; this.base = baseString || undefined;
if (!absolute && !baseString) { if (!absolute && typeof(baseString) !== "string") {
this.base = window && window.location.href; this.base = window && window.location.href;
} }
@ -32,12 +33,15 @@ function Url(urlString, baseString) {
this.origin = this.Url.origin; this.origin = this.Url.origin;
this.fragment = this.Url.fragment; this.fragment = this.Url.fragment;
this.search = this.Url.search; this.search = this.Url.search;
pathname = this.Url.pathname;
} catch (e) { } catch (e) {
// console.error(e); // console.error(e);
this.Url = undefined; this.Url = undefined;
pathname = urlString;
} }
this.Path = new Path(this.Url.pathname); this.Path = new Path(pathname);
this.directory = this.Path.directory; this.directory = this.Path.directory;
this.filename = this.Path.filename; this.filename = this.Path.filename;
this.extension = this.Path.extension; this.extension = this.Path.extension;
@ -96,6 +100,10 @@ Path.prototype.parse = function (what) {
return path.parse(what); return path.parse(what);
}; };
Path.prototype.isAbsolute = function (what) {
return path.isAbsolute(what || this.path);
};
Path.prototype.isDirectory = function (what) { Path.prototype.isDirectory = function (what) {
return (what.charAt(what.length-1) === '/'); 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) { function isElement(obj) {
return !!(obj && obj.nodeType == 1); return !!(obj && obj.nodeType == 1);
}; };
@ -630,8 +603,6 @@ function defer() {
module.exports = { module.exports = {
'extension' : extension,
'directory' : directory,
'isElement': isElement, 'isElement': isElement,
'uuid': uuid, 'uuid': uuid,
'values': values, 'values': values,

View file

@ -58,11 +58,6 @@ function Rendition(book, options) {
// this.starting = new core.defer(); // this.starting = new core.defer();
// this.started = this.starting.promise; // this.started = this.starting.promise;
this.q.enqueue(this.start); this.q.enqueue(this.start);
if(this.book.archived) {
this.q.enqueue(this.replacements.bind(this));
}
}; };
Rendition.prototype.setManager = function(manager) { Rendition.prototype.setManager = function(manager) {
@ -400,156 +395,6 @@ Rendition.prototype.triggerSelectedEvent = function(cfirange){
this.emit("selected", 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){ Rendition.prototype.range = function(_cfi, ignoreClass){
var cfi = new EpubCFI(_cfi); var cfi = new EpubCFI(_cfi);
var found = this.visible().filter(function (view) { var found = this.visible().filter(function (view) {

View file

@ -1,4 +1,5 @@
var core = require('./core'); var core = require('./core');
var Path = require('./core').Path;
function request(url, type, withCredentials, headers) { function request(url, type, withCredentials, headers) {
var supportsURL = (typeof window != "undefined") ? window.URL : false; // TODO: fallback for url if window isn't defined var supportsURL = (typeof window != "undefined") ? window.URL : false; // TODO: fallback for url if window isn't defined
@ -40,9 +41,7 @@ function request(url, type, withCredentials, headers) {
// If type isn't set, determine it from the file extension // If type isn't set, determine it from the file extension
if(!type) { if(!type) {
// uri = new URI(url); type = new Path(url).extension;
// type = uri.suffix();
type = core.extension(url);
} }
if(type == 'blob'){ if(type == 'blob'){

172
src/resources.js Normal file
View 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;

View file

@ -1,6 +1,7 @@
var core = require('./core'); var core = require('./core');
var EpubCFI = require('./epubcfi'); var EpubCFI = require('./epubcfi');
var Hook = require('./hook'); var Hook = require('./hook');
var Url = require('./core').Url;
function Section(item, hooks){ function Section(item, hooks){
this.idref = item.idref; this.idref = item.idref;
@ -36,7 +37,7 @@ Section.prototype.load = function(_request){
request(this.url) request(this.url)
.then(function(xml){ .then(function(xml){
var base; var base;
var directory = core.directory(this.url); var directory = new Url(this.url).directory;
this.document = xml; this.document = xml;
this.contents = xml.documentElement; this.contents = xml.documentElement;

View file

@ -45,7 +45,7 @@ describe('ePub', function() {
return book.opened.then(function(){ return book.opened.then(function(){
assert.equal( book.isOpen, true, "book is opened" ); assert.equal( book.isOpen, true, "book is opened" );
assert( book.unarchived, "book is unarchived" ); assert( book.archive, "book is unarchived" );
}); });
}); });