mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-02 14:49:16 +02:00
Updates for rendering in embedded Webviews (#643)
* Initial embedding support * Updates for rendering in embedded webviews * toLowerCase nodeName check
This commit is contained in:
parent
5cc8b191d0
commit
bb1ab21a33
23 changed files with 987 additions and 213 deletions
|
@ -14,13 +14,14 @@
|
|||
.epub-container {
|
||||
min-width: 320px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.epub-container .epub-view > iframe {
|
||||
background: white;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
margin: 10px;
|
||||
padding: 20px;
|
||||
/*margin: 10px;
|
||||
padding: 20px;*/
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
height: 600
|
||||
});
|
||||
|
||||
var displayed = rendition.display(0);
|
||||
var displayed = rendition.display();
|
||||
|
||||
|
||||
displayed.then(function(renderer){
|
||||
|
|
80
examples/embedded.html
Normal file
80
examples/embedded.html
Normal file
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title></title>
|
||||
|
||||
<script src="../dist/epub.js"></script>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-scroll-snap-type: mandatory;
|
||||
-webkit-scroll-snap-points-x: repeat(100%);
|
||||
|
||||
/*This scroll snap functionality is part of a polyfill
|
||||
that enables the functionality in Chrome.*/
|
||||
scroll-snap-type: mandatory;
|
||||
scroll-snap-points-x: repeat(100%);
|
||||
width: 100vw;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.epub-container {
|
||||
margin: 0;
|
||||
/*-webkit-scroll-snap-type: mandatory;
|
||||
-webkit-scroll-snap-points-x: repeat(100%);*/
|
||||
/* -webkit-overflow-scrolling: touch; */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
|
||||
var url = params && params.get("url") && decodeURIComponent(params.get("url"));
|
||||
var currentCfi = (params && params.get("cfi")) ? params.get("cfi") : undefined;
|
||||
var currentSectionIndex = (params && params.get("loc")) ? parseInt(params.get("loc")) : 6;
|
||||
|
||||
// Load the opf
|
||||
var book = ePub(url || "https://s3.amazonaws.com/moby-dick/");
|
||||
var rendition = book.renderTo(document.body, {
|
||||
// width: "100vw",
|
||||
// height: "100vh",
|
||||
overflow: "visible",
|
||||
manager: "continuous",
|
||||
flow: "paginated"
|
||||
});
|
||||
|
||||
rendition.display(currentCfi || currentSectionIndex);
|
||||
|
||||
|
||||
rendition.on("rendered", function(section){
|
||||
var nextSection = section.next();
|
||||
var prevSection = section.prev();
|
||||
|
||||
var current = book.navigation && book.navigation.get(section.href);
|
||||
|
||||
if (current) {
|
||||
document.title = current.label;
|
||||
}
|
||||
});
|
||||
|
||||
rendition.on("relocated", function(location){
|
||||
console.log("locationChanged", location)
|
||||
console.log("locationChanged start", location.start.cfi)
|
||||
console.log("locationChanged end", location.end.cfi)
|
||||
});
|
||||
|
||||
window.addEventListener("unload", function () {
|
||||
console.log("unloading");
|
||||
this.book.destroy();
|
||||
});
|
||||
|
||||
</script>
|
||||
<!-- <script src="../node_modules/scrollsnap-polyfill/vendor/philipwalton/polyfill.js"></script>
|
||||
<script src="../node_modules/scrollsnap-polyfill/src/scrollsnap-polyfill.js"></script> -->
|
||||
</body>
|
||||
</html>
|
|
@ -29,7 +29,7 @@ body {
|
|||
height: 600px;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
border-radius: 5px;
|
||||
padding: 20px 40px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
margin: 10px auto;
|
||||
background: white url('ajax-loader.gif') center center no-repeat;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>EPUB.js Pagination Example</title>
|
||||
<title>EPUB.js Highlights Example</title>
|
||||
|
||||
<script src="../dist/epub.js"></script>
|
||||
|
||||
|
|
|
@ -75,19 +75,19 @@
|
|||
// Hooks
|
||||
|
||||
// Add a single script
|
||||
rendition.hooks.content.register(function(view){
|
||||
return view.addScript("https://code.jquery.com/jquery-2.1.4.min.js")
|
||||
rendition.hooks.content.register(function(contents){
|
||||
return contents.addScript("https://code.jquery.com/jquery-2.1.4.min.js")
|
||||
.then(function(){
|
||||
// init code
|
||||
});
|
||||
});
|
||||
|
||||
// Add several scripts / css
|
||||
rendition.hooks.content.register(function(view){
|
||||
rendition.hooks.content.register(function(contents){
|
||||
|
||||
var loaded = Promise.all([
|
||||
view.addScript("http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"),
|
||||
view.addCss("http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css")
|
||||
contents.addScript("https://code.jquery.com/jquery-2.1.4.min.js"),
|
||||
contents.addStylesheet("http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css")
|
||||
]);
|
||||
|
||||
// return loaded promise
|
||||
|
|
408
examples/hypothesis-spreads.html
Normal file
408
examples/hypothesis-spreads.html
Normal file
|
@ -0,0 +1,408 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>EPUB.js + Hypothes.is Example</title>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.1/jszip.min.js"></script>
|
||||
<script src="../dist/epub.js"></script>
|
||||
|
||||
<!-- <script>
|
||||
window.hypothesisConfig = function () {
|
||||
return {
|
||||
// constructor: this.Annotator.Sidebar,
|
||||
app: 'https://hypothes.is/app.html',
|
||||
};
|
||||
};
|
||||
</script> -->
|
||||
|
||||
<script type="text/javascript">
|
||||
window.hypothesisConfig = function () {
|
||||
return {
|
||||
// Open the sidebar when the page loads
|
||||
openSidebar: true,
|
||||
|
||||
// Needed for multi frame support
|
||||
enableMultiFrameSupport: true,
|
||||
embedScriptUrl: "https://cdn.hypothes.is/hypothesis"
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdn.hypothes.is/hypothesis"></script>
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="examples.css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fafafa;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
width: 400px;
|
||||
position: fixed;
|
||||
overflow: auto;
|
||||
top: 0;
|
||||
left: -425px;
|
||||
|
||||
background: #ECECEC;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
height: 100vh;
|
||||
|
||||
overflow: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 9px;
|
||||
padding-top: 10px;
|
||||
|
||||
transition: left .2s ease-out;
|
||||
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
|
||||
}
|
||||
|
||||
#navigation.open {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#navigation.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#navigation h1 {
|
||||
width: 200px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
color: #777;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#navigation h2 {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #B0B0B0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#navigation ul {
|
||||
padding-left: 28px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#navigation ul li {
|
||||
list-style: decimal;
|
||||
margin-bottom: 10px;
|
||||
color: #585858;
|
||||
font-size: 12px;
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#navigation ul li a {
|
||||
color: #585858;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navigation ul li a:hover {
|
||||
color: #585858;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#navigation ul li a.active {
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#navigation #author {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#cover {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
#pagination {
|
||||
text-align: center;
|
||||
margin: 20px;
|
||||
/*padding: 0 50px;*/
|
||||
}
|
||||
|
||||
.arrow:hover {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.arrow:active {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.arrow .material-icons {
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
#prev {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#next {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#toc {
|
||||
display: block;
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
||||
#hypothesis-custom {
|
||||
overflow: hidden;
|
||||
/*position: absolute;*/
|
||||
right: 0;
|
||||
/*top: 0;*/
|
||||
height: 100%;
|
||||
width: 200px;
|
||||
/*z-index: -2;*/
|
||||
}
|
||||
|
||||
#hypothesis-custom iframe {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#closer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#closer .material-icons {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#opener {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<a id="opener">
|
||||
<i class="material-icons">menu</i>
|
||||
</a>
|
||||
<div id="viewer" class="spreads"></div>
|
||||
<a id="prev" href="#prev" class="arrow">
|
||||
<i class="material-icons">chevron_left</i>
|
||||
</a>
|
||||
<a id="next" href="#next" class="arrow">
|
||||
<i class="material-icons">chevron_right</i>
|
||||
</a>
|
||||
</div>
|
||||
<div id="navigation">
|
||||
<a id="closer">
|
||||
<i class="material-icons">close</i>
|
||||
</a>
|
||||
<h1 id="title">...</h1>
|
||||
<image id="cover" width="150px"/>
|
||||
<h2 id="author">...</h2>
|
||||
<ul id="toc"></ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Load the opf
|
||||
var book = ePub(window.location.protocol + "//s3.amazonaws.com/epubjs/books/alice/OPS/package.opf");
|
||||
var rendition = book.renderTo("viewer", {
|
||||
ignoreClass: "annotator-hl",
|
||||
width: "100%",
|
||||
height: 600
|
||||
});
|
||||
|
||||
// var hash = window.location.hash.slice(2);
|
||||
var loc = window.location.href.indexOf("?loc=");
|
||||
if (loc > -1) {
|
||||
var href = window.location.href.slice(loc + 5);
|
||||
var hash = decodeURIComponent(href);
|
||||
}
|
||||
rendition.display(hash || undefined);
|
||||
|
||||
|
||||
var next = document.getElementById("next");
|
||||
next.addEventListener("click", function(e){
|
||||
rendition.next();
|
||||
e.preventDefault();
|
||||
}, false);
|
||||
|
||||
var prev = document.getElementById("prev");
|
||||
prev.addEventListener("click", function(e){
|
||||
rendition.prev();
|
||||
e.preventDefault();
|
||||
}, false);
|
||||
|
||||
var nav = document.getElementById("navigation");
|
||||
var opener = document.getElementById("opener");
|
||||
opener.addEventListener("click", function(e){
|
||||
nav.classList.add("open");
|
||||
}, false);
|
||||
|
||||
var closer = document.getElementById("closer");
|
||||
closer.addEventListener("click", function(e){
|
||||
nav.classList.remove("open");
|
||||
}, false);
|
||||
|
||||
|
||||
rendition.on("rendered", function(section){
|
||||
var old = document.querySelectorAll('.active');
|
||||
Array.prototype.slice.call(old, 0).forEach(function (link) {
|
||||
link.classList.remove("active");
|
||||
})
|
||||
|
||||
var active = document.querySelector('a[href="'+section.href+'"]');
|
||||
if (active) {
|
||||
active.classList.add("active");
|
||||
}
|
||||
// Add CFI fragment to the history
|
||||
history.pushState({}, '', "?loc=" + encodeURIComponent(section.href));
|
||||
// window.location.hash = "#/"+section.href
|
||||
});
|
||||
|
||||
book.loaded.navigation.then(function(toc){
|
||||
var $nav = document.getElementById("toc"),
|
||||
docfrag = document.createDocumentFragment();
|
||||
|
||||
toc.forEach(function(chapter, index) {
|
||||
var item = document.createElement("li");
|
||||
var link = document.createElement("a");
|
||||
link.id = "chap-" + chapter.id;
|
||||
link.textContent = chapter.label;
|
||||
link.href = chapter.href;
|
||||
item.appendChild(link);
|
||||
docfrag.appendChild(item);
|
||||
|
||||
link.onclick = function(){
|
||||
var url = link.getAttribute("href");
|
||||
console.log(url)
|
||||
rendition.display(url);
|
||||
return false;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
$nav.appendChild(docfrag);
|
||||
|
||||
|
||||
});
|
||||
|
||||
book.loaded.metadata.then(function(meta){
|
||||
var $title = document.getElementById("title");
|
||||
var $author = document.getElementById("author");
|
||||
var $cover = document.getElementById("cover");
|
||||
var $nav = document.getElementById('navigation');
|
||||
|
||||
$title.textContent = meta.title;
|
||||
$author.textContent = meta.creator;
|
||||
if (book.archive) {
|
||||
book.archive.createUrl(book.cover)
|
||||
.then(function (url) {
|
||||
$cover.src = url;
|
||||
})
|
||||
} else {
|
||||
$cover.src = book.cover;
|
||||
}
|
||||
|
||||
// if ($nav.offsetHeight + 60 < window.innerHeight) {
|
||||
// $nav.classList.add("fixed");
|
||||
// }
|
||||
|
||||
});
|
||||
|
||||
function checkForAnnotator(cb, w) {
|
||||
if (!w) {
|
||||
w = window;
|
||||
}
|
||||
setTimeout(function () {
|
||||
if (w && w.annotator) {
|
||||
cb();
|
||||
} else {
|
||||
checkForAnnotator(cb, w);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
book.rendition.hooks.content.register(function(contents, view) {
|
||||
|
||||
checkForAnnotator(function () {
|
||||
|
||||
var annotator = contents.window.annotator;
|
||||
|
||||
contents.window.addEventListener('scrolltorange', function (e) {
|
||||
var range = e.detail;
|
||||
var cfi = new ePub.CFI(range, contents.cfiBase).toString();
|
||||
if (cfi) {
|
||||
book.rendition.display(cfi);
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
annotator.on("highlightClick", function (annotation) {
|
||||
console.log(annotation);
|
||||
window.annotator.show();
|
||||
})
|
||||
|
||||
annotator.on("beforeAnnotationCreated", function (annotation) {
|
||||
console.log(annotation);
|
||||
window.annotator.show();
|
||||
})
|
||||
|
||||
}, contents.window);
|
||||
|
||||
});
|
||||
|
||||
checkForAnnotator(function () {
|
||||
var main = document.querySelector('#main');
|
||||
var target = document.querySelector('.annotator-frame');
|
||||
|
||||
|
||||
if(window.innerWidth < 1400) {
|
||||
/*
|
||||
window.annotator.on("show", function () {
|
||||
main.classList.add("open");
|
||||
});
|
||||
|
||||
window.annotator.on("hide", function () {
|
||||
main.classList.remove("open");
|
||||
});
|
||||
*/
|
||||
|
||||
// create an observer instance
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName === "class") {
|
||||
if (target.classList.contains("annotator-collapsed")) {
|
||||
main.classList.remove("open");
|
||||
} else {
|
||||
main.classList.add("open");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(target, { attributes: true });
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -66,7 +66,7 @@
|
|||
<li><a href="renderless.html">Renderless</a></li>
|
||||
<li><a href="hooks.html">Hooks</a></li>
|
||||
<li><a href="highlights.html">Highlights</a></li>
|
||||
<li><a href="annotator.html">Annotator</a></li>
|
||||
<li><a href="hypothesis.html">Hypothes.is</a></li>
|
||||
<!-- <li><a href="hypothesis.html">Annotations with Hypothes.is</a></li> -->
|
||||
</ol>
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
<div id="title"></div>
|
||||
<!-- <div id="title"></div> -->
|
||||
<select id="toc"></select>
|
||||
<div id="viewer" class="spreads"></div>
|
||||
<a id="prev" href="#prev" class="arrow">‹</a>
|
||||
<a id="next" href="#next" class="arrow">›</a>
|
||||
|
@ -72,7 +73,19 @@
|
|||
var current = book.navigation && book.navigation.get(section.href);
|
||||
|
||||
if (current) {
|
||||
title.textContent = current.label;
|
||||
var $select = document.getElementById("toc");
|
||||
var $selected = $select.querySelector("option[selected]");
|
||||
if ($selected) {
|
||||
$selected.removeAttribute("selected");
|
||||
}
|
||||
|
||||
var $options = $select.querySelectorAll("option");
|
||||
for (var i = 0; i < $options.length; ++i) {
|
||||
let selected = $options[i].getAttribute("ref") === current.href;
|
||||
if (selected) {
|
||||
$options[i].setAttribute("selected", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(nextSection) {
|
||||
|
@ -98,6 +111,29 @@
|
|||
this.book.destroy();
|
||||
});
|
||||
|
||||
book.loaded.navigation.then(function(toc){
|
||||
var $select = document.getElementById("toc"),
|
||||
docfrag = document.createDocumentFragment();
|
||||
|
||||
toc.forEach(function(chapter) {
|
||||
var option = document.createElement("option");
|
||||
option.textContent = chapter.label;
|
||||
option.setAttribute("ref", chapter.href);
|
||||
|
||||
docfrag.appendChild(option);
|
||||
});
|
||||
|
||||
$select.appendChild(docfrag);
|
||||
|
||||
$select.onchange = function(){
|
||||
var index = $select.selectedIndex,
|
||||
url = $select.options[index].getAttribute("ref");
|
||||
rendition.display(url);
|
||||
return false;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
}
|
||||
});
|
||||
|
||||
// rendition.themes.apply("tan");
|
||||
// rendition.themes.select("tan");
|
||||
// rendition.themes.fontSize("140%");
|
||||
|
||||
</script>
|
||||
|
|
11
package-lock.json
generated
11
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "epubjs",
|
||||
"version": "0.3.40",
|
||||
"version": "0.3.41",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -8530,8 +8530,7 @@
|
|||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"lodash._baseassign": {
|
||||
"version": "3.2.0",
|
||||
|
@ -8928,9 +8927,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"marks-pane": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.1.tgz",
|
||||
"integrity": "sha512-b93yiOd1dorO8fT4wH3AhoYenkosJgPHMEZeCl1MQOhhVXe8oJgBhrDKaYreguSiCjGmBP0CG+RMBOuvR60t/w=="
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.2.tgz",
|
||||
"integrity": "sha512-S3OuXWgPlCR9nQEN52Ut/beuw7SwkmVrTd9Ce38uEoaTbaO3/5fzD5KPERlWILH1mfi/B91DYfwCeC0bgsliXQ=="
|
||||
},
|
||||
"math-expression-evaluator": {
|
||||
"version": "1.2.17",
|
||||
|
|
|
@ -73,7 +73,8 @@
|
|||
"dependencies": {
|
||||
"event-emitter": "^0.3.5",
|
||||
"jszip": "^3.1.3",
|
||||
"marks-pane": "^1.0.1",
|
||||
"lodash": "^4.17.4",
|
||||
"marks-pane": "^1.0.2",
|
||||
"path-webpack": "0.0.3",
|
||||
"stream-browserify": "^2.0.1",
|
||||
"xmldom": "^0.1.27"
|
||||
|
|
|
@ -302,11 +302,11 @@ class Contents {
|
|||
|
||||
this.addSelectionListeners();
|
||||
|
||||
this.transitionListeners();
|
||||
// this.transitionListeners();
|
||||
|
||||
this.resizeListeners();
|
||||
|
||||
this.resizeObservers();
|
||||
// this.resizeObservers();
|
||||
|
||||
this.linksHandler();
|
||||
}
|
||||
|
@ -717,6 +717,7 @@ class Contents {
|
|||
if (width >= 0) {
|
||||
this.width(width);
|
||||
viewport.width = width;
|
||||
this.css("padding", "0 "+(width/12)+"px", true);
|
||||
}
|
||||
|
||||
if (height >= 0) {
|
||||
|
@ -727,6 +728,7 @@ class Contents {
|
|||
this.css("margin", "0");
|
||||
this.css("box-sizing", "border-box");
|
||||
|
||||
|
||||
this.viewport(viewport);
|
||||
}
|
||||
|
||||
|
@ -745,7 +747,9 @@ class Contents {
|
|||
this.css("display", "inline-block"); // Fixes Safari column cut offs
|
||||
this.css("overflow-y", "hidden");
|
||||
this.css("margin", "0", true);
|
||||
this.css("padding", "0", true);
|
||||
|
||||
this.css("padding", "20px " + (gap / 2) + "px", true);
|
||||
|
||||
this.css("box-sizing", "border-box");
|
||||
this.css("max-width", "inherit");
|
||||
|
||||
|
@ -852,6 +856,7 @@ class Contents {
|
|||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
mark(cfiRange, data={}, cb) {
|
||||
let range = this.range(cfiRange);
|
||||
|
||||
|
@ -881,6 +886,50 @@ class Contents {
|
|||
|
||||
return parent;
|
||||
}
|
||||
*/
|
||||
|
||||
mark(cfiRange, data={}, cb) {
|
||||
|
||||
if (cfiRange in this.marks) {
|
||||
item = this.marks[cfiRange];
|
||||
return item;
|
||||
}
|
||||
|
||||
let range = this.range(cfiRange);
|
||||
|
||||
let container = range.commonAncestorContainer;
|
||||
let parent = (container.nodeType === 1) ? container : container.parentNode;
|
||||
let emitter = (e) => {
|
||||
this.emit("markClicked", cfiRange, data);
|
||||
};
|
||||
|
||||
let pos = parent.getBoundingClientRect();
|
||||
let mark = this.document.createElement('a');
|
||||
mark.setAttribute("ref", "epubjs-mk");
|
||||
mark.style.position = "absolute";
|
||||
mark.style.top = `${pos.top}px`;
|
||||
mark.style.left = `${pos.right}px`;
|
||||
|
||||
mark.dataset["epubcfi"] = cfiRange;
|
||||
|
||||
if (data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
mark.dataset[key] = data[key];
|
||||
});
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
mark.addEventListener("click", cb);
|
||||
}
|
||||
|
||||
mark.addEventListener("click", emitter);
|
||||
|
||||
this.content.appendChild(mark);
|
||||
|
||||
this.marks[cfiRange] = { "element": mark, "listeners": [emitter, cb] };
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
unhighlight(cfiRange) {
|
||||
let item;
|
||||
|
@ -910,7 +959,7 @@ class Contents {
|
|||
let item;
|
||||
if (cfiRange in this.marks) {
|
||||
item = this.marks[cfiRange];
|
||||
item.element.removeAttribute("ref");
|
||||
this.content.removeChild(item.element);
|
||||
item.listeners.forEach((l) => {
|
||||
if (l) { item.element.removeEventListener("click", l) };
|
||||
});
|
||||
|
|
|
@ -101,7 +101,7 @@ class Layout {
|
|||
// var fullWidth = Math.floor(_width);
|
||||
var width = _width;
|
||||
|
||||
var section = Math.floor(width / 8);
|
||||
var section = Math.floor(width / 12);
|
||||
|
||||
var colWidth;
|
||||
var spreadWidth;
|
||||
|
@ -123,7 +123,10 @@ class Layout {
|
|||
|
||||
//-- Double Page
|
||||
if(divisor > 1) {
|
||||
colWidth = (width - gap) / divisor;
|
||||
// width = width - gap;
|
||||
// colWidth = (width - gap) / divisor;
|
||||
// gap = gap / divisor;
|
||||
colWidth = (width / divisor) - gap;
|
||||
} else {
|
||||
colWidth = width;
|
||||
}
|
||||
|
@ -134,7 +137,8 @@ class Layout {
|
|||
|
||||
spreadWidth = colWidth * divisor;
|
||||
|
||||
delta = (colWidth + gap) * divisor;
|
||||
delta = width;
|
||||
// console.log(delta, width);
|
||||
|
||||
this.width = width;
|
||||
this.height = _height;
|
||||
|
|
|
@ -239,7 +239,11 @@ class Locations {
|
|||
}
|
||||
|
||||
load(locations){
|
||||
if (typeof locations === "string") {
|
||||
this._locations = JSON.parse(locations);
|
||||
} else {
|
||||
this._locations = locations;
|
||||
}
|
||||
this.total = this._locations.length - 1;
|
||||
return this._locations;
|
||||
}
|
||||
|
@ -296,7 +300,7 @@ class Locations {
|
|||
this.request = undefined;
|
||||
this.pause = undefined;
|
||||
|
||||
this.q.clear();
|
||||
this.q.stop();
|
||||
this.q = undefined;
|
||||
this.epubcfi = undefined;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {extend, defer, requestAnimationFrame} from "../../utils/core";
|
||||
import DefaultViewManager from "../default";
|
||||
import debounce from 'lodash/debounce'
|
||||
|
||||
class ContinuousViewManager extends DefaultViewManager {
|
||||
constructor(options) {
|
||||
|
@ -10,7 +11,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
this.settings = extend(this.settings || {}, {
|
||||
infinite: true,
|
||||
overflow: "auto",
|
||||
overflow: undefined,
|
||||
axis: "vertical",
|
||||
offset: 500,
|
||||
offsetDelta: 250,
|
||||
|
@ -48,13 +49,15 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
fill(_full){
|
||||
var full = _full || new defer();
|
||||
|
||||
this.check().then(function(result) {
|
||||
this.q.enqueue(() => {
|
||||
return this.check();
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.fill(full);
|
||||
} else {
|
||||
full.resolve();
|
||||
}
|
||||
}.bind(this));
|
||||
});
|
||||
|
||||
return full.promise;
|
||||
}
|
||||
|
@ -76,10 +79,13 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
offsetX = distX+this.settings.offset;
|
||||
}
|
||||
|
||||
return this.check(offsetX, offsetY)
|
||||
.then(function(){
|
||||
this.check(offsetX, offsetY);
|
||||
this.scrollBy(distX, distY, true);
|
||||
}.bind(this));
|
||||
|
||||
// return this.check(offsetX, offsetY)
|
||||
// .then(function(){
|
||||
// this.scrollBy(distX, distY, true);
|
||||
// }.bind(this));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -106,37 +112,37 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
*/
|
||||
|
||||
resize(width, height){
|
||||
|
||||
// Clear the queue
|
||||
this.q.clear();
|
||||
|
||||
this._stageSize = this.stage.size(width, height);
|
||||
this._bounds = this.bounds();
|
||||
console.log("set bounds", this._bounds);
|
||||
|
||||
// Update for new views
|
||||
this.viewSettings.width = this._stageSize.width;
|
||||
this.viewSettings.height = this._stageSize.height;
|
||||
|
||||
// Update for existing views
|
||||
this.views.each(function(view) {
|
||||
view.size(this._stageSize.width, this._stageSize.height);
|
||||
}.bind(this));
|
||||
|
||||
this.updateLayout();
|
||||
|
||||
// if(this.location) {
|
||||
// this.rendition.display(this.location.start);
|
||||
// resize(width, height){
|
||||
//
|
||||
// // Clear the queue
|
||||
// this.q.clear();
|
||||
//
|
||||
// this._stageSize = this.stage.size(width, height);
|
||||
// console.log("resize says", this._stageSize, width, height);
|
||||
// this._bounds = this.bounds();
|
||||
//
|
||||
// // Update for new views
|
||||
// this.viewSettings.width = this._stageSize.width;
|
||||
// this.viewSettings.height = this._stageSize.height;
|
||||
//
|
||||
// // Update for existing views
|
||||
// this.views.each(function(view) {
|
||||
// view.size(this._stageSize.width, this._stageSize.height);
|
||||
// }.bind(this));
|
||||
//
|
||||
// this.updateLayout();
|
||||
//
|
||||
// // if(this.location) {
|
||||
// // this.rendition.display(this.location.start);
|
||||
// // }
|
||||
//
|
||||
// this.emit("resized", {
|
||||
// width: this._stageSize.width,
|
||||
// height: this._stageSize.height
|
||||
// });
|
||||
//
|
||||
// }
|
||||
|
||||
this.emit("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onResized(e) {
|
||||
|
||||
// this.views.clear();
|
||||
|
@ -179,8 +185,29 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
//
|
||||
// };
|
||||
|
||||
add(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
this.views.append(view);
|
||||
|
||||
view.on("resized", (bounds) => {
|
||||
view.expanded = true;
|
||||
});
|
||||
|
||||
// view.on("shown", this.afterDisplayed.bind(this));
|
||||
view.onDisplayed = this.afterDisplayed.bind(this);
|
||||
view.onResize = this.afterResized.bind(this);
|
||||
|
||||
return view.display(this.request);
|
||||
}
|
||||
|
||||
append(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
view.on("resized", (bounds) => {
|
||||
view.expanded = true;
|
||||
});
|
||||
|
||||
this.views.append(view);
|
||||
|
||||
view.onDisplayed = this.afterDisplayed.bind(this);
|
||||
|
@ -191,7 +218,10 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
prepend(section){
|
||||
var view = this.createView(section);
|
||||
|
||||
view.on("resized", this.counter.bind(this));
|
||||
view.on("resized", (bounds) => {
|
||||
this.counter(bounds);
|
||||
view.expanded = true;
|
||||
});
|
||||
|
||||
this.views.prepend(view);
|
||||
|
||||
|
@ -201,7 +231,6 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
|
||||
counter(bounds){
|
||||
|
||||
if(this.settings.axis === "vertical") {
|
||||
this.scrollBy(0, bounds.heightDelta, true);
|
||||
} else {
|
||||
|
@ -228,14 +257,19 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
isVisible = this.isVisible(view, offset, offset, container);
|
||||
|
||||
if(isVisible === true) {
|
||||
// console.log("visible " + view.index);
|
||||
|
||||
if (!view.displayed) {
|
||||
promises.push(view.display(this.request).then(function (view) {
|
||||
view.show();
|
||||
}));
|
||||
} else {
|
||||
view.show();
|
||||
}
|
||||
visible.push(view);
|
||||
} else {
|
||||
this.q.enqueue(view.destroy.bind(view));
|
||||
// this.q.enqueue(view.destroy.bind(view));
|
||||
// console.log("hidden " + view.index);
|
||||
|
||||
clearTimeout(this.trimTimeout);
|
||||
this.trimTimeout = setTimeout(function(){
|
||||
|
@ -280,6 +314,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
if (offset + visibleLength + delta >= contentLength) {
|
||||
last = this.views.last();
|
||||
next = last && last.section.next();
|
||||
|
||||
if(next) {
|
||||
newViews.push(this.append(next));
|
||||
}
|
||||
|
@ -287,19 +322,26 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
if (offset - delta < 0 ) {
|
||||
first = this.views.first();
|
||||
|
||||
prev = first && first.section.prev();
|
||||
if(prev) {
|
||||
newViews.push(this.prepend(prev));
|
||||
}
|
||||
}
|
||||
|
||||
let promises = newViews.map((view) => {
|
||||
return view.displayed;
|
||||
});
|
||||
|
||||
if(newViews.length){
|
||||
// Promise.all(promises)
|
||||
// .then(function() {
|
||||
// Check to see if anything new is on screen after rendering
|
||||
return this.q.enqueue(function(){
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
return this.update(delta);
|
||||
}.bind(this));
|
||||
});
|
||||
// Check to see if anything new is on screen after rendering
|
||||
// return this.q.enqueue(function(){
|
||||
// this.update(delta);
|
||||
// }.bind(this));
|
||||
|
||||
|
||||
// }.bind(this));
|
||||
|
@ -351,6 +393,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
var bounds = view.bounds();
|
||||
|
||||
view.destroy.bind(view)
|
||||
this.views.remove(view);
|
||||
|
||||
if(above) {
|
||||
|
@ -402,7 +445,7 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
}
|
||||
|
||||
scroller.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
this._scrolled = debounce(this.scrolled.bind(this), 300);
|
||||
// this.tick.call(window, this.onScroll.bind(this));
|
||||
|
||||
this.scrolled = false;
|
||||
|
@ -440,31 +483,35 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
if(!this.ignore) {
|
||||
|
||||
if((this.scrollDeltaVert === 0 &&
|
||||
this.scrollDeltaHorz === 0) ||
|
||||
this.scrollDeltaVert > this.settings.offsetDelta ||
|
||||
this._scrolled();
|
||||
// if((this.scrollDeltaVert === 0 &&
|
||||
// this.scrollDeltaHorz === 0) ||
|
||||
// this.scrollDeltaVert > this.settings.offsetDelta ||
|
||||
// this.scrollDeltaHorz > this.settings.offsetDelta) {
|
||||
if(this.scrollDeltaVert > this.settings.offsetDelta ||
|
||||
this.scrollDeltaHorz > this.settings.offsetDelta) {
|
||||
|
||||
this.q.enqueue(function() {
|
||||
this.check();
|
||||
}.bind(this));
|
||||
// console.log("scroll", this.scrollDeltaHorz);
|
||||
//
|
||||
// this.q.enqueue(function() {
|
||||
// this.check();
|
||||
|
||||
this.scrollDeltaVert = 0;
|
||||
this.scrollDeltaHorz = 0;
|
||||
|
||||
this.emit("scroll", {
|
||||
top: scrollTop,
|
||||
left: scrollLeft
|
||||
});
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
this.afterScrolled = setTimeout(function () {
|
||||
this.emit("scrolled", {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
});
|
||||
}.bind(this));
|
||||
// }.bind(this));
|
||||
// // this.check();
|
||||
//
|
||||
// this.scrollDeltaVert = 0;
|
||||
// this.scrollDeltaHorz = 0;
|
||||
//
|
||||
// this.emit("scroll", {
|
||||
// top: scrollTop,
|
||||
// left: scrollLeft
|
||||
// });
|
||||
//
|
||||
// clearTimeout(this.afterScrolled);
|
||||
// this.afterScrolled = setTimeout(function () {
|
||||
// this.emit("scrolled", {
|
||||
// top: this.scrollTop,
|
||||
// left: this.scrollLeft
|
||||
// });
|
||||
// }.bind(this));
|
||||
|
||||
}
|
||||
|
||||
|
@ -492,35 +539,54 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
}
|
||||
|
||||
updateLayout() {
|
||||
scrolled() {
|
||||
this.q.enqueue(function() {
|
||||
this.check();
|
||||
}.bind(this));
|
||||
|
||||
if (!this.stage) {
|
||||
return;
|
||||
this.emit("scroll", {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
});
|
||||
|
||||
clearTimeout(this.afterScrolled);
|
||||
this.afterScrolled = setTimeout(function () {
|
||||
this.emit("scrolled", {
|
||||
top: this.scrollTop,
|
||||
left: this.scrollLeft
|
||||
});
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
if(this.settings.axis === "vertical") {
|
||||
this.layout.calculate(this._stageSize.width, this._stageSize.height);
|
||||
} else {
|
||||
this.layout.calculate(
|
||||
this._stageSize.width,
|
||||
this._stageSize.height,
|
||||
this.settings.gap
|
||||
);
|
||||
|
||||
// Set the look ahead offset for what is visible
|
||||
this.settings.offset = this.layout.delta;
|
||||
|
||||
this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]);
|
||||
|
||||
}
|
||||
|
||||
// Set the dimensions for views
|
||||
this.viewSettings.width = this.layout.width;
|
||||
this.viewSettings.height = this.layout.height;
|
||||
|
||||
this.setLayout(this.layout);
|
||||
|
||||
}
|
||||
// updateLayout() {
|
||||
//
|
||||
// if (!this.stage) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(this.settings.axis === "vertical") {
|
||||
// this.layout.calculate(this._stageSize.width, this._stageSize.height);
|
||||
// } else {
|
||||
// this.layout.calculate(
|
||||
// this._stageSize.width,
|
||||
// this._stageSize.height,
|
||||
// this.settings.gap
|
||||
// );
|
||||
//
|
||||
// // Set the look ahead offset for what is visible
|
||||
// this.settings.offset = this.layout.delta;
|
||||
//
|
||||
// // this.stage.addStyleRules("iframe", [{"padding" : "0 " + (this.layout.gap / 2) + "px"}]);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // Set the dimensions for views
|
||||
// this.viewSettings.width = this.layout.width;
|
||||
// this.viewSettings.height = this.layout.height;
|
||||
//
|
||||
// this.setLayout(this.layout);
|
||||
//
|
||||
// }
|
||||
|
||||
next(){
|
||||
|
||||
|
@ -562,9 +628,15 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
|
||||
this.settings.axis = axis;
|
||||
|
||||
this.stage && this.stage.axis(axis);
|
||||
|
||||
this.viewSettings.axis = axis;
|
||||
|
||||
this.settings.overflow = (flow === "paginated") ? "hidden" : "auto";
|
||||
if (!this.settings.overflow) {
|
||||
this.overflow = (flow === "paginated") ? "hidden" : "auto";
|
||||
} else {
|
||||
this.overflow = this.settings.overflow;
|
||||
}
|
||||
|
||||
// this.views.each(function(view){
|
||||
// view.setAxis(axis);
|
||||
|
@ -576,6 +648,8 @@ class ContinuousViewManager extends DefaultViewManager {
|
|||
this.settings.infinite = false;
|
||||
}
|
||||
|
||||
this.updateLayout();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,14 +38,28 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
render(element, size){
|
||||
let tag = element.tagName;
|
||||
|
||||
if (tag && (tag.toLowerCase() == "body" ||
|
||||
tag.toLowerCase() == "html")) {
|
||||
this.fullsize = true;
|
||||
}
|
||||
|
||||
if (this.fullsize) {
|
||||
this.settings.overflow = "visible";
|
||||
this.overflow = this.settings.overflow;
|
||||
}
|
||||
|
||||
this.settings.size = size;
|
||||
|
||||
// Save the stage
|
||||
this.stage = new Stage({
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
overflow: this.settings.overflow,
|
||||
overflow: this.overflow,
|
||||
hidden: this.settings.hidden,
|
||||
axis: this.settings.axis
|
||||
axis: this.settings.axis,
|
||||
fullsize: this.fullsize
|
||||
});
|
||||
|
||||
this.stage.attachTo(element);
|
||||
|
@ -85,7 +99,7 @@ class DefaultViewManager {
|
|||
this.destroy();
|
||||
}.bind(this));
|
||||
|
||||
if(this.settings.height) {
|
||||
if(!this.fullsize) {
|
||||
scroller = this.container;
|
||||
} else {
|
||||
scroller = window;
|
||||
|
@ -97,7 +111,7 @@ class DefaultViewManager {
|
|||
removeEventListeners(){
|
||||
var scroller;
|
||||
|
||||
if(this.settings.height) {
|
||||
if(!this.fullsize) {
|
||||
scroller = this.container;
|
||||
} else {
|
||||
scroller = window;
|
||||
|
@ -127,6 +141,25 @@ class DefaultViewManager {
|
|||
*/
|
||||
}
|
||||
|
||||
onOrientationChange(e) {
|
||||
let {orientation} = window;
|
||||
|
||||
this._stageSize = this.stage.size();
|
||||
this._bounds = this.bounds();
|
||||
// Update for new views
|
||||
this.viewSettings.width = this._stageSize.width;
|
||||
this.viewSettings.height = this._stageSize.height;
|
||||
|
||||
this.updateLayout();
|
||||
|
||||
// Update for existing views
|
||||
// this.views.each(function(view) {
|
||||
// view.size(this._stageSize.width, this._stageSize.height);
|
||||
// }.bind(this));
|
||||
|
||||
this.emit("orientationChange", orientation);
|
||||
}
|
||||
|
||||
onResized(e) {
|
||||
clearTimeout(this.resizeTimeout);
|
||||
this.resizeTimeout = setTimeout(function(){
|
||||
|
@ -139,6 +172,7 @@ class DefaultViewManager {
|
|||
this.q.clear();
|
||||
|
||||
this._stageSize = this.stage.size(width, height);
|
||||
|
||||
this._bounds = this.bounds();
|
||||
|
||||
// Update for new views
|
||||
|
@ -148,14 +182,18 @@ class DefaultViewManager {
|
|||
this.updateLayout();
|
||||
|
||||
// Update for existing views
|
||||
// TODO: this is not updating correctly, just clear and rerender for now
|
||||
/*
|
||||
this.views.each(function(view) {
|
||||
view.reset();
|
||||
view.size(this._stageSize.width, this._stageSize.height);
|
||||
}.bind(this));
|
||||
|
||||
*/
|
||||
this.clear();
|
||||
|
||||
this.emit("resized", {
|
||||
width: this.stage.width,
|
||||
height: this.stage.height
|
||||
width: this._stageSize.width,
|
||||
height: this._stageSize.height
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -393,10 +431,12 @@ class DefaultViewManager {
|
|||
}
|
||||
|
||||
clear () {
|
||||
if (this.views) {
|
||||
this.views.hide();
|
||||
this.scrollTo(0,0, true);
|
||||
this.views.clear();
|
||||
}
|
||||
}
|
||||
|
||||
currentLocation(){
|
||||
|
||||
|
@ -464,7 +504,7 @@ class DefaultViewManager {
|
|||
|
||||
var offset = 0;
|
||||
|
||||
if(!this.settings.height) {
|
||||
if(this.fullsize) {
|
||||
offset = window.scrollY;
|
||||
}
|
||||
|
||||
|
@ -504,16 +544,22 @@ class DefaultViewManager {
|
|||
let visible = this.visible();
|
||||
var container = this.container.getBoundingClientRect();
|
||||
|
||||
var left = 0;
|
||||
|
||||
if(this.fullsize) {
|
||||
left = window.scrollX;
|
||||
}
|
||||
|
||||
let sections = visible.map((view) => {
|
||||
let {index, href} = view.section;
|
||||
let offset = view.offset().left;
|
||||
let position = view.position().left;
|
||||
let width = view.width();
|
||||
|
||||
let startPos = this.container.scrollLeft + offset;
|
||||
let startPos = left + offset;
|
||||
let endPos = startPos + this.layout.spreadWidth + this.layout.gap;
|
||||
if (endPos > this.container.scrollLeft + offset + width) {
|
||||
endPos = this.container.scrollLeft + offset + width;
|
||||
if (endPos > left + offset + width) {
|
||||
endPos = left + offset + width;
|
||||
}
|
||||
|
||||
let totalPages = this.layout.count(width).pages;
|
||||
|
@ -525,8 +571,9 @@ class DefaultViewManager {
|
|||
pages.push(pg);
|
||||
}
|
||||
|
||||
let start = container.left - position;
|
||||
let start = left + container.left - position;
|
||||
let end = start + this.layout.spreadWidth + this.layout.gap;
|
||||
|
||||
let mapping = this.mapping.page(view.contents, view.section.cfiBase, start, end);
|
||||
|
||||
return {
|
||||
|
@ -587,11 +634,9 @@ class DefaultViewManager {
|
|||
this.ignore = true;
|
||||
}
|
||||
|
||||
if(this.settings.height) {
|
||||
|
||||
if(!this.fullsize) {
|
||||
if(x) this.container.scrollLeft += x;
|
||||
if(y) this.container.scrollTop += y;
|
||||
|
||||
} else {
|
||||
window.scrollBy(x,y);
|
||||
}
|
||||
|
@ -603,27 +648,20 @@ class DefaultViewManager {
|
|||
this.ignore = true;
|
||||
}
|
||||
|
||||
if(this.settings.height) {
|
||||
if(!this.fullsize) {
|
||||
this.container.scrollLeft = x;
|
||||
this.container.scrollTop = y;
|
||||
} else {
|
||||
window.scrollTo(x,y);
|
||||
}
|
||||
this.scrolled = true;
|
||||
|
||||
// if(this.container.scrollLeft != x){
|
||||
// setTimeout(function() {
|
||||
// this.scrollTo(x, y, silent);
|
||||
// }.bind(this), 10);
|
||||
// return;
|
||||
// };
|
||||
}
|
||||
|
||||
onScroll(){
|
||||
let scrollTop;
|
||||
let scrollLeft;
|
||||
|
||||
if(this.settings.height) {
|
||||
if(!this.fullsize) {
|
||||
scrollTop = this.container.scrollTop;
|
||||
scrollLeft = this.container.scrollLeft;
|
||||
} else {
|
||||
|
@ -670,6 +708,7 @@ class DefaultViewManager {
|
|||
this.updateLayout();
|
||||
|
||||
this.mapping = new Mapping(this.layout.props);
|
||||
|
||||
// this.manager.layout(this.layout.format);
|
||||
}
|
||||
|
||||
|
@ -692,7 +731,7 @@ class DefaultViewManager {
|
|||
// Set the look ahead offset for what is visible
|
||||
this.settings.offset = this.layout.delta;
|
||||
|
||||
this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]);
|
||||
// this.stage.addStyleRules("iframe", [{"margin-right" : this.layout.gap + "px"}]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -701,7 +740,6 @@ class DefaultViewManager {
|
|||
this.viewSettings.height = this.layout.height;
|
||||
|
||||
this.setLayout(this.layout);
|
||||
|
||||
}
|
||||
|
||||
setLayout(layout){
|
||||
|
@ -723,13 +761,21 @@ class DefaultViewManager {
|
|||
|
||||
this.settings.axis = axis;
|
||||
|
||||
this.stage && this.stage.axis(axis);
|
||||
|
||||
this.viewSettings.axis = axis;
|
||||
|
||||
this.settings.overflow = (flow === "paginated") ? "hidden" : "auto";
|
||||
if (!this.settings.overflow) {
|
||||
this.overflow = (flow === "paginated") ? "hidden" : "auto";
|
||||
} else {
|
||||
this.overflow = this.settings.overflow;
|
||||
}
|
||||
// this.views.each(function(view){
|
||||
// view.setAxis(axis);
|
||||
// });
|
||||
|
||||
this.updateLayout();
|
||||
|
||||
}
|
||||
|
||||
getContents(){
|
||||
|
|
|
@ -45,7 +45,10 @@ class Stage {
|
|||
container.style.position = "relative";
|
||||
|
||||
if(axis === "horizontal") {
|
||||
container.style.whiteSpace = "nowrap";
|
||||
// container.style.whiteSpace = "nowrap";
|
||||
container.style.display = "flex";
|
||||
container.style.flexDirection = "row";
|
||||
container.style.flexWrap = "nowrap";
|
||||
}
|
||||
|
||||
if(width){
|
||||
|
@ -124,11 +127,17 @@ class Stage {
|
|||
// This applies if it is set to a percent or auto.
|
||||
if(!isNumber(this.settings.width) ||
|
||||
!isNumber(this.settings.height) ) {
|
||||
window.addEventListener("resize", func, false);
|
||||
this.resizeFunc = func;
|
||||
window.addEventListener("resize", this.resizeFunc, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onOrientationChange(func){
|
||||
this.orientationChangeFunc = func;
|
||||
window.addEventListener("orientationChange", this.orientationChangeFunc, false);
|
||||
}
|
||||
|
||||
size(width, height){
|
||||
var bounds;
|
||||
// var width = _width || this.settings.width;
|
||||
|
@ -176,6 +185,15 @@ class Stage {
|
|||
bottom: parseFloat(this.containerStyles["padding-bottom"]) || 0
|
||||
};
|
||||
|
||||
// Bounds not set, get them from window
|
||||
let _windowBounds = windowBounds();
|
||||
if (!width) {
|
||||
width = _windowBounds.width;
|
||||
}
|
||||
if (this.settings.fullsize || !height) {
|
||||
height = _windowBounds.height;
|
||||
}
|
||||
|
||||
return {
|
||||
width: width -
|
||||
this.containerPadding.left -
|
||||
|
@ -188,7 +206,11 @@ class Stage {
|
|||
}
|
||||
|
||||
bounds(){
|
||||
let box = this.container && this.container.getBoundingClientRect();
|
||||
let box;
|
||||
if (this.container.style.overflow !== "visible") {
|
||||
box = this.container && this.container.getBoundingClientRect();
|
||||
}
|
||||
|
||||
if(!box || !box.width || !box.height) {
|
||||
return windowBounds();
|
||||
} else {
|
||||
|
@ -227,6 +249,26 @@ class Stage {
|
|||
this.sheet.insertRule(scope + selector + " {" + rules + "}", 0);
|
||||
}
|
||||
|
||||
axis(axis) {
|
||||
if(axis === "horizontal") {
|
||||
this.container.style.display = "flex";
|
||||
this.container.style.flexDirection = "row";
|
||||
this.container.style.flexWrap = "nowrap";
|
||||
} else {
|
||||
this.container.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
// orientation(orientation) {
|
||||
// if (orientation === "landscape") {
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// this.orientation = orientation;
|
||||
// }
|
||||
|
||||
destroy() {
|
||||
var base;
|
||||
|
||||
|
@ -241,6 +283,10 @@ class Stage {
|
|||
if(this.element.contains(this.container)) {
|
||||
this.element.removeChild(this.container);
|
||||
}
|
||||
|
||||
window.removeEventListener("resize", this.resizeFunc);
|
||||
window.removeEventListener("orientationChange", this.orientationChangeFunc);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ class IframeView {
|
|||
element.style.overflow = "hidden";
|
||||
|
||||
if(axis && axis == "horizontal"){
|
||||
element.style.display = "inline-block";
|
||||
element.style.display = "block";
|
||||
element.style.flex = "none";
|
||||
} else {
|
||||
element.style.display = "block";
|
||||
}
|
||||
|
@ -86,6 +87,8 @@ class IframeView {
|
|||
this._width = 0;
|
||||
this._height = 0;
|
||||
|
||||
this.element.setAttribute("ref", this.index);
|
||||
|
||||
this.element.appendChild(this.iframe);
|
||||
this.added = true;
|
||||
|
||||
|
@ -129,19 +132,6 @@ class IframeView {
|
|||
.then(function(contents){
|
||||
return this.load(contents);
|
||||
}.bind(this))
|
||||
// .then(function(doc){
|
||||
// return this.hooks.content.trigger(view, this);
|
||||
// }.bind(this))
|
||||
.then(function(){
|
||||
// this.settings.layout.format(view.contents);
|
||||
// return this.hooks.layout.trigger(view, this);
|
||||
}.bind(this))
|
||||
// .then(function(){
|
||||
// return this.display();
|
||||
// }.bind(this))
|
||||
// .then(function(){
|
||||
// return this.hooks.render.trigger(view, this);
|
||||
// }.bind(this))
|
||||
.then(function(){
|
||||
|
||||
// apply the layout function to the contents
|
||||
|
@ -169,6 +159,20 @@ class IframeView {
|
|||
|
||||
}
|
||||
|
||||
reset () {
|
||||
if (this.iframe) {
|
||||
this.iframe.style.width = "0";
|
||||
this.iframe.style.height = "0";
|
||||
this._width = 0;
|
||||
this._height = 0;
|
||||
this._textWidth = undefined;
|
||||
this._contentWidth = undefined;
|
||||
this._textHeight = undefined;
|
||||
this._contentHeight = undefined;
|
||||
}
|
||||
this._needsReframe = true;
|
||||
}
|
||||
|
||||
// Determine locks base on settings
|
||||
size(_width, _height) {
|
||||
var width = _width || this.settings.width;
|
||||
|
@ -181,7 +185,6 @@ class IframeView {
|
|||
} else {
|
||||
this.lock("width", width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Lock an axis to element dimensions, taking borders into account
|
||||
|
@ -197,12 +200,12 @@ class IframeView {
|
|||
|
||||
if(what == "width" && isNumber(width)){
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
// this.resize(this.lockedWidth, width); // width keeps ratio correct
|
||||
}
|
||||
|
||||
if(what == "height" && isNumber(height)){
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(width, this.lockedHeight);
|
||||
// this.resize(width, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(what === "both" &&
|
||||
|
@ -211,7 +214,7 @@ class IframeView {
|
|||
|
||||
this.lockedWidth = width - elBorders.width - iframeBorders.width;
|
||||
this.lockedHeight = height - elBorders.height - iframeBorders.height;
|
||||
this.resize(this.lockedWidth, this.lockedHeight);
|
||||
// this.resize(this.lockedWidth, this.lockedHeight);
|
||||
}
|
||||
|
||||
if(this.displayed && this.iframe) {
|
||||
|
@ -252,7 +255,8 @@ class IframeView {
|
|||
|
||||
// width = this.contentWidth(textWidth);
|
||||
|
||||
columns = Math.ceil(width / (this.settings.layout.columnWidth + this.settings.layout.gap));
|
||||
/*
|
||||
columns = Math.ceil(width / (this.settings.layout.columnWidth));
|
||||
|
||||
if ( this.settings.layout.divisor > 1 &&
|
||||
this.settings.layout.name === "reflowable" &&
|
||||
|
@ -260,6 +264,12 @@ class IframeView {
|
|||
// add a blank page
|
||||
width += this.settings.layout.gap + this.settings.layout.columnWidth;
|
||||
}
|
||||
*/
|
||||
|
||||
// Add padding back
|
||||
if (width % this.layout.width > 0) {
|
||||
width += this.layout.gap / 2;
|
||||
}
|
||||
|
||||
// Save the textWdith
|
||||
this._textWidth = textWidth;
|
||||
|
@ -357,15 +367,16 @@ class IframeView {
|
|||
this.element.style.height = height + "px";
|
||||
}
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
this.elementBounds = bounds(this.element);
|
||||
|
||||
let widthDelta = this.prevBounds ? this.elementBounds.width - this.prevBounds.width : this.elementBounds.width;
|
||||
let heightDelta = this.prevBounds ? this.elementBounds.height - this.prevBounds.height : this.elementBounds.height;
|
||||
|
||||
size = {
|
||||
width: this.elementBounds.width,
|
||||
height: this.elementBounds.height,
|
||||
widthDelta: this.elementBounds.width - this.prevBounds.width,
|
||||
heightDelta: this.elementBounds.height - this.prevBounds.height,
|
||||
widthDelta: widthDelta,
|
||||
heightDelta: heightDelta,
|
||||
};
|
||||
|
||||
this.onResize(this, size);
|
||||
|
@ -376,6 +387,8 @@ class IframeView {
|
|||
|
||||
this.emit("resized", size);
|
||||
|
||||
this.prevBounds = this.elementBounds;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,29 +461,6 @@ class IframeView {
|
|||
promise.resolve(this.contents);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// layout(layoutFunc) {
|
||||
//
|
||||
// this.iframe.style.display = "inline-block";
|
||||
//
|
||||
// // Reset Body Styles
|
||||
// // this.document.body.style.margin = "0";
|
||||
// //this.document.body.style.display = "inline-block";
|
||||
// //this.document.documentElement.style.width = "auto";
|
||||
//
|
||||
// if(layoutFunc){
|
||||
// this.layoutFunc = layoutFunc;
|
||||
// }
|
||||
//
|
||||
// this.contents.layout(this.layoutFunc);
|
||||
//
|
||||
// };
|
||||
//
|
||||
// onLayout(view) {
|
||||
// // stub
|
||||
// };
|
||||
|
||||
setLayout(layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class Navigation {
|
|||
|
||||
var index = id ? id : 0;
|
||||
tocLinkArray.forEach((linkElm) => {
|
||||
if (linkElm.nodeName === 'li') {
|
||||
if (linkElm.nodeName.toLowerCase() === 'li') {
|
||||
var tocLink = qs(linkElm, 'a'),
|
||||
tocLinkData = {
|
||||
id: -1,
|
||||
|
|
|
@ -182,6 +182,9 @@ class Rendition {
|
|||
// Listen for resizing
|
||||
this.manager.on("resized", this.onResized.bind(this));
|
||||
|
||||
// Listen for rotation
|
||||
this.manager.on("orientationChange", this.onOrientationChange.bind(this));
|
||||
|
||||
// Listen for scroll changes
|
||||
this.manager.on("scrolled", this.reportLocation.bind(this));
|
||||
|
||||
|
@ -343,6 +346,7 @@ class Rendition {
|
|||
onResized(size){
|
||||
|
||||
if (this.location) {
|
||||
// this.manager.clear();
|
||||
this.display(this.location.start.cfi);
|
||||
}
|
||||
|
||||
|
@ -353,6 +357,19 @@ class Rendition {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Report orientation events and display the last seen location
|
||||
* @private
|
||||
*/
|
||||
onOrientationChange(orientation){
|
||||
if (this.location) {
|
||||
this.manager.clear();
|
||||
this.display(this.location.start.cfi);
|
||||
}
|
||||
|
||||
this.emit("orientationChange", orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the Rendition to a specific offset
|
||||
* Usually you would be better off calling display()
|
||||
|
@ -443,9 +460,18 @@ class Rendition {
|
|||
this._layout.flow(_flow);
|
||||
}
|
||||
|
||||
if (this.manager && this._layout) {
|
||||
this.manager.applyLayout(this._layout);
|
||||
}
|
||||
|
||||
if (this.manager) {
|
||||
this.manager.updateFlow(_flow);
|
||||
}
|
||||
|
||||
if (this.location) {
|
||||
this.manager.clear();
|
||||
this.display(this.location.start.cfi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -538,8 +564,11 @@ class Rendition {
|
|||
}
|
||||
|
||||
located(location){
|
||||
if (!location.length) {
|
||||
return {};
|
||||
}
|
||||
let start = location[0];
|
||||
let end = location[location.length-1]
|
||||
let end = location[location.length-1];
|
||||
|
||||
let located = {
|
||||
start: {
|
||||
|
|
|
@ -76,7 +76,7 @@ class Themes {
|
|||
}
|
||||
}
|
||||
|
||||
apply (name) {
|
||||
select (name) {
|
||||
var prev = this._current;
|
||||
var contents;
|
||||
|
||||
|
|
|
@ -177,8 +177,6 @@ class Queue {
|
|||
*/
|
||||
clear(){
|
||||
this._q = [];
|
||||
this.running = false;
|
||||
this.paused = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,6 +193,15 @@ class Queue {
|
|||
pause(){
|
||||
this.paused = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* End the queue
|
||||
*/
|
||||
stop(){
|
||||
this._q = [];
|
||||
this.running = false;
|
||||
this.paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue