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

added Endnotes pop up and image resizing

This commit is contained in:
Fred Chasen 2013-03-26 17:26:47 -07:00
parent d69e12dc7e
commit 7f41f00775
18 changed files with 335 additions and 25 deletions

View file

@ -100,7 +100,6 @@ FP.Hooks.register("beforeChapterDisplay").example = function(callback, chapter){
if(callback) callback();
}
```

View file

@ -55,7 +55,7 @@
<!-- Plugins -->
<script async src="fpjs/hooks/transculsions.js"></script>
<script async src="fpjs/hooks/annotate.js"></script>
<script async src="fpjs/hooks/extras/annotate.js"></script>
<!-- Reader -->
<script async src="fpjs/reader/utils.js"></script>

View file

@ -55,8 +55,10 @@ body {
#area {
width: 80%;
height: 80%;
margin: 0 auto;
margin-left: 10%;
max-width: 1250px;
z-index: 2;
position: absolute;
}
#area iframe {
@ -175,7 +177,7 @@ input:-moz-placeholder {
width: 1px;
border-right: 1px #000 solid;
height: 80%;
z-index: 10;
z-index: 1;
left: 50%;
top: 10%;
opacity: .15;
@ -294,9 +296,11 @@ input:-moz-placeholder {
#settingsPanel .large { font-size:large; }
#settingsPanel .xlarge { font-size:x-large; }
@media only screen and (max-width: 1040px) {
#area{
width: 50%;
margin-left: 25%;
}
#divider,
@ -308,6 +312,7 @@ input:-moz-placeholder {
@media only screen and (max-width: 900px) {
#area{
width: 60%;
margin-left: 20%;
}
#prev {
@ -322,6 +327,7 @@ input:-moz-placeholder {
@media only screen and (max-width: 550px) {
#area{
width: 80%;
margin-left: 10%;
}
#prev {
@ -371,3 +377,5 @@ input:-moz-placeholder {
}
}

96
css/popup.css Normal file
View file

@ -0,0 +1,96 @@
/* http://davidwalsh.name/css-tooltips */
/* base CSS element */
.popup {
background: #eee;
border: 1px solid #ccc;
padding: 10px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
position: fixed;
max-width: 300px;
font-size: 12px;
display: none;
margin-left: 2px;
margin-top: 30px;
}
.popup.above {
margin-top: -10px;
}
.popup.left {
margin-left: -20px;
}
.popup.right {
margin-left: 40px;
}
.pop_content {
max-height: 225px;
overflow-y: auto;
}
.pop_content > p {
margin-top: 0;
}
/* below */
.popup:before {
position: absolute;
display: inline-block;
border-bottom: 10px solid #eee;
border-right: 10px solid transparent;
border-left: 10px solid transparent;
border-bottom-color: rgba(0, 0, 0, 0.2);
left: 50%;
top: -10px;
margin-left: -6px;
content: '';
}
.popup:after {
position: absolute;
display: inline-block;
border-bottom: 9px solid #eee;
border-right: 9px solid transparent;
border-left: 9px solid transparent;
left: 50%;
top: -9px;
margin-left: -5px;
content: '';
}
/* above */
.popup.above:before {
border-bottom: none;
border-top: 10px solid #eee;
border-top-color: rgba(0, 0, 0, 0.2);
top: 100%;
}
.popup.above:after {
border-bottom: none;
border-top: 9px solid #eee;
top: 100%;
}
.popup.left:before,
.popup.left:after
{
left: 20px;
}
.popup.right:before,
.popup.right:after
{
left: auto;
right: 20px;
}
.popup.show, .popup.on {
display: block;
}

View file

@ -47,6 +47,8 @@
<!-- Plugins -->
<script async src="fpjs/hooks/transculsions.js"></script>
<script async src="fpjs/hooks/music.js"></script>
<script async src="fpjs/hooks/endnotes.js"></script>
<script async src="fpjs/hooks/smartimages.js"></script>
<!-- Reader -->
<script async src="fpjs/reader/utils.js"></script>
@ -77,10 +79,11 @@
<span id="title-seperator">&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span id="chapter-title"> </span>
</div>
<div id="divider"></div>
<div id="prev" class="arrow"></div>
<div id="area"></div>
<div id="next" class="arrow"></div>
<div id="divider"></div>
<div id="loader"><img src="img/loader.gif"></div>
</div>
</body>

2
dist/hooks/hooks.min.js vendored Normal file
View file

@ -0,0 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-26 */
FP.Hooks.register("beforeChapterDisplay").endnotes=function(e,t){var n=t.doc.querySelectorAll("a[href]"),r=Array.prototype.slice.call(n),i="epub:type",s="noteref",o={};FP.core.addCss("css/popup.css",!1,t.doc.head),r.forEach(function(e){function d(){var n,r=t.iframe.height,i=t.iframe.width,s,f,d=225;p||(f=a.cloneNode(!0),p=f.querySelector("p")),o[u]||(o[u]=document.createElement("div"),o[u].setAttribute("class","popup"),pop_content=document.createElement("div"),o[u].appendChild(pop_content),pop_content.appendChild(p),pop_content.setAttribute("class","pop_content"),t.bodyEl.appendChild(o[u]),o[u].addEventListener("mouseover",v,!1),o[u].addEventListener("mouseout",m,!1),t.book.listenUntil("book:pageChanged","book:chapterDestroy",g),t.book.listenUntil("book:pageChanged","book:chapterDestroy",m)),f=o[u],l=e.getBoundingClientRect(),c=l.left,h=l.top,f.classList.add("show"),f.style.left=c-f.offsetWidth/2+"px",f.style.top=h+"px",n=f.getBoundingClientRect(),d>r/2.5&&(d=r/2.5,pop_content.style.maxHeight=d+"px"),n.height+h>=r-25?(f.style.top=h-n.height+"px",f.classList.add("above")):f.classList.remove("above"),c-n.width<=0?(f.style.left=c+"px",f.classList.add("left")):f.classList.remove("left"),c+n.width/2>=i?(console.log("right"),f.style.left=c-300+"px",n=f.getBoundingClientRect(),f.style.left=c-n.width+"px",n.height+h>=r-25?(f.style.top=h-n.height+"px",f.classList.add("above")):f.classList.remove("above"),f.classList.add("right")):f.classList.remove("right")}function v(){o[u].classList.add("on")}function m(){o[u].classList.remove("on")}function g(){setTimeout(function(){o[u].classList.remove("show")},100)}var n=e.getAttribute(i),r,u,a,f,l,c,h,p;if(n!=s)return;r=e.getAttribute("href"),u=r.replace("#",""),a=t.doc.getElementById(u),e.addEventListener("mouseover",d,!1),e.addEventListener("mouseout",g,!1)}),e&&e()},FP.Hooks.register("beforeChapterDisplay").smartimages=function(e,t){var n=t.doc.querySelectorAll("img"),r=Array.prototype.slice.call(n),i=t.iframe.height,s;r.forEach(function(e){function n(){var n=e.offsetHeight,r=e.offsetTop;i=t.iframe.height,n+r>=i?r<i/2?e.style.maxHeight=i-r+"px":(e.style.maxHeight=(n<i?n:i)+"px",e.style.marginTop=i-r+"px"):(e.style.removeProperty("max-height"),e.style.removeProperty("margin-top"))}t.book.listenUntil("book:resized","book:chapterDestroy",n),n()}),e&&e()},FP.Hooks.register("beforeChapterDisplay").transculsions=function(e,t){var n=t.doc.querySelectorAll("[transclusion]"),r=Array.prototype.slice.call(n);r.forEach(function(e){function l(){u=i,a=s,u>t.colWidth&&(f=t.colWidth/u,u=t.colWidth,a*=f),r.width=u,r.height=a}var n=e.getAttribute("ref"),r=document.createElement("iframe"),i=e.getAttribute("width"),s=e.getAttribute("height"),o=e.parentNode,u=i,a=s,f;l(),t.book.listenUntil("book:resized","book:chapterDestroy",l),r.src=n,o.replaceChild(r,e)}),e&&e()};

2
dist/reader.min.js vendored
View file

@ -1,2 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-25 */
/*! FuturePress - v0.1.0 - 2013-03-26 */
var FPR=FPR||{};FPR.app={},FPR.app.init=function(e){"use strict";function s(n){var s=window.location.search.match(/book=(.*)/),n=n||(s?s[1]:"moby-dick");FP.core.crossBrowserColumnCss(),i=e(window).width(),i>550?e("#main").width(i-r):e("#main").width(i),a(),t=new FP.Book("area"),t.listen("book:metadataReady",o),t.listen("book:tocReady",u),t.listen("book:bookReady",l),t.listen("book:chapterReady",p),t.listen("book:online",c),t.listen("book:offline",h),t.start(n),e(function(){d()})}function o(){var n=t.getTitle(),r=t.getCreator(),i=e("#book-title"),s=e("#chapter-title"),o=e("#title-seperator");document.title=n+" "+r,i.html(n),s.html(r),o.show()}function u(){var n=t.getTOC(),r=e("#toc"),i,s;r.empty(),s=f(n,1),r.append(s),i=e(".toc_link"),i.on("click",function(n){var r=e(this),i=r.data("url");e(".openChapter").removeClass("openChapter"),r.parents("li").addClass("openChapter"),t.useHash||(t.show(i),n.preventDefault())})}function a(){var n="";localStorage.getItem("fontSize")?n=localStorage.getItem("fontSize"):(n="medium",localStorage.setItem("fontSize",n));var r=e("#settingsPanel");r.append("<ul></ul>");var i=e("<li><h3></h3></li>"),s=e("<input type='radio' name='fontSize' value='x-small'><span class='xsmall'>Extra Small</span><br><input type='radio' name='fontSize' value='small'><span class='small'>Small</span><br><input type='radio' name='fontSize' value='medium'><span class='medium'>Medium</span><br><input type='radio' name='fontSize' value='large'><span class='large'>Large</span><br><input type='radio' name='fontSize' value='x-large'><span class='xlarge'>Extra Large</span>");i.find("h3").text("Font Size").after(s),r.find("ul").append(i);var o=e('input[name="fontSize"]');o.each(function(){e(this).attr("value")==n&&e(this).attr("checked","checked"),e(this).on("click",function(){localStorage.setItem("fontSize",e(this).attr("value")),t.iframe.contentDocument.location.reload(!0)})})}function f(t,n){var r=e("<ul>"),i=n==1?"chapter":"section";return t.forEach(function(t){var s,o=e("<li id='toc-"+t.id+"'>"),u=e("<a class='toc_link "+i+"' href='#/"+t.href+"' data-url='"+t.href+"'>"+t.label+"</a>");o.append(u),t.subitems&&t.subitems.length&&(n++,s=f(t.subitems,n),o.append(s)),r.append(o)}),r}function l(){var n=e("#divider"),r=e("#loader");r.hide(),t.single||n.addClass("show")}function c(){var t=e("#store");n=!1,t.attr("src","img/save.png")}function h(){var t=e("#store");n=!0,t.attr("src","img/saved.png")}function p(t){var n=t.msg,r=e("#toc-"+n),i=e(".currentChapter");r.length&&(i.removeClass("currentChapter"),r.addClass("currentChapter"))}function d(){function y(){f.addClass("open"),u.addClass("closed"),c.attr("src","img/close.png")}function b(){a.css("pointer-events","visible"),f.removeClass("open"),u.removeClass("closed"),c.attr("src","img/menu-icon.png")}function w(){v.hide(),d.show()}function E(){d.hide(),v.show()}var s=e("#next"),o=e("#prev"),u=e("#main"),a=e("#area"),f=e("#sidebar"),l=e("#open"),c=l.find("img"),h=e("#network"),p=e("#setting"),d=e("#settingsPanel"),v=e("#toc"),m=e(window);m.on("resize",function(){i=e(window).width(),i>550?u.width(i-r):u.width(i)}),s.on("click",function(){t.nextPage()}),o.on("click",function(){t.prevPage()}),p.on("click",function(){d.is(":visible")?E():w()}),m.bind("touchy-swipe",function(e,n,r,i){(i.direction="left")&&t.nextPage(),(i.direction="right")&&t.prevPage()});var g=!1;e(document).keydown(function(e){if(g)return;if(e.keyCode==37)return o.trigger("click"),g=!0,setTimeout(function(){g=!1},100),!1;if(e.keyCode==39)return s.trigger("click"),g=!0,setTimeout(function(){g=!1},100),!1}),l.on("click",function(){f.hasClass("open")?b():y()}),h.on("click",function(){n=!n,t.fromStorage(n)})}var t,n=!1,r=0,i;return s}(jQuery),jQuery.fn.extend({clickOutside:function(e,t){var n=this;return jQuery(document).on("click.offer",function(r){if(t&&jQuery.inArray(r.target,t)>-1)return;if(jQuery.contains(n[0],r.target))return;jQuery(document).off("click.offer"),e(r,n)}),this}}),Modernizr.addTest("filesystem",function(){var e=Modernizr._domPrefixes;for(var t=-1,n=e.length;++t<n;)if(window[e[t]+"RequestFileSystem"])return!0;return"requestFileSystem"in window});

4
dist/render.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
/*! FuturePress - v0.1.0 - 2013-03-25 */
/*! FuturePress - v0.1.0 - 2013-03-26 */
;

BIN
fpjs/.DS_Store vendored

Binary file not shown.

154
fpjs/hooks/endnotes.js Normal file
View file

@ -0,0 +1,154 @@
FP.Hooks.register("beforeChapterDisplay").endnotes = function(callback, chapter){
var notes = chapter.doc.querySelectorAll('a[href]'),
items = Array.prototype.slice.call(notes),
attr = "epub:type",
type = "noteref",
popups = {};
FP.core.addCss("css/popup.css", false, chapter.doc.head);
//console.log("notes", items)
items.forEach(function(item){
var epubType = item.getAttribute(attr),
href,
id,
el,
pop,
pos,
left,
top,
txt;
if(epubType != type) return;
href = item.getAttribute("href");
id = href.replace("#", '');
el = chapter.doc.getElementById(id);
item.addEventListener("mouseover", showPop, false);
item.addEventListener("mouseout", hidePop, false);
function showPop(){
var poppos,
iheight = chapter.iframe.height,
iwidth = chapter.iframe.width,
tip,
pop,
maxHeight = 225;
if(!txt) {
pop = el.cloneNode(true);
txt = pop.querySelector("p");
}
//-- create a popup with endnote inside of it
if(!popups[id]) {
popups[id] = document.createElement("div");
popups[id].setAttribute("class", "popup");
pop_content = document.createElement("div");
popups[id].appendChild(pop_content);
pop_content.appendChild(txt);
pop_content.setAttribute("class", "pop_content");
chapter.bodyEl.appendChild(popups[id]);
//-- TODO: will these leak memory? - Fred
popups[id].addEventListener("mouseover", onPop, false);
popups[id].addEventListener("mouseout", offPop, false);
//-- Add hide on page change
chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", hidePop);
chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", offPop);
}
pop = popups[id];
//-- get location of item
pos = item.getBoundingClientRect();
left = pos.left;
top = pos.top;
//-- show the popup
pop.classList.add("show");
//-- position the popup
pop.style.left = left - pop.offsetWidth / 2 + "px";
pop.style.top = top + "px";
//-- checking to keep within current column
poppos = pop.getBoundingClientRect();
//-- Adjust max height
if(maxHeight > iheight / 2.5) {
maxHeight = iheight / 2.5;
pop_content.style.maxHeight = maxHeight + "px";
}
//-- switch above / below
if(poppos.height + top >= iheight - 25) {
pop.style.top = top - poppos.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
//-- switch left
if(left - poppos.width <= 0) {
pop.style.left = left + "px";
pop.classList.add("left");
}else{
pop.classList.remove("left");
}
//-- switch right
if(left + poppos.width / 2 >= iwidth) {
console.log("right")
//-- TEMP MOVE: 300
pop.style.left = left - 300 + "px";
poppos = pop.getBoundingClientRect();
pop.style.left = left - poppos.width + "px";
//-- switch above / below again
if(poppos.height + top >= iheight - 25) {
pop.style.top = top - poppos.height + "px";
pop.classList.add("above");
}else{
pop.classList.remove("above");
}
pop.classList.add("right");
}else{
pop.classList.remove("right");
}
}
function onPop(){
popups[id].classList.add("on");
}
function offPop(){
popups[id].classList.remove("on");
}
function hidePop(){
setTimeout(function(){
popups[id].classList.remove("show");
}, 100);
}
});
if(callback) callback();
}

42
fpjs/hooks/smartimages.js Normal file
View file

@ -0,0 +1,42 @@
FP.Hooks.register("beforeChapterDisplay").smartimages = function(callback, chapter){
var image = chapter.doc.querySelectorAll('img'),
items = Array.prototype.slice.call(image),
iheight = chapter.iframe.height,
oheight;
items.forEach(function(item){
function size() {
var height = item.offsetHeight,
top = item.offsetTop;
iheight = chapter.iframe.height;
if(height + top >= iheight) {
if(top < iheight/2) {
item.style.maxHeight = iheight - top + "px";
}else{
item.style.maxHeight = (height < iheight ? height : iheight) + "px";
item.style.marginTop = iheight - top + "px";
}
}else{
item.style.removeProperty('max-height');
item.style.removeProperty('margin-top');
}
}
chapter.book.listenUntil("book:resized", "book:chapterDestroy", size);
size();
});
if(callback) callback();
}

View file

@ -87,14 +87,14 @@ FP.Book.prototype.listeners = function(){
FP.Book.prototype.start = function(bookPath){
var location = window.location,
pathname = location.pathname,
absolute = this.bookUrl.search("://") != -1,
absolute = bookPath.search("://") != -1,
fromRoot = pathname[0] == "/",
cleaned = [],
folder = "/",
origin,
split;
//folder = (pathname[pathname.length - 1] == "/") ? pathname : "/",
if(bookPath[bookPath.length - 1] != "/") bookPath += "/";
@ -120,7 +120,7 @@ FP.Book.prototype.start = function(bookPath){
//-- 2. Check if url starts with /, add base url
if(!absolute && fromRoot){
this.bookUrl = origin + bookPath;
this.bookUrl = origin + "/" + bookPath;
}
//-- 3. Or find full path to url and add that

View file

@ -42,21 +42,27 @@ FP.Chapter.prototype.loadFromStorage = function(path){
FP.Chapter.prototype.setIframeSrc = function(url){
var that = this;
//-- Not sure if this is the best time to do this, but hides current text
this.visible(false);
this.iframe.src = url;
this.iframe.onload = function() {
that.doc = that.iframe.contentDocument;
that.bodyEl = that.doc.body;
that.formatSpread();
//-- Trigger registered hooks before displaying
that.beforeDisplay(function(){
that.calcPages();
that.book.tell("book:chapterDisplayed");
that.visible(true);
});
that.afterLoaded(that);
@ -109,7 +115,7 @@ FP.Chapter.prototype.formatSpread = function(){
this.bodyEl.style.fontSize = localStorage.getItem("fontSize") || "medium";
//-- Clear Margins
this.bodyEl.style.visibility = "hidden";
//this.bodyEl.style.visibility = "hidden";
this.bodyEl.style.margin = "0";
this.bodyEl.style.overflow = "hidden";
@ -123,14 +129,12 @@ FP.Chapter.prototype.formatSpread = function(){
this.bodyEl.style[FP.core.columnGap] = this.gap+"px";
this.bodyEl.style[FP.core.columnWidth] = this.colWidth+"px";
this.calcPages();
//-- Go to current page after resize
if(this.OldcolWidth){
this.leftPos = (this.chapterPos - 1 ) * this.spreadWidth;
this.bodyEl.scrollLeft = this.leftPos;
this.visible(true);
//this.visible(true);
}
}
@ -138,13 +142,15 @@ FP.Chapter.prototype.goToChapterEnd = function(){
this.chapterEnd();
}
FP.Chapter.prototype.visible = function(bool){
if(!this.bodyEl) return false;
FP.Chapter.prototype.visible = function(bool){
if(typeof(bool) == "undefined") {
return this.iframe.style.visibility;
}
if(bool){
this.bodyEl.style.visibility = "visible";
}else{
this.bodyEl.style.visibility = "hidden";
if(bool == true){
this.iframe.style.visibility = "visible";
}else if(bool == false){
this.iframe.style.visibility = "hidden";
}
}

View file

@ -11,7 +11,7 @@ module.exports = function(grunt) {
'dist/render.min.js': ['<banner>', 'fpjs/render/*.js'],
'dist/workers/loader_filesystem.js': ['<banner>', 'fpjs/render/workers/loader_filesystem.js'],
'dist/reader.min.js': ['<banner>', 'fpjs/reader/*.js'],
'dist/hooks/transculsions.min.js': ['<banner>', 'fpjs/hooks/transculsions.js'],
'dist/hooks/hooks.min.js': ['<banner>', 'fpjs/hooks/*.js'],
'dist/libs/zip.js': ['fpjs/libs/zip.js'],
'dist/libs/deflate.js': ['fpjs/libs/deflate.js'],
'dist/libs/inflate.js': ['fpjs/libs/inflate.js'],

View file

@ -29,7 +29,7 @@
<script src="dist/render.min.js"></script>
<!-- Hooks -->
<script async src="dist/hooks/transculsions.min.js"></script>
<script async src="dist/hooks/hooks.min.js"></script>
<!-- Reader -->
<script src="dist/reader.min.js"></script>