Open peeter-tomberg opened 8 years ago
Not sure what is happening here. Could you post a screenshot of the cut off?
Also, how are you adding the class?
I added that css to moby dick and tried reader/index.html
with the following function:
function test() {
reader.book.renderer.render.bodyEl.classList.add('opus-font-size-large');
reader.book.renderer.reformat();
}
and was able to get to all the pages in the ios simulator.
Steps to reproduce on a browser:
My setup:
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Basic ePubJS Example</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- EPUBJS Renderer -->
<script src="../build/epub.js"></script>
<style type="text/css">
body {
overflow: hidden;
}
#main {
position: absolute;
width: 100%;
height: 100%;
}
#area {
margin: 0px 20px;
}
#area iframe {
border: none;
}
#prev {
left: 40px;
}
#next {
right: 40px;
}
.arrow {
position: absolute;
top: 50%;
margin-top: -32px;
font-size: 64px;
color: #E2E2E2;
font-family: arial, sans-serif;
font-weight: bold;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.arrow:hover {
color: #777;
}
.arrow:active {
color: #000;
}
</style>
</head>
<body>
<button onclick="changeClass('small');">Small</button>
<button onclick="changeClass('medium');">Medium</button>
<button onclick="changeClass('large');">Large</button>
<div id="main">
<div id="prev" onclick="reader.prevPage();" class="arrow">‹</div>
<div id="area"></div>
<div id="next" onclick="reader.nextPage();" class="arrow">›</div>
</div>
<script>
"use strict";
EPUBJS.Hooks.register('beforeChapterDisplay').touchHandlers = function (callback, renderer) {
EPUBJS.core.addCss('http://localhost:63342/epub.js/examples/styles/reader.css', function() { }, renderer.render.document.head); //Same file that is added in the ticket, update to the correct path
callback();
};
var reader = ePub({
height : window.innerHeight - 40,
width : window.innerWidth,
styles : {
padding : '0 20px'
}
});
reader.forceSingle(true);
reader.open("https://s3.amazonaws.com/moby-dick/");
reader.renderTo("area");
var changeClass = function (type) {
var body = reader.renderer.doc.body;
var map = {
'small' : 'opus-font-size-small',
'medium': 'opus-font-size-medium',
'large' : 'opus-font-size-large'
};
Object.keys(map).forEach(function (key) {
body.classList.remove(map[key]);
});
body.classList.add(map[type]);
reader.renderer.reformat();
};
</script>
</body>
</html>
Video of the bug: https://www.youtube.com/watch?v=oa2ExSpuYbQ Plunkr used in the video: http://plnkr.co/edit/O9LSIFLdfVhmI5YTeYcn?p=preview
Steps to reproduce:
A common reason for this issue:
Currently on first load and on every chapter display additional css gets requested (from external site or from filesystem) and reported that it is loaded, as soon as this reporting happens reflow calculation starts for the script. Page calculation starts and repositioning happens.
Too bad this happens in the default css context as when the css file is loaded it's not actually applied to DOM yet. So page calculation get's everything wrong as it doesn't know yet how wide the page really is.
Possible solution:
I agree that this is probably an issue with the timing of the css being applied.
On that note, the changeClass
and the callback
should be in the callback of the addCSS
function, so that they don't execute until the css has been loaded.
EPUBJS.Hooks.register('beforeChapterDisplay').touchHandlers = function (callback, renderer) {
EPUBJS.core.addCss(renderer.element.baseURI + 'reader.css', function() {
changeClass(fontSize);
callback();
}, renderer.render.document.head); //Same file that is added in the ticket, update to the correct path
};
One other thing to try for testing if it is a timing issue is putting book.renderer.reformat();
a setTimeout
.
After putting reformat in a timeout, it helped a bit but the calculation is still off by a page.
Why do I need to re-load the CSS for every paragraph load? Cant I add the CSS/JS files at a configuration step and they stay there?
Alright, after 4h of just trying out different approaches, this is what worked for me:
EPUBJS.Hooks.register('beforeChapterDisplay').touchHandlers = (callback, renderer) => {
var doc = renderer.render.document;
var node = doc.createElement('style');
node.type = 'text/css';
node.appendChild(document.createTextNode(css));
doc.head.appendChild(node);
window.setTimeout(() => {
this.CurrentBookService.updateContrastClass();
this.CurrentBookService.updateLineSpacingClass();
this.CurrentBookService.updateFontSizeClass();
this.CurrentBookService.updateDeviceClass();
callback();
}, 100);
};
I've in-lined the CSS, instead of adding a remote file. I also deferred the callback by a 100ms. No idea why deferring the callback by a 100ms worked, but it did.
What I've done is encrypt the book coming from the server in base64, decrypt in Javascript and render the ArrayBuffer.
We're adding a class to the iframe's body element to define if the user has the default size (no extra class), medium size (opus-font-size-medium) or large (opus-font-size-large).
After adding the class (medium or large), we trigger a reformat:
Any idea what we might be doing wrong? Happens with every book, the end of the paragraphs pages gets cut off (when going from paragraph b back to paragraph a)