mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-02 14:49:16 +02:00
Added pageList, initial documentation
This commit is contained in:
parent
52fd6fa7d3
commit
d14280b917
42 changed files with 7799 additions and 259 deletions
6
documentation.yml
Normal file
6
documentation.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
toc:
|
||||||
|
- ePub
|
||||||
|
- name: ePubJS
|
||||||
|
description: |
|
||||||
|
main entry
|
||||||
|
- EpubCFI
|
197
documentation/html/assets/anchor.js
Normal file
197
documentation/html/assets/anchor.js
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/*!
|
||||||
|
* AnchorJS - v1.2.1 - 2015-07-02
|
||||||
|
* https://github.com/bryanbraun/anchorjs
|
||||||
|
* Copyright (c) 2015 Bryan Braun; Licensed MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
function AnchorJS(options) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
this._applyRemainingDefaultOptions = function(opts) {
|
||||||
|
this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
|
||||||
|
this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always'
|
||||||
|
this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left'
|
||||||
|
this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
|
||||||
|
};
|
||||||
|
|
||||||
|
this._applyRemainingDefaultOptions(options);
|
||||||
|
|
||||||
|
this.add = function(selector) {
|
||||||
|
var elements,
|
||||||
|
elsWithIds,
|
||||||
|
idList,
|
||||||
|
elementID,
|
||||||
|
i,
|
||||||
|
roughText,
|
||||||
|
tidyText,
|
||||||
|
index,
|
||||||
|
count,
|
||||||
|
newTidyText,
|
||||||
|
readableID,
|
||||||
|
anchor;
|
||||||
|
|
||||||
|
this._applyRemainingDefaultOptions(this.options);
|
||||||
|
|
||||||
|
// Provide a sensible default selector, if none is given.
|
||||||
|
if (!selector) {
|
||||||
|
selector = 'h1, h2, h3, h4, h5, h6';
|
||||||
|
} else if (typeof selector !== 'string') {
|
||||||
|
throw new Error('The selector provided to AnchorJS was invalid.');
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = document.querySelectorAll(selector);
|
||||||
|
if (elements.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._addBaselineStyles();
|
||||||
|
|
||||||
|
// We produce a list of existing IDs so we don't generate a duplicate.
|
||||||
|
elsWithIds = document.querySelectorAll('[id]');
|
||||||
|
idList = [].map.call(elsWithIds, function assign(el) {
|
||||||
|
return el.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (i = 0; i < elements.length; i++) {
|
||||||
|
|
||||||
|
if (elements[i].hasAttribute('id')) {
|
||||||
|
elementID = elements[i].getAttribute('id');
|
||||||
|
} else {
|
||||||
|
roughText = elements[i].textContent;
|
||||||
|
|
||||||
|
// Refine it so it makes a good ID. Strip out non-safe characters, replace
|
||||||
|
// spaces with hyphens, truncate to 32 characters, and make toLowerCase.
|
||||||
|
//
|
||||||
|
// Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.'
|
||||||
|
tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment'
|
||||||
|
.replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment'
|
||||||
|
.replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment'
|
||||||
|
.substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
|
||||||
|
.replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
|
||||||
|
.toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url'
|
||||||
|
|
||||||
|
// Compare our generated ID to existing IDs (and increment it if needed)
|
||||||
|
// before we add it to the page.
|
||||||
|
newTidyText = tidyText;
|
||||||
|
count = 0;
|
||||||
|
do {
|
||||||
|
if (index !== undefined) {
|
||||||
|
newTidyText = tidyText + '-' + count;
|
||||||
|
}
|
||||||
|
// .indexOf is supported in IE9+.
|
||||||
|
index = idList.indexOf(newTidyText);
|
||||||
|
count += 1;
|
||||||
|
} while (index !== -1);
|
||||||
|
index = undefined;
|
||||||
|
idList.push(newTidyText);
|
||||||
|
|
||||||
|
// Assign it to our element.
|
||||||
|
// Currently the setAttribute element is only supported in IE9 and above.
|
||||||
|
elements[i].setAttribute('id', newTidyText);
|
||||||
|
|
||||||
|
elementID = newTidyText;
|
||||||
|
}
|
||||||
|
|
||||||
|
readableID = elementID.replace(/-/g, ' ');
|
||||||
|
|
||||||
|
// The following code builds the following DOM structure in a more effiecient (albeit opaque) way.
|
||||||
|
// '<a class="anchorjs-link ' + this.options.class + '" href="#' + elementID + '" aria-label="Anchor link for: ' + readableID + '" data-anchorjs-icon="' + this.options.icon + '"></a>';
|
||||||
|
anchor = document.createElement('a');
|
||||||
|
anchor.className = 'anchorjs-link ' + this.options.class;
|
||||||
|
anchor.href = '#' + elementID;
|
||||||
|
anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
|
||||||
|
anchor.setAttribute('data-anchorjs-icon', this.options.icon);
|
||||||
|
|
||||||
|
if (this.options.visible === 'always') {
|
||||||
|
anchor.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.icon === '\ue9cb') {
|
||||||
|
anchor.style.fontFamily = 'anchorjs-icons';
|
||||||
|
anchor.style.fontStyle = 'normal';
|
||||||
|
anchor.style.fontVariant = 'normal';
|
||||||
|
anchor.style.fontWeight = 'normal';
|
||||||
|
anchor.style.lineHeight = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.placement === 'left') {
|
||||||
|
anchor.style.position = 'absolute';
|
||||||
|
anchor.style.marginLeft = '-1em';
|
||||||
|
anchor.style.paddingRight = '0.5em';
|
||||||
|
elements[i].insertBefore(anchor, elements[i].firstChild);
|
||||||
|
} else { // if the option provided is `right` (or anything else).
|
||||||
|
anchor.style.paddingLeft = '0.375em';
|
||||||
|
elements[i].appendChild(anchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function(selector) {
|
||||||
|
var domAnchor,
|
||||||
|
elements = document.querySelectorAll(selector);
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
domAnchor = elements[i].querySelector('.anchorjs-link');
|
||||||
|
if (domAnchor) {
|
||||||
|
elements[i].removeChild(domAnchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
this._addBaselineStyles = function() {
|
||||||
|
// We don't want to add global baseline styles if they've been added before.
|
||||||
|
if (document.head.querySelector('style.anchorjs') !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var style = document.createElement('style'),
|
||||||
|
linkRule =
|
||||||
|
' .anchorjs-link {' +
|
||||||
|
' opacity: 0;' +
|
||||||
|
' text-decoration: none;' +
|
||||||
|
' -webkit-font-smoothing: antialiased;' +
|
||||||
|
' -moz-osx-font-smoothing: grayscale;' +
|
||||||
|
' }',
|
||||||
|
hoverRule =
|
||||||
|
' *:hover > .anchorjs-link,' +
|
||||||
|
' .anchorjs-link:focus {' +
|
||||||
|
' opacity: 1;' +
|
||||||
|
' }',
|
||||||
|
anchorjsLinkFontFace =
|
||||||
|
' @font-face {' +
|
||||||
|
' font-family: "anchorjs-icons";' +
|
||||||
|
' font-style: normal;' +
|
||||||
|
' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
|
||||||
|
' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' +
|
||||||
|
' }',
|
||||||
|
pseudoElContent =
|
||||||
|
' [data-anchorjs-icon]::after {' +
|
||||||
|
' content: attr(data-anchorjs-icon);' +
|
||||||
|
' }',
|
||||||
|
firstStyleEl;
|
||||||
|
|
||||||
|
style.className = 'anchorjs';
|
||||||
|
style.appendChild(document.createTextNode('')); // Necessary for Webkit.
|
||||||
|
|
||||||
|
// We place it in the head with the other style tags, if possible, so as to
|
||||||
|
// not look out of place. We insert before the others so these styles can be
|
||||||
|
// overridden if necessary.
|
||||||
|
firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
|
||||||
|
if (firstStyleEl === undefined) {
|
||||||
|
document.head.appendChild(style);
|
||||||
|
} else {
|
||||||
|
document.head.insertBefore(style, firstStyleEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
|
||||||
|
style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
|
||||||
|
style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
|
||||||
|
style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var anchors = new AnchorJS();
|
12
documentation/html/assets/bass-addons.css
Normal file
12
documentation/html/assets/bass-addons.css
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.input {
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: .875rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
543
documentation/html/assets/bass.css
Normal file
543
documentation/html/assets/bass.css
Normal file
|
@ -0,0 +1,543 @@
|
||||||
|
/*! Basscss | http://basscss.com | MIT License */
|
||||||
|
|
||||||
|
.h1{ font-size: 2rem }
|
||||||
|
.h2{ font-size: 1.5rem }
|
||||||
|
.h3{ font-size: 1.25rem }
|
||||||
|
.h4{ font-size: 1rem }
|
||||||
|
.h5{ font-size: .875rem }
|
||||||
|
.h6{ font-size: .75rem }
|
||||||
|
|
||||||
|
.font-family-inherit{ font-family:inherit }
|
||||||
|
.font-size-inherit{ font-size:inherit }
|
||||||
|
.text-decoration-none{ text-decoration:none }
|
||||||
|
|
||||||
|
.bold{ font-weight: bold; font-weight: bold }
|
||||||
|
.regular{ font-weight:normal }
|
||||||
|
.italic{ font-style:italic }
|
||||||
|
.caps{ text-transform:uppercase; letter-spacing: .2em; }
|
||||||
|
|
||||||
|
.left-align{ text-align:left }
|
||||||
|
.center{ text-align:center }
|
||||||
|
.right-align{ text-align:right }
|
||||||
|
.justify{ text-align:justify }
|
||||||
|
|
||||||
|
.nowrap{ white-space:nowrap }
|
||||||
|
.break-word{ word-wrap:break-word }
|
||||||
|
|
||||||
|
.line-height-1{ line-height: 1 }
|
||||||
|
.line-height-2{ line-height: 1.125 }
|
||||||
|
.line-height-3{ line-height: 1.25 }
|
||||||
|
.line-height-4{ line-height: 1.5 }
|
||||||
|
|
||||||
|
.list-style-none{ list-style:none }
|
||||||
|
.underline{ text-decoration:underline }
|
||||||
|
|
||||||
|
.truncate{
|
||||||
|
max-width:100%;
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow:ellipsis;
|
||||||
|
white-space:nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-reset{
|
||||||
|
list-style:none;
|
||||||
|
padding-left:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline{ display:inline }
|
||||||
|
.block{ display:block }
|
||||||
|
.inline-block{ display:inline-block }
|
||||||
|
.table{ display:table }
|
||||||
|
.table-cell{ display:table-cell }
|
||||||
|
|
||||||
|
.overflow-hidden{ overflow:hidden }
|
||||||
|
.overflow-scroll{ overflow:scroll }
|
||||||
|
.overflow-auto{ overflow:auto }
|
||||||
|
|
||||||
|
.clearfix:before,
|
||||||
|
.clearfix:after{
|
||||||
|
content:" ";
|
||||||
|
display:table
|
||||||
|
}
|
||||||
|
.clearfix:after{ clear:both }
|
||||||
|
|
||||||
|
.left{ float:left }
|
||||||
|
.right{ float:right }
|
||||||
|
|
||||||
|
.fit{ max-width:100% }
|
||||||
|
|
||||||
|
.max-width-1{ max-width: 24rem }
|
||||||
|
.max-width-2{ max-width: 32rem }
|
||||||
|
.max-width-3{ max-width: 48rem }
|
||||||
|
.max-width-4{ max-width: 64rem }
|
||||||
|
|
||||||
|
.border-box{ box-sizing:border-box }
|
||||||
|
|
||||||
|
.align-baseline{ vertical-align:baseline }
|
||||||
|
.align-top{ vertical-align:top }
|
||||||
|
.align-middle{ vertical-align:middle }
|
||||||
|
.align-bottom{ vertical-align:bottom }
|
||||||
|
|
||||||
|
.m0{ margin:0 }
|
||||||
|
.mt0{ margin-top:0 }
|
||||||
|
.mr0{ margin-right:0 }
|
||||||
|
.mb0{ margin-bottom:0 }
|
||||||
|
.ml0{ margin-left:0 }
|
||||||
|
.mx0{ margin-left:0; margin-right:0 }
|
||||||
|
.my0{ margin-top:0; margin-bottom:0 }
|
||||||
|
|
||||||
|
.m1{ margin: .5rem }
|
||||||
|
.mt1{ margin-top: .5rem }
|
||||||
|
.mr1{ margin-right: .5rem }
|
||||||
|
.mb1{ margin-bottom: .5rem }
|
||||||
|
.ml1{ margin-left: .5rem }
|
||||||
|
.mx1{ margin-left: .5rem; margin-right: .5rem }
|
||||||
|
.my1{ margin-top: .5rem; margin-bottom: .5rem }
|
||||||
|
|
||||||
|
.m2{ margin: 1rem }
|
||||||
|
.mt2{ margin-top: 1rem }
|
||||||
|
.mr2{ margin-right: 1rem }
|
||||||
|
.mb2{ margin-bottom: 1rem }
|
||||||
|
.ml2{ margin-left: 1rem }
|
||||||
|
.mx2{ margin-left: 1rem; margin-right: 1rem }
|
||||||
|
.my2{ margin-top: 1rem; margin-bottom: 1rem }
|
||||||
|
|
||||||
|
.m3{ margin: 2rem }
|
||||||
|
.mt3{ margin-top: 2rem }
|
||||||
|
.mr3{ margin-right: 2rem }
|
||||||
|
.mb3{ margin-bottom: 2rem }
|
||||||
|
.ml3{ margin-left: 2rem }
|
||||||
|
.mx3{ margin-left: 2rem; margin-right: 2rem }
|
||||||
|
.my3{ margin-top: 2rem; margin-bottom: 2rem }
|
||||||
|
|
||||||
|
.m4{ margin: 4rem }
|
||||||
|
.mt4{ margin-top: 4rem }
|
||||||
|
.mr4{ margin-right: 4rem }
|
||||||
|
.mb4{ margin-bottom: 4rem }
|
||||||
|
.ml4{ margin-left: 4rem }
|
||||||
|
.mx4{ margin-left: 4rem; margin-right: 4rem }
|
||||||
|
.my4{ margin-top: 4rem; margin-bottom: 4rem }
|
||||||
|
|
||||||
|
.mxn1{ margin-left: -.5rem; margin-right: -.5rem; }
|
||||||
|
.mxn2{ margin-left: -1rem; margin-right: -1rem; }
|
||||||
|
.mxn3{ margin-left: -2rem; margin-right: -2rem; }
|
||||||
|
.mxn4{ margin-left: -4rem; margin-right: -4rem; }
|
||||||
|
|
||||||
|
.ml-auto{ margin-left:auto }
|
||||||
|
.mr-auto{ margin-right:auto }
|
||||||
|
.mx-auto{ margin-left:auto; margin-right:auto; }
|
||||||
|
|
||||||
|
.p0{ padding:0 }
|
||||||
|
.pt0{ padding-top:0 }
|
||||||
|
.pr0{ padding-right:0 }
|
||||||
|
.pb0{ padding-bottom:0 }
|
||||||
|
.pl0{ padding-left:0 }
|
||||||
|
.px0{ padding-left:0; padding-right:0 }
|
||||||
|
.py0{ padding-top:0; padding-bottom:0 }
|
||||||
|
|
||||||
|
.p1{ padding: .5rem }
|
||||||
|
.pt1{ padding-top: .5rem }
|
||||||
|
.pr1{ padding-right: .5rem }
|
||||||
|
.pb1{ padding-bottom: .5rem }
|
||||||
|
.pl1{ padding-left: .5rem }
|
||||||
|
.py1{ padding-top: .5rem; padding-bottom: .5rem }
|
||||||
|
.px1{ padding-left: .5rem; padding-right: .5rem }
|
||||||
|
|
||||||
|
.p2{ padding: 1rem }
|
||||||
|
.pt2{ padding-top: 1rem }
|
||||||
|
.pr2{ padding-right: 1rem }
|
||||||
|
.pb2{ padding-bottom: 1rem }
|
||||||
|
.pl2{ padding-left: 1rem }
|
||||||
|
.py2{ padding-top: 1rem; padding-bottom: 1rem }
|
||||||
|
.px2{ padding-left: 1rem; padding-right: 1rem }
|
||||||
|
|
||||||
|
.p3{ padding: 2rem }
|
||||||
|
.pt3{ padding-top: 2rem }
|
||||||
|
.pr3{ padding-right: 2rem }
|
||||||
|
.pb3{ padding-bottom: 2rem }
|
||||||
|
.pl3{ padding-left: 2rem }
|
||||||
|
.py3{ padding-top: 2rem; padding-bottom: 2rem }
|
||||||
|
.px3{ padding-left: 2rem; padding-right: 2rem }
|
||||||
|
|
||||||
|
.p4{ padding: 4rem }
|
||||||
|
.pt4{ padding-top: 4rem }
|
||||||
|
.pr4{ padding-right: 4rem }
|
||||||
|
.pb4{ padding-bottom: 4rem }
|
||||||
|
.pl4{ padding-left: 4rem }
|
||||||
|
.py4{ padding-top: 4rem; padding-bottom: 4rem }
|
||||||
|
.px4{ padding-left: 4rem; padding-right: 4rem }
|
||||||
|
|
||||||
|
.col{
|
||||||
|
float:left;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-right{
|
||||||
|
float:right;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-1{
|
||||||
|
width:8.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-2{
|
||||||
|
width:16.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-3{
|
||||||
|
width:25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-4{
|
||||||
|
width:33.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-5{
|
||||||
|
width:41.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-6{
|
||||||
|
width:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-7{
|
||||||
|
width:58.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-8{
|
||||||
|
width:66.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-9{
|
||||||
|
width:75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-10{
|
||||||
|
width:83.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-11{
|
||||||
|
width:91.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 40em){
|
||||||
|
|
||||||
|
.sm-col{
|
||||||
|
float:left;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-right{
|
||||||
|
float:right;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-1{
|
||||||
|
width:8.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-2{
|
||||||
|
width:16.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-3{
|
||||||
|
width:25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-4{
|
||||||
|
width:33.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-5{
|
||||||
|
width:41.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-6{
|
||||||
|
width:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-7{
|
||||||
|
width:58.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-8{
|
||||||
|
width:66.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-9{
|
||||||
|
width:75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-10{
|
||||||
|
width:83.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-11{
|
||||||
|
width:91.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-col-12{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (min-width: 52em){
|
||||||
|
|
||||||
|
.md-col{
|
||||||
|
float:left;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-right{
|
||||||
|
float:right;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-1{
|
||||||
|
width:8.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-2{
|
||||||
|
width:16.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-3{
|
||||||
|
width:25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-4{
|
||||||
|
width:33.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-5{
|
||||||
|
width:41.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-6{
|
||||||
|
width:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-7{
|
||||||
|
width:58.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-8{
|
||||||
|
width:66.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-9{
|
||||||
|
width:75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-10{
|
||||||
|
width:83.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-11{
|
||||||
|
width:91.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-col-12{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (min-width: 64em){
|
||||||
|
|
||||||
|
.lg-col{
|
||||||
|
float:left;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-right{
|
||||||
|
float:right;
|
||||||
|
box-sizing:border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-1{
|
||||||
|
width:8.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-2{
|
||||||
|
width:16.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-3{
|
||||||
|
width:25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-4{
|
||||||
|
width:33.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-5{
|
||||||
|
width:41.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-6{
|
||||||
|
width:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-7{
|
||||||
|
width:58.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-8{
|
||||||
|
width:66.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-9{
|
||||||
|
width:75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-10{
|
||||||
|
width:83.33333%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-11{
|
||||||
|
width:91.66667%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg-col-12{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
|
||||||
|
|
||||||
|
@media (min-width: 40em){
|
||||||
|
.sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 52em){
|
||||||
|
.md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 64em){
|
||||||
|
.lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column }
|
||||||
|
.flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap }
|
||||||
|
|
||||||
|
.items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start }
|
||||||
|
.items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end }
|
||||||
|
.items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center }
|
||||||
|
.items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline }
|
||||||
|
.items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch }
|
||||||
|
|
||||||
|
.self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start }
|
||||||
|
.self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end }
|
||||||
|
.self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center }
|
||||||
|
.self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline }
|
||||||
|
.self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch }
|
||||||
|
|
||||||
|
.justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start }
|
||||||
|
.justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end }
|
||||||
|
.justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center }
|
||||||
|
.justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between }
|
||||||
|
.justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around }
|
||||||
|
|
||||||
|
.content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start }
|
||||||
|
.content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end }
|
||||||
|
.content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center }
|
||||||
|
.content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between }
|
||||||
|
.content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around }
|
||||||
|
.content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch }
|
||||||
|
.flex-auto{
|
||||||
|
-webkit-box-flex:1;
|
||||||
|
-webkit-flex:1 1 auto;
|
||||||
|
-ms-flex:1 1 auto;
|
||||||
|
flex:1 1 auto;
|
||||||
|
min-width:0;
|
||||||
|
min-height:0;
|
||||||
|
}
|
||||||
|
.flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none }
|
||||||
|
|
||||||
|
.order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 }
|
||||||
|
.order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 }
|
||||||
|
.order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 }
|
||||||
|
.order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 }
|
||||||
|
.order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 }
|
||||||
|
|
||||||
|
.relative{ position:relative }
|
||||||
|
.absolute{ position:absolute }
|
||||||
|
.fixed{ position:fixed }
|
||||||
|
|
||||||
|
.top-0{ top:0 }
|
||||||
|
.right-0{ right:0 }
|
||||||
|
.bottom-0{ bottom:0 }
|
||||||
|
.left-0{ left:0 }
|
||||||
|
|
||||||
|
.z1{ z-index: 1 }
|
||||||
|
.z2{ z-index: 2 }
|
||||||
|
.z3{ z-index: 3 }
|
||||||
|
.z4{ z-index: 4 }
|
||||||
|
|
||||||
|
.border{
|
||||||
|
border-style:solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-top{
|
||||||
|
border-top-style:solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-right{
|
||||||
|
border-right-style:solid;
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom{
|
||||||
|
border-bottom-style:solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-left{
|
||||||
|
border-left-style:solid;
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-none{ border:0 }
|
||||||
|
|
||||||
|
.rounded{ border-radius: 3px }
|
||||||
|
.circle{ border-radius:50% }
|
||||||
|
|
||||||
|
.rounded-top{ border-radius: 3px 3px 0 0 }
|
||||||
|
.rounded-right{ border-radius: 0 3px 3px 0 }
|
||||||
|
.rounded-bottom{ border-radius: 0 0 3px 3px }
|
||||||
|
.rounded-left{ border-radius: 3px 0 0 3px }
|
||||||
|
|
||||||
|
.not-rounded{ border-radius:0 }
|
||||||
|
|
||||||
|
.hide{
|
||||||
|
position:absolute !important;
|
||||||
|
height:1px;
|
||||||
|
width:1px;
|
||||||
|
overflow:hidden;
|
||||||
|
clip:rect(1px, 1px, 1px, 1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 40em){
|
||||||
|
.xs-hide{ display:none !important }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 40em) and (max-width: 52em){
|
||||||
|
.sm-hide{ display:none !important }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 52em) and (max-width: 64em){
|
||||||
|
.md-hide{ display:none !important }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 64em){
|
||||||
|
.lg-hide{ display:none !important }
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-none{ display:none !important }
|
||||||
|
|
BIN
documentation/html/assets/fonts/EOT/SourceCodePro-Bold.eot
Executable file
BIN
documentation/html/assets/fonts/EOT/SourceCodePro-Bold.eot
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/EOT/SourceCodePro-Regular.eot
Executable file
BIN
documentation/html/assets/fonts/EOT/SourceCodePro-Regular.eot
Executable file
Binary file not shown.
93
documentation/html/assets/fonts/LICENSE.txt
Executable file
93
documentation/html/assets/fonts/LICENSE.txt
Executable file
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
documentation/html/assets/fonts/OTF/SourceCodePro-Bold.otf
Executable file
BIN
documentation/html/assets/fonts/OTF/SourceCodePro-Bold.otf
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/OTF/SourceCodePro-Regular.otf
Executable file
BIN
documentation/html/assets/fonts/OTF/SourceCodePro-Regular.otf
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/TTF/SourceCodePro-Bold.ttf
Executable file
BIN
documentation/html/assets/fonts/TTF/SourceCodePro-Bold.ttf
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/TTF/SourceCodePro-Regular.ttf
Executable file
BIN
documentation/html/assets/fonts/TTF/SourceCodePro-Regular.ttf
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
Executable file
BIN
documentation/html/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
Executable file
BIN
documentation/html/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
Executable file
BIN
documentation/html/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
Executable file
BIN
documentation/html/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
Executable file
BIN
documentation/html/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
Executable file
BIN
documentation/html/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
Executable file
BIN
documentation/html/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
Executable file
Binary file not shown.
BIN
documentation/html/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
Executable file
BIN
documentation/html/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
Executable file
Binary file not shown.
23
documentation/html/assets/fonts/source-code-pro.css
Executable file
23
documentation/html/assets/fonts/source-code-pro.css
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
@font-face{
|
||||||
|
font-family: 'Source Code Pro';
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
|
||||||
|
url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
|
||||||
|
url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
|
||||||
|
url('OTF/SourceCodePro-Regular.otf') format('opentype'),
|
||||||
|
url('TTF/SourceCodePro-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face{
|
||||||
|
font-family: 'Source Code Pro';
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
|
||||||
|
url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
|
||||||
|
url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
|
||||||
|
url('OTF/SourceCodePro-Bold.otf') format('opentype'),
|
||||||
|
url('TTF/SourceCodePro-Bold.ttf') format('truetype');
|
||||||
|
}
|
123
documentation/html/assets/github.css
Normal file
123
documentation/html/assets/github.css
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #333;
|
||||||
|
background: #f8f8f8;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.diff .hljs-header,
|
||||||
|
.hljs-javadoc {
|
||||||
|
color: #998;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.css .rule .hljs-keyword,
|
||||||
|
.hljs-winutils,
|
||||||
|
.nginx .hljs-title,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-request,
|
||||||
|
.hljs-status {
|
||||||
|
color: #1184CE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-hexcolor,
|
||||||
|
.ruby .hljs-constant {
|
||||||
|
color: #ed225d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-tag .hljs-value,
|
||||||
|
.hljs-phpdoc,
|
||||||
|
.hljs-dartdoc,
|
||||||
|
.tex .hljs-formula {
|
||||||
|
color: #ed225d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-id,
|
||||||
|
.scss .hljs-preprocessor {
|
||||||
|
color: #900;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-list .hljs-keyword,
|
||||||
|
.hljs-subst {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-class .hljs-title,
|
||||||
|
.hljs-type,
|
||||||
|
.vhdl .hljs-literal,
|
||||||
|
.tex .hljs-command {
|
||||||
|
color: #458;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag,
|
||||||
|
.hljs-tag .hljs-title,
|
||||||
|
.hljs-rules .hljs-property,
|
||||||
|
.django .hljs-tag .hljs-keyword {
|
||||||
|
color: #000080;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-variable,
|
||||||
|
.lisp .hljs-body {
|
||||||
|
color: #008080;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-regexp {
|
||||||
|
color: #009926;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-symbol,
|
||||||
|
.ruby .hljs-symbol .hljs-string,
|
||||||
|
.lisp .hljs-keyword,
|
||||||
|
.clojure .hljs-keyword,
|
||||||
|
.scheme .hljs-keyword,
|
||||||
|
.tex .hljs-special,
|
||||||
|
.hljs-prompt {
|
||||||
|
color: #990073;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-built_in {
|
||||||
|
color: #0086b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-preprocessor,
|
||||||
|
.hljs-pragma,
|
||||||
|
.hljs-pi,
|
||||||
|
.hljs-doctype,
|
||||||
|
.hljs-shebang,
|
||||||
|
.hljs-cdata {
|
||||||
|
color: #999;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
background: #fdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
background: #dfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff .hljs-change {
|
||||||
|
background: #0086b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-chunk {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
108
documentation/html/assets/site.js
Normal file
108
documentation/html/assets/site.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/* global anchors */
|
||||||
|
|
||||||
|
// add anchor links to headers
|
||||||
|
anchors.options.placement = 'left';
|
||||||
|
anchors.add('h3');
|
||||||
|
|
||||||
|
// Filter UI
|
||||||
|
var tocElements = document.getElementById('toc')
|
||||||
|
.getElementsByTagName('li');
|
||||||
|
|
||||||
|
document.getElementById('filter-input')
|
||||||
|
.addEventListener('keyup', function (e) {
|
||||||
|
|
||||||
|
var i, element, children;
|
||||||
|
|
||||||
|
// enter key
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
// go to the first displayed item in the toc
|
||||||
|
for (i = 0; i < tocElements.length; i++) {
|
||||||
|
element = tocElements[i];
|
||||||
|
if (!element.classList.contains('display-none')) {
|
||||||
|
location.replace(element.firstChild.href);
|
||||||
|
return e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var value = this.value.toLowerCase();
|
||||||
|
|
||||||
|
if (!value.match(/^\s*$/)) {
|
||||||
|
match = function (element) {
|
||||||
|
return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < tocElements.length; i++) {
|
||||||
|
element = tocElements[i];
|
||||||
|
children = Array.from(element.getElementsByTagName('li'));
|
||||||
|
if (match(element) || children.some(match)) {
|
||||||
|
element.classList.remove('display-none');
|
||||||
|
} else {
|
||||||
|
element.classList.add('display-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var toggles = document.getElementsByClassName('toggle-step-sibling');
|
||||||
|
for (var i = 0; i < toggles.length; i++) {
|
||||||
|
toggles[i].addEventListener('click', toggleStepSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStepSibling() {
|
||||||
|
var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0];
|
||||||
|
var klass = 'display-none';
|
||||||
|
if (stepSibling.classList.contains(klass)) {
|
||||||
|
stepSibling.classList.remove(klass);
|
||||||
|
stepSibling.innerHTML = '▾';
|
||||||
|
} else {
|
||||||
|
stepSibling.classList.add(klass);
|
||||||
|
stepSibling.innerHTML = '▸';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = document.getElementsByClassName('toggle-sibling');
|
||||||
|
for (var j = 0; j < items.length; j++) {
|
||||||
|
items[j].addEventListener('click', toggleSibling);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSibling() {
|
||||||
|
var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
|
||||||
|
var icon = this.getElementsByClassName('icon')[0];
|
||||||
|
var klass = 'display-none';
|
||||||
|
if (stepSibling.classList.contains(klass)) {
|
||||||
|
stepSibling.classList.remove(klass);
|
||||||
|
icon.innerHTML = '▾';
|
||||||
|
} else {
|
||||||
|
stepSibling.classList.add(klass);
|
||||||
|
icon.innerHTML = '▸';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHashTarget(targetId) {
|
||||||
|
var hashTarget = document.getElementById(targetId);
|
||||||
|
// new target is hidden
|
||||||
|
if (hashTarget && hashTarget.offsetHeight === 0 &&
|
||||||
|
hashTarget.parentNode.parentNode.classList.contains('display-none')) {
|
||||||
|
hashTarget.parentNode.parentNode.classList.remove('display-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('hashchange', function() {
|
||||||
|
showHashTarget(location.hash.substring(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
showHashTarget(location.hash.substring(1));
|
||||||
|
|
||||||
|
var toclinks = document.getElementsByClassName('pre-open');
|
||||||
|
for (var k = 0; k < toclinks.length; k++) {
|
||||||
|
toclinks[k].addEventListener('mousedown', preOpen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function preOpen() {
|
||||||
|
showHashTarget(this.hash.substring(1));
|
||||||
|
}
|
136
documentation/html/assets/style.css
Normal file
136
documentation/html/assets/style.css
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
.documentation {
|
||||||
|
font-family: Helvetica, sans-serif;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.black {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-white {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.documentation h3 {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom {
|
||||||
|
border-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #1184CE;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.documentation a[href]:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py1-ul li {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-height-100 {
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section:target h3 {
|
||||||
|
font-weight:700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.documentation td,
|
||||||
|
.documentation th {
|
||||||
|
padding: .25rem .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1:hover .anchorjs-link,
|
||||||
|
h2:hover .anchorjs-link,
|
||||||
|
h3:hover .anchorjs-link,
|
||||||
|
h4:hover .anchorjs-link {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix-3 {
|
||||||
|
width: 25%;
|
||||||
|
max-width: 244px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix-3 {
|
||||||
|
width: 25%;
|
||||||
|
max-width: 244px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 52em) {
|
||||||
|
.fix-margin-3 {
|
||||||
|
margin-left: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pre, pre, code, .code {
|
||||||
|
font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fill-light {
|
||||||
|
background: #F9F9F9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.width2 {
|
||||||
|
width: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
font-size: .875rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose table th,
|
||||||
|
.prose table td {
|
||||||
|
text-align: left;
|
||||||
|
padding:8px;
|
||||||
|
border:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose table th:nth-child(1) { border-right: none; }
|
||||||
|
.prose table th:nth-child(2) { border-left: none; }
|
||||||
|
|
||||||
|
.prose table {
|
||||||
|
border:1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prose-big {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quiet {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minishadow {
|
||||||
|
box-shadow: 2px 2px 10px #f3f3f3;
|
||||||
|
}
|
5468
documentation/html/index.html
Normal file
5468
documentation/html/index.html
Normal file
File diff suppressed because it is too large
Load diff
146
documentation/md/API.md
Normal file
146
documentation/md/API.md
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||||
|
|
||||||
|
# ePub
|
||||||
|
|
||||||
|
Creates a new Book
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `url` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer))** URL, Path or ArrayBuffer
|
||||||
|
- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** to pass to the book
|
||||||
|
- `options.request` the request function to use
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
ePub("/path/to/book.epub", {})
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[Book](#book)** a new Book object
|
||||||
|
|
||||||
|
# Book
|
||||||
|
|
||||||
|
Creates a new Book
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `_url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
|
||||||
|
- `options` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
|
||||||
|
- `options.requestMethod` **method** a request function to use instead of the default
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
new Book("/path/to/book.epub", {})
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[Book](#book)**
|
||||||
|
|
||||||
|
## url
|
||||||
|
|
||||||
|
## loaded
|
||||||
|
|
||||||
|
**Properties**
|
||||||
|
|
||||||
|
- `loaded.manifest` **[promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A child method as property defination
|
||||||
|
|
||||||
|
## open
|
||||||
|
|
||||||
|
open a url
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `_url` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** URL, Path or ArrayBuffer
|
||||||
|
- `options` **\[[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)]** to force opening
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
book.open("/path/to/book.epub", { base64: false })
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** of when the book has been loaded
|
||||||
|
|
||||||
|
## unpack
|
||||||
|
|
||||||
|
unpack the contents of the Books packageXml
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `packageXml` **[document](https://developer.mozilla.org/en-US/docs/Web/JavaScript)** XML Document
|
||||||
|
|
||||||
|
## section
|
||||||
|
|
||||||
|
Alias for book.spine.get
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `target` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
|
||||||
|
|
||||||
|
## renderTo
|
||||||
|
|
||||||
|
Sugar to render a book
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `element`
|
||||||
|
- `options`
|
||||||
|
|
||||||
|
## requestMethod
|
||||||
|
|
||||||
|
Switch request methods depending on if book is archived or not
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `_url`
|
||||||
|
|
||||||
|
## unarchive
|
||||||
|
|
||||||
|
Unarchive a zipped epub
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `bookUrl`
|
||||||
|
- `isBase64`
|
||||||
|
|
||||||
|
## isArchivedUrl
|
||||||
|
|
||||||
|
Checks if url has a .epub or .zip extension, or is ArrayBuffer (of zip/epub)
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `bookUrl`
|
||||||
|
|
||||||
|
## coverUrl
|
||||||
|
|
||||||
|
Get the cover url
|
||||||
|
|
||||||
|
## range
|
||||||
|
|
||||||
|
Find a DOM Range for a given CFI Range
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `cfiRange`
|
||||||
|
|
||||||
|
# EpubCFI
|
||||||
|
|
||||||
|
EPUB CFI spec: <http://www.idpf.org/epub/linking/cfi/epub-cfi.html>
|
||||||
|
|
||||||
|
Implements:
|
||||||
|
|
||||||
|
- Character Offset: epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)
|
||||||
|
- Simple Ranges : epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)
|
||||||
|
|
||||||
|
Does Not Implement:
|
||||||
|
|
||||||
|
- Temporal Offset (~)
|
||||||
|
- Spatial Offset (@)
|
||||||
|
- Temporal-Spatial Offset (~ + @)
|
||||||
|
- Text Location Assertion (\[)
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
|
||||||
|
- `cfiFrom`
|
||||||
|
- `base`
|
||||||
|
- `ignoreClass`
|
|
@ -3,14 +3,22 @@ var request = require('./request');
|
||||||
var mime = require('../libs/mime/mime');
|
var mime = require('../libs/mime/mime');
|
||||||
var Path = require('./core').Path;
|
var Path = require('./core').Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles Unzipping a requesting files from an Epub Archive
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
function Archive() {
|
function Archive() {
|
||||||
|
this.zip = undefined;
|
||||||
this.checkRequirements();
|
this.checkRequirements();
|
||||||
this.urlCache = {};
|
this.urlCache = {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Archive.prototype.checkRequirements = function(callback){
|
/**
|
||||||
|
* Checks to see if JSZip exists in global namspace,
|
||||||
|
* Requires JSZip if it isn't there
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Archive.prototype.checkRequirements = function(){
|
||||||
try {
|
try {
|
||||||
if (typeof JSZip === 'undefined') {
|
if (typeof JSZip === 'undefined') {
|
||||||
JSZip = require('jszip');
|
JSZip = require('jszip');
|
||||||
|
@ -21,10 +29,22 @@ Archive.prototype.checkRequirements = function(callback){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an archive
|
||||||
|
* @param {binary} input
|
||||||
|
* @param {boolean} isBase64 tells JSZip if the input data is base64 encoded
|
||||||
|
* @return {Promise} zipfile
|
||||||
|
*/
|
||||||
Archive.prototype.open = function(input, isBase64){
|
Archive.prototype.open = function(input, isBase64){
|
||||||
return this.zip.loadAsync(input, {"base64": isBase64});
|
return this.zip.loadAsync(input, {"base64": isBase64});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and Open an archive
|
||||||
|
* @param {string} zipUrl
|
||||||
|
* @param {boolean} isBase64 tells JSZip if the input data is base64 encoded
|
||||||
|
* @return {Promise} zipfile
|
||||||
|
*/
|
||||||
Archive.prototype.openUrl = function(zipUrl, isBase64){
|
Archive.prototype.openUrl = function(zipUrl, isBase64){
|
||||||
return request(zipUrl, "binary")
|
return request(zipUrl, "binary")
|
||||||
.then(function(data){
|
.then(function(data){
|
||||||
|
@ -32,6 +52,12 @@ Archive.prototype.openUrl = function(zipUrl, isBase64){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request
|
||||||
|
* @param {string} url a url to request from the archive
|
||||||
|
* @param {[string]} type specify the type of the returned result
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Archive.prototype.request = function(url, type){
|
Archive.prototype.request = function(url, type){
|
||||||
var deferred = new core.defer();
|
var deferred = new core.defer();
|
||||||
var response;
|
var response;
|
||||||
|
@ -63,6 +89,13 @@ Archive.prototype.request = function(url, type){
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the response from request
|
||||||
|
* @private
|
||||||
|
* @param {any} response
|
||||||
|
* @param {[string]} type
|
||||||
|
* @return {any} the parsed result
|
||||||
|
*/
|
||||||
Archive.prototype.handleResponse = function(response, type){
|
Archive.prototype.handleResponse = function(response, type){
|
||||||
var r;
|
var r;
|
||||||
|
|
||||||
|
@ -87,19 +120,30 @@ Archive.prototype.handleResponse = function(response, type){
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
|
|
||||||
Archive.prototype.getBlob = function(url, _mimeType){
|
/**
|
||||||
|
* Get a Blob from Archive by Url
|
||||||
|
* @param {string} url
|
||||||
|
* @param {[string]} mimeType
|
||||||
|
* @return {Blob}
|
||||||
|
*/
|
||||||
|
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;
|
|
||||||
|
|
||||||
if(entry) {
|
if(entry) {
|
||||||
mimeType = _mimeType || mime.lookup(entry.name);
|
mimeType = mimeType || mime.lookup(entry.name);
|
||||||
return entry.async("uint8array").then(function(uint8array) {
|
return entry.async("uint8array").then(function(uint8array) {
|
||||||
return new Blob([uint8array], {type : mimeType});
|
return new Blob([uint8array], {type : mimeType});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Text from Archive by Url
|
||||||
|
* @param {string} url
|
||||||
|
* @param {[string]} encoding
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
Archive.prototype.getText = function(url, encoding){
|
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);
|
||||||
|
@ -111,19 +155,30 @@ Archive.prototype.getText = function(url, encoding){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Archive.prototype.getBase64 = function(url, _mimeType){
|
/**
|
||||||
|
* Get a base64 encoded result from Archive by Url
|
||||||
|
* @param {string} url
|
||||||
|
* @param {[string]} mimeType
|
||||||
|
* @return {string} base64 encoded
|
||||||
|
*/
|
||||||
|
Archive.prototype.getBase64 = function(url, mimeType){
|
||||||
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;
|
|
||||||
|
|
||||||
if(entry) {
|
if(entry) {
|
||||||
mimeType = _mimeType || mime.lookup(entry.name);
|
mimeType = mimeType || mime.lookup(entry.name);
|
||||||
return entry.async("base64").then(function(data) {
|
return entry.async("base64").then(function(data) {
|
||||||
return "data:" + mimeType + ";base64," + data;
|
return "data:" + mimeType + ";base64," + data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Url from an unarchived item
|
||||||
|
* @param {string} url
|
||||||
|
* @param {[object]} options.base64 use base64 encoding or blob url
|
||||||
|
* @return {Promise} url promise with Url string
|
||||||
|
*/
|
||||||
Archive.prototype.createUrl = function(url, options){
|
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;
|
||||||
|
@ -177,6 +232,10 @@ Archive.prototype.createUrl = function(url, options){
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke Temp Url for a achive item
|
||||||
|
* @param {string} url url of the item in the archive
|
||||||
|
*/
|
||||||
Archive.prototype.revokeUrl = function(url){
|
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];
|
||||||
|
|
123
src/book.js
123
src/book.js
|
@ -10,6 +10,7 @@ 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 Resources = require('./resources');
|
||||||
|
var PageList = require('./pagelist');
|
||||||
var Rendition = require('./rendition');
|
var Rendition = require('./rendition');
|
||||||
var Archive = require('./archive');
|
var Archive = require('./archive');
|
||||||
var request = require('./request');
|
var request = require('./request');
|
||||||
|
@ -21,19 +22,24 @@ var CONTAINER_PATH = "META-INF/container.xml";
|
||||||
/**
|
/**
|
||||||
* Creates a new Book
|
* Creates a new Book
|
||||||
* @class
|
* @class
|
||||||
* @param {string} _url
|
* @param {string} url
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
* @param {method} options.requestMethod a request function to use instead of the default
|
* @param {method} options.requestMethod a request function to use instead of the default
|
||||||
|
* @param {boolean} [options.requestCredentials=undefined] send the xhr request withCredentials
|
||||||
|
* @param {object} [options.requestHeaders=undefined] send the xhr request headers
|
||||||
|
* @param {string} [options.encoding=binary] optional to pass 'binary' or base64' for archived Epubs
|
||||||
|
* @param {string} [options.replacements=base64] use base64, blobs, or none for replacing assets in archived Epubs
|
||||||
* @returns {Book}
|
* @returns {Book}
|
||||||
* @example new Book("/path/to/book.epub", {})
|
* @example new Book("/path/to/book.epub", {})
|
||||||
*/
|
*/
|
||||||
function Book(url, options){
|
function Book(url, options){
|
||||||
|
|
||||||
this.settings = core.extend(this.settings || {}, {
|
this.settings = core.extend(this.settings || {}, {
|
||||||
requestMethod: this.requestMethod,
|
requestMethod: undefined,
|
||||||
requestCredentials: undefined,
|
requestCredentials: undefined,
|
||||||
encoding: undefined, // optional to pass 'binary' or base64' for archived Epubs
|
requestHeaders: undefined,
|
||||||
base64: true
|
encoding: undefined,
|
||||||
|
replacements: 'base64'
|
||||||
});
|
});
|
||||||
|
|
||||||
core.extend(this.settings, options);
|
core.extend(this.settings, options);
|
||||||
|
@ -70,6 +76,7 @@ function Book(url, options){
|
||||||
// this.ready = RSVP.hash(this.loaded);
|
// this.ready = RSVP.hash(this.loaded);
|
||||||
/**
|
/**
|
||||||
* @property {promise} ready returns after the book is loaded and parsed
|
* @property {promise} ready returns after the book is loaded and parsed
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
this.ready = Promise.all([this.loaded.manifest,
|
this.ready = Promise.all([this.loaded.manifest,
|
||||||
this.loaded.spine,
|
this.loaded.spine,
|
||||||
|
@ -85,6 +92,7 @@ function Book(url, options){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {method} request
|
* @property {method} request
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
this.request = this.settings.requestMethod || request;
|
this.request = this.settings.requestMethod || request;
|
||||||
|
|
||||||
|
@ -103,9 +111,27 @@ function Book(url, options){
|
||||||
*/
|
*/
|
||||||
this.navigation = undefined;
|
this.navigation = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {PageList} pagelist
|
||||||
|
*/
|
||||||
|
this.pageList = new PageList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {Url} url
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
this.url = undefined;
|
this.url = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {Path} path
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
this.path = undefined;
|
this.path = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {boolean} archived
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
this.archived = false;
|
this.archived = false;
|
||||||
|
|
||||||
if(url) {
|
if(url) {
|
||||||
|
@ -119,7 +145,7 @@ function Book(url, options){
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open a url
|
* Open a epub or url
|
||||||
* @param {string} input URL, Path or ArrayBuffer
|
* @param {string} input URL, Path or ArrayBuffer
|
||||||
* @param {string} [what] to force opening
|
* @param {string} [what] to force opening
|
||||||
* @returns {Promise} of when the book has been loaded
|
* @returns {Promise} of when the book has been loaded
|
||||||
|
@ -150,6 +176,13 @@ Book.prototype.open = function(input, what){
|
||||||
return opening;
|
return opening;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open an archived epub
|
||||||
|
* @private
|
||||||
|
* @param {binary} data
|
||||||
|
* @param {[string]} encoding
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
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() {
|
||||||
|
@ -160,6 +193,12 @@ Book.prototype.openEpub = function(data, encoding){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the epub container
|
||||||
|
* @private
|
||||||
|
* @param {string} url
|
||||||
|
* @return {string} packagePath
|
||||||
|
*/
|
||||||
Book.prototype.openContainer = function(url){
|
Book.prototype.openContainer = function(url){
|
||||||
return this.load(url)
|
return this.load(url)
|
||||||
.then(function(xml) {
|
.then(function(xml) {
|
||||||
|
@ -168,6 +207,12 @@ Book.prototype.openContainer = function(url){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Open Packaging Format Xml
|
||||||
|
* @private
|
||||||
|
* @param {string} url
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Book.prototype.openPackaging = function(url){
|
Book.prototype.openPackaging = function(url){
|
||||||
var packageUrl;
|
var packageUrl;
|
||||||
this.path = new Path(url);
|
this.path = new Path(url);
|
||||||
|
@ -179,6 +224,11 @@ Book.prototype.openPackaging = function(url){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a resource from the Book
|
||||||
|
* @param {string} path path to the resource to load
|
||||||
|
* @return {Promise} returns a promise with the requested resource
|
||||||
|
*/
|
||||||
Book.prototype.load = function (path) {
|
Book.prototype.load = function (path) {
|
||||||
var resolved;
|
var resolved;
|
||||||
if(this.archived) {
|
if(this.archived) {
|
||||||
|
@ -186,10 +236,16 @@ Book.prototype.load = function (path) {
|
||||||
return this.archive.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.settings.requestCredentials, this.settings.requestHeaders);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a path to it's absolute position in the Book
|
||||||
|
* @param {string} path
|
||||||
|
* @param {[boolean]} absolute force resolving the full URL
|
||||||
|
* @return {string} the resolved path string
|
||||||
|
*/
|
||||||
Book.prototype.resolve = function (path, absolute) {
|
Book.prototype.resolve = function (path, absolute) {
|
||||||
var resolved = path;
|
var resolved = path;
|
||||||
var isAbsolute = (path.indexOf('://') > -1);
|
var isAbsolute = (path.indexOf('://') > -1);
|
||||||
|
@ -209,6 +265,12 @@ Book.prototype.resolve = function (path, absolute) {
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the type of they input passed to open
|
||||||
|
* @private
|
||||||
|
* @param {string} input
|
||||||
|
* @return {string} binary | directory | epub | opf
|
||||||
|
*/
|
||||||
Book.prototype.determineType = function(input) {
|
Book.prototype.determineType = function(input) {
|
||||||
var url;
|
var url;
|
||||||
var path;
|
var path;
|
||||||
|
@ -238,6 +300,7 @@ Book.prototype.determineType = function(input) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unpack the contents of the Books packageXml
|
* unpack the contents of the Books packageXml
|
||||||
|
* @private
|
||||||
* @param {document} packageXml XML Document
|
* @param {document} packageXml XML Document
|
||||||
*/
|
*/
|
||||||
Book.prototype.unpack = function(opf){
|
Book.prototype.unpack = function(opf){
|
||||||
|
@ -248,7 +311,7 @@ Book.prototype.unpack = function(opf){
|
||||||
this.resources = new Resources(this.package.manifest, {
|
this.resources = new Resources(this.package.manifest, {
|
||||||
archive: this.archive,
|
archive: this.archive,
|
||||||
resolver: this.resolve.bind(this),
|
resolver: this.resolve.bind(this),
|
||||||
base64: this.settings.base64
|
replacements: this.settings.replacements
|
||||||
});
|
});
|
||||||
|
|
||||||
this.loadNavigation(this.package).then(function(toc){
|
this.loadNavigation(this.package).then(function(toc){
|
||||||
|
@ -264,6 +327,7 @@ Book.prototype.unpack = function(opf){
|
||||||
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.loading.resources.resolve(this.resources);
|
||||||
|
this.loading.pageList.resolve(this.pageList);
|
||||||
|
|
||||||
|
|
||||||
this.isOpen = true;
|
this.isOpen = true;
|
||||||
|
@ -279,6 +343,11 @@ Book.prototype.unpack = function(opf){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Navigation and PageList from package
|
||||||
|
* @private
|
||||||
|
* @param {document} opf XML Document
|
||||||
|
*/
|
||||||
Book.prototype.loadNavigation = function(opf){
|
Book.prototype.loadNavigation = function(opf){
|
||||||
var navPath = opf.navPath || opf.ncxPath;
|
var navPath = opf.navPath || opf.ncxPath;
|
||||||
|
|
||||||
|
@ -289,6 +358,7 @@ Book.prototype.loadNavigation = function(opf){
|
||||||
return this.load(navPath, 'xml')
|
return this.load(navPath, 'xml')
|
||||||
.then(function(xml) {
|
.then(function(xml) {
|
||||||
this.navigation = new Navigation(xml);
|
this.navigation = new Navigation(xml);
|
||||||
|
this.pageList = new PageList(xml);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,6 +372,9 @@ Book.prototype.section = function(target) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sugar to render a book
|
* Sugar to render a book
|
||||||
|
* @param {element} element element to add the views to
|
||||||
|
* @param {[object]} options
|
||||||
|
* @return {Rendition}
|
||||||
*/
|
*/
|
||||||
Book.prototype.renderTo = function(element, options) {
|
Book.prototype.renderTo = function(element, options) {
|
||||||
// var renderMethod = (options && options.method) ?
|
// var renderMethod = (options && options.method) ?
|
||||||
|
@ -314,31 +387,44 @@ Book.prototype.renderTo = function(element, options) {
|
||||||
return this.rendition;
|
return this.rendition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
Book.prototype.setRequestCredentials = function(_credentials) {
|
* Set if request should use withCredentials
|
||||||
this.requestCredentials = _credentials;
|
* @param {boolean} credentials
|
||||||
|
*/
|
||||||
|
Book.prototype.setRequestCredentials = function(credentials) {
|
||||||
|
this.settings.requestCredentials = credentials;
|
||||||
};
|
};
|
||||||
|
|
||||||
Book.prototype.setRequestHeaders = function(_headers) {
|
/**
|
||||||
this.requestHeaders = _headers;
|
* Set headers request should use
|
||||||
|
* @param {object} headers
|
||||||
|
*/
|
||||||
|
Book.prototype.setRequestHeaders = function(headers) {
|
||||||
|
this.settings.requestHeaders = headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unarchive a zipped epub
|
* Unarchive a zipped epub
|
||||||
|
* @private
|
||||||
|
* @param {binary} input epub data
|
||||||
|
* @param {[string]} encoding
|
||||||
|
* @return {Archive}
|
||||||
*/
|
*/
|
||||||
Book.prototype.unarchive = function(bookUrl, encoding){
|
Book.prototype.unarchive = function(input, encoding){
|
||||||
this.archive = new Archive();
|
this.archive = new Archive();
|
||||||
return this.archive.open(bookUrl, encoding);
|
return this.archive.open(input, encoding);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cover url
|
* Get the cover url
|
||||||
|
* @return {string} coverUrl
|
||||||
*/
|
*/
|
||||||
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.archived) {
|
if(this.archived) {
|
||||||
return this.archive.createUrl(this.cover);
|
// return this.archive.createUrl(this.cover);
|
||||||
|
return this.resources.get(this.cover);
|
||||||
}else{
|
}else{
|
||||||
return this.cover;
|
return this.cover;
|
||||||
}
|
}
|
||||||
|
@ -349,6 +435,11 @@ Book.prototype.coverUrl = function(){
|
||||||
return retrieved;
|
return retrieved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load replacement urls
|
||||||
|
* @private
|
||||||
|
* @return {Promise} completed loading urls
|
||||||
|
*/
|
||||||
Book.prototype.replacements = function(){
|
Book.prototype.replacements = function(){
|
||||||
this.spine.hooks.serialize.register(function(output, section) {
|
this.spine.hooks.serialize.register(function(output, section) {
|
||||||
section.output = this.resources.substitute(output, section.url);
|
section.output = this.resources.substitute(output, section.url);
|
||||||
|
@ -362,6 +453,8 @@ Book.prototype.replacements = function(){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a DOM Range for a given CFI Range
|
* Find a DOM Range for a given CFI Range
|
||||||
|
* @param {EpubCFI} cfiRange a epub cfi range
|
||||||
|
* @return {Range}
|
||||||
*/
|
*/
|
||||||
Book.prototype.range = function(cfiRange) {
|
Book.prototype.range = function(cfiRange) {
|
||||||
var cfi = new EpubCFI(cfiRange);
|
var cfi = new EpubCFI(cfiRange);
|
||||||
|
|
|
@ -2,13 +2,21 @@ var path = require('path');
|
||||||
var core = require('./core');
|
var core = require('./core');
|
||||||
var EpubCFI = require('./epubcfi');
|
var EpubCFI = require('./epubcfi');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles Parsing and Accessing an Epub Container
|
||||||
|
* @class
|
||||||
|
* @param {[document]} containerDocument xml document
|
||||||
|
*/
|
||||||
function Container(containerDocument) {
|
function Container(containerDocument) {
|
||||||
if (containerDocument) {
|
if (containerDocument) {
|
||||||
this.parse(containerDocument);
|
this.parse(containerDocument);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the Container XML
|
||||||
|
* @param {document} containerDocument
|
||||||
|
*/
|
||||||
Container.prototype.parse = function(containerDocument){
|
Container.prototype.parse = function(containerDocument){
|
||||||
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
//-- <rootfile full-path="OPS/package.opf" media-type="application/oebps-package+xml"/>
|
||||||
var rootfile, fullpath, folder, encoding;
|
var rootfile, fullpath, folder, encoding;
|
||||||
|
|
|
@ -592,7 +592,7 @@ function defer() {
|
||||||
}
|
}
|
||||||
// Handle IE not supporting namespaced epub:type in querySelector
|
// Handle IE not supporting namespaced epub:type in querySelector
|
||||||
if(!query || query.length === 0) {
|
if(!query || query.length === 0) {
|
||||||
query = core.qsa(html, element);
|
query = this.qsa(html, element);
|
||||||
for (var i = 0; i < query.length; i++) {
|
for (var i = 0; i < query.length; i++) {
|
||||||
if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type) {
|
if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type) {
|
||||||
return query[i];
|
return query[i];
|
||||||
|
|
|
@ -7,7 +7,6 @@ var Contents = require('./contents');
|
||||||
* Creates a new Book
|
* Creates a new Book
|
||||||
* @param {string|ArrayBuffer} url URL, Path or ArrayBuffer
|
* @param {string|ArrayBuffer} url URL, Path or ArrayBuffer
|
||||||
* @param {object} options to pass to the book
|
* @param {object} options to pass to the book
|
||||||
* @param options.requestMethod the request function to use
|
|
||||||
* @returns {Book} a new Book object
|
* @returns {Book} a new Book object
|
||||||
* @example ePub("/path/to/book.epub", {})
|
* @example ePub("/path/to/book.epub", {})
|
||||||
*/
|
*/
|
||||||
|
|
25
src/hook.js
25
src/hook.js
|
@ -1,17 +1,19 @@
|
||||||
//-- Hooks allow for injecting functions that must all complete in order before finishing
|
/**
|
||||||
// They will execute in parallel but all must finish before continuing
|
* Hooks allow for injecting functions that must all complete in order before finishing
|
||||||
// Functions may return a promise if they are asycn.
|
* They will execute in parallel but all must finish before continuing
|
||||||
|
* Functions may return a promise if they are asycn.
|
||||||
// this.content = new EPUBJS.Hook();
|
* @param {any} context scope of this
|
||||||
// this.content.register(function(){});
|
* @example this.content = new EPUBJS.Hook(this);
|
||||||
// this.content.trigger(args).then(function(){});
|
*/
|
||||||
|
|
||||||
function Hook(context){
|
function Hook(context){
|
||||||
this.context = context || this;
|
this.context = context || this;
|
||||||
this.hooks = [];
|
this.hooks = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adds a function to be run before a hook completes
|
/**
|
||||||
|
* Adds a function to be run before a hook completes
|
||||||
|
* @example this.content.register(function(){...});
|
||||||
|
*/
|
||||||
Hook.prototype.register = function(){
|
Hook.prototype.register = function(){
|
||||||
for(var i = 0; i < arguments.length; ++i) {
|
for(var i = 0; i < arguments.length; ++i) {
|
||||||
if (typeof arguments[i] === "function") {
|
if (typeof arguments[i] === "function") {
|
||||||
|
@ -25,7 +27,10 @@ Hook.prototype.register = function(){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Triggers a hook to run all functions
|
/**
|
||||||
|
* Triggers a hook to run all functions
|
||||||
|
* @example this.content.trigger(args).then(function(){...});
|
||||||
|
*/
|
||||||
Hook.prototype.trigger = function(){
|
Hook.prototype.trigger = function(){
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
var context = this.context;
|
var context = this.context;
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
var core = require('./core');
|
var core = require('./core');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figures out the CSS to apply for a layout
|
||||||
|
* @class
|
||||||
|
* @param {object} settings
|
||||||
|
* @param {[string=reflowable]} settings.layout
|
||||||
|
* @param {[string]} settings.spread
|
||||||
|
* @param {[int=800]} settings.minSpreadWidth
|
||||||
|
* @param {[boolean=false]} settings.evenSpreads
|
||||||
|
*/
|
||||||
function Layout(settings){
|
function Layout(settings){
|
||||||
this.name = settings.layout || "reflowable";
|
this.name = settings.layout || "reflowable";
|
||||||
this._spread = (settings.spread === "none") ? false : true;
|
this._spread = (settings.spread === "none") ? false : true;
|
||||||
this._minSpreadWidth = settings.spread || 800;
|
this._minSpreadWidth = settings.minSpreadWidth || 800;
|
||||||
this._evenSpreads = settings.evenSpreads || false;
|
this._evenSpreads = settings.evenSpreads || false;
|
||||||
|
|
||||||
if (settings.flow === "scrolled-continuous" ||
|
if (settings.flow === "scrolled-continuous" ||
|
||||||
|
@ -24,12 +33,20 @@ function Layout(settings){
|
||||||
this.divisor = 1;
|
this.divisor = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// paginated | scrolled
|
/**
|
||||||
|
* Switch the flow between paginated and scrolled
|
||||||
|
* @param {string} flow paginated | scrolled
|
||||||
|
*/
|
||||||
Layout.prototype.flow = function(flow) {
|
Layout.prototype.flow = function(flow) {
|
||||||
this._flow = (flow === "paginated") ? "paginated" : "scrolled";
|
this._flow = (flow === "paginated") ? "paginated" : "scrolled";
|
||||||
}
|
}
|
||||||
|
|
||||||
// true | false
|
/**
|
||||||
|
* Switch between using spreads or not, and set the
|
||||||
|
* width at which they switch to single.
|
||||||
|
* @param {string} spread true | false
|
||||||
|
* @param {boolean} min integer in pixels
|
||||||
|
*/
|
||||||
Layout.prototype.spread = function(spread, min) {
|
Layout.prototype.spread = function(spread, min) {
|
||||||
|
|
||||||
this._spread = (spread === "none") ? false : true;
|
this._spread = (spread === "none") ? false : true;
|
||||||
|
@ -39,6 +56,12 @@ Layout.prototype.spread = function(spread, min) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the dimensions of the pagination
|
||||||
|
* @param {number} _width [description]
|
||||||
|
* @param {number} _height [description]
|
||||||
|
* @param {number} _gap [description]
|
||||||
|
*/
|
||||||
Layout.prototype.calculate = function(_width, _height, _gap){
|
Layout.prototype.calculate = function(_width, _height, _gap){
|
||||||
|
|
||||||
var divisor = 1;
|
var divisor = 1;
|
||||||
|
@ -93,6 +116,11 @@ Layout.prototype.calculate = function(_width, _height, _gap){
|
||||||
this.divisor = divisor;
|
this.divisor = divisor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply Css to a Document
|
||||||
|
* @param {Contents} contents
|
||||||
|
* @return {[Promise]}
|
||||||
|
*/
|
||||||
Layout.prototype.format = function(contents){
|
Layout.prototype.format = function(contents){
|
||||||
var formating;
|
var formating;
|
||||||
|
|
||||||
|
@ -107,6 +135,12 @@ Layout.prototype.format = function(contents){
|
||||||
return formating; // might be a promise in some View Managers
|
return formating; // might be a promise in some View Managers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count number of pages
|
||||||
|
* @param {number} totalWidth
|
||||||
|
* @return {number} spreads
|
||||||
|
* @return {number} pages
|
||||||
|
*/
|
||||||
Layout.prototype.count = function(totalWidth) {
|
Layout.prototype.count = function(totalWidth) {
|
||||||
// var totalWidth = contents.scrollWidth();
|
// var totalWidth = contents.scrollWidth();
|
||||||
var spreads = Math.ceil( totalWidth / this.spreadWidth);
|
var spreads = Math.ceil( totalWidth / this.spreadWidth);
|
||||||
|
|
|
@ -3,6 +3,11 @@ var Queue = require('./queue');
|
||||||
var EpubCFI = require('./epubcfi');
|
var EpubCFI = require('./epubcfi');
|
||||||
var EventEmitter = require('event-emitter');
|
var EventEmitter = require('event-emitter');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Locations for a Book
|
||||||
|
* @param {Spine} spine
|
||||||
|
* @param {request} request
|
||||||
|
*/
|
||||||
function Locations(spine, request) {
|
function Locations(spine, request) {
|
||||||
this.spine = spine;
|
this.spine = spine;
|
||||||
this.request = request;
|
this.request = request;
|
||||||
|
@ -19,7 +24,11 @@ function Locations(spine, request) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load all of sections in the book
|
/**
|
||||||
|
* Load all of sections in the book to generate locations
|
||||||
|
* @param {int} chars how many chars to split on
|
||||||
|
* @return {object} locations
|
||||||
|
*/
|
||||||
Locations.prototype.generate = function(chars) {
|
Locations.prototype.generate = function(chars) {
|
||||||
|
|
||||||
if (chars) {
|
if (chars) {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
var core = require('./core');
|
var core = require('./core');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigation Parser
|
||||||
|
* @param {document} xml navigation html / xhtml / ncx
|
||||||
|
*/
|
||||||
function Navigation(xml){
|
function Navigation(xml){
|
||||||
this.toc = [];
|
this.toc = [];
|
||||||
this.tocByHref = {};
|
this.tocByHref = {};
|
||||||
|
@ -11,6 +15,10 @@ function Navigation(xml){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse out the navigation items
|
||||||
|
* @param {document} xml navigation html / xhtml / ncx
|
||||||
|
*/
|
||||||
Navigation.prototype.parse = function(xml) {
|
Navigation.prototype.parse = function(xml) {
|
||||||
var html = core.qs(xml, "html");
|
var html = core.qs(xml, "html");
|
||||||
var ncx = core.qs(xml, "ncx");
|
var ncx = core.qs(xml, "ncx");
|
||||||
|
@ -24,6 +32,11 @@ Navigation.prototype.parse = function(xml) {
|
||||||
this.unpack(this.toc);
|
this.unpack(this.toc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpack navigation items
|
||||||
|
* @private
|
||||||
|
* @param {array} toc
|
||||||
|
*/
|
||||||
Navigation.prototype.unpack = function(toc) {
|
Navigation.prototype.unpack = function(toc) {
|
||||||
var item;
|
var item;
|
||||||
|
|
||||||
|
@ -35,7 +48,11 @@ Navigation.prototype.unpack = function(toc) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get an item from the navigation
|
/**
|
||||||
|
* Get an item from the navigation
|
||||||
|
* @param {string} target
|
||||||
|
* @return {object} navItems
|
||||||
|
*/
|
||||||
Navigation.prototype.get = function(target) {
|
Navigation.prototype.get = function(target) {
|
||||||
var index;
|
var index;
|
||||||
|
|
||||||
|
@ -52,9 +69,14 @@ Navigation.prototype.get = function(target) {
|
||||||
return this.toc[index];
|
return this.toc[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
Navigation.prototype.parseNav = function(navHtml, spineIndexByURL, bookSpine){
|
/**
|
||||||
|
* Parse from a Epub > 3.0 Nav
|
||||||
|
* @private
|
||||||
|
* @param {document} navHtml
|
||||||
|
* @return {array} navigation list
|
||||||
|
*/
|
||||||
|
Navigation.prototype.parseNav = function(navHtml){
|
||||||
var navElement = core.querySelectorByType(navHtml, "nav", "toc");
|
var navElement = core.querySelectorByType(navHtml, "nav", "toc");
|
||||||
// var navItems = navElement ? navElement.querySelectorAll("ol li") : [];
|
|
||||||
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||||
var length = navItems.length;
|
var length = navItems.length;
|
||||||
var i;
|
var i;
|
||||||
|
@ -65,7 +87,7 @@ Navigation.prototype.parseNav = function(navHtml, spineIndexByURL, bookSpine){
|
||||||
if(!navItems || length === 0) return list;
|
if(!navItems || length === 0) return list;
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
item = this.navItem(navItems[i], spineIndexByURL, bookSpine);
|
item = this.navItem(navItems[i]);
|
||||||
toc[item.id] = item;
|
toc[item.id] = item;
|
||||||
if(!item.parent) {
|
if(!item.parent) {
|
||||||
list.push(item);
|
list.push(item);
|
||||||
|
@ -78,38 +100,25 @@ Navigation.prototype.parseNav = function(navHtml, spineIndexByURL, bookSpine){
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
Navigation.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
/**
|
||||||
|
* Create a navItem
|
||||||
|
* @private
|
||||||
|
* @param {element} item
|
||||||
|
* @return {object} navItem
|
||||||
|
*/
|
||||||
|
Navigation.prototype.navItem = function(item){
|
||||||
var id = item.getAttribute('id') || false,
|
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') || '',
|
src = content.getAttribute('href') || '',
|
||||||
text = content.textContent || "",
|
text = content.textContent || "",
|
||||||
// split = src.split("#"),
|
|
||||||
// baseUrl = split[0],
|
|
||||||
// spinePos = spineIndexByURL[baseUrl],
|
|
||||||
// spineItem = bookSpine[spinePos],
|
|
||||||
subitems = [],
|
subitems = [],
|
||||||
parentNode = item.parentNode,
|
parentNode = item.parentNode,
|
||||||
parent;
|
parent;
|
||||||
// cfi = spineItem ? spineItem.cfi : '';
|
|
||||||
|
|
||||||
if(parentNode && parentNode.nodeName === "navPoint") {
|
if(parentNode && parentNode.nodeName === "navPoint") {
|
||||||
parent = parentNode.getAttribute('id');
|
parent = parentNode.getAttribute('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if(!id) {
|
|
||||||
if(spinePos) {
|
|
||||||
spineItem = bookSpine[spinePos];
|
|
||||||
id = spineItem.id;
|
|
||||||
cfi = spineItem.cfi;
|
|
||||||
} else {
|
|
||||||
id = 'epubjs-autogen-toc-id-' + EPUBJS.core.uuid();
|
|
||||||
item.setAttribute('id', id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
"href": src,
|
"href": src,
|
||||||
|
@ -119,8 +128,13 @@ Navigation.prototype.navItem = function(item, spineIndexByURL, bookSpine){
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Navigation.prototype.parseNcx = function(tocXml, spineIndexByURL, bookSpine){
|
/**
|
||||||
// var navPoints = tocXml.querySelectorAll("navMap navPoint");
|
* Parse from a Epub > 3.0 NC
|
||||||
|
* @private
|
||||||
|
* @param {document} navHtml
|
||||||
|
* @return {array} navigation list
|
||||||
|
*/
|
||||||
|
Navigation.prototype.parseNcx = function(tocXml){
|
||||||
var navPoints = core.qsa(tocXml, "navPoint");
|
var navPoints = core.qsa(tocXml, "navPoint");
|
||||||
var length = navPoints.length;
|
var length = navPoints.length;
|
||||||
var i;
|
var i;
|
||||||
|
@ -131,7 +145,7 @@ Navigation.prototype.parseNcx = function(tocXml, spineIndexByURL, bookSpine){
|
||||||
if(!navPoints || length === 0) return list;
|
if(!navPoints || length === 0) return list;
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
item = this.ncxItem(navPoints[i], spineIndexByURL, bookSpine);
|
item = this.ncxItem(navPoints[i]);
|
||||||
toc[item.id] = item;
|
toc[item.id] = item;
|
||||||
if(!item.parent) {
|
if(!item.parent) {
|
||||||
list.push(item);
|
list.push(item);
|
||||||
|
@ -144,39 +158,26 @@ Navigation.prototype.parseNcx = function(tocXml, spineIndexByURL, bookSpine){
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
Navigation.prototype.ncxItem = function(item, spineIndexByURL, bookSpine){
|
/**
|
||||||
|
* Create a ncxItem
|
||||||
|
* @private
|
||||||
|
* @param {element} item
|
||||||
|
* @return {object} ncxItem
|
||||||
|
*/
|
||||||
|
Navigation.prototype.ncxItem = function(item){
|
||||||
var id = item.getAttribute('id') || false,
|
var id = item.getAttribute('id') || false,
|
||||||
// content = item.querySelector("content"),
|
|
||||||
content = core.qs(item, "content"),
|
content = core.qs(item, "content"),
|
||||||
src = content.getAttribute('src'),
|
src = content.getAttribute('src'),
|
||||||
// navLabel = item.querySelector("navLabel"),
|
|
||||||
navLabel = core.qs(item, "navLabel"),
|
navLabel = core.qs(item, "navLabel"),
|
||||||
text = navLabel.textContent ? navLabel.textContent : "",
|
text = navLabel.textContent ? navLabel.textContent : "",
|
||||||
// split = src.split("#"),
|
|
||||||
// baseUrl = split[0],
|
|
||||||
// spinePos = spineIndexByURL[baseUrl],
|
|
||||||
// spineItem = bookSpine[spinePos],
|
|
||||||
subitems = [],
|
subitems = [],
|
||||||
parentNode = item.parentNode,
|
parentNode = item.parentNode,
|
||||||
parent;
|
parent;
|
||||||
// cfi = spineItem ? spineItem.cfi : '';
|
|
||||||
|
|
||||||
if(parentNode && parentNode.nodeName === "navPoint") {
|
if(parentNode && parentNode.nodeName === "navPoint") {
|
||||||
parent = parentNode.getAttribute('id');
|
parent = parentNode.getAttribute('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if(!id) {
|
|
||||||
if(spinePos) {
|
|
||||||
spineItem = bookSpine[spinePos];
|
|
||||||
id = spineItem.id;
|
|
||||||
cfi = spineItem.cfi;
|
|
||||||
} else {
|
|
||||||
id = 'epubjs-autogen-toc-id-' + EPUBJS.core.uuid();
|
|
||||||
item.setAttribute('id', id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
|
|
|
@ -2,13 +2,22 @@ var path = require('path');
|
||||||
var core = require('./core');
|
var core = require('./core');
|
||||||
var EpubCFI = require('./epubcfi');
|
var EpubCFI = require('./epubcfi');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Packaging Format Parser
|
||||||
|
* @class
|
||||||
|
* @param {document} packageDocument OPF XML
|
||||||
|
*/
|
||||||
function Packaging(packageDocument) {
|
function Packaging(packageDocument) {
|
||||||
if (packageDocument) {
|
if (packageDocument) {
|
||||||
this.parse(packageDocument);
|
this.parse(packageDocument);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse OPF XML
|
||||||
|
* @param {document} packageDocument OPF XML
|
||||||
|
* @return {object} parsed package parts
|
||||||
|
*/
|
||||||
Packaging.prototype.parse = function(packageDocument){
|
Packaging.prototype.parse = function(packageDocument){
|
||||||
var metadataNode, manifestNode, spineNode;
|
var metadataNode, manifestNode, spineNode;
|
||||||
|
|
||||||
|
@ -60,6 +69,12 @@ Packaging.prototype.parse = function(packageDocument){
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse Metadata
|
||||||
|
* @private
|
||||||
|
* @param {document} xml
|
||||||
|
* @return {object} metadata
|
||||||
|
*/
|
||||||
Packaging.prototype.parseMetadata = function(xml){
|
Packaging.prototype.parseMetadata = function(xml){
|
||||||
var metadata = {};
|
var metadata = {};
|
||||||
|
|
||||||
|
@ -86,6 +101,12 @@ Packaging.prototype.parseMetadata = function(xml){
|
||||||
return metadata;
|
return metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse Manifest
|
||||||
|
* @private
|
||||||
|
* @param {document} manifestXml
|
||||||
|
* @return {object} manifest
|
||||||
|
*/
|
||||||
Packaging.prototype.parseManifest = function(manifestXml){
|
Packaging.prototype.parseManifest = function(manifestXml){
|
||||||
var manifest = {};
|
var manifest = {};
|
||||||
|
|
||||||
|
@ -114,6 +135,12 @@ Packaging.prototype.parseManifest = function(manifestXml){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse Spine
|
||||||
|
* @param {document} spineXml
|
||||||
|
* @param {Packaging.manifest} manifest
|
||||||
|
* @return {object} spine
|
||||||
|
*/
|
||||||
Packaging.prototype.parseSpine = function(spineXml, manifest){
|
Packaging.prototype.parseSpine = function(spineXml, manifest){
|
||||||
var spine = [];
|
var spine = [];
|
||||||
|
|
||||||
|
@ -148,6 +175,7 @@ Packaging.prototype.parseSpine = function(spineXml, manifest){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find TOC NAV
|
* Find TOC NAV
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
Packaging.prototype.findNavPath = function(manifestNode){
|
Packaging.prototype.findNavPath = function(manifestNode){
|
||||||
// Find item with property 'nav'
|
// Find item with property 'nav'
|
||||||
|
@ -160,6 +188,7 @@ Packaging.prototype.findNavPath = function(manifestNode){
|
||||||
/**
|
/**
|
||||||
* Find TOC NCX
|
* Find TOC NCX
|
||||||
* media-type="application/x-dtbncx+xml" href="toc.ncx"
|
* media-type="application/x-dtbncx+xml" href="toc.ncx"
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
|
Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
|
||||||
// var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
|
// var node = manifestNode.querySelector("item[media-type='application/x-dtbncx+xml']");
|
||||||
|
@ -180,8 +209,13 @@ Packaging.prototype.findNcxPath = function(manifestNode, spineNode){
|
||||||
return node ? node.getAttribute('href') : false;
|
return node ? node.getAttribute('href') : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-- Find Cover: <item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />
|
/**
|
||||||
//-- Fallback for Epub 2.0
|
* Find the Cover Path
|
||||||
|
* <item properties="cover-image" id="ci" href="cover.svg" media-type="image/svg+xml" />
|
||||||
|
* Fallback for Epub 2.0
|
||||||
|
* @param {document} packageXml
|
||||||
|
* @return {string} href
|
||||||
|
*/
|
||||||
Packaging.prototype.findCoverPath = function(packageXml){
|
Packaging.prototype.findCoverPath = function(packageXml){
|
||||||
var pkg = core.qs(packageXml, "package");
|
var pkg = core.qs(packageXml, "package");
|
||||||
var epubVersion = pkg.getAttribute('version');
|
var epubVersion = pkg.getAttribute('version');
|
||||||
|
@ -205,6 +239,13 @@ Packaging.prototype.findCoverPath = function(packageXml){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get text of a namespaced element
|
||||||
|
* @private
|
||||||
|
* @param {document} xml
|
||||||
|
* @param {string} tag
|
||||||
|
* @return {string} text
|
||||||
|
*/
|
||||||
Packaging.prototype.getElementText = function(xml, tag){
|
Packaging.prototype.getElementText = function(xml, tag){
|
||||||
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
|
var found = xml.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", tag),
|
||||||
el;
|
el;
|
||||||
|
@ -221,6 +262,13 @@ Packaging.prototype.getElementText = function(xml, tag){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get text by property
|
||||||
|
* @private
|
||||||
|
* @param {document} xml
|
||||||
|
* @param {string} property
|
||||||
|
* @return {string} text
|
||||||
|
*/
|
||||||
Packaging.prototype.getPropertyText = function(xml, property){
|
Packaging.prototype.getPropertyText = function(xml, property){
|
||||||
var el = core.qsp(xml, "meta", {"property":property});
|
var el = core.qsp(xml, "meta", {"property":property});
|
||||||
|
|
||||||
|
|
249
src/pagelist.js
Normal file
249
src/pagelist.js
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
var EpubCFI = require('./epubcfi');
|
||||||
|
var core = require('./core');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page List Parser
|
||||||
|
* @param {[document]} xml
|
||||||
|
*/
|
||||||
|
function PageList(xml) {
|
||||||
|
this.pages = [];
|
||||||
|
this.locations = [];
|
||||||
|
this.epubcfi = new EpubCFI();
|
||||||
|
|
||||||
|
if (xml) {
|
||||||
|
this.pageList = this.parse(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.pageList && this.pageList.length) {
|
||||||
|
this.process(this.pageList);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse PageList Xml
|
||||||
|
* @param {document} xml
|
||||||
|
*/
|
||||||
|
PageList.prototype.parse = function(xml) {
|
||||||
|
var html = core.qs(xml, "html");
|
||||||
|
// var ncx = core.qs(xml, "ncx");
|
||||||
|
|
||||||
|
if(html) {
|
||||||
|
this.toc = this.parseNav(xml);
|
||||||
|
} else if(ncx){ // Not supported
|
||||||
|
// this.toc = this.parseNcx(xml);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a Nav PageList
|
||||||
|
* @private
|
||||||
|
* @param {document} navHtml
|
||||||
|
* @return {PageList.item[]} list
|
||||||
|
*/
|
||||||
|
PageList.prototype.parseNav = function(navHtml){
|
||||||
|
var navElement = core.querySelectorByType(navHtml, "nav", "page-list");
|
||||||
|
var navItems = navElement ? core.qsa(navElement, "li") : [];
|
||||||
|
var length = navItems.length;
|
||||||
|
var i;
|
||||||
|
var toc = {};
|
||||||
|
var list = [];
|
||||||
|
var item;
|
||||||
|
|
||||||
|
if(!navItems || length === 0) return list;
|
||||||
|
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
item = this.item(navItems[i]);
|
||||||
|
list.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page List Item
|
||||||
|
* @private
|
||||||
|
* @param {object} item
|
||||||
|
* @return {object} pageListItem
|
||||||
|
*/
|
||||||
|
PageList.prototype.item = function(item){
|
||||||
|
var id = item.getAttribute('id') || false,
|
||||||
|
content = core.qs(item, "a"),
|
||||||
|
href = content.getAttribute('href') || '',
|
||||||
|
text = content.textContent || "",
|
||||||
|
page = parseInt(text),
|
||||||
|
isCfi = href.indexOf("epubcfi"),
|
||||||
|
split,
|
||||||
|
packageUrl,
|
||||||
|
cfi;
|
||||||
|
|
||||||
|
if(isCfi != -1) {
|
||||||
|
split = href.split("#");
|
||||||
|
packageUrl = split[0];
|
||||||
|
cfi = split.length > 1 ? split[1] : false;
|
||||||
|
return {
|
||||||
|
"cfi" : cfi,
|
||||||
|
"href" : href,
|
||||||
|
"packageUrl" : packageUrl,
|
||||||
|
"page" : page
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
"href" : href,
|
||||||
|
"page" : page
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process pageList items
|
||||||
|
* @private
|
||||||
|
* @param {array} pageList
|
||||||
|
*/
|
||||||
|
PageList.prototype.process = function(pageList){
|
||||||
|
pageList.forEach(function(item){
|
||||||
|
this.pages.push(item.page);
|
||||||
|
if (item.cfi) {
|
||||||
|
this.locations.push(item.cfi);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
this.firstPage = parseInt(this.pages[0]);
|
||||||
|
this.lastPage = parseInt(this.pages[this.pages.length-1]);
|
||||||
|
this.totalPages = this.lastPage - this.firstPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace HREFs with CFI
|
||||||
|
* TODO: implement getting CFI from Href
|
||||||
|
*/
|
||||||
|
PageList.prototype.addCFIs = function() {
|
||||||
|
this.pageList.forEach(function(pg){
|
||||||
|
if(!pg.cfi) {
|
||||||
|
// epubcfi.generateCfiFromHref(pg.href, book).then(function(cfi){
|
||||||
|
// pg.cfi = cfi;
|
||||||
|
// pg.packageUrl = book.settings.packageUrl;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
EPUBJS.EpubCFI.prototype.generateCfiFromHref = function(href, book) {
|
||||||
|
var uri = EPUBJS.core.uri(href);
|
||||||
|
var path = uri.path;
|
||||||
|
var fragment = uri.fragment;
|
||||||
|
var spinePos = book.spineIndexByURL[path];
|
||||||
|
var loaded;
|
||||||
|
var deferred = new RSVP.defer();
|
||||||
|
var epubcfi = new EPUBJS.EpubCFI();
|
||||||
|
var spineItem;
|
||||||
|
|
||||||
|
if(typeof spinePos !== "undefined"){
|
||||||
|
spineItem = book.spine[spinePos];
|
||||||
|
loaded = book.loadXml(spineItem.url);
|
||||||
|
loaded.then(function(doc){
|
||||||
|
var element = doc.getElementById(fragment);
|
||||||
|
var cfi;
|
||||||
|
cfi = epubcfi.generateCfiFromElement(element, spineItem.cfiBase);
|
||||||
|
deferred.resolve(cfi);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a PageList result from a EpubCFI
|
||||||
|
* @param {string} cfi EpubCFI String
|
||||||
|
* @return {string} page
|
||||||
|
*/
|
||||||
|
PageList.prototype.pageFromCfi = function(cfi){
|
||||||
|
var pg = -1;
|
||||||
|
|
||||||
|
// Check if the pageList has not been set yet
|
||||||
|
if(this.locations.length === 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check if CFI is valid?
|
||||||
|
|
||||||
|
// check if the cfi is in the location list
|
||||||
|
// var index = this.locations.indexOf(cfi);
|
||||||
|
var index = core.indexOfSorted(cfi, this.locations, this.epubcfi.compare);
|
||||||
|
if(index != -1) {
|
||||||
|
pg = this.pages[index];
|
||||||
|
} else {
|
||||||
|
// Otherwise add it to the list of locations
|
||||||
|
// Insert it in the correct position in the locations page
|
||||||
|
//index = EPUBJS.core.insert(cfi, this.locations, this.epubcfi.compare);
|
||||||
|
index = EPUBJS.core.locationOf(cfi, this.locations, this.epubcfi.compare);
|
||||||
|
// Get the page at the location just before the new one, or return the first
|
||||||
|
pg = index-1 >= 0 ? this.pages[index-1] : this.pages[0];
|
||||||
|
if(pg !== undefined) {
|
||||||
|
// Add the new page in so that the locations and page array match up
|
||||||
|
//this.pages.splice(index, 0, pg);
|
||||||
|
} else {
|
||||||
|
pg = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return pg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an EpubCFI from a Page List Item
|
||||||
|
* @param {string} pg
|
||||||
|
* @return {string} cfi
|
||||||
|
*/
|
||||||
|
PageList.prototype.cfiFromPage = function(pg){
|
||||||
|
var cfi = -1;
|
||||||
|
// check that pg is an int
|
||||||
|
if(typeof pg != "number"){
|
||||||
|
pg = parseInt(pg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the cfi is in the page list
|
||||||
|
// Pages could be unsorted.
|
||||||
|
var index = this.pages.indexOf(pg);
|
||||||
|
if(index != -1) {
|
||||||
|
cfi = this.locations[index];
|
||||||
|
}
|
||||||
|
// TODO: handle pages not in the list
|
||||||
|
return cfi;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Page from Book percentage
|
||||||
|
* @param {number} percent
|
||||||
|
* @return {string} page
|
||||||
|
*/
|
||||||
|
PageList.prototype.pageFromPercentage = function(percent){
|
||||||
|
var pg = Math.round(this.totalPages * percent);
|
||||||
|
return pg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value between 0 - 1 corresponding to the location of a page
|
||||||
|
* @param {int} pg the page
|
||||||
|
* @return {number} percentage
|
||||||
|
*/
|
||||||
|
PageList.prototype.percentageFromPage = function(pg){
|
||||||
|
var percentage = (pg - this.firstPage) / this.totalPages;
|
||||||
|
return Math.round(percentage * 1000) / 1000;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value between 0 - 1 corresponding to the location of a cfi
|
||||||
|
* @param {string} cfi EpubCFI String
|
||||||
|
* @return {number} percentage
|
||||||
|
*/
|
||||||
|
PageList.prototype.percentageFromCfi = function(cfi){
|
||||||
|
var pg = this.pageFromCfi(cfi);
|
||||||
|
var percentage = this.percentageFromPage(pg);
|
||||||
|
return percentage;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = PageList;
|
|
@ -1,90 +0,0 @@
|
||||||
var path = require('path');
|
|
||||||
var core = require('./core');
|
|
||||||
var EpubCFI = require('./epubcfi');
|
|
||||||
|
|
||||||
|
|
||||||
function Parser(){};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parser.prototype.querySelectorText = function(xml, q){
|
|
||||||
var el = xml.querySelector(q);
|
|
||||||
|
|
||||||
if(el && el.childNodes.length){
|
|
||||||
return el.childNodes[0].nodeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parser.prototype.querySelectorByType = function(html, element, type){
|
|
||||||
var query;
|
|
||||||
if (typeof html.querySelector != "undefined") {
|
|
||||||
query = html.querySelector(element+'[*|type="'+type+'"]');
|
|
||||||
}
|
|
||||||
// Handle IE not supporting namespaced epub:type in querySelector
|
|
||||||
if(!query || query.length === 0) {
|
|
||||||
query = core.qsa(html, element);
|
|
||||||
for (var i = 0; i < query.length; i++) {
|
|
||||||
if(query[i].getAttributeNS("http://www.idpf.org/2007/ops", "type") === type) {
|
|
||||||
return query[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 ? core.qsa(navElement, "li") : [];
|
|
||||||
var length = navItems.length;
|
|
||||||
var i;
|
|
||||||
var toc = {};
|
|
||||||
var list = [];
|
|
||||||
var item;
|
|
||||||
|
|
||||||
if(!navItems || length === 0) return list;
|
|
||||||
|
|
||||||
for (i = 0; i < length; ++i) {
|
|
||||||
item = this.pageListItem(navItems[i], spineIndexByURL, bookSpine);
|
|
||||||
list.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype.pageListItem = function(item, spineIndexByURL, bookSpine){
|
|
||||||
var id = item.getAttribute('id') || false,
|
|
||||||
// content = item.querySelector("a"),
|
|
||||||
content = core.qs(item, "a"),
|
|
||||||
href = content.getAttribute('href') || '',
|
|
||||||
text = content.textContent || "",
|
|
||||||
page = parseInt(text),
|
|
||||||
isCfi = href.indexOf("epubcfi"),
|
|
||||||
split,
|
|
||||||
packageUrl,
|
|
||||||
cfi;
|
|
||||||
|
|
||||||
if(isCfi != -1) {
|
|
||||||
split = href.split("#");
|
|
||||||
packageUrl = split[0];
|
|
||||||
cfi = split.length > 1 ? split[1] : false;
|
|
||||||
return {
|
|
||||||
"cfi" : cfi,
|
|
||||||
"href" : href,
|
|
||||||
"packageUrl" : packageUrl,
|
|
||||||
"page" : page
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
"href" : href,
|
|
||||||
"page" : page
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Parser;
|
|
51
src/queue.js
51
src/queue.js
|
@ -1,14 +1,22 @@
|
||||||
var core = require('./core');
|
var core = require('./core');
|
||||||
|
|
||||||
function Queue(_context){
|
/**
|
||||||
|
* Queue for handling tasks one at a time
|
||||||
|
* @class
|
||||||
|
* @param {scope} context what this will resolve to in the tasks
|
||||||
|
*/
|
||||||
|
function Queue(context){
|
||||||
this._q = [];
|
this._q = [];
|
||||||
this.context = _context;
|
this.context = context;
|
||||||
this.tick = core.requestAnimationFrame;
|
this.tick = core.requestAnimationFrame;
|
||||||
this.running = false;
|
this.running = false;
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add an item to the queue
|
/**
|
||||||
|
* Add an item to the queue
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Queue.prototype.enqueue = function() {
|
Queue.prototype.enqueue = function() {
|
||||||
var deferred, promise;
|
var deferred, promise;
|
||||||
var queued;
|
var queued;
|
||||||
|
@ -56,7 +64,10 @@ Queue.prototype.enqueue = function() {
|
||||||
return queued.promise;
|
return queued.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run one item
|
/**
|
||||||
|
* Run one item
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Queue.prototype.dequeue = function(){
|
Queue.prototype.dequeue = function(){
|
||||||
var inwait, task, result;
|
var inwait, task, result;
|
||||||
|
|
||||||
|
@ -101,8 +112,10 @@ Queue.prototype.dump = function(){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run all sequentially, at convince
|
/**
|
||||||
|
* Run all tasks sequentially, at convince
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Queue.prototype.run = function(){
|
Queue.prototype.run = function(){
|
||||||
|
|
||||||
if(!this.running){
|
if(!this.running){
|
||||||
|
@ -134,7 +147,10 @@ Queue.prototype.run = function(){
|
||||||
return this.defered.promise;
|
return this.defered.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flush all, as quickly as possible
|
/**
|
||||||
|
* Flush all, as quickly as possible
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Queue.prototype.flush = function(){
|
Queue.prototype.flush = function(){
|
||||||
|
|
||||||
if(this.running){
|
if(this.running){
|
||||||
|
@ -153,21 +169,38 @@ Queue.prototype.flush = function(){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clear all items in wait
|
/**
|
||||||
|
* Clear all items in wait
|
||||||
|
*/
|
||||||
Queue.prototype.clear = function(){
|
Queue.prototype.clear = function(){
|
||||||
this._q = [];
|
this._q = [];
|
||||||
this.running = false;
|
this.running = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of tasks in the queue
|
||||||
|
* @return {int} tasks
|
||||||
|
*/
|
||||||
Queue.prototype.length = function(){
|
Queue.prototype.length = function(){
|
||||||
return this._q.length;
|
return this._q.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause a running queue
|
||||||
|
*/
|
||||||
Queue.prototype.pause = function(){
|
Queue.prototype.pause = function(){
|
||||||
this.paused = true;
|
this.paused = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a new task from a callback
|
/**
|
||||||
|
* Create a new task from a callback
|
||||||
|
* @class
|
||||||
|
* @private
|
||||||
|
* @param {function} task
|
||||||
|
* @param {array} args
|
||||||
|
* @param {scope} context
|
||||||
|
* @return {function} task
|
||||||
|
*/
|
||||||
function Task(task, args, context){
|
function Task(task, args, context){
|
||||||
|
|
||||||
return function(){
|
return function(){
|
||||||
|
|
183
src/rendition.js
183
src/rendition.js
|
@ -9,6 +9,20 @@ var Layout = require('./layout');
|
||||||
var Mapping = require('./mapping');
|
var Mapping = require('./mapping');
|
||||||
var Path = require('./core').Path;
|
var Path = require('./core').Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Rendition description]
|
||||||
|
* @class
|
||||||
|
* @param {Book} book
|
||||||
|
* @param {object} options
|
||||||
|
* @param {int} options.width
|
||||||
|
* @param {int} options.height
|
||||||
|
* @param {string} options.ignoreClass
|
||||||
|
* @param {string} options.manager
|
||||||
|
* @param {string} options.view
|
||||||
|
* @param {string} options.layout
|
||||||
|
* @param {string} options.spread
|
||||||
|
* @param {int} options.minSpreadWidth overridden by spread: none (never) / both (always)
|
||||||
|
*/
|
||||||
function Rendition(book, options) {
|
function Rendition(book, options) {
|
||||||
|
|
||||||
this.settings = core.extend(this.settings || {}, {
|
this.settings = core.extend(this.settings || {}, {
|
||||||
|
@ -20,8 +34,7 @@ function Rendition(book, options) {
|
||||||
flow: null,
|
flow: null,
|
||||||
layout: null,
|
layout: null,
|
||||||
spread: null,
|
spread: null,
|
||||||
minSpreadWidth: 800, //-- overridden by spread: none (never) / both (always),
|
minSpreadWidth: 800
|
||||||
useBase64: true
|
|
||||||
});
|
});
|
||||||
|
|
||||||
core.extend(this.settings, options);
|
core.extend(this.settings, options);
|
||||||
|
@ -34,10 +47,17 @@ function Rendition(book, options) {
|
||||||
|
|
||||||
this.views = null;
|
this.views = null;
|
||||||
|
|
||||||
//-- Adds Hook methods to the Rendition prototype
|
/**
|
||||||
|
* Adds Hook methods to the Rendition prototype
|
||||||
|
* @property {Hook} hooks
|
||||||
|
*/
|
||||||
this.hooks = {};
|
this.hooks = {};
|
||||||
this.hooks.display = new Hook(this);
|
this.hooks.display = new Hook(this);
|
||||||
this.hooks.serialize = new Hook(this);
|
this.hooks.serialize = new Hook(this);
|
||||||
|
/**
|
||||||
|
* @property {method} hooks.content
|
||||||
|
* @type {Hook}
|
||||||
|
*/
|
||||||
this.hooks.content = new Hook(this);
|
this.hooks.content = new Hook(this);
|
||||||
this.hooks.layout = new Hook(this);
|
this.hooks.layout = new Hook(this);
|
||||||
this.hooks.render = new Hook(this);
|
this.hooks.render = new Hook(this);
|
||||||
|
@ -55,15 +75,24 @@ function Rendition(book, options) {
|
||||||
this.q.enqueue(this.book.opened);
|
this.q.enqueue(this.book.opened);
|
||||||
|
|
||||||
// Block the queue until rendering is started
|
// Block the queue until rendering is started
|
||||||
// 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the manager function
|
||||||
|
* @param {function} manager
|
||||||
|
*/
|
||||||
Rendition.prototype.setManager = function(manager) {
|
Rendition.prototype.setManager = function(manager) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require the manager from passed string, or as a function
|
||||||
|
* @param {string|function} manager [description]
|
||||||
|
* @return {method}
|
||||||
|
*/
|
||||||
Rendition.prototype.requireManager = function(manager) {
|
Rendition.prototype.requireManager = function(manager) {
|
||||||
var viewManager;
|
var viewManager;
|
||||||
|
|
||||||
|
@ -80,6 +109,11 @@ Rendition.prototype.requireManager = function(manager) {
|
||||||
return viewManager;
|
return viewManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require the view from passed string, or as a function
|
||||||
|
* @param {string|function} view
|
||||||
|
* @return {view}
|
||||||
|
*/
|
||||||
Rendition.prototype.requireView = function(view) {
|
Rendition.prototype.requireView = function(view) {
|
||||||
var View;
|
var View;
|
||||||
|
|
||||||
|
@ -93,6 +127,10 @@ Rendition.prototype.requireView = function(view) {
|
||||||
return View;
|
return View;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the rendering
|
||||||
|
* @return {Promise} rendering has started
|
||||||
|
*/
|
||||||
Rendition.prototype.start = function(){
|
Rendition.prototype.start = function(){
|
||||||
|
|
||||||
if(!this.manager) {
|
if(!this.manager) {
|
||||||
|
@ -130,11 +168,15 @@ Rendition.prototype.start = function(){
|
||||||
this.emit("started");
|
this.emit("started");
|
||||||
|
|
||||||
// Start processing queue
|
// Start processing queue
|
||||||
// this.starting.resolve();
|
this.starting.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call to attach the container to an element in the dom
|
/**
|
||||||
// Container must be attached before rendering can begin
|
* Call to attach the container to an element in the dom
|
||||||
|
* Container must be attached before rendering can begin
|
||||||
|
* @param {element} element to attach to
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Rendition.prototype.attachTo = function(element){
|
Rendition.prototype.attachTo = function(element){
|
||||||
|
|
||||||
return this.q.enqueue(function () {
|
return this.q.enqueue(function () {
|
||||||
|
@ -152,6 +194,14 @@ Rendition.prototype.attachTo = function(element){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a point in the book
|
||||||
|
* The request will be added to the rendering Queue,
|
||||||
|
* so it will wait until book is opened, rendering started
|
||||||
|
* and all other rendering tasks have finished to be called.
|
||||||
|
* @param {string} target Url or EpubCFI
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Rendition.prototype.display = function(target){
|
Rendition.prototype.display = function(target){
|
||||||
|
|
||||||
// if (!this.book.spine.spineItems.length > 0) {
|
// if (!this.book.spine.spineItems.length > 0) {
|
||||||
|
@ -163,6 +213,12 @@ Rendition.prototype.display = function(target){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the manager what to display immediately
|
||||||
|
* @private
|
||||||
|
* @param {string} target Url or EpubCFI
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Rendition.prototype._display = function(target){
|
Rendition.prototype._display = function(target){
|
||||||
var isCfiString = this.epubcfi.isCfiString(target);
|
var isCfiString = this.epubcfi.isCfiString(target);
|
||||||
var displaying = new core.defer();
|
var displaying = new core.defer();
|
||||||
|
@ -240,13 +296,22 @@ Rendition.prototype.render = function(view, show) {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report what has been displayed
|
||||||
|
* @private
|
||||||
|
* @param {*} view
|
||||||
|
*/
|
||||||
Rendition.prototype.afterDisplayed = function(view){
|
Rendition.prototype.afterDisplayed = function(view){
|
||||||
this.hooks.content.trigger(view, this);
|
this.hooks.content.trigger(view, this);
|
||||||
this.emit("rendered", view.section);
|
this.emit("rendered", view.section);
|
||||||
this.reportLocation();
|
this.reportLocation();
|
||||||
};
|
};
|
||||||
|
|
||||||
Rendition.prototype.onResized = function(size){
|
/**
|
||||||
|
* Report resize events and display the last seen location
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Rendition.prototype.onResized = function(){
|
||||||
|
|
||||||
if(this.location) {
|
if(this.location) {
|
||||||
this.display(this.location.start);
|
this.display(this.location.start);
|
||||||
|
@ -259,23 +324,42 @@ Rendition.prototype.onResized = function(size){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the Rendition to a specific offset
|
||||||
|
* Usually you would be better off calling display()
|
||||||
|
* @param {object} offset
|
||||||
|
*/
|
||||||
Rendition.prototype.moveTo = function(offset){
|
Rendition.prototype.moveTo = function(offset){
|
||||||
this.manager.moveTo(offset);
|
this.manager.moveTo(offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to the next "page" in the rendition
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Rendition.prototype.next = function(){
|
Rendition.prototype.next = function(){
|
||||||
return this.q.enqueue(this.manager.next.bind(this.manager))
|
return this.q.enqueue(this.manager.next.bind(this.manager))
|
||||||
.then(this.reportLocation.bind(this));
|
.then(this.reportLocation.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go to the previous "page" in the rendition
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Rendition.prototype.prev = function(){
|
Rendition.prototype.prev = function(){
|
||||||
return this.q.enqueue(this.manager.prev.bind(this.manager))
|
return this.q.enqueue(this.manager.prev.bind(this.manager))
|
||||||
.then(this.reportLocation.bind(this));
|
.then(this.reportLocation.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
//-- http://www.idpf.org/epub/301/spec/epub-publications.html#meta-properties-rendering
|
//-- http://www.idpf.org/epub/301/spec/epub-publications.html#meta-properties-rendering
|
||||||
|
/**
|
||||||
|
* Determine the Layout properties from metadata and settings
|
||||||
|
* @private
|
||||||
|
* @param {object} metadata
|
||||||
|
* @return {object} properties
|
||||||
|
*/
|
||||||
Rendition.prototype.determineLayoutProperties = function(metadata){
|
Rendition.prototype.determineLayoutProperties = function(metadata){
|
||||||
var settings;
|
var properties;
|
||||||
var layout = this.settings.layout || metadata.layout || "reflowable";
|
var layout = this.settings.layout || metadata.layout || "reflowable";
|
||||||
var spread = this.settings.spread || metadata.spread || "auto";
|
var spread = this.settings.spread || metadata.spread || "auto";
|
||||||
var orientation = this.settings.orientation || metadata.orientation || "auto";
|
var orientation = this.settings.orientation || metadata.orientation || "auto";
|
||||||
|
@ -287,7 +371,7 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
|
||||||
viewport = "width="+this.settings.width+", height="+this.settings.height+"";
|
viewport = "width="+this.settings.width+", height="+this.settings.height+"";
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = {
|
properties = {
|
||||||
layout : layout,
|
layout : layout,
|
||||||
spread : spread,
|
spread : spread,
|
||||||
orientation : orientation,
|
orientation : orientation,
|
||||||
|
@ -296,7 +380,7 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
|
||||||
minSpreadWidth : minSpreadWidth
|
minSpreadWidth : minSpreadWidth
|
||||||
};
|
};
|
||||||
|
|
||||||
return settings;
|
return properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rendition.prototype.applyLayoutProperties = function(){
|
// Rendition.prototype.applyLayoutProperties = function(){
|
||||||
|
@ -307,28 +391,34 @@ Rendition.prototype.determineLayoutProperties = function(metadata){
|
||||||
// this.layout(settings);
|
// this.layout(settings);
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// paginated | scrolled
|
/**
|
||||||
// (scrolled-continuous vs scrolled-doc are handled by different view managers)
|
* Adjust the flow of the rendition to paginated or scrolled
|
||||||
Rendition.prototype.flow = function(_flow){
|
* (scrolled-continuous vs scrolled-doc are handled by different view managers)
|
||||||
var flow;
|
* @param {string} flow
|
||||||
if (_flow === "scrolled-doc" || _flow === "scrolled-continuous") {
|
*/
|
||||||
flow = "scrolled";
|
Rendition.prototype.flow = function(flow){
|
||||||
|
var _flow;
|
||||||
|
if (flow === "scrolled-doc" || flow === "scrolled-continuous") {
|
||||||
|
_flow = "scrolled";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_flow === "auto" || _flow === "paginated") {
|
if (flow === "auto" || flow === "paginated") {
|
||||||
flow = "paginated";
|
_flow = "paginated";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._layout) {
|
if (this._layout) {
|
||||||
this._layout.flow(flow);
|
this._layout.flow(_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.manager) {
|
if (this.manager) {
|
||||||
this.manager.updateFlow(flow);
|
this.manager.updateFlow(_flow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// reflowable | pre-paginated
|
/**
|
||||||
|
* Adjust the layout of the rendition to reflowable or pre-paginated
|
||||||
|
* @param {object} settings
|
||||||
|
*/
|
||||||
Rendition.prototype.layout = function(settings){
|
Rendition.prototype.layout = function(settings){
|
||||||
if (settings) {
|
if (settings) {
|
||||||
this._layout = new Layout(settings);
|
this._layout = new Layout(settings);
|
||||||
|
@ -344,7 +434,11 @@ Rendition.prototype.layout = function(settings){
|
||||||
return this._layout;
|
return this._layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// none | auto (TODO: implement landscape, portrait, both)
|
/**
|
||||||
|
* Adjust if the rendition uses spreads
|
||||||
|
* @param {string} spread none | auto (TODO: implement landscape, portrait, both)
|
||||||
|
* @param {int} min min width to use spreads at
|
||||||
|
*/
|
||||||
Rendition.prototype.spread = function(spread, min){
|
Rendition.prototype.spread = function(spread, min){
|
||||||
|
|
||||||
this._layout.spread(spread, min);
|
this._layout.spread(spread, min);
|
||||||
|
@ -354,7 +448,9 @@ Rendition.prototype.spread = function(spread, min){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report the current location
|
||||||
|
*/
|
||||||
Rendition.prototype.reportLocation = function(){
|
Rendition.prototype.reportLocation = function(){
|
||||||
return this.q.enqueue(function(){
|
return this.q.enqueue(function(){
|
||||||
var location = this.manager.currentLocation();
|
var location = this.manager.currentLocation();
|
||||||
|
@ -371,7 +467,9 @@ Rendition.prototype.reportLocation = function(){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove and Clean Up the Rendition
|
||||||
|
*/
|
||||||
Rendition.prototype.destroy = function(){
|
Rendition.prototype.destroy = function(){
|
||||||
// Clear the queue
|
// Clear the queue
|
||||||
this.q.clear();
|
this.q.clear();
|
||||||
|
@ -379,6 +477,11 @@ Rendition.prototype.destroy = function(){
|
||||||
this.manager.destroy();
|
this.manager.destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass the events from a view
|
||||||
|
* @private
|
||||||
|
* @param {View} view
|
||||||
|
*/
|
||||||
Rendition.prototype.passViewEvents = function(view){
|
Rendition.prototype.passViewEvents = function(view){
|
||||||
view.contents.listenedEvents.forEach(function(e){
|
view.contents.listenedEvents.forEach(function(e){
|
||||||
view.on(e, this.triggerViewEvent.bind(this));
|
view.on(e, this.triggerViewEvent.bind(this));
|
||||||
|
@ -387,26 +490,46 @@ Rendition.prototype.passViewEvents = function(view){
|
||||||
view.on("selected", this.triggerSelectedEvent.bind(this));
|
view.on("selected", this.triggerSelectedEvent.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit events passed by a view
|
||||||
|
* @private
|
||||||
|
* @param {event} e
|
||||||
|
*/
|
||||||
Rendition.prototype.triggerViewEvent = function(e){
|
Rendition.prototype.triggerViewEvent = function(e){
|
||||||
this.emit(e.type, e);
|
this.emit(e.type, e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit a selection event's CFI Range passed from a a view
|
||||||
|
* @private
|
||||||
|
* @param {EpubCFI} cfirange
|
||||||
|
*/
|
||||||
Rendition.prototype.triggerSelectedEvent = function(cfirange){
|
Rendition.prototype.triggerSelectedEvent = function(cfirange){
|
||||||
this.emit("selected", cfirange);
|
this.emit("selected", cfirange);
|
||||||
};
|
};
|
||||||
|
|
||||||
Rendition.prototype.range = function(_cfi, ignoreClass){
|
/**
|
||||||
var cfi = new EpubCFI(_cfi);
|
* Get a Range from a Visible CFI
|
||||||
|
* @param {string} cfi EpubCfi String
|
||||||
|
* @param {string} ignoreClass
|
||||||
|
* @return {range}
|
||||||
|
*/
|
||||||
|
Rendition.prototype.range = function(cfi, ignoreClass){
|
||||||
|
var _cfi = new EpubCFI(cfi);
|
||||||
var found = this.visible().filter(function (view) {
|
var found = this.visible().filter(function (view) {
|
||||||
if(cfi.spinePos === view.index) return true;
|
if(_cfi.spinePos === view.index) return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Should only every return 1 item
|
// Should only every return 1 item
|
||||||
if (found.length) {
|
if (found.length) {
|
||||||
return found[0].range(cfi, ignoreClass);
|
return found[0].range(_cfi, ignoreClass);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to adjust images to fit in columns
|
||||||
|
* @param {View} view
|
||||||
|
*/
|
||||||
Rendition.prototype.adjustImages = function(view) {
|
Rendition.prototype.adjustImages = function(view) {
|
||||||
|
|
||||||
view.addStylesheetRules([
|
view.addStylesheetRules([
|
||||||
|
|
|
@ -3,9 +3,18 @@ var core = require('./core');
|
||||||
var Path = require('./core').Path;
|
var Path = require('./core').Path;
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Package Resources
|
||||||
|
* @class
|
||||||
|
* @param {Manifest} manifest
|
||||||
|
* @param {[object]} options
|
||||||
|
* @param {[string='base64']} options.replacements
|
||||||
|
* @param {[Archive]} options.archive
|
||||||
|
* @param {[method]} options.resolver
|
||||||
|
*/
|
||||||
function Resources(manifest, options) {
|
function Resources(manifest, options) {
|
||||||
this.settings = {
|
this.settings = {
|
||||||
base64: (options && options.base64) || true,
|
replacements: (options && options.replacements) || 'base64',
|
||||||
archive: (options && options.archive),
|
archive: (options && options.archive),
|
||||||
resolver: (options && options.resolver)
|
resolver: (options && options.resolver)
|
||||||
};
|
};
|
||||||
|
@ -15,12 +24,16 @@ function Resources(manifest, options) {
|
||||||
return manifest[key];
|
return manifest[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
this.replacementUrls = undefined;
|
this.replacementUrls = [];
|
||||||
|
|
||||||
this.split();
|
this.split();
|
||||||
this.urls();
|
this.splitUrls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split resources by type
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
Resources.prototype.split = function(){
|
Resources.prototype.split = function(){
|
||||||
|
|
||||||
// HTML
|
// HTML
|
||||||
|
@ -50,7 +63,11 @@ Resources.prototype.split = function(){
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Resources.prototype.urls = function(){
|
/**
|
||||||
|
* Convert split resources into Urls
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Resources.prototype.splitUrls = function(){
|
||||||
|
|
||||||
// All Assets Urls
|
// All Assets Urls
|
||||||
this.urls = this.assets.
|
this.urls = this.assets.
|
||||||
|
@ -74,11 +91,18 @@ Resources.prototype.urls = function(){
|
||||||
Resources.prototype.replacements = function(archive, resolver){
|
Resources.prototype.replacements = function(archive, resolver){
|
||||||
archive = archive || this.settings.archive;
|
archive = archive || this.settings.archive;
|
||||||
resolver = resolver || this.settings.resolver;
|
resolver = resolver || this.settings.resolver;
|
||||||
|
|
||||||
|
if (this.settings.replacements === "none") {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
resolve(this.urls);
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
var replacements = this.urls.
|
var replacements = this.urls.
|
||||||
map(function(url) {
|
map(function(url) {
|
||||||
var absolute = resolver(url);
|
var absolute = resolver(url);
|
||||||
|
|
||||||
return archive.createUrl(absolute, {"base64": this.settings.base64});
|
return archive.createUrl(absolute, {"base64": (this.settings.replacements === "base64")});
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
|
|
||||||
return Promise.all(replacements)
|
return Promise.all(replacements)
|
||||||
|
@ -88,12 +112,19 @@ Resources.prototype.replacements = function(archive, resolver){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace URLs in CSS resources
|
||||||
|
* @private
|
||||||
|
* @param {[Archive]} archive
|
||||||
|
* @param {[method]} resolver
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
Resources.prototype.replaceCss = function(archive, resolver){
|
Resources.prototype.replaceCss = function(archive, resolver){
|
||||||
var replaced = [];
|
var replaced = [];
|
||||||
archive = archive || this.settings.archive;
|
archive = archive || this.settings.archive;
|
||||||
resolver = resolver || this.settings.resolver;
|
resolver = resolver || this.settings.resolver;
|
||||||
this.cssUrls.forEach(function(href) {
|
this.cssUrls.forEach(function(href) {
|
||||||
var replacment = this.createCssFile(href, archive, resolver)
|
var replacement = this.createCssFile(href, archive, resolver)
|
||||||
.then(function (replacementUrl) {
|
.then(function (replacementUrl) {
|
||||||
// switch the url in the replacementUrls
|
// switch the url in the replacementUrls
|
||||||
var indexInUrls = this.urls.indexOf(href);
|
var indexInUrls = this.urls.indexOf(href);
|
||||||
|
@ -102,11 +133,19 @@ Resources.prototype.replaceCss = function(archive, resolver){
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
replaced.push(replacment);
|
replaced.push(replacement);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
return Promise.all(replaced);
|
return Promise.all(replaced);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new CSS file with the replaced URLs
|
||||||
|
* @private
|
||||||
|
* @param {string} href the original css file
|
||||||
|
* @param {[Archive]} archive
|
||||||
|
* @param {[method]} resolver
|
||||||
|
* @return {Promise} returns a BlobUrl to the new CSS file or a data url
|
||||||
|
*/
|
||||||
Resources.prototype.createCssFile = function(href, archive, resolver){
|
Resources.prototype.createCssFile = function(href, archive, resolver){
|
||||||
var newUrl;
|
var newUrl;
|
||||||
var indexInUrls;
|
var indexInUrls;
|
||||||
|
@ -136,7 +175,7 @@ Resources.prototype.createCssFile = function(href, archive, resolver){
|
||||||
text = replace.substitute(text, relUrls, this.replacementUrls);
|
text = replace.substitute(text, relUrls, this.replacementUrls);
|
||||||
|
|
||||||
// Get the new url
|
// Get the new url
|
||||||
if (this.settings.base64) {
|
if (this.settings.replacements === "base64") {
|
||||||
newUrl = core.createBase64Url(text, 'text/css');
|
newUrl = core.createBase64Url(text, 'text/css');
|
||||||
} else {
|
} else {
|
||||||
newUrl = core.createBlobUrl(text, 'text/css');
|
newUrl = core.createBlobUrl(text, 'text/css');
|
||||||
|
@ -147,6 +186,12 @@ Resources.prototype.createCssFile = function(href, archive, resolver){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve all resources URLs relative to an absolute URL
|
||||||
|
* @param {string} absolute to be resolved to
|
||||||
|
* @param {[resolver]} resolver
|
||||||
|
* @return {string[]} array with relative Urls
|
||||||
|
*/
|
||||||
Resources.prototype.relativeTo = function(absolute, resolver){
|
Resources.prototype.relativeTo = function(absolute, resolver){
|
||||||
resolver = resolver || this.settings.resolver;
|
resolver = resolver || this.settings.resolver;
|
||||||
|
|
||||||
|
@ -159,14 +204,24 @@ Resources.prototype.relativeTo = function(absolute, resolver){
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
Resources.prototype.substitute = function(content, url) {
|
/**
|
||||||
var relUrls;
|
* Get a URL for a resource
|
||||||
if (url) {
|
* @param {string} path
|
||||||
relUrls = this.relativeTo(url);
|
* @return {string} url
|
||||||
} else {
|
*/
|
||||||
relUrls = this.urls;
|
Resources.prototype.get = function(path) {
|
||||||
|
var indexInUrls = this.urls.indexOf(path);
|
||||||
|
if (indexInUrls === -1) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return replace.substitute(content, relUrls, this.replacementUrls);
|
if (this.replacementUrls.length) {
|
||||||
};
|
return new Promise(function(resolve, reject) {
|
||||||
|
resolve(this.replacementUrls[indexInUrls]);
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
return archive.createUrl(absolute,
|
||||||
|
{"base64": (this.settings.replacements === "base64")})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Resources;
|
module.exports = Resources;
|
||||||
|
|
|
@ -3,6 +3,12 @@ var EpubCFI = require('./epubcfi');
|
||||||
var Hook = require('./hook');
|
var Hook = require('./hook');
|
||||||
var Url = require('./core').Url;
|
var Url = require('./core').Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Section of the Book
|
||||||
|
* In most books this is equivelent to a Chapter
|
||||||
|
* @param {object} item The spine item representing the section
|
||||||
|
* @param {object} hooks hooks for serialize and content
|
||||||
|
*/
|
||||||
function Section(item, hooks){
|
function Section(item, hooks){
|
||||||
this.idref = item.idref;
|
this.idref = item.idref;
|
||||||
this.linear = item.linear;
|
this.linear = item.linear;
|
||||||
|
@ -25,7 +31,11 @@ function Section(item, hooks){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the section from its url
|
||||||
|
* @param {method} _request a request method to use for loading
|
||||||
|
* @return {document} a promise with the xml document
|
||||||
|
*/
|
||||||
Section.prototype.load = function(_request){
|
Section.prototype.load = function(_request){
|
||||||
var request = _request || this.request || require('./request');
|
var request = _request || this.request || require('./request');
|
||||||
var loading = new core.defer();
|
var loading = new core.defer();
|
||||||
|
@ -55,6 +65,11 @@ Section.prototype.load = function(_request){
|
||||||
return loaded;
|
return loaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a base tag for resolving urls in the section
|
||||||
|
* @private
|
||||||
|
* @param {document} _document
|
||||||
|
*/
|
||||||
Section.prototype.base = function(_document){
|
Section.prototype.base = function(_document){
|
||||||
var task = new core.defer();
|
var task = new core.defer();
|
||||||
var base = _document.createElement("base"); // TODO: check if exists
|
var base = _document.createElement("base"); // TODO: check if exists
|
||||||
|
@ -76,10 +91,11 @@ Section.prototype.base = function(_document){
|
||||||
return task.promise;
|
return task.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
Section.prototype.beforeSectionLoad = function(){
|
/**
|
||||||
// Stub for a hook - replace me for now
|
* Render the contents of a section
|
||||||
};
|
* @param {method} _request a request method to use for loading
|
||||||
|
* @return {string} output a serialized XML Document
|
||||||
|
*/
|
||||||
Section.prototype.render = function(_request){
|
Section.prototype.render = function(_request){
|
||||||
var rendering = new core.defer();
|
var rendering = new core.defer();
|
||||||
var rendered = rendering.promise;
|
var rendered = rendering.promise;
|
||||||
|
@ -109,15 +125,21 @@ Section.prototype.render = function(_request){
|
||||||
return rendered;
|
return rendered;
|
||||||
};
|
};
|
||||||
|
|
||||||
Section.prototype.find = function(_query){
|
/**
|
||||||
|
* Find a string in a section
|
||||||
|
* TODO: need reimplementation from v0.2
|
||||||
|
* @param {string} query [description]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
Section.prototype.find = function(query){
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Reconciles the current chapters layout properies with
|
* Reconciles the current chapters layout properies with
|
||||||
* the global layout properities.
|
* the global layout properities.
|
||||||
* Takes: global layout settings object, chapter properties string
|
* @param {object} global The globa layout settings object, chapter properties string
|
||||||
* Returns: Object with layout properties
|
* @return {object} layoutProperties Object with layout properties
|
||||||
*/
|
*/
|
||||||
Section.prototype.reconcileLayoutSettings = function(global){
|
Section.prototype.reconcileLayoutSettings = function(global){
|
||||||
//-- Get the global defaults
|
//-- Get the global defaults
|
||||||
|
@ -143,10 +165,20 @@ Section.prototype.reconcileLayoutSettings = function(global){
|
||||||
return settings;
|
return settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a CFI from a Range in the Section
|
||||||
|
* @param {range} _range
|
||||||
|
* @return {string} cfi an EpubCFI string
|
||||||
|
*/
|
||||||
Section.prototype.cfiFromRange = function(_range) {
|
Section.prototype.cfiFromRange = function(_range) {
|
||||||
return new EpubCFI(_range, this.cfiBase).toString();
|
return new EpubCFI(_range, this.cfiBase).toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a CFI from an Element in the Section
|
||||||
|
* @param {element} el
|
||||||
|
* @return {string} cfi an EpubCFI string
|
||||||
|
*/
|
||||||
Section.prototype.cfiFromElement = function(el) {
|
Section.prototype.cfiFromElement = function(el) {
|
||||||
return new EpubCFI(el, this.cfiBase).toString();
|
return new EpubCFI(el, this.cfiBase).toString();
|
||||||
};
|
};
|
||||||
|
|
55
src/spine.js
55
src/spine.js
|
@ -4,6 +4,9 @@ var Hook = require('./hook');
|
||||||
var Section = require('./section');
|
var Section = require('./section');
|
||||||
var replacements = require('./replacements');
|
var replacements = require('./replacements');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of Spine Items
|
||||||
|
*/
|
||||||
function Spine(){
|
function Spine(){
|
||||||
this.spineItems = [];
|
this.spineItems = [];
|
||||||
this.spineByHref = {};
|
this.spineByHref = {};
|
||||||
|
@ -22,6 +25,11 @@ function Spine(){
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpack items from a opf into spine items
|
||||||
|
* @param {Package} _package
|
||||||
|
* @param {method} resolver URL resolver
|
||||||
|
*/
|
||||||
Spine.prototype.unpack = function(_package, resolver) {
|
Spine.prototype.unpack = function(_package, resolver) {
|
||||||
|
|
||||||
this.items = _package.spine;
|
this.items = _package.spine;
|
||||||
|
@ -46,13 +54,8 @@ Spine.prototype.unpack = function(_package, resolver) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(index > 0) {
|
item.prev = function(){ return this.get(index-1); }.bind(this);
|
||||||
item.prev = function(){ return this.get(index-1); }.bind(this);
|
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);
|
||||||
|
|
||||||
|
@ -64,10 +67,15 @@ Spine.prototype.unpack = function(_package, resolver) {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// book.spine.get();
|
/**
|
||||||
// book.spine.get(1);
|
* Get an item from the spine
|
||||||
// book.spine.get("chap1.html");
|
* @param {[string|int]} target
|
||||||
// book.spine.get("#id1234");
|
* @return {Section} section
|
||||||
|
* @example spine.get();
|
||||||
|
* @example spine.get(1);
|
||||||
|
* @example spine.get("chap1.html");
|
||||||
|
* @example spine.get("#id1234");
|
||||||
|
*/
|
||||||
Spine.prototype.get = function(target) {
|
Spine.prototype.get = function(target) {
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
|
@ -87,6 +95,11 @@ Spine.prototype.get = function(target) {
|
||||||
return this.spineItems[index] || null;
|
return this.spineItems[index] || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a Section to the Spine
|
||||||
|
* @private
|
||||||
|
* @param {Section} section
|
||||||
|
*/
|
||||||
Spine.prototype.append = function(section) {
|
Spine.prototype.append = function(section) {
|
||||||
var index = this.spineItems.length;
|
var index = this.spineItems.length;
|
||||||
section.index = index;
|
section.index = index;
|
||||||
|
@ -99,6 +112,11 @@ Spine.prototype.append = function(section) {
|
||||||
return index;
|
return index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepend a Section to the Spine
|
||||||
|
* @private
|
||||||
|
* @param {Section} section
|
||||||
|
*/
|
||||||
Spine.prototype.prepend = function(section) {
|
Spine.prototype.prepend = function(section) {
|
||||||
var index = this.spineItems.unshift(section);
|
var index = this.spineItems.unshift(section);
|
||||||
this.spineByHref[section.href] = 0;
|
this.spineByHref[section.href] = 0;
|
||||||
|
@ -112,10 +130,15 @@ Spine.prototype.prepend = function(section) {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Spine.prototype.insert = function(section, index) {
|
// Spine.prototype.insert = function(section, index) {
|
||||||
|
//
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a Section from the Spine
|
||||||
|
* @private
|
||||||
|
* @param {Section} section
|
||||||
|
*/
|
||||||
Spine.prototype.remove = function(section) {
|
Spine.prototype.remove = function(section) {
|
||||||
var index = this.spineItems.indexOf(section);
|
var index = this.spineItems.indexOf(section);
|
||||||
|
|
||||||
|
@ -127,6 +150,10 @@ Spine.prototype.remove = function(section) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop over the Sections in the Spine
|
||||||
|
* @return {method} forEach
|
||||||
|
*/
|
||||||
Spine.prototype.each = function() {
|
Spine.prototype.each = function() {
|
||||||
return this.spineItems.forEach.apply(this.spineItems, arguments);
|
return this.spineItems.forEach.apply(this.spineItems, arguments);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue