1
0
Fork 0
mirror of https://github.com/futurepress/epub.js.git synced 2025-10-03 14:59:18 +02:00

Switched to Gulp, Basic Scrolling Renderer

This commit is contained in:
Fred Chasen 2014-08-05 23:52:41 -04:00
parent b1b98f9d57
commit d73133e2c7
12 changed files with 4826 additions and 186 deletions

View file

@ -1,32 +0,0 @@
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
},
connect: {
server: {
options: {
port: 9001,
base: '.'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-connect');
// Default task(s).
grunt.registerTask('default', ['uglify']);
grunt.registerTask('serve', ['connect']);
};

4542
dist/epub.js vendored Normal file

File diff suppressed because it is too large Load diff

2
dist/epub.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -4,32 +4,19 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>EPUB.js Basic Example</title> <title>EPUB.js Basic Example</title>
<script src="../bower_components/rsvp/rsvp.js"></script> <script src="../dist/epub.js"></script>
<script src="../lib/epub.js"></script>
<script src="../lib/epubjs/core.js"></script>
<script src="../lib/epubjs/hooks.js"></script>
<script src="../lib/epubjs/book.js"></script>
<script src="../lib/epubjs/parser.js"></script>
<script src="../lib/epubjs/spine.js"></script>
<script src="../lib/epubjs/navigation.js"></script>
<script src="../lib/epubjs/epubcfi.js"></script>
<script src="../lib/epubjs/renderer.js"></script>
<script src="../lib/epubjs/view.js"></script>
<script src="../lib/epubjs/infinite.js"></script>
<style type="text/css"> <style type="text/css">
body { body {
margin: 0; margin: 0;
height: 100%;
} }
#viewer { #viewer {
display: block; position: absolute;
margin: 5% auto; left: 10%;
width: 80%; width: 80%;
height: 80%; height: 100%;
border: none; overflow: hidden;
} }
#prev { #prev {
@ -70,57 +57,26 @@
</style> </style>
</head> </head>
<body> <body>
<!-- <select id="toc"></select> -->
<!-- <iframe id="viewer"></iframe> -->
<div id="viewer"></div> <div id="viewer"></div>
<div id="prev" class="arrow"></div>
<div id="next" class="arrow"></div>
<script> <script>
var $viewer = document.getElementById("viewer"); var currentSectionIndex = 10;
var $next = document.getElementById("next"); // Load the opf
var $prev = document.getElementById("prev");
var currentSection;
var currentSectionIndex = 0;
var book = ePub("../books/moby-dick/OPS/package.opf"); var book = ePub("../books/moby-dick/OPS/package.opf");
var rendition = book.renderTo("viewer"); var rendition = book.renderTo("viewer");
rendition.display(currentSectionIndex); var displayed = rendition.display(currentSectionIndex);
// Navigations Drop Down displayed.then(function(renderer){
// -- do stuff
});
// Navigation loaded
book.loaded.navigation.then(function(toc){ book.loaded.navigation.then(function(toc){
var $select = document.getElementById("toc"), // console.log(toc);
docfrag = document.createDocumentFragment();
toc.forEach(function(chapter) {
var option = document.createElement("option");
option.textContent = chapter.label;
option.ref = chapter.href;
docfrag.appendChild(option);
}); });
// $select.appendChild(docfrag);
// $select.onchange = function(){
// var index = $select.selectedIndex;
// var url = $select.options[index].ref;
// rendition.display(url);
// return false;
// };
$next.addEventListener("click", function(){
rendition.display(currentSectionIndex+1);
currentSectionIndex++;
}, false);
$prev.addEventListener("click", function(){
rendition.display(currentSectionIndex-1);
currentSectionIndex--;
}, false);
});
</script> </script>
</body> </body>

35
gulpfile.js Normal file
View file

