mirror of
https://github.com/futurepress/epub.js.git
synced 2025-10-05 15:32:55 +02:00
Updated CFI and added search example
This commit is contained in:
parent
d06e5b219e
commit
7eb6622c8e
15 changed files with 510 additions and 37 deletions
|
@ -679,9 +679,8 @@ EPUBJS.plugins = EPUBJS.plugins || {};
|
|||
|
||||
EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";
|
||||
|
||||
(function() {
|
||||
(function(root) {
|
||||
|
||||
var root = this;
|
||||
var previousEpub = root.ePub || {};
|
||||
|
||||
var ePub = root.ePub = function() {
|
||||
|
@ -734,7 +733,7 @@ EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";
|
|||
//Node
|
||||
module.exports = ePub;
|
||||
|
||||
})();
|
||||
})(window);
|
||||
EPUBJS.Book = function(options){
|
||||
|
||||
var book = this;
|
||||
|
@ -1886,7 +1885,7 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
|
|||
var stack = [],
|
||||
children;
|
||||
|
||||
while(node && node.parentNode !== null) {
|
||||
while(node && node.parentNode.nodeName == "html" && node.parentNode !== null) {
|
||||
children = node.parentNode.children;
|
||||
|
||||
stack.unshift({
|
||||
|
@ -1934,7 +1933,6 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.chapter = this.getChapter(cfiStr);
|
||||
|
||||
cfi.fragment = this.getFragment(cfiStr);
|
||||
|
||||
cfi.spinePos = (parseInt(cfi.chapter.split("/")[2]) / 2 - 1 ) || 0;
|
||||
|
||||
chapId = cfi.chapter.match(/\[(.*)\]/);
|
||||
|
@ -1985,7 +1983,7 @@ EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
|
|||
num, index, part,
|
||||
has_id, id;
|
||||
|
||||
sections.shift(); //-- html
|
||||
// sections.shift(); //-- html
|
||||
|
||||
while(sections.length > 0) {
|
||||
|
||||
|
|
4
build/epub.min.js
vendored
4
build/epub.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -380,10 +380,107 @@ EPUBJSR.app.init = (function($){
|
|||
|
||||
}
|
||||
|
||||
|
||||
return init;
|
||||
|
||||
})(jQuery);
|
||||
EPUBJSR.search = {};
|
||||
|
||||
// Search Server -- https://github.com/futurepress/epubjs-search
|
||||
EPUBJSR.search.SERVER = "http://localhost:5000";
|
||||
|
||||
EPUBJSR.search.request = function(q, callback) {
|
||||
var fetch = $.ajax({
|
||||
dataType: "json",
|
||||
url: EPUBJSR.search.SERVER + "/search?q=" + encodeURIComponent(q)
|
||||
});
|
||||
|
||||
fetch.fail(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
fetch.done(function(results) {
|
||||
callback(results);
|
||||
});
|
||||
};
|
||||
|
||||
EPUBJSR.search.View = function() {
|
||||
|
||||
var $searchBox = $("#searchBox"),
|
||||
$searchResults = $("#searchResults"),
|
||||
$tocView = $("#toc"),
|
||||
$searchView = $("#searchView"),
|
||||
iframeDoc;
|
||||
|
||||
|
||||
$searchBox.on("search", function(e) {
|
||||
var q = $searchBox.val();
|
||||
|
||||
e.preventDefault();
|
||||
//-- SearchBox is empty or cleared
|
||||
if(q == '') {
|
||||
$searchResults.empty();
|
||||
$searchView.removeClass("shown");
|
||||
$tocView.removeClass("hidden");
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
iframeDoc = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$searchView.hasClass("shown")) {
|
||||
$searchView.addClass("shown");
|
||||
$tocView.addClass("hidden");
|
||||
}
|
||||
|
||||
$searchResults.empty();
|
||||
$searchResults.append("<li><p>Searching...</p></li>");
|
||||
|
||||
|
||||
|
||||
EPUBJSR.search.request(q, function(data) {
|
||||
var results = data.results;
|
||||
|
||||
$searchResults.empty();
|
||||
|
||||
if(iframeDoc) {
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
}
|
||||
|
||||
if(results.length == 0) {
|
||||
$searchResults.append("<li><p>No Results Found</p></li>");
|
||||
return;
|
||||
}
|
||||
|
||||
iframeDoc = $("#area iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
|
||||
results.forEach(function(result) {
|
||||
var $li = $("<li></li>");
|
||||
var $item = $("<a href='"+result.href+"' data-cfi='"+result.cfi+"'><span>"+result.title+"</span><p>"+result.highlight+"</p></a>");
|
||||
|
||||
$item.on("click", function(e) {
|
||||
var $this = $(this),
|
||||
cfi = $this.data("cfi");
|
||||
|
||||
Book.gotoCfi(cfi);
|
||||
|
||||
Book.on("renderer:chapterDisplayed", function() {
|
||||
iframeDoc = $("#area iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
})
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
});
|
||||
$li.append($item);
|
||||
$searchResults.append($li);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
//-- http://stackoverflow.com/questions/2124684/jquery-how-click-anywhere-outside-of-the-div-the-div-fades-out
|
||||
|
||||
jQuery.fn.extend({
|
||||
|
|
|
@ -153,8 +153,13 @@ body {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
#search {
|
||||
#searchBox {
|
||||
width: 155px;
|
||||
float: left;
|
||||
margin-left: 5px;
|
||||
margin-top: -5px;
|
||||
|
||||
/*
|
||||
border-radius: 5px;
|
||||
background: #9b9b9b;
|
||||
float: left;
|
||||
|
@ -163,7 +168,8 @@ body {
|
|||
padding: 3px 10px;
|
||||
color: #000;
|
||||
border: none;
|
||||
outline: none;
|
||||
outline: none; */
|
||||
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder {
|
||||
|
@ -208,6 +214,8 @@ input:-moz-placeholder {
|
|||
-moz-transition: visibility 0 ease .5s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#sidebar.open #toc {
|
||||
overflow-y: auto;
|
||||
visibility: visible;
|
||||
|
@ -271,6 +279,59 @@ input:-moz-placeholder {
|
|||
display: block;
|
||||
}
|
||||
|
||||
#toc.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#searchView {
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#searchResults {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 50px;
|
||||
padding-left: 20px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#searchResults li {
|
||||
margin-bottom:10px;
|
||||
width: 225px;
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#searchResults a {
|
||||
color: #AAA;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#searchResults p {
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
#searchResults p .match {
|
||||
background: #ccc;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#searchResults li > p {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
#searchResults li a:hover {
|
||||
color: #E2E2E2;
|
||||
}
|
||||
|
||||
#searchView.shown {
|
||||
display: block;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#settingsPanel {
|
||||
display:none;
|
||||
}
|
||||
|
@ -297,6 +358,7 @@ input:-moz-placeholder {
|
|||
#settingsPanel .large { font-size:large; }
|
||||
#settingsPanel .xlarge { font-size:x-large; }
|
||||
|
||||
.highlight { background-color: yellow }
|
||||
|
||||
@media only screen and (max-width: 1040px) {
|
||||
#area{
|
||||
|
|
11
demo/css/normalize.css
vendored
11
demo/css/normalize.css
vendored
|
@ -452,23 +452,24 @@ input[type="radio"] {
|
|||
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
/*
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-webkit-appearance: textfield;
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
-webkit-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Removes inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
/* input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
} */
|
||||
|
||||
/*
|
||||
* Removes inner padding and border in Firefox 3+.
|
||||
|
|
|
@ -64,18 +64,21 @@
|
|||
<script async src="../hooks/default/smartimages.js"></script>
|
||||
|
||||
<!-- Reader -->
|
||||
<script async src="../reader/utils.js"></script>
|
||||
<script async src="../reader/app.js"></script>
|
||||
<script src="../reader/utils.js"></script>
|
||||
<script src="../reader/app.js"></script>
|
||||
|
||||
<!-- Full Screen -->
|
||||
<script src="js/libs/screenfull.min.js"></script>
|
||||
|
||||
<!-- Highlights -->
|
||||
<script src="js/libs/jquery.highlight.js"></script>
|
||||
<script async src="../hooks/extensions/highlight.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="sidebar">
|
||||
<div id="controls">
|
||||
<input id="search" placeholder="search">
|
||||
<input id="searchBox" placeholder="search" type="search">
|
||||
<a id="network"><img id="store" src="../demo/img/save.png" save="../demo/img/save.png" data-saved="../demo/img/saved.png"></a>
|
||||
<a id="setting"><img id="settings" src="../demo/img/settings.png"></a>
|
||||
<a id="fullscreen">
|
||||
|
@ -85,6 +88,9 @@
|
|||
</div>
|
||||
<div id="toc">
|
||||
</div>
|
||||
<div id="searchView">
|
||||
<ul id="searchResults"></ul>
|
||||
</div>
|
||||
<div id="settingsPanel">
|
||||
</div>
|
||||
|
||||
|
@ -105,5 +111,6 @@
|
|||
|
||||
<div id="loader"><img src="../demo/img/loader.gif"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
4
demo/js/epub.min.js
vendored
4
demo/js/epub.min.js
vendored
File diff suppressed because one or more lines are too long
108
demo/js/libs/jquery.highlight.js
Normal file
108
demo/js/libs/jquery.highlight.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* jQuery Highlight plugin
|
||||
*
|
||||
* Based on highlight v3 by Johann Burkard
|
||||
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
|
||||
*
|
||||
* Code a little bit refactored and cleaned (in my humble opinion).
|
||||
* Most important changes:
|
||||
* - has an option to highlight only entire words (wordsOnly - false by default),
|
||||
* - has an option to be case sensitive (caseSensitive - false by default)
|
||||
* - highlight element tag and class names can be specified in options
|
||||
*
|
||||
* Usage:
|
||||
* // wrap every occurrance of text 'lorem' in content
|
||||
* // with <span class='highlight'> (default options)
|
||||
* $('#content').highlight('lorem');
|
||||
*
|
||||
* // search for and highlight more terms at once
|
||||
* // so you can save some time on traversing DOM
|
||||
* $('#content').highlight(['lorem', 'ipsum']);
|
||||
* $('#content').highlight('lorem ipsum');
|
||||
*
|
||||
* // search only for entire word 'lorem'
|
||||
* $('#content').highlight('lorem', { wordsOnly: true });
|
||||
*
|
||||
* // don't ignore case during search of term 'lorem'
|
||||
* $('#content').highlight('lorem', { caseSensitive: true });
|
||||
*
|
||||
* // wrap every occurrance of term 'ipsum' in content
|
||||
* // with <em class='important'>
|
||||
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
|
||||
*
|
||||
* // remove default highlight
|
||||
* $('#content').unhighlight();
|
||||
*
|
||||
* // remove custom highlight
|
||||
* $('#content').unhighlight({ element: 'em', className: 'important' });
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2009 Bartek Szopka
|
||||
*
|
||||
* Licensed under MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
jQuery.extend({
|
||||
highlight: function (node, re, nodeName, className) {
|
||||
if (node.nodeType === 3) {
|
||||
var match = node.data.match(re);
|
||||
if (match) {
|
||||
var highlight = document.createElement(nodeName || 'span');
|
||||
highlight.className = className || 'highlight';
|
||||
var wordNode = node.splitText(match.index);
|
||||
wordNode.splitText(match[0].length);
|
||||
var wordClone = wordNode.cloneNode(true);
|
||||
highlight.appendChild(wordClone);
|
||||
wordNode.parentNode.replaceChild(highlight, wordNode);
|
||||
return 1; //skip added node in parent
|
||||
}
|
||||
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
|
||||
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
|
||||
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
jQuery.fn.unhighlight = function (options) {
|
||||
var settings = { className: 'highlight', element: 'span' };
|
||||
jQuery.extend(settings, options);
|
||||
|
||||
return this.find(settings.element + "." + settings.className).each(function () {
|
||||
var parent = this.parentNode;
|
||||
parent.replaceChild(this.firstChild, this);
|
||||
parent.normalize();
|
||||
}).end();
|
||||
};
|
||||
|
||||
jQuery.fn.highlight = function (words, options) {
|
||||
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
|
||||
jQuery.extend(settings, options);
|
||||
|
||||
if (words.constructor === String) {
|
||||
words = [words];
|
||||
}
|
||||
words = jQuery.grep(words, function(word, i){
|
||||
return word != '';
|
||||
});
|
||||
words = jQuery.map(words, function(word, i) {
|
||||
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
});
|
||||
if (words.length == 0) { return this; };
|
||||
|
||||
var flag = settings.caseSensitive ? "" : "i";
|
||||
var pattern = "(" + words.join("|") + ")";
|
||||
if (settings.wordsOnly) {
|
||||
pattern = "\\b" + pattern + "\\b";
|
||||
}
|
||||
var re = new RegExp(pattern, flag);
|
||||
|
||||
return this.each(function () {
|
||||
jQuery.highlight(this, re, settings.element, settings.className);
|
||||
});
|
||||
};
|
||||
|
2
demo/js/reader.min.js
vendored
2
demo/js/reader.min.js
vendored
|
@ -1 +1 @@
|
|||
var EPUBJSR=EPUBJSR||{};EPUBJSR.app={},EPUBJSR.app.init=function(a){"use strict";function b(b){var e=window.location.search.match(/book=(.*)/),b=b||(e?e[1]:"moby-dick");return k=a(window).width(),k>550?a("#main").width(k-m):a("#main").width(k),j=new EPUBJS.Book({bookPath:b,restore:!0}),j.on("book:online",g),j.on("book:offline",h),j.getMetadata().then(c),j.getToc().then(d),j.ready.all.then(f),j.renderTo("area"),a(function(){i()}),j}function c(b){var c=b.bookTitle,d=b.creator,e=a("#book-title"),f=a("#chapter-title"),g=a("#title-seperator");document.title=c+" – "+d,e.html(c),f.html(d),g.show()}function d(b){var c,d,f=a("#toc");f.empty(),d=e(b,1),f.append(d),c=a(".toc_link"),c.on("click",function(b){var c=a(this),d=c.data("url");a(".openChapter").removeClass("openChapter"),c.parents("li").addClass("openChapter"),j.goto(d),b.preventDefault()})}function e(b,c){var d=a("<ul>"),f=1==c?"chapter":"section";return b.forEach(function(b){var g,h=a("<li id='toc-"+b.id+"'>"),i=a("<a class='toc_link "+f+"' href='#/"+b.href+"' data-url='"+b.href+"'>"+b.label+"</a>");h.append(i),b.subitems&&b.subitems.length&&(c++,g=e(b.subitems,c),h.append(g)),d.append(h)}),d}function f(){var b=a("#divider"),c=a("#loader");c.hide(),j.single||b.addClass("show")}function g(){var b=a("#store");l=!1,b.attr("src",b.data("save"))}function h(){var b=a("#store");l=!0,b.attr("src",b.data("saved"))}function i(){function b(){n.addClass("open"),h.addClass("closed"),p.attr("src",p.data("close"))}function c(){i.css("pointer-events","visible"),n.removeClass("open"),h.removeClass("closed"),p.attr("src",p.data("open"))}function d(){t.hide(),s.show()}function e(){s.hide(),t.show()}var f=a("#next"),g=a("#prev"),h=a("#main"),i=a("#area"),n=a("#sidebar"),o=a("#open"),p=o.find("img"),q=a("#network"),r=a("#setting"),s=a("#settingsPanel"),t=a("#toc"),u=a("#fullscreen"),v=a("#fullscreenicon"),w=a("#cancelfullscreenicon"),x=a(window);x.on("resize",function(){k=a(window).width(),k>550?h.width(k-m):h.width(k)}),f.on("click",function(){j.nextPage()}),g.on("click",function(){j.prevPage()}),r.on("click",function(){s.is(":visible")?e():d()}),u.on("click",function(){screenfull.toggle(a("#container")[0]),v.toggle(),w.toggle()});var y=!1;a(document).keydown(function(a){return y?void 0:37==a.keyCode?(g.trigger("click"),y=!0,setTimeout(function(){y=!1},100),!1):39==a.keyCode?(f.trigger("click"),y=!0,setTimeout(function(){y=!1},100),!1):void 0}),o.on("click",function(){n.hasClass("open")?c():b()}),q.on("click",function(){l=!l,j.fromStorage(l)})}var j,k,l=!1,m=0;return b}(jQuery),jQuery.fn.extend({clickOutside:function(a,b){var c=this;return jQuery(document).on("click.offer",function(d){b&&jQuery.inArray(d.target,b)>-1||jQuery.contains(c[0],d.target)||(jQuery(document).off("click.offer"),a(d,c))}),this}});
|
||||
var EPUBJSR=EPUBJSR||{};EPUBJSR.app={},EPUBJSR.app.init=function(a){"use strict";function b(b){var e=window.location.search.match(/book=(.*)/),b=b||(e?e[1]:"moby-dick");return k=a(window).width(),k>550?a("#main").width(k-m):a("#main").width(k),j=new EPUBJS.Book({bookPath:b,restore:!0}),j.on("book:online",g),j.on("book:offline",h),j.getMetadata().then(c),j.getToc().then(d),j.ready.all.then(f),j.renderTo("area"),a(function(){i()}),j}function c(b){var c=b.bookTitle,d=b.creator,e=a("#book-title"),f=a("#chapter-title"),g=a("#title-seperator");document.title=c+" – "+d,e.html(c),f.html(d),g.show()}function d(b){var c,d,f=a("#toc");f.empty(),d=e(b,1),f.append(d),c=a(".toc_link"),c.on("click",function(b){var c=a(this),d=c.data("url");a(".openChapter").removeClass("openChapter"),c.parents("li").addClass("openChapter"),j.goto(d),b.preventDefault()})}function e(b,c){var d=a("<ul>"),f=1==c?"chapter":"section";return b.forEach(function(b){var g,h=a("<li id='toc-"+b.id+"'>"),i=a("<a class='toc_link "+f+"' href='#/"+b.href+"' data-url='"+b.href+"'>"+b.label+"</a>");h.append(i),b.subitems&&b.subitems.length&&(c++,g=e(b.subitems,c),h.append(g)),d.append(h)}),d}function f(){var b=a("#divider"),c=a("#loader");c.hide(),j.single||b.addClass("show")}function g(){var b=a("#store");l=!1,b.attr("src",b.data("save"))}function h(){var b=a("#store");l=!0,b.attr("src",b.data("saved"))}function i(){function b(){n.addClass("open"),h.addClass("closed"),p.attr("src",p.data("close"))}function c(){i.css("pointer-events","visible"),n.removeClass("open"),h.removeClass("closed"),p.attr("src",p.data("open"))}function d(){t.hide(),s.show()}function e(){s.hide(),t.show()}var f=a("#next"),g=a("#prev"),h=a("#main"),i=a("#area"),n=a("#sidebar"),o=a("#open"),p=o.find("img"),q=a("#network"),r=a("#setting"),s=a("#settingsPanel"),t=a("#toc"),u=a("#fullscreen"),v=a("#fullscreenicon"),w=a("#cancelfullscreenicon"),x=a(window);x.on("resize",function(){k=a(window).width(),k>550?h.width(k-m):h.width(k)}),f.on("click",function(){j.nextPage()}),g.on("click",function(){j.prevPage()}),r.on("click",function(){s.is(":visible")?e():d()}),u.on("click",function(){screenfull.toggle(a("#container")[0]),v.toggle(),w.toggle()});var y=!1;a(document).keydown(function(a){return y?void 0:37==a.keyCode?(g.trigger("click"),y=!0,setTimeout(function(){y=!1},100),!1):39==a.keyCode?(f.trigger("click"),y=!0,setTimeout(function(){y=!1},100),!1):void 0}),o.on("click",function(){n.hasClass("open")?c():b()}),q.on("click",function(){l=!l,j.fromStorage(l)})}var j,k,l=!1,m=0;return b}(jQuery),EPUBJSR.search={},EPUBJSR.search.SERVER="http://localhost:5000",EPUBJSR.search.request=function(a,b){var c=$.ajax({dataType:"json",url:EPUBJSR.search.SERVER+"/search?q="+encodeURIComponent(a)});c.fail(function(a){console.error(a)}),c.done(function(a){b(a)})},EPUBJSR.search.View=function(){var a,b=$("#searchBox"),c=$("#searchResults"),d=$("#toc"),e=$("#searchView");b.on("search",function(f){var g=b.val();return f.preventDefault(),""==g?(c.empty(),e.removeClass("shown"),d.removeClass("hidden"),$(a).find("body").unhighlight(),a=!1,void 0):(e.hasClass("shown")||(e.addClass("shown"),d.addClass("hidden")),c.empty(),c.append("<li><p>Searching...</p></li>"),EPUBJSR.search.request(g,function(b){var d=b.results;return c.empty(),a&&$(a).find("body").unhighlight(),0==d.length?(c.append("<li><p>No Results Found</p></li>"),void 0):(a=$("#area iframe")[0].contentDocument,$(a).find("body").highlight(g,{element:"span"}),d.forEach(function(b){var d=$("<li></li>"),e=$("<a href='"+b.href+"' data-cfi='"+b.cfi+"'><span>"+b.title+"</span><p>"+b.highlight+"</p></a>");e.on("click",function(b){var c=$(this),d=c.data("cfi");Book.gotoCfi(d),Book.on("renderer:chapterDisplayed",function(){a=$("#area iframe")[0].contentDocument,$(a).find("body").highlight(g,{element:"span"})}),b.preventDefault()}),d.append(e),c.append(d)}),void 0)}),void 0)})},jQuery.fn.extend({clickOutside:function(a,b){var c=this;return jQuery(document).on("click.offer",function(d){b&&jQuery.inArray(d.target,b)>-1||jQuery.contains(c[0],d.target)||(jQuery(document).off("click.offer"),a(d,c))}),this}});
|
92
examples/search.html
Executable file
92
examples/search.html
Executable file
|
@ -0,0 +1,92 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
|
||||
<link rel="stylesheet" href="../demo/css/normalize.css">
|
||||
<link rel="stylesheet" href="../demo/css/main.css">
|
||||
<link rel="stylesheet" href="../demo/css/popup.css">
|
||||
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
|
||||
<script>window.jQuery || document.write('<script src="epubjs/libs/jquery-1.9.0.min.js"><\/script>')</script>
|
||||
-->
|
||||
<script src="../libs/jquery/jquery-1.9.0.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
document.onreadystatechange = function () {
|
||||
if (document.readyState == "complete") {
|
||||
EPUBJS.VERSION = "0.1.6";
|
||||
|
||||
EPUBJS.filePath = "js/libs/";
|
||||
EPUBJS.cssPath = "css/";
|
||||
// fileStorage.filePath = EPUBJS.filePath;
|
||||
|
||||
EPUBJSR.app.init("moby-dick/");
|
||||
}
|
||||
};
|
||||
|
||||
$(function() {
|
||||
EPUBJSR.search.View();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script src="../build/epub.min.js"></script>
|
||||
|
||||
<!-- Reader -->
|
||||
<script src="../reader/utils.js"></script>
|
||||
<script src="../reader/app.js"></script>
|
||||
<script src="../reader/search.js"></script>
|
||||
|
||||
<!-- Full Screen -->
|
||||
<script src="../demo/js/libs/screenfull.min.js"></script>
|
||||
|
||||
<!-- Highlights -->
|
||||
<script src="../demo/js/libs/jquery.highlight.js"></script>
|
||||
<script src="../hooks/extensions/highlight.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="sidebar">
|
||||
<div id="controls">
|
||||
<input id="searchBox" placeholder="search" type="search">
|
||||
<a id="network"><img id="store" src="../demo/img/save.png" save="../demo/img/save.png" data-saved="../demo/img/saved.png"></a>
|
||||
<a id="setting"><img id="settings" src="../demo/img/settings.png"></a>
|
||||
<a id="fullscreen">
|
||||
<img id="fullscreenicon" src="../demo/img/fullscreen.png">
|
||||
<img id="cancelfullscreenicon" src="../demo/img/cancelfullscreen.png" style="display: none">
|
||||
</a>
|
||||
</div>
|
||||
<div id="toc">
|
||||
</div>
|
||||
<div id="searchView">
|
||||
<ul id="searchResults"></ul>
|
||||
</div>
|
||||
<div id="settingsPanel">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="opener">
|
||||
<a id="open"><img src="../demo/img/menu-icon.png" data-close="../demo/img/close.png" data-open="../demo/img/menu-icon.png"></a>
|
||||
</div>
|
||||
<div id="titlebar">
|
||||
<span id="book-title"></span>
|
||||
<span id="title-seperator"> – </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="loader"><img src="../demo/img/loader.gif"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
14
hooks/extensions/highlight.js
Normal file
14
hooks/extensions/highlight.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
EPUBJS.Hooks.register("beforeChapterDisplay").highlight = function(callback, renderer){
|
||||
|
||||
// EPUBJS.core.addScript("js/libs/jquery.highlight.js", null, renderer.doc.head);
|
||||
|
||||
var s = document.createElement("style");
|
||||
s.innerHTML =".highlight { background: yellow; font-weight: normal; }";
|
||||
|
||||
renderer.doc.body.appendChild(s);
|
||||
|
||||
if(callback) callback();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +380,6 @@ EPUBJSR.app.init = (function($){
|
|||
|
||||
}
|
||||
|
||||
|
||||
return init;
|
||||
|
||||
})(jQuery);
|
97
reader/search.js
Normal file
97
reader/search.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
EPUBJSR.search = {};
|
||||
|
||||
// Search Server -- https://github.com/futurepress/epubjs-search
|
||||
EPUBJSR.search.SERVER = "http://localhost:5000";
|
||||
|
||||
EPUBJSR.search.request = function(q, callback) {
|
||||
var fetch = $.ajax({
|
||||
dataType: "json",
|
||||
url: EPUBJSR.search.SERVER + "/search?q=" + encodeURIComponent(q)
|
||||
});
|
||||
|
||||
fetch.fail(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
fetch.done(function(results) {
|
||||
callback(results);
|
||||
});
|
||||
};
|
||||
|
||||
EPUBJSR.search.View = function() {
|
||||
|
||||
var $searchBox = $("#searchBox"),
|
||||
$searchResults = $("#searchResults"),
|
||||
$tocView = $("#toc"),
|
||||
$searchView = $("#searchView"),
|
||||
iframeDoc;
|
||||
|
||||
|
||||
$searchBox.on("search", function(e) {
|
||||
var q = $searchBox.val();
|
||||
|
||||
e.preventDefault();
|
||||
//-- SearchBox is empty or cleared
|
||||
if(q == '') {
|
||||
$searchResults.empty();
|
||||
$searchView.removeClass("shown");
|
||||
$tocView.removeClass("hidden");
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
iframeDoc = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$searchView.hasClass("shown")) {
|
||||
$searchView.addClass("shown");
|
||||
$tocView.addClass("hidden");
|
||||
}
|
||||
|
||||
$searchResults.empty();
|
||||
$searchResults.append("<li><p>Searching...</p></li>");
|
||||
|
||||
|
||||
|
||||
EPUBJSR.search.request(q, function(data) {
|
||||
var results = data.results;
|
||||
|
||||
$searchResults.empty();
|
||||
|
||||
if(iframeDoc) {
|
||||
$(iframeDoc).find('body').unhighlight();
|
||||
}
|
||||
|
||||
if(results.length == 0) {
|
||||
$searchResults.append("<li><p>No Results Found</p></li>");
|
||||
return;
|
||||
}
|
||||
|
||||
iframeDoc = $("#area iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
|
||||
results.forEach(function(result) {
|
||||
var $li = $("<li></li>");
|
||||
var $item = $("<a href='"+result.href+"' data-cfi='"+result.cfi+"'><span>"+result.title+"</span><p>"+result.highlight+"</p></a>");
|
||||
|
||||
$item.on("click", function(e) {
|
||||
var $this = $(this),
|
||||
cfi = $this.data("cfi");
|
||||
|
||||
Book.gotoCfi(cfi);
|
||||
|
||||
Book.on("renderer:chapterDisplayed", function() {
|
||||
iframeDoc = $("#area iframe")[0].contentDocument;
|
||||
$(iframeDoc).find('body').highlight(q, { element: 'span' });
|
||||
})
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
});
|
||||
$li.append($item);
|
||||
$searchResults.append($li);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
|
@ -7,9 +7,8 @@ EPUBJS.plugins = EPUBJS.plugins || {};
|
|||
|
||||
EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";
|
||||
|
||||
(function() {
|
||||
(function(root) {
|
||||
|
||||
var root = this;
|
||||
var previousEpub = root.ePub || {};
|
||||
|
||||
var ePub = root.ePub = function() {
|
||||
|
@ -62,4 +61,4 @@ EPUBJS.filePath = EPUBJS.filePath || "/epubjs/";
|
|||
//Node
|
||||
module.exports = ePub;
|
||||
|
||||
})();
|
||||
})(window);
|
|
@ -45,7 +45,7 @@ EPUBJS.EpubCFI.prototype.pathTo = function(node) {
|
|||
var stack = [],
|
||||
children;
|
||||
|
||||
while(node && node.parentNode !== null) {
|
||||
while(node && node.parentNode.nodeName == "html" && node.parentNode !== null) {
|
||||
children = node.parentNode.children;
|
||||
|
||||
stack.unshift({
|
||||
|
@ -93,7 +93,6 @@ EPUBJS.EpubCFI.prototype.parse = function(cfiStr) {
|
|||
cfi.chapter = this.getChapter(cfiStr);
|
||||
|
||||
cfi.fragment = this.getFragment(cfiStr);
|
||||
|
||||
cfi.spinePos = (parseInt(cfi.chapter.split("/")[2]) / 2 - 1 ) || 0;
|
||||
|
||||
chapId = cfi.chapter.match(/\[(.*)\]/);
|
||||
|
@ -144,7 +143,7 @@ EPUBJS.EpubCFI.prototype.getElement = function(cfi, _doc) {
|
|||
num, index, part,
|
||||
has_id, id;
|
||||
|
||||
sections.shift(); //-- html
|
||||
// sections.shift(); //-- html
|
||||
|
||||
while(sections.length > 0) {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue