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">
<title>EPUB.js Basic Example</title>
<script src="../bower_components/rsvp/rsvp.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>
<script src="../dist/epub.js"></script>
<style type="text/css">
body {
margin: 0;
height: 100%;
}
#viewer {
display: block;
margin: 5% auto;
position: absolute;
left: 10%;
width: 80%;
height: 80%;
border: none;
height: 100%;
overflow: hidden;
}
#prev {
@ -70,57 +57,26 @@
</style>
</head>
<body>
<!-- <select id="toc"></select> -->
<!-- <iframe id="viewer"></iframe> -->
<div id="viewer"></div>
<div id="prev" class="arrow"></div>
<div id="next" class="arrow"></div>
<script>
var $viewer = document.getElementById("viewer");
var $next = document.getElementById("next");
var $prev = document.getElementById("prev");
var currentSection;
var currentSectionIndex = 0;
var currentSectionIndex = 10;
// Load the opf
var book = ePub("../books/moby-dick/OPS/package.opf");
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){
var $select = document.getElementById("toc"),
docfrag = document.createDocumentFragment();
toc.forEach(function(chapter) {
var option = document.createElement("option");
option.textContent = chapter.label;
option.ref = chapter.href;
docfrag.appendChild(option);
// console.log(toc);
});
// $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>
</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

@ -258,3 +258,13 @@ EPUBJS.core.resolveUrl = function(base, path) {
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,21 +3,35 @@ EPUBJS.Infinite = function(container, renderer){
this.windowHeight = window.innerHeight;
this.tick = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
this.scrolled = false;
this.ignore = false;
this.displaying = false;
this.offset = 250;
this.views = [];
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.container.addEventListener("scroll", function(e){
if(!this.ignore) {
this.scrolled = true;
} else {
this.ignore = false;
}
// console.log("scroll", this.container.scrollTop)
}.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));
// Fill Screen
this.scrolled = false;
};
@ -29,7 +43,6 @@ EPUBJS.Infinite.prototype.forwards = function() {
EPUBJS.Infinite.prototype.backwards = function() {
this.trigger("backwards");
};
/*
@ -75,18 +88,28 @@ EPUBJS.Infinite.prototype.check = function(){
if(this.scrolled && !this.displaying) {
var scrollTop = document.body.scrollTop;//TODO: make document.body a variable
var scrollHeight = document.body.scrollHeight;
// console.log(scrollTop, this.windowHeight - (scrollHeight - scrollTop) )
if(this.windowHeight - (scrollHeight - scrollTop) > -this.offset) {
// var scrollTop = window.pageYOffset || document.documentElement.scrollTop
// var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
var scrollTop = this.container.scrollTop;
// 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();
}
else if(scrollTop < this.offset) {
else if(down && direction < 0) {
this.backwards();
}
// console.log(document.body.scrollTop)
this.prevScrollTop = scrollTop;
this.scrolled = false;
}

View file

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

View file

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

View file

@ -1,6 +1,6 @@
EPUBJS.Renderer = function(book, _options) {
var options = _options || {};
var settings = {
this.settings = {
hidden: options.hidden || false,
viewLimit: 3,
width: options.width || false,
@ -14,7 +14,6 @@ EPUBJS.Renderer = function(book, _options) {
// Blank Cfi for Parsing
this.epubcfi = new EPUBJS.EpubCFI();
// this.resized = _.debounce(this.onResized.bind(this), 100);
this.layoutSettings = {};
@ -31,12 +30,12 @@ EPUBJS.Renderer = function(book, _options) {
this.position = 1;
this.initialize({
"width" : settings.width,
"height" : settings.height,
"width" : this.settings.width,
"height" : this.settings.height,
"hidden" : true
});
this.displaying = false;
this.rendering = false;
this.views = [];
this.positions = [];
@ -48,8 +47,8 @@ EPUBJS.Renderer = function(book, _options) {
*/
EPUBJS.Renderer.prototype.initialize = function(_options){
var options = _options || {};
var height = options.height || "100%";
var width = options.width || "100%";
var height = options.height ? options.height + "px" : "100%";
var width = options.width ? options.width + "px" : "100%";
var hidden = options.hidden || false;
@ -74,28 +73,63 @@ EPUBJS.Renderer.prototype.initialize = function(_options){
return this.container;
};
EPUBJS.Renderer.prototype.resize = function(_width, _height){
var width = _width;
var height = _height;
EPUBJS.Renderer.prototype.attachTo = function(_element){
var element;
if(EPUBJS.core.isElement(_element)) {
element = _element;
} else if (typeof _element === "string") {
element = document.getElementById(_element);
if(!_width) {
width = window.innerWidth;
}
if(!_height) {
height = window.innerHeight;
}
if(!element){
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){
var bounds;
if(EPUBJS.core.isElement(_element)) {
this.element = _element;
} else if (typeof _element === "string") {
this.element = document.getElementById(_element);
}
if(!this.element){
console.error("Not an Element");
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.on("forwards", this.forwards.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(){
var section = this.book.spine.get(what);
var rendered;
var rendered = this.render(section);
if(!section) {
displaying.reject();
return;
};
rendered = section.render();
view.index = section.index;
rendered.then(function(contents){
return view.load(contents);
}).then(function(){
rendered.then(function(){
this.fill();
displaying.resolve(this);
}.bind(this));
// Place view in correct position
this.insert(view, section.index);
}.bind(this));
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(){
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;
@ -144,40 +188,62 @@ EPUBJS.Renderer.prototype.forwards = function(){
return;
}
displayed = this.display(next);
this.displaying = true;
section = this.book.spine.get(next);
rendered = this.render(section);
this.rendering = true;
displayed.then(function(){
this.displaying = false;
rendered.then(function(){
console.log("last:", this.last().height)
this.rendering = false;
}.bind(this));
return displayed;
return rendered;
};
EPUBJS.Renderer.prototype.backwards = function(view){
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;
if(prev < 0){
return;
return; //TODO: should reject
}
displayed = this.display(prev);
this.displaying = true;
section = this.book.spine.get(prev);
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));
return displayed;
return rendered;
};
// 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){
this.views.push(view);
};
@ -218,3 +284,6 @@ EPUBJS.Renderer.prototype.first = function() {
EPUBJS.Renderer.prototype.last = function() {
return this.views[this.views.length-1];
};
//-- Enable binding events to Renderer
RSVP.EventTarget.mixin(EPUBJS.Renderer.prototype);

View file

@ -7,24 +7,6 @@ EPUBJS.View = function(options) {
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) {
var loading = new RSVP.defer();
var loaded = loading.promise;
@ -37,9 +19,20 @@ EPUBJS.View.prototype.load = function(contents) {
this.document.close();
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";
// Reset Body Styles
this.document.body.style.margin = "0";
this.document.body.style.display = "inline-block";
this.layout();
this.iframe.style.visibility = "visible";
loading.resolve(this);
this.loading.resolve(this);
}.bind(this);
@ -60,18 +53,49 @@ EPUBJS.View.prototype.create = function() {
// Back up if seamless isn't supported
this.iframe.style.border = "none";
this.iframe.width = "100%";
this.iframe.height = "100%";
// this.iframe.addEventListener("load", this.loaded.bind(this), false);
this.iframe.style.height = "0";
this.iframe.style.display = "none";
this.iframe.style.visibility = "hidden";
return this.iframe;
};
EPUBJS.View.prototype.resized = function() {
if (!this.resizing) {
this.layout();
} else {
this.resizing = false;
}
};
EPUBJS.View.prototype.layout = function() {
this.height = this.document.documentElement.getBoundingClientRect().height;
this.width = this.document.documentElement.getBoundingClientRect().width;
this.iframe.style.height = this.height + "px";
var bounds = {}, content, width = 0, height = 0;
// 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) {
@ -82,6 +106,11 @@ EPUBJS.View.prototype.prependTo = function(element) {
element.insertBefore(this.iframe, element.firstChild);
};
EPUBJS.View.prototype.bounds = function() {
return this.iframe.getBoundingClientRect();
};
EPUBJS.View.prototype.destroy = function() {
};

View file

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