@ -0,0 +1,35 @@
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
// Lint JS
gulp.task('lint', function() {
return gulp.src('lib/*/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
// Concat & Minify JS
gulp.task('minify', function(){
return gulp.src(['lib/*.js', 'bower_components/rsvp/rsvp.js', 'lib/epubjs/*.js'])
.pipe(concat('epub.js'))
.pipe(gulp.dest('dist'))
.pipe(rename('epub.min.js'))
.pipe(uglify())
.pipe(gulp.dest('dist'));
});
// Watch Our Files
gulp.task('watch', function() {
gulp.watch('lib/*/*.js', ['lint', 'minify']);
});
// Default
gulp.task('default', ['lint', 'minify']);
// gulp.task('default', function() {
// // place code for your default task here
// });

View file

@ -257,4 +257,14 @@ EPUBJS.core.resolveUrl = function(base, path) {
url = folders.concat(segments); url = folders.concat(segments);
return url.join("/"); return url.join("/");
};
EPUBJS.core.documentHeight = function() {
return Math.max(
document.documentElement.clientHeight,
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight
);
}; };

View file

@ -3,23 +3,37 @@ EPUBJS.Infinite = function(container, renderer){
this.windowHeight = window.innerHeight; this.windowHeight = window.innerHeight;
this.tick = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; this.tick = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
this.scrolled = false; this.scrolled = false;
this.ignore = false;
this.displaying = false; this.displaying = false;
this.offset = 250; this.offset = 250;
this.views = []; this.views = [];
this.renderer = renderer; this.renderer = renderer;
this.prevScrollTop = 0;
}; };
EPUBJS.Infinite.prototype.start = function(first_argument) { EPUBJS.Infinite.prototype.start = function() {
window.addEventListener("scroll", function(){ var firstScroll = true;
this.scrolled = true;
this.container.addEventListener("scroll", function(e){
if(!this.ignore) {
this.scrolled = true;
} else {
this.ignore = false;
}
// console.log("scroll", this.container.scrollTop)
}.bind(this)); }.bind(this));
// Reset to prevent jump
window.addEventListener('unload', function(e){
this.ignore = true;
// window.scroll(0,0);
});
this.tick.call(window, this.check.bind(this)); this.tick.call(window, this.check.bind(this));
// Fill Screen
this.scrolled = false; this.scrolled = false;
}; };
EPUBJS.Infinite.prototype.forwards = function() { EPUBJS.Infinite.prototype.forwards = function() {
@ -29,7 +43,6 @@ EPUBJS.Infinite.prototype.forwards = function() {
EPUBJS.Infinite.prototype.backwards = function() { EPUBJS.Infinite.prototype.backwards = function() {
this.trigger("backwards"); this.trigger("backwards");
}; };
/* /*
@ -75,18 +88,28 @@ EPUBJS.Infinite.prototype.check = function(){
if(this.scrolled && !this.displaying) { if(this.scrolled && !this.displaying) {
var scrollTop = document.body.scrollTop;//TODO: make document.body a variable // var scrollTop = window.pageYOffset || document.documentElement.scrollTop
var scrollHeight = document.body.scrollHeight; // var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
// console.log(scrollTop, this.windowHeight - (scrollHeight - scrollTop) ) var scrollTop = this.container.scrollTop;
if(this.windowHeight - (scrollHeight - scrollTop) > -this.offset) {
// var scrollTop = document.body.scrollTop;//TODO: make document.body a variable
// var scrollHeight = document.documentElement.scrollHeight;
var scrollHeight = this.container.scrollHeight;
var direction = scrollTop - this.prevScrollTop;
var height = this.container.getBoundingClientRect().height;
var up = height - (scrollHeight - scrollTop) > -this.offset;
var down = scrollTop < this.offset;
if(up && direction > 0) {
this.forwards(); this.forwards();
} }
else if(scrollTop < this.offset) { else if(down && direction < 0) {
this.backwards(); this.backwards();
} }
// console.log(document.body.scrollTop) // console.log(document.body.scrollTop)
this.prevScrollTop = scrollTop;
this.scrolled = false; this.scrolled = false;
} }

View file

@ -1,10 +1,12 @@
EPUBJS.Layout = function(){};
/** /**
* 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 * Takes: global layout settings object, chapter properties string
* Returns: Object with layout properties * Returns: Object with layout properties
*/ */
EPUBJS.Renderer.prototype.reconcileLayoutSettings = function(global, chapter){ EPUBJS.Layout.prototype.reconcileLayoutSettings = function(global, chapter){
var settings = {}; var settings = {};
//-- Get the global defaults //-- Get the global defaults
@ -35,7 +37,7 @@ EPUBJS.Renderer.prototype.reconcileLayoutSettings = function(global, chapter){
* Takes: Layout settings object * Takes: Layout settings object
* Returns: String of appropriate for EPUBJS.Layout function * Returns: String of appropriate for EPUBJS.Layout function
*/ */
EPUBJS.Renderer.prototype.determineLayout = function(settings){ EPUBJS.Layout.prototype.determineLayout = function(settings){
// Default is layout: reflowable & spread: auto // Default is layout: reflowable & spread: auto
var spreads = this.determineSpreads(this.minSpreadWidth); var spreads = this.determineSpreads(this.minSpreadWidth);
var layoutMethod = spreads ? "ReflowableSpreads" : "Reflowable"; var layoutMethod = spreads ? "ReflowableSpreads" : "Reflowable";
@ -67,7 +69,7 @@ EPUBJS.Renderer.prototype.determineLayout = function(settings){
//-- STYLES //-- STYLES
EPUBJS.Renderer.prototype.applyStyles = function(styles) { EPUBJS.Layout.prototype.applyStyles = function(styles) {
for (var style in styles) { for (var style in styles) {
for (var view in this.views) { for (var view in this.views) {
view.setStyle(style, styles[style]); view.setStyle(style, styles[style]);
@ -75,20 +77,20 @@ EPUBJS.Renderer.prototype.applyStyles = function(styles) {
} }
}; };
EPUBJS.Renderer.prototype.setStyle = function(style, val, prefixed){ EPUBJS.Layout.prototype.setStyle = function(style, val, prefixed){
for (var view in this.views) { for (var view in this.views) {
view.setStyle(style, val, prefixed); view.setStyle(style, val, prefixed);
} }
}; };
EPUBJS.Renderer.prototype.removeStyle = function(style){ EPUBJS.Layout.prototype.removeStyle = function(style){
for (var view in this.views) { for (var view in this.views) {
view.removeStyle(style); view.removeStyle(style);
} }
}; };
//-- HEAD TAGS //-- HEAD TAGS
EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) { EPUBJS.Layout.prototype.applyHeadTags = function(headTags) {
for ( var headTag in headTags ) { for ( var headTag in headTags ) {
this.render.addHeadTag(headTag, headTags[headTag]); this.render.addHeadTag(headTag, headTags[headTag]);
} }

View file

@ -1,3 +1,4 @@
/*
EPUBJS.Renderer.prototype.listeners = function(){ EPUBJS.Renderer.prototype.listeners = function(){
// Dom events to listen for // Dom events to listen for
this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click"]; this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click"];
@ -67,4 +68,5 @@ EPUBJS.Renderer.prototype.onSelectionChange = function(e){
this.selectedRange = this.render.window.getSelection(); this.selectedRange = this.render.window.getSelection();
this.trigger("renderer:selected", this.selectedRange); this.trigger("renderer:selected", this.selectedRange);
}.bind(this), 500); }.bind(this), 500);
}; };
*/

View file

@ -1,6 +1,6 @@
EPUBJS.Renderer = function(book, _options) { EPUBJS.Renderer = function(book, _options) {
var options = _options || {}; var options = _options || {};
var settings = { this.settings = {
hidden: options.hidden || false, hidden: options.hidden || false,
viewLimit: 3, viewLimit: 3,
width: options.width || false, width: options.width || false,
@ -14,7 +14,6 @@ EPUBJS.Renderer = function(book, _options) {
// Blank Cfi for Parsing // Blank Cfi for Parsing
this.epubcfi = new EPUBJS.EpubCFI(); this.epubcfi = new EPUBJS.EpubCFI();
// this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {}; this.layoutSettings = {};
@ -31,12 +30,12 @@ EPUBJS.Renderer = function(book, _options) {
this.position = 1; this.position = 1;
this.initialize({ this.initialize({
"width" : settings.width, "width" : this.settings.width,
"height" : settings.height, "height" : this.settings.height,
"hidden" : true "hidden" : true
}); });
this.displaying = false; this.rendering = false;
this.views = []; this.views = [];
this.positions = []; this.positions = [];
@ -48,8 +47,8 @@ EPUBJS.Renderer = function(book, _options) {
*/ */
EPUBJS.Renderer.prototype.initialize = function(_options){ EPUBJS.Renderer.prototype.initialize = function(_options){
var options = _options || {}; var options = _options || {};
var height = options.height || "100%"; var height = options.height ? options.height + "px" : "100%";
var width = options.width || "100%"; var width = options.width ? options.width + "px" : "100%";
var hidden = options.hidden || false; var hidden = options.hidden || false;
@ -74,28 +73,63 @@ EPUBJS.Renderer.prototype.initialize = function(_options){
return this.container; return this.container;
}; };
EPUBJS.Renderer.prototype.resize = function(_width, _height){
var width = _width;
var height = _height;
if(!_width) {
width = window.innerWidth;
}
if(!_height) {
height = window.innerHeight;
}
this.container.style.width = width + "px";
this.container.style.height = height + "px";
this.trigger("resized", {
width: this.width,
height: this.height
});
};
EPUBJS.Renderer.prototype.onResized = function(e) {
var bounds = this.element.getBoundingClientRect();
this.resize(bounds.width, bounds.height);
};
EPUBJS.Renderer.prototype.attachTo = function(_element){ EPUBJS.Renderer.prototype.attachTo = function(_element){
var element; var bounds;
if(EPUBJS.core.isElement(_element)) { if(EPUBJS.core.isElement(_element)) {
element = _element; this.element = _element;
} else if (typeof _element === "string") { } else if (typeof _element === "string") {
element = document.getElementById(_element); this.element = document.getElementById(_element);
} }
if(!element){ if(!this.element){
console.error("Not an Element"); console.error("Not an Element");
return; return;
} }
element.appendChild(this.container); this.element.appendChild(this.container);
if(!this.settings.height && !this.settings.width) {
bounds = this.element.getBoundingClientRect();
this.resize(bounds.width, bounds.height);
}
this.infinite.start(); this.infinite.start();
this.infinite.on("forwards", this.forwards.bind(this)); this.infinite.on("forwards", this.forwards.bind(this));
this.infinite.on("backwards", this.backwards.bind(this)); this.infinite.on("backwards", this.backwards.bind(this));
window.addEventListener("resize", this.onResized.bind(this), false);
}; };
@ -106,37 +140,47 @@ EPUBJS.Renderer.prototype.display = function(what){
this.book.opened.then(function(){ this.book.opened.then(function(){
var section = this.book.spine.get(what); var section = this.book.spine.get(what);
var rendered; var rendered = this.render(section);
if(!section) { rendered.then(function(){
displaying.reject(); this.fill();
return;
};
rendered = section.render();
view.index = section.index;
rendered.then(function(contents){
return view.load(contents);
}).then(function(){
displaying.resolve(this); displaying.resolve(this);
}.bind(this)); }.bind(this));
// Place view in correct position
this.insert(view, section.index);
}.bind(this)); }.bind(this));
return displayed; return displayed;
}; };
EPUBJS.Renderer.prototype.render = function(section){
var rendered;
var view = new EPUBJS.View();
if(!section) {
rendered.reject();
return;
};
rendered = section.render();
view.index = section.index;
// Place view in correct position
this.insert(view, section.index);
return rendered.then(function(contents){
return view.load(contents);
});
};
EPUBJS.Renderer.prototype.forwards = function(){ EPUBJS.Renderer.prototype.forwards = function(){
var next; var next;
var displayed; var rendered;
var section;
if(this.displaying) return; if(this.rendering) return;
console.log("going forwards")
next = this.last().index + 1; next = this.last().index + 1;
@ -144,40 +188,62 @@ EPUBJS.Renderer.prototype.forwards = function(){
return; return;
} }
displayed = this.display(next); section = this.book.spine.get(next);
this.displaying = true; rendered = this.render(section);
this.rendering = true;
displayed.then(function(){ rendered.then(function(){
this.displaying = false; console.log("last:", this.last().height)
this.rendering = false;
}.bind(this)); }.bind(this));
return displayed; return rendered;
}; };
EPUBJS.Renderer.prototype.backwards = function(view){ EPUBJS.Renderer.prototype.backwards = function(view){
var prev; var prev;
var displayed; var rendered;
var section;
if(this.displaying) return; if(this.rendering) return;
console.log("going backwards")
prev = this.first().index - 1; prev = this.first().index - 1;
if(prev < 0){ if(prev < 0){
return; return; //TODO: should reject
} }
displayed = this.display(prev); section = this.book.spine.get(prev);
this.displaying = true; rendered = this.render(section);
this.rendering = true;
rendered.then(function(){
this.rendering = false;
// -- this might want to be in infinite
this.container.scrollTop += this.first().height;
displayed.then(function(){
this.displaying = false;
window.scrollBy(0, this.first().height + 20);
}.bind(this)); }.bind(this));
return displayed; return rendered;
}; };
// Manage Views // Manage Views
// -- this might want to be in infinite
EPUBJS.Renderer.prototype.fill = function() {
console.log("filling")
var filling = this.backwards();
var height = this.container.getBoundingClientRect().height;
filling.then(function(){
var bottom = this.last().bounds().bottom;
while (height && bottom && bottom < height) {
this.forwards();
};
}.bind(this));
};
EPUBJS.Renderer.prototype.jump = function(view){ EPUBJS.Renderer.prototype.jump = function(view){
this.views.push(view); this.views.push(view);
}; };
@ -217,4 +283,7 @@ EPUBJS.Renderer.prototype.first = function() {
EPUBJS.Renderer.prototype.last = function() { EPUBJS.Renderer.prototype.last = function() {
return this.views[this.views.length-1]; return this.views[this.views.length-1];
}; };
//-- Enable binding events to Renderer
RSVP.EventTarget.mixin(EPUBJS.Renderer.prototype);

View file

@ -7,28 +7,10 @@ EPUBJS.View = function(options) {
this.width; this.width;
}; };
// EPUBJS.View.prototype.load = function(section) {
// var contents = section.render();
// var loading = new RSVP.defer();
// var loaded = loading.promise;
// this.section = section;
// contents.then(function(contents) {
// //TODO: Add a more generic set contents
// this.iframe.srcdoc = contents;
// this.layout();
// loading.resolve(this);
// }.bind(this));
// return loaded;
// };
EPUBJS.View.prototype.load = function(contents) { EPUBJS.View.prototype.load = function(contents) {
var loading = new RSVP.defer(); var loading = new RSVP.defer();
var loaded = loading.promise; var loaded = loading.promise;
this.document = this.iframe.contentDocument; this.document = this.iframe.contentDocument;
// this.iframe.srcdoc = contents; // this.iframe.srcdoc = contents;
@ -37,9 +19,20 @@ EPUBJS.View.prototype.load = function(contents) {
this.document.close(); this.document.close();
this.iframe.onload = function(e) { this.iframe.onload = function(e) {
this.window = this.iframe.contentWindow;
this.window.addEventListener("resize", this.resized.bind(this), false);
this.document = this.iframe.contentDocument;
this.iframe.style.display = "block"; this.iframe.style.display = "block";
// Reset Body Styles
this.document.body.style.margin = "0";
this.document.body.style.display = "inline-block";
this.layout(); this.layout();
this.iframe.style.visibility = "visible"; this.iframe.style.visibility = "visible";
loading.resolve(this); loading.resolve(this);
this.loading.resolve(this); this.loading.resolve(this);
}.bind(this); }.bind(this);
@ -60,18 +53,49 @@ EPUBJS.View.prototype.create = function() {
// Back up if seamless isn't supported // Back up if seamless isn't supported
this.iframe.style.border = "none"; this.iframe.style.border = "none";
this.iframe.width = "100%"; this.iframe.width = "100%";
this.iframe.height = "100%"; this.iframe.style.height = "0";
// this.iframe.addEventListener("load", this.loaded.bind(this), false);
this.iframe.style.display = "none"; this.iframe.style.display = "none";
this.iframe.style.visibility = "hidden"; this.iframe.style.visibility = "hidden";
return this.iframe; return this.iframe;
}; };
EPUBJS.View.prototype.resized = function() {
if (!this.resizing) {
this.layout();
} else {
this.resizing = false;
}
};
EPUBJS.View.prototype.layout = function() { EPUBJS.View.prototype.layout = function() {
this.height = this.document.documentElement.getBoundingClientRect().height; var bounds = {}, content, width = 0, height = 0;
this.width = this.document.documentElement.getBoundingClientRect().width;
this.iframe.style.height = this.height + "px"; // This needs to run twice to get to the correct size
while(bounds.height != height || bounds.width != width) {
this.resizing = true;
// Check bounds
bounds = this.document.body.getBoundingClientRect();
// Apply Changes
this.iframe.style.height = bounds.height + "px";
this.iframe.style.width = bounds.width + "px";
// Check again
content = this.document.body.getBoundingClientRect();
height = content.height;
width = content.width;
this.width = width;
this.height = height;
}
}; };
EPUBJS.View.prototype.appendTo = function(element) { EPUBJS.View.prototype.appendTo = function(element) {
@ -82,6 +106,11 @@ EPUBJS.View.prototype.prependTo = function(element) {
element.insertBefore(this.iframe, element.firstChild); element.insertBefore(this.iframe, element.firstChild);
}; };
EPUBJS.View.prototype.bounds = function() {
return this.iframe.getBoundingClientRect();
};
EPUBJS.View.prototype.destroy = function() { EPUBJS.View.prototype.destroy = function() {
}; };

View file

@ -15,9 +15,11 @@
"colors": "^0.6.2", "colors": "^0.6.2",
"connect": "^3.0.1", "connect": "^3.0.1",
"express": "^4.5.1", "express": "^4.5.1",
"grunt": "^0.4.5", "gulp": "^3.8.7",
"grunt-contrib-connect": "^0.8.0", "gulp-concat": "^2.3.4",
"grunt-contrib-uglify": "^0.5.0", "gulp-jshint": "^1.8.4",
"gulp-rename": "^1.2.0",
"gulp-uglify": "^0.3.1",
"morgan": "^1.1.1", "morgan": "^1.1.1",
"optimist": "^0.6.1", "optimist": "^0.6.1",
"portfinder": "^0.2.1", "portfinder": "^0.2.1",