├── languages └── epub-reader.pot ├── public ├── epubjs │ ├── img │ │ ├── star.png │ │ ├── close.png │ │ ├── save.png │ │ ├── saved.png │ │ ├── loader.gif │ │ ├── settings.png │ │ ├── fullscreen.png │ │ ├── menu-icon.png │ │ ├── settings-s.png │ │ ├── apple-touch-icon.png │ │ ├── cancelfullscreen.png │ │ ├── annotator-glyph-sprite.png │ │ └── annotator-icon-sprite.png │ ├── ebook │ │ ├── mimetype │ │ ├── cover_image.jpg │ │ ├── META-INF │ │ │ └── container.xml │ │ ├── toc.ncx │ │ ├── content.opf │ │ ├── ch2.html │ │ └── main.html │ ├── css │ │ ├── annotations.css │ │ ├── popup.css │ │ └── normalize.css │ ├── font │ │ ├── epub-fontello.eot │ │ ├── epub-fontello.ttf │ │ ├── epub-fontello.woff │ │ ├── epub-fontello.woff2 │ │ ├── config.json │ │ └── epub-fontello.svg │ ├── js │ │ ├── hooks │ │ │ └── extensions │ │ │ │ ├── protection.js │ │ │ │ ├── book_styles.js │ │ │ │ └── highlight.js │ │ ├── libs │ │ │ ├── protection.js │ │ │ ├── screenfull.min.js │ │ │ ├── screenfull.js │ │ │ └── jquery.highlight.js │ │ ├── plugins │ │ │ ├── hypothesis.js │ │ │ └── search.js │ │ ├── hooks.min.js │ │ ├── hooks.js │ │ └── reader.min.js │ └── index.html ├── index.php ├── js │ └── epub-reader-public.js ├── css │ └── epub-reader-public.css ├── partials │ └── epub-reader-public-shortcode.php ├── views │ ├── epub-reader-template.php │ └── epub-reader-frame.php └── class-epub-reader-public.php ├── index.php ├── admin ├── index.php ├── css │ └── epub-reader-admin.css ├── js │ └── epub-reader-admin.js ├── partials │ └── epub-reader-admin-display.php └── class-epub-reader-admin.php ├── .gitignore ├── includes ├── index.php ├── class-epub-reader-i18n.php ├── class-epub-reader-activator.php ├── class-epub-reader-posttype.php ├── class-epub-reader-loader.php └── class-epub-reader.php ├── uninstall.php ├── epub-reader.php ├── README.txt └── LICENSE.txt /languages/epub-reader.pot: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/epubjs/img/star.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/epubjs/js/hooks/extensions/protection.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").protection = function(callback, renderer){ 2 | 3 | EPUBJS.core.addScript(EPUBJS.filePath + "jquery.min.js", null, renderer.doc.head); 4 | EPUBJS.core.addScript(EPUBJS.filePath + "protection.js", null, renderer.doc.head); 5 | 6 | if(callback) callback(); 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/epubjs/js/hooks/extensions/book_styles.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").bookStyles = function(callback, renderer){ 2 | 3 | var s = document.createElement("style"); 4 | s.innerHTML ="* { box-sizing: border-box };\n"+ 5 | "html, body { margin:0; padding:0; }\n"; 6 | renderer.render.document.head.appendChild(s); 7 | 8 | if(callback) callback(); 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/epubjs/js/hooks/extensions/highlight.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").highlight = function(callback, renderer){ 2 | 3 | // EPUBJS.core.addScript("js/libs/jquery.highlight.js", null, renderer.doc.head); 4 | 5 | var s = document.createElement("style"); 6 | s.innerHTML =".highlight { background: yellow; font-weight: normal; }"; 7 | 8 | renderer.render.document.head.appendChild(s); 9 | 10 | if(callback) callback(); 11 | 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /public/epubjs/ebook/toc.ncx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Sample eBook 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /admin/js/epub-reader-admin.js: -------------------------------------------------------------------------------- 1 | (function( $ ) { 2 | 'use strict'; 3 | 4 | /** 5 | * All of the code for your admin-facing JavaScript source 6 | * should reside in this file. 7 | * 8 | * Note: It has been assumed you will write jQuery code here, so the 9 | * $ function reference has been prepared for usage within the scope 10 | * of this function. 11 | * 12 | * This enables you to define handlers, for when the DOM is ready: 13 | * 14 | * $(function() { 15 | * 16 | * }); 17 | * 18 | * When the window is loaded: 19 | * 20 | * $( window ).load(function() { 21 | * 22 | * }); 23 | * 24 | * ...and/or other possibilities. 25 | * 26 | * Ideally, it is not considered best practise to attach more than a 27 | * single DOM-ready or window-load handler for a particular page. 28 | * Although scripts in the WordPress core, Plugins and Themes may be 29 | * practising this, we should strive to set a better example in our own work. 30 | */ 31 | 32 | })( jQuery ); 33 | -------------------------------------------------------------------------------- /public/js/epub-reader-public.js: -------------------------------------------------------------------------------- 1 | (function( $ ) { 2 | 'use strict'; 3 | 4 | /** 5 | * All of the code for your public-facing JavaScript source 6 | * should reside in this file. 7 | * 8 | * Note: It has been assumed you will write jQuery code here, so the 9 | * $ function reference has been prepared for usage within the scope 10 | * of this function. 11 | * 12 | * This enables you to define handlers, for when the DOM is ready: 13 | * 14 | * $(function() { 15 | * 16 | * }); 17 | * 18 | * When the window is loaded: 19 | * 20 | * $( window ).load(function() { 21 | * 22 | * }); 23 | * 24 | * ...and/or other possibilities. 25 | * 26 | * Ideally, it is not considered best practise to attach more than a 27 | * single DOM-ready or window-load handler for a particular page. 28 | * Although scripts in the WordPress core, Plugins and Themes may be 29 | * practising this, we should strive to set a better example in our own work. 30 | */ 31 | 32 | })( jQuery ); 33 | -------------------------------------------------------------------------------- /public/css/epub-reader-public.css: -------------------------------------------------------------------------------- 1 | /** 2 | * epub-reader 3 | */ 4 | 5 | 6 | .epub-reader-frame { 7 | background: #fff; 8 | width: 100%; 9 | height: 100%; 10 | border:none; 11 | } 12 | 13 | /* ePub Reader Page specific */ 14 | html.epub-reader-html { 15 | } 16 | body.epub-reader-body { 17 | height: 100%; 18 | margin: 0; 19 | padding: 0; 20 | overflow: hidden; 21 | } 22 | body.epub-reader-body { 23 | background-color: #fff; 24 | } 25 | 26 | 27 | body:not(.epub-reader-body) { 28 | min-height: 300px; /* shortcode in a normal/other page */ 29 | } 30 | 31 | body.epub-reader-body .epub-reader-frame { 32 | margin: 0; 33 | padding: 0; 34 | /*z-index: 100000; higher than #wpadminbar */ 35 | position: absolute; 36 | top:0; 37 | left:0; 38 | } 39 | body.epub-reader-body::before, 40 | body.epub-reader-body::after { 41 | display: none; /* override some themes that use this! */ 42 | } 43 | body.epub-reader-body #wpadminbar { 44 | display: none; /* hide the admin bar -- it gets in the way of the frame's titlebar! */ 45 | } -------------------------------------------------------------------------------- /public/partials/epub-reader-public-shortcode.php: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /includes/class-epub-reader-i18n.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Epub_Reader_i18n { 28 | 29 | 30 | /** 31 | * Load the plugin text domain for translation. 32 | * 33 | * @since 0.9.0 34 | */ 35 | public function load_plugin_textdomain() { 36 | 37 | load_plugin_textdomain( 38 | 'epub-reader', 39 | false, 40 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' 41 | ); 42 | 43 | } 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | =0) 8 | return; 9 | //console.log("copy protection enabled") 10 | $('body').css({ 11 | cursor: 'default', 12 | 'user-select': 'none', 13 | '-moz-user-select': 'none', 14 | '-webkit-user-select': 'none', 15 | '-ms-user-select': 'none'} 16 | ); 17 | $(document).bind("cut copy paste",function(e) { 18 | e.preventDefault(); 19 | }); 20 | $("html,body").on("contextmenu",function(e){ 21 | e.preventDefault(); 22 | return false; 23 | }); 24 | $(window).keydown(function(e) { deKey('keydown', e); }); 25 | $(window).keyup(function(e) { deKey('keyup', e); }); 26 | 27 | var wasMetaKey = false; 28 | function deKey(name, e){ 29 | if(e.which == 44){ // printscr 30 | e.preventDefault(); 31 | } 32 | else if (e.metaKey) { 33 | e.preventDefault(); 34 | e.stopPropagation(); 35 | wasMetaKey = true; 36 | } 37 | else if (wasMetaKey) { 38 | e.preventDefault(); 39 | e.stopPropagation(); 40 | wasMetaKey = false; 41 | } 42 | } 43 | }); 44 | 45 | 46 | -------------------------------------------------------------------------------- /public/epubjs/ebook/content.opf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample eBook 5 | John Doe 6 | 0101-01-01T00:00:00+00:00 7 | calibre (1.28.0) [http://calibre-ebook.com] 8 | cc07aff7-0799-452a-abf2-b047b9840927 9 | en 10 | cc07aff7-0799-452a-abf2-b047b9840927 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /public/views/epub-reader-template.php: -------------------------------------------------------------------------------- 1 | 12 | class="no-js epub-reader-html"> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | > 26 | 27 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /public/epubjs/js/libs/screenfull.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v3.3.1 - 2017-07-07 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | 7 | !function(){"use strict";var a="undefined"!=typeof window&&void 0!==window.document?window.document:{},b="undefined"!=typeof module&&module.exports,c="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,d=function(){for(var b,c=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],d=0,e=c.length,f={};d p { 47 | margin-top: 0; 48 | } 49 | 50 | /* below */ 51 | .popup:before { 52 | position: absolute; 53 | display: inline-block; 54 | border-bottom: 10px solid #eee; 55 | border-right: 10px solid transparent; 56 | border-left: 10px solid transparent; 57 | border-bottom-color: rgba(0, 0, 0, 0.2); 58 | left: 50%; 59 | top: -10px; 60 | margin-left: -6px; 61 | content: ''; 62 | } 63 | 64 | .popup:after { 65 | position: absolute; 66 | display: inline-block; 67 | border-bottom: 9px solid #eee; 68 | border-right: 9px solid transparent; 69 | border-left: 9px solid transparent; 70 | left: 50%; 71 | top: -9px; 72 | margin-left: -5px; 73 | content: ''; 74 | } 75 | 76 | /* above */ 77 | .popup.above:before { 78 | border-bottom: none; 79 | border-top: 10px solid #eee; 80 | border-top-color: rgba(0, 0, 0, 0.2); 81 | top: 100%; 82 | } 83 | 84 | .popup.above:after { 85 | border-bottom: none; 86 | border-top: 9px solid #eee; 87 | top: 100%; 88 | } 89 | 90 | .popup.left:before, 91 | .popup.left:after 92 | { 93 | left: 20px; 94 | } 95 | 96 | .popup.right:before, 97 | .popup.right:after 98 | { 99 | left: auto; 100 | right: 20px; 101 | } 102 | 103 | 104 | .popup.show, .popup.on { 105 | display: block; 106 | } 107 | 108 | .footnotesuperscript { 109 | font-family: "Times New Roman", Georgia, Serif; 110 | } -------------------------------------------------------------------------------- /includes/class-epub-reader-activator.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Epub_Reader_Activator { 24 | 25 | /** 26 | * Short Description. (use period) 27 | * 28 | * Long Description. 29 | * 30 | * @since 0.9.0 31 | */ 32 | public static function activate() { 33 | require_once 'class-epub-reader-posttype.php'; 34 | $pt = new Epub_Reader_PostType(); 35 | $pt->register_post_type(); 36 | 37 | // Page Arguments 38 | $page_args = array( 39 | 'post_title' => __( 'ebook Demo', 'ebook-demo' ), 40 | 'post_content' => '[epub-reader src="wp-content/plugins/epub-reader/public/epubjs/ebook"]', 41 | 'post_status' => 'publish', 42 | 'post_type' => EPUB_READER_POSTTYPE 43 | ); 44 | // Insert the page and get its id. 45 | $_page_id = wp_insert_post( $page_args ); 46 | // Save page id to the database. 47 | add_option( 'epub_reader_page_id', $_page_id ); 48 | 49 | flush_rewrite_rules(); 50 | } 51 | 52 | /** 53 | * Called when the plugin is deactivated. 54 | * 55 | * @since 0.9.0 56 | */ 57 | public static function deactivate() { 58 | // Get Saved page id. 59 | $_page_id = get_option( 'epub_reader_page_id' ); 60 | 61 | // Check if the saved page id exists. 62 | if ( $_page_id ) { 63 | 64 | // Delete saved page. 65 | wp_delete_post( $_page_id, true ); 66 | 67 | // Delete saved page id record in the database. 68 | delete_option( 'epub_reader_page_id' ); 69 | 70 | } 71 | flush_rewrite_rules(); 72 | } 73 | 74 | /** 75 | * Called when the plugin is updated. 76 | * 77 | * @since 0.9.19 78 | */ 79 | public static function updated() { 80 | if ( function_exists('wp_cache_flush') ) 81 | wp_cache_flush(); 82 | 83 | if ( function_exists('w3tc_pgcache_flush') ) 84 | w3tc_pgcache_flush(); 85 | 86 | if ( function_exists('wp_cache_clear_cache') ) 87 | wp_cache_clear_cache(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /admin/partials/epub-reader-admin-display.php: -------------------------------------------------------------------------------- 1 | 15 | 19 | 20 | 21 |

ePub Reader Shortcode

22 |

The following attributes can be specified in the shortcode [epub-reader]:

23 | 24 |
25 |
src
Defaults to 'epub/', which correlates to http://<wp-install-location>/epub/. Note that the path is always relative to the wordpress installation. Full URL's are not supported at this time.
26 |
version
Set a version of the book. Major changes (eg new chapters) should increase this value. eg. version="2-beta".
27 | Note: This has the effect of causing each user's individual reading position to be reset. However failure to do so will cause unexpected errors to the user's reading experience if the changes are large.
28 |
width
Set the width of the widget. eg width="300px".
29 |
height
Set the height of the region. eg height="480px".
30 |
style
Set any css style on the region directly. eg style="min-height:480px".
31 |
class
Set any css class on the region. eg class="some-ebook-class".
32 |
33 | 34 |

Examples

35 |
    36 |
  1. [epub-reader src="uploads/Wuthering_Heights.epub"]. (Loads the compressed book from http://<wp-install-location>/uploads/Wuthering_Heights.epub. Note this is very inefficient!)
  2. 37 |
  3. [epub-reader src="epubs/Wuthering_Heights/"]. (Loads from an unpacked epub http://<wp-install-location>/epubs/Wuthering_Heights/. This is the most efficient method)
  4. 38 |
39 | 40 |
41 |
42 | 50 |
51 |
-------------------------------------------------------------------------------- /public/epubjs/js/plugins/hypothesis.js: -------------------------------------------------------------------------------- 1 | // Hypothesis Customized embedding 2 | // This hypothesis config function returns a new constructor which modifies 3 | // annotator for a better integration. Below we create our own EpubAnnotationSidebar 4 | // Constructor, customizing the show and hide function to take acount for the reader UI. 5 | 6 | window.hypothesisConfig = function() { 7 | var Annotator = window.Annotator; 8 | var $main = $("#main"); 9 | 10 | function EpubAnnotationSidebar(elem, options) { 11 | options = { 12 | server: true, 13 | origin: true, 14 | showHighlights: true, 15 | Toolbar: {container: '#annotation-controls'} 16 | } 17 | 18 | Annotator.Host.call(this, elem, options); 19 | } 20 | 21 | EpubAnnotationSidebar.prototype = Object.create(Annotator.Host.prototype); 22 | 23 | EpubAnnotationSidebar.prototype.show = function() { 24 | this.frame.css({ 25 | 'margin-left': (-1 * this.frame.width()) + "px" 26 | }); 27 | this.frame.removeClass('annotator-collapsed'); 28 | if (!$main.hasClass('single')) { 29 | $main.addClass("single"); 30 | this.toolbar.find('[name=sidebar-toggle]').removeClass('h-icon-chevron-left').addClass('h-icon-chevron-right'); 31 | this.setVisibleHighlights(true); 32 | } 33 | }; 34 | 35 | EpubAnnotationSidebar.prototype.hide = function() { 36 | this.frame.css({ 37 | 'margin-left': '' 38 | }); 39 | this.frame.addClass('annotator-collapsed'); 40 | if ($main.hasClass('single')) { 41 | $main.removeClass("single"); 42 | this.toolbar.find('[name=sidebar-toggle]').removeClass('h-icon-chevron-right').addClass('h-icon-chevron-left'); 43 | this.setVisibleHighlights(false); 44 | } 45 | }; 46 | 47 | return { 48 | constructor: EpubAnnotationSidebar, 49 | } 50 | }; 51 | 52 | // This is the Epub.js plugin. Annotations are updated on location change. 53 | EPUBJS.reader.plugins.HypothesisController = function (Book) { 54 | var reader = this; 55 | var $main = $("#main"); 56 | 57 | var updateAnnotations = function () { 58 | var annotator = Book.renderer.render.window.annotator; 59 | if (annotator && annotator.constructor.$) { 60 | var annotations = getVisibleAnnotations(annotator.constructor.$); 61 | annotator.showAnnotations(annotations) 62 | } 63 | }; 64 | 65 | var getVisibleAnnotations = function ($) { 66 | var width = Book.renderer.render.iframe.clientWidth; 67 | return $('.annotator-hl').map(function() { 68 | var $this = $(this), 69 | left = this.getBoundingClientRect().left; 70 | 71 | if (left >= 0 && left <= width) { 72 | return $this.data('annotation'); 73 | } 74 | }).get(); 75 | }; 76 | 77 | Book.on("renderer:locationChanged", updateAnnotations); 78 | 79 | return {} 80 | }; 81 | -------------------------------------------------------------------------------- /public/epubjs/js/plugins/search.js: -------------------------------------------------------------------------------- 1 | EPUBJS.reader.search = {}; 2 | 3 | // Search Server -- https://github.com/futurepress/epubjs-search 4 | EPUBJS.reader.search.SERVER = "https://pacific-cliffs-3579.herokuapp.com"; 5 | 6 | EPUBJS.reader.search.request = function(q, callback) { 7 | var fetch = $.ajax({ 8 | dataType: "json", 9 | url: EPUBJS.reader.search.SERVER + "/search?q=" + encodeURIComponent(q) 10 | }); 11 | 12 | fetch.fail(function(err) { 13 | console.error(err); 14 | }); 15 | 16 | fetch.done(function(results) { 17 | callback(results); 18 | }); 19 | }; 20 | 21 | EPUBJS.reader.plugins.SearchController = function(Book) { 22 | var reader = this; 23 | 24 | var $searchBox = $("#searchBox"), 25 | $searchResults = $("#searchResults"), 26 | $searchView = $("#searchView"), 27 | iframeDoc; 28 | 29 | var searchShown = false; 30 | 31 | var onShow = function() { 32 | query(); 33 | searchShown = true; 34 | $searchView.addClass("shown"); 35 | }; 36 | 37 | var onHide = function() { 38 | searchShown = false; 39 | $searchView.removeClass("shown"); 40 | }; 41 | 42 | var query = function() { 43 | var q = $searchBox.val(); 44 | 45 | if(q == '') { 46 | return; 47 | } 48 | 49 | $searchResults.empty(); 50 | $searchResults.append("
  • Searching...

  • "); 51 | 52 | 53 | 54 | EPUBJS.reader.search.request(q, function(data) { 55 | var results = data.results; 56 | 57 | $searchResults.empty(); 58 | 59 | if(iframeDoc) { 60 | $(iframeDoc).find('body').unhighlight(); 61 | } 62 | 63 | if(results.length == 0) { 64 | $searchResults.append("
  • No Results Found

  • "); 65 | return; 66 | } 67 | 68 | iframeDoc = $("#viewer iframe")[0].contentDocument; 69 | $(iframeDoc).find('body').highlight(q, { element: 'span' }); 70 | 71 | results.forEach(function(result) { 72 | var $li = $("
  • "); 73 | var $item = $(""+result.title+"

    "+result.highlight+"

    "); 74 | 75 | $item.on("click", function(e) { 76 | var $this = $(this), 77 | cfi = $this.data("cfi"); 78 | 79 | e.preventDefault(); 80 | 81 | Book.gotoCfi(cfi+"/1:0"); 82 | 83 | Book.on("renderer:chapterDisplayed", function() { 84 | iframeDoc = $("#viewer iframe")[0].contentDocument; 85 | $(iframeDoc).find('body').highlight(q, { element: 'span' }); 86 | }) 87 | 88 | 89 | 90 | }); 91 | $li.append($item); 92 | $searchResults.append($li); 93 | }); 94 | 95 | }); 96 | 97 | }; 98 | 99 | $searchBox.on("search", function(e) { 100 | var q = $searchBox.val(); 101 | 102 | //-- SearchBox is empty or cleared 103 | if(q == '') { 104 | $searchResults.empty(); 105 | if(reader.SidebarController.getActivePanel() == "Search") { 106 | reader.SidebarController.changePanelTo("Toc"); 107 | } 108 | 109 | $(iframeDoc).find('body').unhighlight(); 110 | iframeDoc = false; 111 | return; 112 | } 113 | 114 | reader.SidebarController.changePanelTo("Search"); 115 | 116 | e.preventDefault(); 117 | }); 118 | 119 | 120 | 121 | return { 122 | "show" : onShow, 123 | "hide" : onHide 124 | }; 125 | }; 126 | -------------------------------------------------------------------------------- /epub-reader.php: -------------------------------------------------------------------------------- 1 | run(); 98 | 99 | } 100 | run_epub_reader(); 101 | -------------------------------------------------------------------------------- /public/epubjs/js/hooks.min.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").endnotes=function(a,b){var c=b.contents.querySelectorAll("a[href]"),d=Array.prototype.slice.call(c),e=EPUBJS.core.folder(location.pathname),f=(EPUBJS.cssPath,{});EPUBJS.core.addCss(EPUBJS.cssPath+"popup.css",!1,b.render.document.head),d.forEach(function(a){function c(){var c,h,n=b.height,o=b.width,p=225;m||(c=j.cloneNode(!0),m=c.querySelector("p")),f[i]||(f[i]=document.createElement("div"),f[i].setAttribute("class","popup"),pop_content=document.createElement("div"),f[i].appendChild(pop_content),pop_content.appendChild(m),pop_content.setAttribute("class","pop_content"),b.render.document.body.appendChild(f[i]),f[i].addEventListener("mouseover",d,!1),f[i].addEventListener("mouseout",e,!1),b.on("renderer:pageChanged",g,this),b.on("renderer:pageChanged",e,this)),c=f[i],h=a.getBoundingClientRect(),k=h.left,l=h.top,c.classList.add("show"),popRect=c.getBoundingClientRect(),c.style.left=k-popRect.width/2+"px",c.style.top=l+"px",p>n/2.5&&(p=n/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),k-popRect.width<=0?(c.style.left=k+"px",c.classList.add("left")):c.classList.remove("left"),k+popRect.width/2>=o?(c.style.left=k-300+"px",popRect=c.getBoundingClientRect(),c.style.left=k-popRect.width+"px",popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){f[i].classList.add("on")}function e(){f[i].classList.remove("on")}function g(){setTimeout(function(){f[i].classList.remove("show")},100)}var h,i,j,k,l,m;"noteref"==a.getAttribute("epub:type")&&(h=a.getAttribute("href"),i=h.replace("#",""),j=b.render.document.getElementById(i),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",g,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(-1!==b.currentChapter.manifestProperties.indexOf("mathml")){b.render.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;if("reflowable"!=b.layoutSettings.layout)return void a();d.forEach(function(a){var c=function(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,g<0&&(g=0),a.style.maxWidth="100%",i+g>=e?(ge&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))},d=function(){b.off("renderer:resized",c),b.off("renderer:chapterUnload",this)};a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnload",d),c()}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]");Array.prototype.slice.call(c).forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()}; -------------------------------------------------------------------------------- /public/epubjs/js/libs/screenfull.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v3.3.1 - 2017-07-07 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | (function () { 7 | 'use strict'; 8 | 9 | var document = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? window.document : {}; 10 | var isCommonjs = typeof module !== 'undefined' && module.exports; 11 | var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element; 12 | 13 | var fn = (function () { 14 | var val; 15 | 16 | var fnMap = [ 17 | [ 18 | 'requestFullscreen', 19 | 'exitFullscreen', 20 | 'fullscreenElement', 21 | 'fullscreenEnabled', 22 | 'fullscreenchange', 23 | 'fullscreenerror' 24 | ], 25 | // New WebKit 26 | [ 27 | 'webkitRequestFullscreen', 28 | 'webkitExitFullscreen', 29 | 'webkitFullscreenElement', 30 | 'webkitFullscreenEnabled', 31 | 'webkitfullscreenchange', 32 | 'webkitfullscreenerror' 33 | 34 | ], 35 | // Old WebKit (Safari 5.1) 36 | [ 37 | 'webkitRequestFullScreen', 38 | 'webkitCancelFullScreen', 39 | 'webkitCurrentFullScreenElement', 40 | 'webkitCancelFullScreen', 41 | 'webkitfullscreenchange', 42 | 'webkitfullscreenerror' 43 | 44 | ], 45 | [ 46 | 'mozRequestFullScreen', 47 | 'mozCancelFullScreen', 48 | 'mozFullScreenElement', 49 | 'mozFullScreenEnabled', 50 | 'mozfullscreenchange', 51 | 'mozfullscreenerror' 52 | ], 53 | [ 54 | 'msRequestFullscreen', 55 | 'msExitFullscreen', 56 | 'msFullscreenElement', 57 | 'msFullscreenEnabled', 58 | 'MSFullscreenChange', 59 | 'MSFullscreenError' 60 | ] 61 | ]; 62 | 63 | var i = 0; 64 | var l = fnMap.length; 65 | var ret = {}; 66 | 67 | for (; i < l; i++) { 68 | val = fnMap[i]; 69 | if (val && val[1] in document) { 70 | for (i = 0; i < val.length; i++) { 71 | ret[fnMap[0][i]] = val[i]; 72 | } 73 | return ret; 74 | } 75 | } 76 | 77 | return false; 78 | })(); 79 | 80 | var eventNameMap = { 81 | change: fn.fullscreenchange, 82 | error: fn.fullscreenerror 83 | }; 84 | 85 | var screenfull = { 86 | request: function (elem) { 87 | var request = fn.requestFullscreen; 88 | 89 | elem = elem || document.documentElement; 90 | 91 | // Work around Safari 5.1 bug: reports support for 92 | // keyboard in fullscreen even though it doesn't. 93 | // Browser sniffing, since the alternative with 94 | // setTimeout is even worse. 95 | if (/5\.1[.\d]* Safari/.test(navigator.userAgent)) { 96 | elem[request](); 97 | } else { 98 | elem[request](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT); 99 | } 100 | }, 101 | exit: function () { 102 | document[fn.exitFullscreen](); 103 | }, 104 | toggle: function (elem) { 105 | if (this.isFullscreen) { 106 | this.exit(); 107 | } else { 108 | this.request(elem); 109 | } 110 | }, 111 | onchange: function (callback) { 112 | this.on('change', callback); 113 | }, 114 | onerror: function (callback) { 115 | this.on('error', callback); 116 | }, 117 | on: function (event, callback) { 118 | var eventName = eventNameMap[event]; 119 | if (eventName) { 120 | document.addEventListener(eventName, callback, false); 121 | } 122 | }, 123 | off: function (event, callback) { 124 | var eventName = eventNameMap[event]; 125 | if (eventName) { 126 | document.removeEventListener(eventName, callback, false); 127 | } 128 | }, 129 | raw: fn 130 | }; 131 | 132 | if (!fn) { 133 | if (isCommonjs) { 134 | module.exports = false; 135 | } else { 136 | window.screenfull = false; 137 | } 138 | 139 | return; 140 | } 141 | 142 | Object.defineProperties(screenfull, { 143 | isFullscreen: { 144 | get: function () { 145 | return Boolean(document[fn.fullscreenElement]); 146 | } 147 | }, 148 | element: { 149 | enumerable: true, 150 | get: function () { 151 | return document[fn.fullscreenElement]; 152 | } 153 | }, 154 | enabled: { 155 | enumerable: true, 156 | get: function () { 157 | // Coerce to boolean in case of old WebKit 158 | return Boolean(document[fn.fullscreenEnabled]); 159 | } 160 | } 161 | }); 162 | 163 | if (isCommonjs) { 164 | module.exports = screenfull; 165 | } else { 166 | window.screenfull = screenfull; 167 | } 168 | })(); 169 | -------------------------------------------------------------------------------- /public/epubjs/js/libs/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Highlight plugin 3 | * 4 | * Based on highlight v3 by Johann Burkard 5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 6 | * 7 | * Code a little bit refactored and cleaned (in my humble opinion). 8 | * Most important changes: 9 | * - has an option to highlight only entire words (wordsOnly - false by default), 10 | * - has an option to be case sensitive (caseSensitive - false by default) 11 | * - highlight element tag and class names can be specified in options 12 | * 13 | * Usage: 14 | * // wrap every occurrance of text 'lorem' in content 15 | * // with (default options) 16 | * $('#content').highlight('lorem'); 17 | * 18 | * // search for and highlight more terms at once 19 | * // so you can save some time on traversing DOM 20 | * $('#content').highlight(['lorem', 'ipsum']); 21 | * $('#content').highlight('lorem ipsum'); 22 | * 23 | * // search only for entire word 'lorem' 24 | * $('#content').highlight('lorem', { wordsOnly: true }); 25 | * 26 | * // don't ignore case during search of term 'lorem' 27 | * $('#content').highlight('lorem', { caseSensitive: true }); 28 | * 29 | * // wrap every occurrance of term 'ipsum' in content 30 | * // with 31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); 32 | * 33 | * // remove default highlight 34 | * $('#content').unhighlight(); 35 | * 36 | * // remove custom highlight 37 | * $('#content').unhighlight({ element: 'em', className: 'important' }); 38 | * 39 | * 40 | * Copyright (c) 2009 Bartek Szopka 41 | * 42 | * Licensed under MIT license. 43 | * 44 | */ 45 | 46 | jQuery.extend({ 47 | highlight: function (node, re, nodeName, className) { 48 | if (node.nodeType === 3) { 49 | var match = node.data.match(re); 50 | if (match) { 51 | var highlight = document.createElement(nodeName || 'span'); 52 | highlight.className = className || 'highlight'; 53 | var wordNode = node.splitText(match.index); 54 | wordNode.splitText(match[0].length); 55 | var wordClone = wordNode.cloneNode(true); 56 | highlight.appendChild(wordClone); 57 | wordNode.parentNode.replaceChild(highlight, wordNode); 58 | return 1; //skip added node in parent 59 | } 60 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 61 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 62 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 63 | for (var i = 0; i < node.childNodes.length; i++) { 64 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 65 | } 66 | } 67 | return 0; 68 | } 69 | }); 70 | 71 | jQuery.fn.unhighlight = function (options) { 72 | var settings = { className: 'highlight', element: 'span' }; 73 | jQuery.extend(settings, options); 74 | 75 | return this.find(settings.element + "." + settings.className).each(function () { 76 | var parent = this.parentNode; 77 | parent.replaceChild(this.firstChild, this); 78 | parent.normalize(); 79 | }).end(); 80 | }; 81 | 82 | jQuery.fn.highlight = function (words, options) { 83 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 84 | jQuery.extend(settings, options); 85 | 86 | if (words.constructor === String) { 87 | words = [words]; 88 | } 89 | words = jQuery.grep(words, function(word, i){ 90 | return word != ''; 91 | }); 92 | words = jQuery.map(words, function(word, i) { 93 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 94 | }); 95 | if (words.length == 0) { return this; }; 96 | 97 | var flag = settings.caseSensitive ? "" : "i"; 98 | var pattern = "(" + words.join("|") + ")"; 99 | if (settings.wordsOnly) { 100 | pattern = "\\b" + pattern + "\\b"; 101 | } 102 | var re = new RegExp(pattern, flag); 103 | 104 | return this.each(function () { 105 | jQuery.highlight(this, re, settings.element, settings.className); 106 | }); 107 | }; 108 | 109 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | === ePub Reader === 2 | Contributors: cmroanirgo 3 | Donate link: https://kodespace.com 4 | Tags: epub 5 | Requires WP: 3.0.1 6 | Tested up to: 4.8.2 7 | Stable tag: master 8 | License: GPLv2 or later 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | An ePub Reader for your WordPress posts and pages. 12 | 13 | == Description == 14 | 15 | An ePub Reader for WordPress. This plugin provides a simple shortcode entry as well as a custom post type to give you control over how the epub is displayed. 16 | 17 | The underlying code uses a fork of the framework provided by [Futurepress' epub.js](https://github.com/futurepress/epub.js). 18 | 19 | === Note === 20 | 21 | There are two ways this plugin can read an epub: 22 | 23 | 1. As an `.epub`. This is clearly the easiest way, just upload and link to the file directly. However, this is *not* the most efficient way for the user (because extra code is needed to download the whole epub in one go and the unzip it and *then* their browser can use it). 24 | 1. As an extracted `.epub`. Upload the epub as normal, but use an 'unzip' tool to extract the contents of the epub to files and folders on your server. This is the most efficient for the end user. (It also has the benefit of stopping 3rd parties easily downloading the whole book easily, if that's important to you). 25 | 26 | 27 | === Short Code === 28 | 29 | Just drop in the shortcode into your blog posts or pages to embed an iFrame with fullscreen reader capabilities. 30 | 31 | eg. 32 | 33 | `[epub-reader src="some/path.epub" width="640" height="480"]` 34 | 35 | 36 | === Custom Post Type === 37 | 38 | In the admin area, you'll see 'ePub Reader Pages' which are pages that are designed to give a full-browser view of the epub. These pages are largely theme-indepdendant. 39 | 40 | 41 | == Installation == 42 | 43 | This section describes how to install the plugin and get it working. Choose one method. 44 | 45 | 46 | ## Use Github Updater 47 | 48 | If you have already installed [Github Updater](https://github.com/afragen/github-updater), then use that. 49 | 50 | 1. Open Github Updater settings and click the 'Install Plugin' tab. 51 | 2. Enter `cmroanirgo/epub-reader` as the Plugin URI and then Install. 52 | 3. Go to the Plugins screen and click __Activate__. 53 | 54 | If you do not have [Github Updater](https://github.com/afragen/github-updater), then you may wish to do so. It is the recommended way to install and keep up-to-date. 55 | 56 | ### Upload 57 | 58 | 1. Download the latest [tagged archive](cmroanirgo/epub-reader/releases/latest) (choose the "zip" option). 59 | 2. Unzip the archive, rename the folder correctly to `epub-reader`, then re-zip the file. 60 | 3. Go to the __Plugins -> Add New__ screen and click the __Upload__ tab. 61 | 4. Upload the zipped archive directly. 62 | 5. Go to the Plugins screen and click __Activate__. 63 | 64 | ### Manual 65 | 66 | 1. Download the latest [tagged archive](cmroanirgo/epub-reader/releases/latest) (choose the "zip" option). 67 | 2. Unzip the archive, rename the folder to `epub-reader`. 68 | 3. Copy the folder to your `/wp-content/plugins/` directory. 69 | 4. Go to the Plugins screen and click __Activate__. 70 | 71 | Check out the Codex for more information about [installing plugins manually](http://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation). 72 | 73 | ### Git 74 | 75 | 1. Using git, browse to your `/wp-content/plugins/` directory and clone this repository: 76 | 77 | `git clone https://github.com/cmroanirgo/epub-reader.git` 78 | 79 | 2. Go to the Plugins screen and click __Activate__. 80 | 81 | == Usage == 82 | 83 | 1. Place `[epub-reader src="some/path.epub"]` in your posts or pages, OR you can also use 'ePub Reader Pages' 84 | 85 | 86 | == Frequently Asked Questions == 87 | 88 | = Does it have full browser support? = 89 | 90 | Unfortunately, the underlying epub.js library has [several known IE incompatibilities](https://github.com/futurepress/epub.js#internet-explorer). However, in general the plugin should work on most modern browsers and phones without issue. 91 | 92 | = Does it support mobile devices? = 93 | 94 | Yes. Although there may be some issues, the plugin is responsive in design and reflows accordingly. 95 | 96 | = What shortcode options are there? = 97 | 98 | The shortcode supports the following attributes: 99 | 100 | 1. src="path/to/epub". This is mandatory 101 | 102 | == Screenshots == 103 | 104 | !https://kodespace.com/epub-reader/images/screenshot1.png! 105 | 106 | == Changelog == 107 | 108 | = 0.9.1 = 109 | * Updated README 110 | * Fixed github repo location 111 | * Added support for github updater 112 | 113 | = 0.9.0 = 114 | * Alpha Release 115 | 116 | == Upgrade Notice == 117 | 118 | == Thanks == 119 | 120 | Thanks to: 121 | 122 | * [Futurepress' epub.js](https://github.com/futurepress/epub.js) 123 | -------------------------------------------------------------------------------- /public/class-epub-reader-public.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Epub_Reader_Public { 26 | 27 | /** 28 | * The ID of this plugin. 29 | * 30 | * @since 0.9.0 31 | * @access private 32 | * @var string $plugin_name The ID of this plugin. 33 | */ 34 | private $plugin_name; 35 | 36 | /** 37 | * The version of this plugin. 38 | * 39 | * @since 0.9.0 40 | * @access private 41 | * @var string $version The current version of this plugin. 42 | */ 43 | private $version; 44 | 45 | /** 46 | * Initialize the class and set its properties. 47 | * 48 | * @since 0.9.0 49 | * @param string $plugin_name The name of the plugin. 50 | * @param string $version The version of this plugin. 51 | */ 52 | public function __construct( $plugin_name, $version ) { 53 | 54 | $this->plugin_name = $plugin_name; 55 | $this->version = $version; 56 | 57 | } 58 | 59 | public function init( $loader ) { 60 | // Add our Shortcode 61 | $loader->add_shortcode( EPUB_READER_SHORTCODE, $this, 'epub_reader_shortcode' ); 62 | $loader->add_action( 'wp_enqueue_scripts', $this, 'enqueue_styles' ); 63 | $loader->add_action( 'wp_enqueue_scripts', $this, 'enqueue_scripts' ); 64 | } 65 | 66 | /** 67 | * Register the stylesheets for the public-facing side of the site. 68 | * 69 | * @since 0.9.0 70 | */ 71 | public function enqueue_styles() { 72 | wp_register_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/epub-reader-public.css', array(), $this->version, 'all' ); 73 | 74 | } 75 | 76 | /** 77 | * Register the JavaScript for the public-facing side of the site. 78 | * 79 | * @since 0.9.0 80 | */ 81 | public function enqueue_scripts() { 82 | /* 83 | $epubjs_url = plugin_dir_url( __FILE__ ) . 'epubjs/'; 84 | wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/epub-reader-public.js', array( 'jquery' ), $this->version, false ); 85 | wp_register_script( $this->plugin_name . '-fs' , $epubjs_url . 'js/libs/screenfull.min.js', array( ), $this->version, false); 86 | wp_register_script( $this->plugin_name . '-epub-js', $epubjs_url . 'js/epub.min.js', array( ), $this->version, false); 87 | wp_register_script( $this->plugin_name . '-hooks' , $epubjs_url . 'js/hooks.min.js', array( ), $this->version, false); 88 | wp_register_script( $this->plugin_name . '-reader' , $epubjs_url . 'js/reader.min.js', array( ), $this->version, false); 89 | wp_register_script( $this->plugin_name . '-zip' , $epubjs_url . 'js/libs/zip.min.js', array( ), $this->version, false); 90 | */ 91 | } 92 | 93 | 94 | /** 95 | * Create Shortcode . 96 | * 97 | * @since 0.9.0 98 | */ 99 | public function epub_reader_shortcode($user_defined_attributes, $content, $shortcode_name) { 100 | wp_enqueue_style( $this->plugin_name); 101 | 102 | 103 | $attributes = shortcode_atts( 104 | array( 105 | 'src' => '/epub/', // a uri path 106 | 'version' => '1', 107 | 'width' => '', 108 | 'height' => '', 109 | 'class' => '', 110 | 'style' => '', 111 | 'zip' => '', 112 | ), 113 | $user_defined_attributes, 114 | EPUB_READER_SHORTCODE 115 | ); 116 | 117 | // do the processing 118 | if (empty( $attributes['src'] )) 119 | die ('src parameter to shortcode epub-reader must NOT be empty!'); 120 | 121 | $attributes['src'] = '/'.ltrim($attributes['src'], '/'); // ensure absolute path 122 | if ( !strstr($attributes['src'], '.epub')) 123 | $attributes['src'] = rtrim($attributes['src'], '/') . '/'; // ensure non-epubs end with a folder sep 124 | 125 | 126 | /* 127 | //$epubjs_url = plugin_dir_url( __FILE__ ) . 'epubjs/'; 128 | wp_enqueue_style( $this->plugin_name); 129 | //wp_enqueue_script( $this->plugin_name); 130 | wp_enqueue_script( $this->plugin_name . '-fs' ); 131 | wp_enqueue_script( $this->plugin_name . '-epub-js'); 132 | wp_enqueue_script( $this->plugin_name . '-hooks' ); 133 | wp_enqueue_script( $this->plugin_name . '-reader' ); 134 | if ($attributes['zip']) 135 | // add zip script if we're dealing directly with an .epub 136 | wp_enqueue_script( $this->plugin_name . '-zip' ); 137 | */ 138 | 139 | // Call the view file, capture it into the output buffer, and then return it. 140 | ob_start(); 141 | require plugin_dir_path( dirname( __FILE__ ) ) . 'public/partials/epub-reader-public-shortcode.php'; 142 | return ob_get_clean(); 143 | 144 | } 145 | 146 | 147 | } 148 | -------------------------------------------------------------------------------- /includes/class-epub-reader-posttype.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class Epub_Reader_PostType { 27 | 28 | public function init($loader) { //$loader is EPub_Reader_Loader 29 | $loader->add_action( 'init', $this, 'register_post_type' ); 30 | $loader->add_filter( 'default_content', $this, 'set_default_content', 10, 2 ); 31 | $loader->add_filter( 'single_template', $this, 'filter_page_template'); 32 | $loader->add_filter( 'page_template', $this, 'filter_page_template' ); 33 | } 34 | 35 | public function register_post_type() { 36 | 37 | $args = array ( 38 | 'label' => esc_html__( 'ePub Reader Pages', 'text-domain' ), 39 | 'labels' => array( 40 | 'menu_name' => esc_html__( 'ePub Reader Pages', 'text-domain' ), 41 | 'name_admin_bar' => esc_html__( 'ePub Reader Page', 'text-domain' ), 42 | 'add_new' => esc_html__( 'Add new', 'text-domain' ), 43 | 'add_new_item' => esc_html__( 'Add new ePub Reader Page', 'text-domain' ), 44 | 'new_item' => esc_html__( 'New ePub Reader Page', 'text-domain' ), 45 | 'edit_item' => esc_html__( 'Edit ePub Reader Page', 'text-domain' ), 46 | 'view_item' => esc_html__( 'View ePub Reader Page', 'text-domain' ), 47 | 'update_item' => esc_html__( 'Update ePub Reader Page', 'text-domain' ), 48 | 'all_items' => esc_html__( 'All ePub Reader Pages', 'text-domain' ), 49 | 'search_items' => esc_html__( 'Search ePub Reader Pages', 'text-domain' ), 50 | 'parent_item_colon' => esc_html__( 'Parent ePub Reader Page', 'text-domain' ), 51 | 'not_found' => esc_html__( 'No ePub Reader Pages found', 'text-domain' ), 52 | 'not_found_in_trash' => esc_html__( 'No ePub Reader Pages found in Trash', 'text-domain' ), 53 | 'name' => esc_html__( 'ePub Reader Pages', 'text-domain' ), 54 | 'singular_name' => esc_html__( 'ePub Reader Page', 'text-domain' ), 55 | ), 56 | 'public' => true, 57 | 'description' => 'Pages for an epub reader', 58 | 'exclude_from_search' => true, 59 | 'publicly_queryable' => true, 60 | 'show_ui' => true, 61 | 'show_in_nav_menus' => true, 62 | 'show_in_menu' => true, 63 | 'show_in_admin_bar' => false, 64 | 'show_in_rest' => false, 65 | 'menu_position' => 11, 66 | 'menu_icon' => 'dashicons-book-alt', 67 | 'capability_type' => 'post', 68 | 'hierarchical' => false, 69 | 'has_archive' => false, 70 | 'query_var' => true, 71 | 'can_export' => true, 72 | 'rewrite_slug' => 'ebook', 73 | 'rewrite_no_front' => true, 74 | 'supports' => array( 75 | 'title', 76 | 'editor', 77 | //'custom-fields', 78 | 'page-attributes', 79 | ), 80 | 'rewrite' => array( 81 | 'slug' => 'ebook', 82 | 'with_front' => false, 83 | 'feeds' => true 84 | ), 85 | ); 86 | 87 | register_post_type( EPUB_READER_POSTTYPE, $args ); 88 | 89 | // todo: http://blog.teamtreehouse.com/create-your-first-wordpress-custom-post-type 90 | 91 | /* 92 | if(false && function_exists("register_field_group")) 93 | { 94 | register_field_group(array ( 95 | 'id' => 'acf_epub', 96 | 'title' => 'ePub', 97 | 'fields' => array ( 98 | array ( 99 | 'key' => 'field_59db6f6f41f50', 100 | 'label' => 'Path', 101 | 'name' => 'path', 102 | 'type' => 'text', 103 | 'instructions' => 'Select the path to the expanded epub, eg \'epubs/Wuthering_Heights/\'', 104 | 'required' => 1, 105 | 'default_value' => '', 106 | 'placeholder' => '', 107 | 'prepend' => '', 108 | 'append' => '', 109 | 'formatting' => 'html', 110 | 'maxlength' => '', 111 | ), 112 | array ( 113 | 'key' => 'field_59db6fdc41f51', 114 | 'label' => 'Allow Text Search', 115 | 'name' => 'allow_text_search', 116 | 'type' => 'true_false', 117 | 'instructions' => '(Warning! Experimental)', 118 | 'message' => '', 119 | 'default_value' => 0, 120 | ), 121 | array ( 122 | 'key' => 'field_59db7131fd7c3', 123 | 'label' => 'Allow Highlighting', 124 | 'name' => 'allow_highlighting', 125 | 'type' => 'true_false', 126 | 'instructions' => '(Warning! Experimental)', 127 | 'message' => '', 128 | 'default_value' => 0, 129 | ), 130 | array ( 131 | 'key' => 'field_59db7150fd7c4', 132 | 'label' => 'Allow Bookmarks', 133 | 'name' => 'allow_bookmarks', 134 | 'type' => 'true_false', 135 | 'instructions' => '(Warning! Experimental)', 136 | 'message' => '', 137 | 'default_value' => 0, 138 | ), 139 | ), 140 | 'location' => array ( 141 | array ( 142 | array ( 143 | 'param' => 'post_type', 144 | 'operator' => '==', 145 | 'value' => 'epub-page', 146 | 'order_no' => 0, 147 | 'group_no' => 0, 148 | ), 149 | ), 150 | ), 151 | 'options' => array ( 152 | 'position' => 'acf_after_title', 153 | 'layout' => 'no_box', 154 | 'hide_on_screen' => array ( 155 | 0 => 'the_content', 156 | ), 157 | ), 158 | 'menu_order' => 1, 159 | )); 160 | }*/ 161 | } 162 | 163 | public function set_default_content($content, $post) { // from https://wordpress.stackexchange.com/a/26028 164 | if ($post->post_type == EPUB_READER_POSTTYPE) 165 | $content = '['.EPUB_READER_SHORTCODE.' src="/path/to/ebook/" width="100%" height="100%"]'; 166 | 167 | return $content; 168 | } 169 | 170 | 171 | /** 172 | * Watch for our post_type & choose our page template (or use a global custom one if defined). 173 | * 174 | * @since 0.9.0 175 | */ 176 | public function filter_page_template( $page_template ) 177 | { 178 | global $post; 179 | 180 | if ($post->post_type == EPUB_READER_POSTTYPE ) { 181 | 182 | $single_postType_template = locate_template("single-epub-reader-page.php"); 183 | if( file_exists( $single_postType_template ) ) 184 | { 185 | return $single_postType_template; 186 | } 187 | else 188 | { 189 | $page_template = dirname( __FILE__ ) . '/../public/views/epub-reader-template.php'; 190 | } 191 | 192 | } 193 | return $page_template; 194 | } 195 | 196 | } 197 | 198 | -------------------------------------------------------------------------------- /includes/class-epub-reader-loader.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class Epub_Reader_Loader { 25 | 26 | /** 27 | * The array of actions registered with WordPress. 28 | * 29 | * @since 0.9.0 30 | * @access protected 31 | * @var array $actions The actions registered with WordPress to fire when the plugin loads. 32 | */ 33 | protected $actions; 34 | 35 | /** 36 | * The array of filters registered with WordPress. 37 | * 38 | * @since 0.9.0 39 | * @access protected 40 | * @var array $filters The filters registered with WordPress to fire when the plugin loads. 41 | */ 42 | protected $filters; 43 | /** 44 | * The array of shortcodes registered with WordPress. 45 | * 46 | * @since 0.9.0 47 | * @access protected 48 | * @var array $shortcodes The shortcodes registered with WordPress to fire when the plugin loads. 49 | */ 50 | protected $shortcodes; 51 | 52 | /** 53 | * Initialize the collections used to maintain the actions and filters. 54 | * 55 | * @since 0.9.0 56 | */ 57 | public function __construct() { 58 | 59 | $this->actions = array(); 60 | $this->filters = array(); 61 | $this->shortcodes = array(); 62 | } 63 | 64 | /** 65 | * Add a new action to the collection to be registered with WordPress. 66 | * 67 | * @since 0.9.0 68 | * @param string $hook The name of the WordPress action that is being registered. 69 | * @param object $component A reference to the instance of the object on which the action is defined. 70 | * @param string $callback The name of the function definition on the $component. 71 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10. 72 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. 73 | */ 74 | public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 75 | $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args ); 76 | } 77 | 78 | /** 79 | * Add a new filter to the collection to be registered with WordPress. 80 | * 81 | * @since 0.9.0 82 | * @param string $hook The name of the WordPress filter that is being registered. 83 | * @param object $component A reference to the instance of the object on which the filter is defined. 84 | * @param string $callback The name of the function definition on the $component. 85 | * @param int $priority Optional. The priority at which the function should be fired. Default is 10. 86 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 87 | */ 88 | public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 89 | $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); 90 | } 91 | 92 | 93 | /** 94 | * Add a new shortcode to the collection to be registered with WordPress. 95 | * 96 | * @since 0.9.0 97 | * @param string $hook The name of the WordPress shortcode that is being registered. 98 | * @param object $component A reference to the instance of the object on which the shortcode is defined. 99 | * @param string $callback The name of the function definition on the $component. 100 | * @param int $priority Optional. he priority at which the function should be fired. Default is 10. 101 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 102 | */ 103 | public function add_shortcode( $hook, $component, $callback ) { 104 | $this->shortcodes = $this->add( $this->shortcodes, $hook, $component, $callback, 10, 1 ); 105 | } 106 | 107 | 108 | 109 | /** 110 | * A utility function that is used to register the actions and hooks into a single 111 | * collection. 112 | * 113 | * @since 0.9.0 114 | * @access private 115 | * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). 116 | * @param string $hook The name of the WordPress filter that is being registered. 117 | * @param object $component A reference to the instance of the object on which the filter is defined. 118 | * @param string $callback The name of the function definition on the $component. 119 | * @param int $priority The priority at which the function should be fired. 120 | * @param int $accepted_args The number of arguments that should be passed to the $callback. 121 | * @return array The collection of actions and filters registered with WordPress. 122 | */ 123 | private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) { 124 | 125 | $hooks[] = array( 126 | 'hook' => $hook, 127 | 'component' => $component, 128 | 'callback' => $callback, 129 | 'priority' => $priority, 130 | 'accepted_args' => $accepted_args 131 | ); 132 | 133 | return $hooks; 134 | 135 | } 136 | 137 | /** 138 | * Register the filters and actions with WordPress. 139 | * 140 | * @since 0.9.0 141 | */ 142 | public function run() { 143 | 144 | foreach ( $this->filters as $hook ) { 145 | add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 146 | } 147 | 148 | foreach ( $this->actions as $hook ) { 149 | add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 150 | } 151 | 152 | foreach ( $this->shortcodes as $hook ) { 153 | add_shortcode( $hook['hook'], array( $hook['component'], $hook['callback'] ) ); 154 | } 155 | 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /includes/class-epub-reader.php: -------------------------------------------------------------------------------- 1 | 33 | */ 34 | class Epub_Reader { 35 | 36 | /** 37 | * The loader that's responsible for maintaining and registering all hooks that power 38 | * the plugin. 39 | * 40 | * @since 0.9.0 41 | * @access protected 42 | * @var Epub_Reader_Loader $loader Maintains and registers all hooks for the plugin. 43 | */ 44 | protected $loader; 45 | 46 | /** 47 | * The unique identifier of this plugin. 48 | * 49 | * @since 0.9.0 50 | * @access protected 51 | * @var string $plugin_name The string used to uniquely identify this plugin. 52 | */ 53 | protected $plugin_name; 54 | 55 | /** 56 | * The current version of the plugin. 57 | * 58 | * @since 0.9.0 59 | * @access protected 60 | * @var string $version The current version of the plugin. 61 | */ 62 | protected $version; 63 | 64 | /** 65 | * Define the core functionality of the plugin. 66 | * 67 | * Set the plugin name and the plugin version that can be used throughout the plugin. 68 | * Load the dependencies, define the locale, and set the hooks for the admin area and 69 | * the public-facing side of the site. 70 | * 71 | * @since 0.9.0 72 | */ 73 | public function __construct() { 74 | if ( defined( 'PLUGIN_NAME_VERSION' ) ) { 75 | $this->version = PLUGIN_NAME_VERSION; 76 | } else { 77 | $this->version = '0.9.0'; 78 | } 79 | $this->plugin_name = 'epub-reader'; 80 | 81 | $this->load_dependencies(); 82 | $this->set_locale(); 83 | $this->define_post_types(); 84 | $this->define_admin_hooks(); 85 | $this->define_public_hooks(); 86 | 87 | } 88 | 89 | /** 90 | * Load the required dependencies for this plugin. 91 | * 92 | * Include the following files that make up the plugin: 93 | * 94 | * - Epub_Reader_Loader. Orchestrates the hooks of the plugin. 95 | * - Epub_Reader_i18n. Defines internationalization functionality. 96 | * - Epub_Reader_Admin. Defines all hooks for the admin area. 97 | * - Epub_Reader_Public. Defines all hooks for the public side of the site. 98 | * 99 | * Create an instance of the loader which will be used to register the hooks 100 | * with WordPress. 101 | * 102 | * @since 0.9.0 103 | * @access private 104 | */ 105 | private function load_dependencies() { 106 | 107 | 108 | 109 | /** 110 | * The class responsible for orchestrating the actions and filters of the 111 | * core plugin. 112 | */ 113 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-epub-reader-loader.php'; 114 | 115 | /** 116 | * The class responsible for defining internationalization functionality 117 | * of the plugin. 118 | */ 119 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-epub-reader-i18n.php'; 120 | 121 | /** 122 | * The class responsible for defining the posttype 123 | * of the plugin. 124 | */ 125 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-epub-reader-posttype.php'; 126 | 127 | /** 128 | * The class responsible for defining all actions that occur in the admin area. 129 | */ 130 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-epub-reader-admin.php'; 131 | 132 | /** 133 | * The class responsible for defining all actions that occur in the public-facing 134 | * side of the site. 135 | */ 136 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-epub-reader-public.php'; 137 | 138 | $this->loader = new Epub_Reader_Loader(); 139 | 140 | } 141 | 142 | /** 143 | * Define the locale for this plugin for internationalization. 144 | * 145 | * Uses the Epub_Reader_i18n class in order to set the domain and to register the hook 146 | * with WordPress. 147 | * 148 | * @since 0.9.0 149 | * @access private 150 | */ 151 | private function set_locale() { 152 | 153 | $plugin_i18n = new Epub_Reader_i18n(); 154 | 155 | $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' ); 156 | 157 | } 158 | 159 | /** 160 | * Define the post_type for this plugin 161 | * 162 | * @since 0.9.0 163 | * @access private 164 | */ 165 | private function define_post_types() { 166 | $plugin_posttype = new Epub_Reader_PostType(); 167 | $plugin_posttype->init($this->loader); 168 | } 169 | 170 | 171 | 172 | /** 173 | * Register all of the hooks related to the admin area functionality 174 | * of the plugin. 175 | * 176 | * @since 0.9.0 177 | * @access private 178 | */ 179 | private function define_admin_hooks() { 180 | 181 | $plugin_admin = new Epub_Reader_Admin( $this->get_plugin_name(), $this->get_version() ); 182 | $plugin_admin->init($this->loader); 183 | 184 | } 185 | 186 | /** 187 | * Register all of the hooks related to the public-facing functionality 188 | * of the plugin. 189 | * 190 | * @since 0.9.0 191 | * @access private 192 | */ 193 | private function define_public_hooks() { 194 | 195 | $plugin_public = new Epub_Reader_Public( $this->get_plugin_name(), $this->get_version() ); 196 | $plugin_public->init($this->loader); 197 | } 198 | 199 | /** 200 | * Run the loader to execute all of the hooks with WordPress. 201 | * 202 | * @since 0.9.0 203 | */ 204 | public function run() { 205 | $this->loader->run(); 206 | } 207 | 208 | /** 209 | * The name of the plugin used to uniquely identify it within the context of 210 | * WordPress and to define internationalization functionality. 211 | * 212 | * @since 0.9.0 213 | * @return string The name of the plugin. 214 | */ 215 | public function get_plugin_name() { 216 | return $this->plugin_name; 217 | } 218 | 219 | /** 220 | * The reference to the class that orchestrates the hooks with the plugin. 221 | * 222 | * @since 0.9.0 223 | * @return Epub_Reader_Loader Orchestrates the hooks of the plugin. 224 | */ 225 | public function get_loader() { 226 | return $this->loader; 227 | } 228 | 229 | /** 230 | * Retrieve the version number of the plugin. 231 | * 232 | * @since 0.9.0 233 | * @return string The version number of the plugin. 234 | */ 235 | public function get_version() { 236 | return $this->version; 237 | } 238 | 239 | } 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /public/epubjs/font/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "epub-fontello", 3 | "css_prefix_text": "icon-", 4 | "css_use_suffix": false, 5 | "hinting": true, 6 | "units_per_em": 1000, 7 | "ascent": 850, 8 | "glyphs": [ 9 | { 10 | "uid": "559647a6f430b3aeadbecd67194451dd", 11 | "css": "menu", 12 | "code": 61641, 13 | "src": "fontawesome" 14 | }, 15 | { 16 | "uid": "5211af474d3a9848f67f945e2ccaf143", 17 | "css": "cancel", 18 | "code": 59392, 19 | "src": "fontawesome" 20 | }, 21 | { 22 | "uid": "9dd9e835aebe1060ba7190ad2b2ed951", 23 | "css": "search", 24 | "code": 59403, 25 | "src": "fontawesome" 26 | }, 27 | { 28 | "uid": "e594fc6e5870b4ab7e49f52571d52577", 29 | "css": "resize-full", 30 | "code": 59404, 31 | "src": "fontawesome" 32 | }, 33 | { 34 | "uid": "3c24ee33c9487bbf18796ca6dffa1905", 35 | "css": "resize-small", 36 | "code": 59405, 37 | "src": "fontawesome" 38 | }, 39 | { 40 | "uid": "48b87105bd38c20315f1b705b8c7b38c", 41 | "css": "list", 42 | "code": 59406, 43 | "src": "fontawesome" 44 | }, 45 | { 46 | "uid": "f04a5d24e9e659145b966739c4fde82a", 47 | "css": "bookmark", 48 | "code": 59407, 49 | "src": "fontawesome" 50 | }, 51 | { 52 | "uid": "2f5ef6f6b7aaebc56458ab4e865beff5", 53 | "css": "bookmark-empty", 54 | "code": 61591, 55 | "src": "fontawesome" 56 | }, 57 | { 58 | "uid": "d35a1d35efeb784d1dc9ac18b9b6c2b6", 59 | "css": "pencil", 60 | "code": 59408, 61 | "src": "fontawesome" 62 | }, 63 | { 64 | "uid": "41087bc74d4b20b55059c60a33bf4008", 65 | "css": "edit", 66 | "code": 59409, 67 | "src": "fontawesome" 68 | }, 69 | { 70 | "uid": "e99461abfef3923546da8d745372c995", 71 | "css": "cog", 72 | "code": 59393, 73 | "src": "fontawesome" 74 | }, 75 | { 76 | "uid": "21b42d3c3e6be44c3cc3d73042faa216", 77 | "css": "sliders", 78 | "code": 61918, 79 | "src": "fontawesome" 80 | }, 81 | { 82 | "uid": "297fe6c2ef08198b03d706ba52f51b7f", 83 | "css": "flight", 84 | "code": 59402, 85 | "src": "fontawesome" 86 | }, 87 | { 88 | "uid": "a2a74f5e7b7d9ba054897d8c795a326a", 89 | "css": "list-bullet", 90 | "code": 61642, 91 | "src": "fontawesome" 92 | }, 93 | { 94 | "uid": "d745d7c05b94e609decabade2cae12cb", 95 | "css": "quote-right", 96 | "code": 61710, 97 | "src": "fontawesome" 98 | }, 99 | { 100 | "uid": "5408be43f7c42bccee419c6be53fdef5", 101 | "css": "doc-text", 102 | "code": 61686, 103 | "src": "fontawesome" 104 | }, 105 | { 106 | "uid": "9755f76110ae4d12ac5f9466c9152031", 107 | "css": "book", 108 | "code": 59394, 109 | "src": "fontawesome" 110 | }, 111 | { 112 | "uid": "f6d72aa5ef8e8f0e553012af9a29a87e", 113 | "css": "left", 114 | "code": 61815, 115 | "src": "fontawesome" 116 | }, 117 | { 118 | "uid": "2e2dba0307a502a8507c1729084c7ab5", 119 | "css": "cancel-circled2", 120 | "code": 59395, 121 | "src": "fontawesome" 122 | }, 123 | { 124 | "uid": "d870630ff8f81e6de3958ecaeac532f2", 125 | "css": "left-open", 126 | "code": 59399, 127 | "src": "fontawesome" 128 | }, 129 | { 130 | "uid": "399ef63b1e23ab1b761dfbb5591fa4da", 131 | "css": "right-open", 132 | "code": 59400, 133 | "src": "fontawesome" 134 | }, 135 | { 136 | "uid": "f3f90c8c89795da30f7444634476ea4f", 137 | "css": "angle-left", 138 | "code": 61700, 139 | "src": "fontawesome" 140 | }, 141 | { 142 | "uid": "7bf14281af5633a597f85b061ef1cfb9", 143 | "css": "angle-right", 144 | "code": 61701, 145 | "src": "fontawesome" 146 | }, 147 | { 148 | "uid": "8933c2579166c2ee56ae40dc6a0b4dc6", 149 | "css": "angle-circled-left", 150 | "code": 61751, 151 | "src": "fontawesome" 152 | }, 153 | { 154 | "uid": "94089b37297572e936b0943bcfa041d3", 155 | "css": "angle-circled-right", 156 | "code": 61752, 157 | "src": "fontawesome" 158 | }, 159 | { 160 | "uid": "eeac355b1ea05c9aa9b71d9ebd4c6a61", 161 | "css": "font-down", 162 | "code": 59396, 163 | "src": "custom_icons", 164 | "selected": true, 165 | "svg": { 166 | "path": "M744.4 811.2L483.2 811.2 483.2 779.8C506.1 778.4 525.2 775.4 540.4 771 555.6 766.6 563.2 761.1 563.2 754.6 563.2 752 562.9 748.8 562.3 744.9 561.7 741.1 560.8 737.7 559.6 734.8L507.5 594.2 287.8 594.2C279.5 614.8 272.8 632.8 267.7 648.1 262.5 663.4 257.9 677.6 253.8 690.6 249.9 703.2 247.3 713.5 245.8 721.5 244.3 729.5 243.6 735.9 243.6 740.9 243.6 752.7 252.9 761.9 271.4 768.3 290 774.8 310.9 778.7 334.2 779.8L334.2 811.2 98.2 811.2 98.2 779.8C105.8 779.3 115.4 777.6 126.9 774.8 138.4 772 147.8 768.2 155.2 763.5 167 755.5 176.1 747.2 182.6 738.5 189.1 729.8 195.4 717.8 201.6 702.5 233.1 623.8 267.9 535.4 305.9 437.3 343.9 339.2 377.8 251.8 407.6 175.2L442.9 175.2 652 716.2C656.4 727.7 661.4 737 667 744 672.6 751.1 680.4 758 690.5 764.8 697.2 768.9 706.1 772.4 717 775.2 727.9 778 737 779.5 744.4 779.8L744.4 811.2ZM491.6 554.9L396.5 311.7 303.3 554.9 491.6 554.9ZM587 305.2L587 254.3 901.8 254.3 901.8 305.2 587 305.2Z", 167 | "width": 1000 168 | }, 169 | "search": [ 170 | "font-down" 171 | ] 172 | }, 173 | { 174 | "uid": "f50dd405fcde0f552faf08f8707b41d8", 175 | "css": "font-up", 176 | "code": 59397, 177 | "src": "custom_icons", 178 | "selected": true, 179 | "svg": { 180 | "path": "M780.2 865.2L471.9 865.2 471.9 828.2C499 826.4 521.5 823 539.5 817.7 557.4 812.5 566.3 806.1 566.3 798.4 566.3 795.3 566 791.5 565.3 787 564.6 782.4 563.5 778.4 562.1 775L500.6 609.1 241.3 609.1C231.6 633.4 223.7 654.6 217.6 672.7 211.5 690.8 206 707.5 201.1 722.8 196.6 737.8 193.5 749.9 191.8 759.3 190 768.7 189.1 776.4 189.1 782.3 189.1 796.2 200.1 807 222 814.6 243.9 822.3 268.6 826.8 296.1 828.2L296.1 865.2 17.5 865.2 17.5 828.2C26.6 827.5 37.9 825.5 51.4 822.2 65 818.9 76.1 814.4 84.8 808.9 98.7 799.5 109.5 789.7 117.2 779.4 124.8 769.1 132.3 755 139.6 736.9 176.8 644 217.8 539.7 262.7 423.9 307.6 308.1 347.6 204.9 382.7 114.5L424.4 114.5 671.2 753.1C676.4 766.6 682.3 777.6 688.9 785.9 695.5 794.3 704.7 802.4 716.6 810.4 724.6 815.3 735 819.4 747.9 822.7 760.7 826 771.5 827.8 780.2 828.2L780.2 865.2ZM481.8 562.6L369.7 275.7 259.6 562.6 481.8 562.6ZM751.4 253.6L612.3 253.6 612.3 307.9 751.4 307.9 751.4 450.4 805.7 450.4 805.7 307.9 948.2 307.9 948.2 253.6 805.7 253.6 805.7 114.5 751.4 114.5 751.4 253.6Z", 181 | "width": 1000 182 | }, 183 | "search": [ 184 | "font-up" 185 | ] 186 | }, 187 | { 188 | "uid": "e15f0d620a7897e2035c18c80142f6d9", 189 | "css": "link-ext", 190 | "code": 61582, 191 | "src": "fontawesome" 192 | }, 193 | { 194 | "uid": "e35de5ea31cd56970498e33efbcb8e36", 195 | "css": "link-ext-alt", 196 | "code": 61772, 197 | "src": "fontawesome" 198 | }, 199 | { 200 | "uid": "fa9a0b7e788c2d78e24cef1de6b70e80", 201 | "css": "brush", 202 | "code": 61948, 203 | "src": "fontawesome" 204 | }, 205 | { 206 | "uid": "97var6sq7rzo72ktzg1c6ph46u9pftbr", 207 | "css": "pencil-alt", 208 | "code": 59398, 209 | "src": "modernpics" 210 | } 211 | ] 212 | } -------------------------------------------------------------------------------- /public/epubjs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 109 | 110 | 111 | 112 | 139 |
    140 | 141 |
    142 |
    143 |   144 |
    145 |
    146 | 147 |  –  148 | 149 |
    150 |
    151 | A+ 152 | A- 153 | 154 | 155 |   156 |   157 |   158 |
    159 |
    160 |
    161 |
    162 | 163 | 164 |
    165 |
    166 |
    167 | 168 |
    169 |
    170 |
    171 | 182 |
    183 | 184 | 185 | -------------------------------------------------------------------------------- /public/epubjs/ebook/ch2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample eBook 5 | 6 | 7 |

    Chapter 2

    8 | 9 |

    Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

    10 | 11 |

    Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.

    12 | 13 |

    Header Level 2

    14 | 15 |
      16 |
    1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    2. 17 |
    3. Aliquam tincidunt mauris eu risus.
    4. 18 |
    19 | 20 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.

    21 | 22 |

    Header Level 3

    23 | 24 |
      25 |
    • Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    • 26 |
    • Aliquam tincidunt mauris eu risus.
    • 27 |
    28 | 29 |
    
    30 | #header h1 a {
    31 |   display: block;
    32 |   width: 300px;
    33 |   height: 80px;
    34 | }
    35 | 
    36 | 37 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    38 | 39 |

    Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Praesent mauris. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Mauris massa. Maecenas mattis. Sed convallis tristique sem. Vestibulum lacinia arcu eget nulla. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum.

    40 | 41 |

    Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices.

    42 | 43 |

    Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Suspendisse in justo eu magna luctus suscipit. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Mauris ipsum. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper.

    44 | 45 |

    Nulla facilisi. Integer lacinia sollicitudin massa. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Nulla facilisi. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo.

    46 | 47 | 48 | 49 |

    Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc.

    50 | 51 |

    Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    52 | 53 |

    Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam.

    54 | 55 |

    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi.

    56 | 57 |

    Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque.

    58 | 59 |

    Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.

    60 | 61 |

    Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem.

    62 | 63 |

    Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti.

    64 | 65 |

    Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet.

    66 | 67 | 68 | -------------------------------------------------------------------------------- /public/epubjs/js/hooks.js: -------------------------------------------------------------------------------- 1 | EPUBJS.Hooks.register("beforeChapterDisplay").endnotes = function(callback, renderer){ 2 | 3 | var notes = renderer.contents.querySelectorAll('a[href]'), 4 | items = Array.prototype.slice.call(notes), //[].slice.call() 5 | attr = "epub:type", 6 | type = "noteref", 7 | folder = EPUBJS.core.folder(location.pathname), 8 | cssPath = (folder + EPUBJS.cssPath) || folder, 9 | popups = {}; 10 | 11 | EPUBJS.core.addCss(EPUBJS.cssPath + "popup.css", false, renderer.render.document.head); 12 | 13 | 14 | items.forEach(function(item){ 15 | var epubType = item.getAttribute(attr), 16 | href, 17 | id, 18 | el, 19 | pop, 20 | pos, 21 | left, 22 | top, 23 | txt; 24 | 25 | if(epubType != type) return; 26 | 27 | href = item.getAttribute("href"); 28 | id = href.replace("#", ''); 29 | el = renderer.render.document.getElementById(id); 30 | 31 | 32 | item.addEventListener("mouseover", showPop, false); 33 | item.addEventListener("mouseout", hidePop, false); 34 | 35 | function showPop(){ 36 | var poppos, 37 | iheight = renderer.height, 38 | iwidth = renderer.width, 39 | tip, 40 | pop, 41 | maxHeight = 225, 42 | itemRect; 43 | 44 | if(!txt) { 45 | pop = el.cloneNode(true); 46 | txt = pop.querySelector("p"); 47 | } 48 | 49 | // chapter.replaceLinks.bind(this) //TODO:Fred - update? 50 | //-- create a popup with endnote inside of it 51 | if(!popups[id]) { 52 | popups[id] = document.createElement("div"); 53 | popups[id].setAttribute("class", "popup"); 54 | 55 | pop_content = document.createElement("div"); 56 | 57 | popups[id].appendChild(pop_content); 58 | 59 | pop_content.appendChild(txt); 60 | pop_content.setAttribute("class", "pop_content"); 61 | 62 | renderer.render.document.body.appendChild(popups[id]); 63 | 64 | //-- TODO: will these leak memory? - Fred 65 | popups[id].addEventListener("mouseover", onPop, false); 66 | popups[id].addEventListener("mouseout", offPop, false); 67 | 68 | //-- Add hide on page change 69 | // chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", hidePop); 70 | // chapter.book.listenUntil("book:pageChanged", "book:chapterDestroy", offPop); 71 | renderer.on("renderer:pageChanged", hidePop, this); 72 | renderer.on("renderer:pageChanged", offPop, this); 73 | // chapter.book.on("renderer:chapterDestroy", hidePop, this); 74 | } 75 | 76 | pop = popups[id]; 77 | 78 | 79 | //-- get location of item 80 | itemRect = item.getBoundingClientRect(); 81 | left = itemRect.left; 82 | top = itemRect.top; 83 | 84 | //-- show the popup 85 | pop.classList.add("show"); 86 | 87 | //-- locations of popup 88 | popRect = pop.getBoundingClientRect(); 89 | 90 | //-- position the popup 91 | pop.style.left = left - popRect.width / 2 + "px"; 92 | pop.style.top = top + "px"; 93 | 94 | 95 | //-- Adjust max height 96 | if(maxHeight > iheight / 2.5) { 97 | maxHeight = iheight / 2.5; 98 | pop_content.style.maxHeight = maxHeight + "px"; 99 | } 100 | 101 | //-- switch above / below 102 | if(popRect.height + top >= iheight - 25) { 103 | pop.style.top = top - popRect.height + "px"; 104 | pop.classList.add("above"); 105 | }else{ 106 | pop.classList.remove("above"); 107 | } 108 | 109 | //-- switch left 110 | if(left - popRect.width <= 0) { 111 | pop.style.left = left + "px"; 112 | pop.classList.add("left"); 113 | }else{ 114 | pop.classList.remove("left"); 115 | } 116 | 117 | //-- switch right 118 | if(left + popRect.width / 2 >= iwidth) { 119 | //-- TEMP MOVE: 300 120 | pop.style.left = left - 300 + "px"; 121 | 122 | popRect = pop.getBoundingClientRect(); 123 | pop.style.left = left - popRect.width + "px"; 124 | //-- switch above / below again 125 | if(popRect.height + top >= iheight - 25) { 126 | pop.style.top = top - popRect.height + "px"; 127 | pop.classList.add("above"); 128 | }else{ 129 | pop.classList.remove("above"); 130 | } 131 | 132 | pop.classList.add("right"); 133 | }else{ 134 | pop.classList.remove("right"); 135 | } 136 | 137 | 138 | } 139 | 140 | function onPop(){ 141 | popups[id].classList.add("on"); 142 | } 143 | 144 | function offPop(){ 145 | popups[id].classList.remove("on"); 146 | } 147 | 148 | function hidePop(){ 149 | setTimeout(function(){ 150 | popups[id].classList.remove("show"); 151 | }, 100); 152 | } 153 | 154 | }); 155 | 156 | 157 | if(callback) callback(); 158 | 159 | } 160 | 161 | EPUBJS.Hooks.register("beforeChapterDisplay").mathml = function(callback, renderer){ 162 | 163 | // check of currentChapter properties contains 'mathml' 164 | if(renderer.currentChapter.manifestProperties.indexOf("mathml") !== -1 ){ 165 | 166 | // Assign callback to be inside iframe window 167 | renderer.render.iframe.contentWindow.mathmlCallback = callback; 168 | 169 | // add MathJax config script tag to the renderer body 170 | var s = document.createElement("script"); 171 | s.type = 'text/x-mathjax-config'; 172 | s.innerHTML = '\ 173 | MathJax.Hub.Register.StartupHook("End",function () { \ 174 | window.mathmlCallback(); \ 175 | });\ 176 | MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); \ 177 | '; 178 | renderer.doc.body.appendChild(s); 179 | // add MathJax.js to renderer head 180 | EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML", null, renderer.doc.head); 181 | 182 | } else { 183 | if(callback) callback(); 184 | } 185 | } 186 | 187 | EPUBJS.Hooks.register("beforeChapterDisplay").smartimages = function(callback, renderer){ 188 | var images = renderer.contents.querySelectorAll('img'), 189 | items = Array.prototype.slice.call(images), 190 | iheight = renderer.height,//chapter.bodyEl.clientHeight,//chapter.doc.body.getBoundingClientRect().height, 191 | oheight; 192 | 193 | if(renderer.layoutSettings.layout != "reflowable") { 194 | callback(); 195 | return; //-- Only adjust images for reflowable text 196 | } 197 | 198 | items.forEach(function(item){ 199 | 200 | var size = function() { 201 | var itemRect = item.getBoundingClientRect(), 202 | rectHeight = itemRect.height, 203 | top = itemRect.top, 204 | oHeight = item.getAttribute('data-height'), 205 | height = oHeight || rectHeight, 206 | newHeight, 207 | fontSize = Number(getComputedStyle(item, "").fontSize.match(/(\d*(\.\d*)?)px/)[1]), 208 | fontAdjust = fontSize ? fontSize / 2 : 0; 209 | 210 | iheight = renderer.contents.clientHeight; 211 | if(top < 0) top = 0; 212 | 213 | item.style.maxWidth = "100%"; 214 | 215 | if(height + top >= iheight) { 216 | 217 | if(top < iheight/2) { 218 | // Remove top and half font-size from height to keep container from overflowing 219 | newHeight = iheight - top - fontAdjust; 220 | item.style.maxHeight = newHeight + "px"; 221 | item.style.width= "auto"; 222 | }else{ 223 | if(height > iheight) { 224 | item.style.maxHeight = iheight + "px"; 225 | item.style.width= "auto"; 226 | itemRect = item.getBoundingClientRect(); 227 | height = itemRect.height; 228 | } 229 | item.style.display = "block"; 230 | item.style["WebkitColumnBreakBefore"] = "always"; 231 | item.style["breakBefore"] = "column"; 232 | 233 | } 234 | 235 | item.setAttribute('data-height', newHeight); 236 | 237 | }else{ 238 | item.style.removeProperty('max-height'); 239 | item.style.removeProperty('margin-top'); 240 | } 241 | } 242 | 243 | var unloaded = function(){ 244 | // item.removeEventListener('load', size); // crashes in IE 245 | renderer.off("renderer:resized", size); 246 | renderer.off("renderer:chapterUnload", this); 247 | }; 248 | 249 | item.addEventListener('load', size, false); 250 | 251 | renderer.on("renderer:resized", size); 252 | 253 | renderer.on("renderer:chapterUnload", unloaded); 254 | 255 | size(); 256 | 257 | }); 258 | 259 | if(callback) callback(); 260 | 261 | } 262 | 263 | EPUBJS.Hooks.register("beforeChapterDisplay").transculsions = function(callback, renderer){ 264 | /* 265 | 268 | */ 269 | 270 | var trans = renderer.contents.querySelectorAll('[transclusion]'), 271 | items = Array.prototype.slice.call(trans); 272 | 273 | items.forEach(function(item){ 274 | var src = item.getAttribute("ref"), 275 | iframe = document.createElement('iframe'), 276 | orginal_width = item.getAttribute("width"), 277 | orginal_height = item.getAttribute("height"), 278 | parent = item.parentNode, 279 | width = orginal_width, 280 | height = orginal_height, 281 | ratio; 282 | 283 | 284 | function size() { 285 | width = orginal_width; 286 | height = orginal_height; 287 | 288 | if(width > chapter.colWidth){ 289 | ratio = chapter.colWidth / width; 290 | 291 | width = chapter.colWidth; 292 | height = height * ratio; 293 | } 294 | 295 | iframe.width = width; 296 | iframe.height = height; 297 | } 298 | 299 | 300 | size(); 301 | 302 | //-- resize event 303 | 304 | 305 | renderer.listenUntil("renderer:resized", "renderer:chapterUnloaded", size); 306 | 307 | iframe.src = src; 308 | 309 | // 310 | parent.replaceChild(iframe, item); 311 | 312 | 313 | }); 314 | 315 | 316 | 317 | 318 | if(callback) callback(); 319 | 320 | 321 | } 322 | 323 | //# sourceMappingURL=hooks.js.map -------------------------------------------------------------------------------- /public/epubjs/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v1.0.1 | MIT License | git.io/normalize */ 2 | 3 | /* ========================================================================== 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /* 8 | * Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3. 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | nav, 20 | section, 21 | summary { 22 | display: block; 23 | } 24 | 25 | /* 26 | * Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. 27 | */ 28 | 29 | audio, 30 | canvas, 31 | video { 32 | display: inline-block; 33 | *display: inline; 34 | *zoom: 1; 35 | } 36 | 37 | /* 38 | * Prevents modern browsers from displaying `audio` without controls. 39 | * Remove excess height in iOS 5 devices. 40 | */ 41 | 42 | audio:not([controls]) { 43 | display: none; 44 | height: 0; 45 | } 46 | 47 | /* 48 | * Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3, 49 | * and Safari 4. 50 | * Known issue: no IE 6 support. 51 | */ 52 | 53 | [hidden] { 54 | display: none; 55 | } 56 | 57 | /* ========================================================================== 58 | Base 59 | ========================================================================== */ 60 | 61 | /* 62 | * 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using 63 | * `em` units. 64 | * 2. Prevents iOS text size adjust after orientation change, without disabling 65 | * user zoom. 66 | */ 67 | 68 | html { 69 | font-size: 100%; /* 1 */ 70 | -webkit-text-size-adjust: 100%; /* 2 */ 71 | -ms-text-size-adjust: 100%; /* 2 */ 72 | } 73 | 74 | /* 75 | * Addresses `font-family` inconsistency between `textarea` and other form 76 | * elements. 77 | */ 78 | 79 | html, 80 | button, 81 | input, 82 | select, 83 | textarea { 84 | font-family: sans-serif; 85 | } 86 | 87 | /* 88 | * Addresses margins handled incorrectly in IE 6/7. 89 | */ 90 | 91 | body { 92 | margin: 0; 93 | } 94 | 95 | /* ========================================================================== 96 | Links 97 | ========================================================================== */ 98 | 99 | /* 100 | * Addresses `outline` inconsistency between Chrome and other browsers. 101 | */ 102 | 103 | a:focus { 104 | outline: thin dotted; 105 | } 106 | 107 | /* 108 | * Improves readability when focused and also mouse hovered in all browsers. 109 | */ 110 | 111 | a:active, 112 | a:hover { 113 | outline: 0; 114 | } 115 | 116 | /* ========================================================================== 117 | Typography 118 | ========================================================================== */ 119 | 120 | /* 121 | * Addresses font sizes and margins set differently in IE 6/7. 122 | * Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5, 123 | * and Chrome. 124 | */ 125 | 126 | h1 { 127 | font-size: 2em; 128 | margin: 0.67em 0; 129 | } 130 | 131 | h2 { 132 | font-size: 1.5em; 133 | margin: 0.83em 0; 134 | } 135 | 136 | h3 { 137 | font-size: 1.17em; 138 | margin: 1em 0; 139 | } 140 | 141 | h4 { 142 | font-size: 1em; 143 | margin: 1.33em 0; 144 | } 145 | 146 | h5 { 147 | font-size: 0.83em; 148 | margin: 1.67em 0; 149 | } 150 | 151 | h6 { 152 | font-size: 0.75em; 153 | margin: 2.33em 0; 154 | } 155 | 156 | /* 157 | * Addresses styling not present in IE 7/8/9, Safari 5, and Chrome. 158 | */ 159 | 160 | abbr[title] { 161 | border-bottom: 1px dotted; 162 | } 163 | 164 | /* 165 | * Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. 166 | */ 167 | 168 | b, 169 | strong { 170 | font-weight: bold; 171 | } 172 | 173 | blockquote { 174 | margin: 1em 40px; 175 | } 176 | 177 | /* 178 | * Addresses styling not present in Safari 5 and Chrome. 179 | */ 180 | 181 | dfn { 182 | font-style: italic; 183 | } 184 | 185 | /* 186 | * Addresses styling not present in IE 6/7/8/9. 187 | */ 188 | 189 | mark { 190 | background: #ff0; 191 | color: #000; 192 | } 193 | 194 | /* 195 | * Addresses margins set differently in IE 6/7. 196 | */ 197 | 198 | p, 199 | pre { 200 | margin: 1em 0; 201 | } 202 | 203 | /* 204 | * Corrects font family set oddly in IE 6, Safari 4/5, and Chrome. 205 | */ 206 | 207 | code, 208 | kbd, 209 | pre, 210 | samp { 211 | font-family: monospace, serif; 212 | _font-family: 'courier new', monospace; 213 | font-size: 1em; 214 | } 215 | 216 | /* 217 | * Improves readability of pre-formatted text in all browsers. 218 | */ 219 | 220 | pre { 221 | white-space: pre; 222 | white-space: pre-wrap; 223 | word-wrap: break-word; 224 | } 225 | 226 | /* 227 | * Addresses CSS quotes not supported in IE 6/7. 228 | */ 229 | 230 | q { 231 | quotes: none; 232 | } 233 | 234 | /* 235 | * Addresses `quotes` property not supported in Safari 4. 236 | */ 237 | 238 | q:before, 239 | q:after { 240 | content: ''; 241 | content: none; 242 | } 243 | 244 | /* 245 | * Addresses inconsistent and variable font size in all browsers. 246 | */ 247 | 248 | small { 249 | font-size: 80%; 250 | } 251 | 252 | /* 253 | * Prevents `sub` and `sup` affecting `line-height` in all browsers. 254 | */ 255 | 256 | sub, 257 | sup { 258 | font-size: 75%; 259 | line-height: 0; 260 | position: relative; 261 | vertical-align: baseline; 262 | } 263 | 264 | sup { 265 | top: -0.5em; 266 | } 267 | 268 | sub { 269 | bottom: -0.25em; 270 | } 271 | 272 | /* ========================================================================== 273 | Lists 274 | ========================================================================== */ 275 | 276 | /* 277 | * Addresses margins set differently in IE 6/7. 278 | */ 279 | 280 | dl, 281 | menu, 282 | ol, 283 | ul { 284 | margin: 1em 0; 285 | } 286 | 287 | dd { 288 | margin: 0 0 0 40px; 289 | } 290 | 291 | /* 292 | * Addresses paddings set differently in IE 6/7. 293 | */ 294 | 295 | menu, 296 | ol, 297 | ul { 298 | padding: 0 0 0 40px; 299 | } 300 | 301 | /* 302 | * Corrects list images handled incorrectly in IE 7. 303 | */ 304 | 305 | nav ul, 306 | nav ol { 307 | list-style: none; 308 | list-style-image: none; 309 | } 310 | 311 | /* ========================================================================== 312 | Embedded content 313 | ========================================================================== */ 314 | 315 | /* 316 | * 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3. 317 | * 2. Improves image quality when scaled in IE 7. 318 | */ 319 | 320 | img { 321 | border: 0; /* 1 */ 322 | -ms-interpolation-mode: bicubic; /* 2 */ 323 | } 324 | 325 | /* 326 | * Corrects overflow displayed oddly in IE 9. 327 | */ 328 | 329 | svg:not(:root) { 330 | overflow: hidden; 331 | } 332 | 333 | /* ========================================================================== 334 | Figures 335 | ========================================================================== */ 336 | 337 | /* 338 | * Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11. 339 | */ 340 | 341 | figure { 342 | margin: 0; 343 | } 344 | 345 | /* ========================================================================== 346 | Forms 347 | ========================================================================== */ 348 | 349 | /* 350 | * Corrects margin displayed oddly in IE 6/7. 351 | */ 352 | 353 | form { 354 | margin: 0; 355 | } 356 | 357 | /* 358 | * Define consistent border, margin, and padding. 359 | */ 360 | 361 | fieldset { 362 | border: 1px solid #c0c0c0; 363 | margin: 0 2px; 364 | padding: 0.35em 0.625em 0.75em; 365 | } 366 | 367 | /* 368 | * 1. Corrects color not being inherited in IE 6/7/8/9. 369 | * 2. Corrects text not wrapping in Firefox 3. 370 | * 3. Corrects alignment displayed oddly in IE 6/7. 371 | */ 372 | 373 | legend { 374 | border: 0; /* 1 */ 375 | padding: 0; 376 | white-space: normal; /* 2 */ 377 | *margin-left: -7px; /* 3 */ 378 | } 379 | 380 | /* 381 | * 1. Corrects font size not being inherited in all browsers. 382 | * 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5, 383 | * and Chrome. 384 | * 3. Improves appearance and consistency in all browsers. 385 | */ 386 | 387 | button, 388 | input, 389 | select, 390 | textarea { 391 | font-size: 100%; /* 1 */ 392 | margin: 0; /* 2 */ 393 | vertical-align: baseline; /* 3 */ 394 | *vertical-align: middle; /* 3 */ 395 | } 396 | 397 | /* 398 | * Addresses Firefox 3+ setting `line-height` on `input` using `!important` in 399 | * the UA stylesheet. 400 | */ 401 | 402 | button, 403 | input { 404 | line-height: normal; 405 | } 406 | 407 | /* 408 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 409 | * and `video` controls. 410 | * 2. Corrects inability to style clickable `input` types in iOS. 411 | * 3. Improves usability and consistency of cursor style between image-type 412 | * `input` and others. 413 | * 4. Removes inner spacing in IE 7 without affecting normal text inputs. 414 | * Known issue: inner spacing remains in IE 6. 415 | */ 416 | 417 | button, 418 | html input[type="button"], /* 1 */ 419 | input[type="reset"], 420 | input[type="submit"] { 421 | -webkit-appearance: button; /* 2 */ 422 | cursor: pointer; /* 3 */ 423 | *overflow: visible; /* 4 */ 424 | } 425 | 426 | /* 427 | * Re-set default cursor for disabled elements. 428 | */ 429 | 430 | button[disabled], 431 | input[disabled] { 432 | cursor: default; 433 | } 434 | 435 | /* 436 | * 1. Addresses box sizing set to content-box in IE 8/9. 437 | * 2. Removes excess padding in IE 8/9. 438 | * 3. Removes excess padding in IE 7. 439 | * Known issue: excess padding remains in IE 6. 440 | */ 441 | 442 | input[type="checkbox"], 443 | input[type="radio"] { 444 | box-sizing: border-box; /* 1 */ 445 | padding: 0; /* 2 */ 446 | *height: 13px; /* 3 */ 447 | *width: 13px; /* 3 */ 448 | } 449 | 450 | /* 451 | * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. 452 | * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome 453 | * (include `-moz` to future-proof). 454 | */ 455 | /* 456 | input[type="search"] { 457 | -webkit-appearance: textfield; 458 | -moz-box-sizing: content-box; 459 | -webkit-box-sizing: content-box; 460 | box-sizing: content-box; 461 | } 462 | */ 463 | 464 | /* 465 | * Removes inner padding and search cancel button in Safari 5 and Chrome 466 | * on OS X. 467 | */ 468 | 469 | /* input[type="search"]::-webkit-search-cancel-button, 470 | input[type="search"]::-webkit-search-decoration { 471 | -webkit-appearance: none; 472 | } */ 473 | 474 | /* 475 | * Removes inner padding and border in Firefox 3+. 476 | */ 477 | 478 | button::-moz-focus-inner, 479 | input::-moz-focus-inner { 480 | border: 0; 481 | padding: 0; 482 | } 483 | 484 | /* 485 | * 1. Removes default vertical scrollbar in IE 6/7/8/9. 486 | * 2. Improves readability and alignment in all browsers. 487 | */ 488 | 489 | textarea { 490 | overflow: auto; /* 1 */ 491 | vertical-align: top; /* 2 */ 492 | } 493 | 494 | /* ========================================================================== 495 | Tables 496 | ========================================================================== */ 497 | 498 | /* 499 | * Remove most spacing between table cells. 500 | */ 501 | 502 | table { 503 | border-collapse: collapse; 504 | border-spacing: 0; 505 | } 506 | -------------------------------------------------------------------------------- /public/views/epub-reader-frame.php: -------------------------------------------------------------------------------- 1 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 202 | 203 | 204 | 205 |
    206 | 207 |
    208 |
    209 |   210 |
    211 |
    212 | 213 |  –  214 | 215 |
    216 |
    217 |   218 |   219 |   220 |   221 |
    222 |
    223 |
    224 |
    225 | 226 | 227 |
    228 |
    229 | 230 |
    231 | 232 |
    233 |
    234 |
    235 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /public/epubjs/ebook/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sample eBook 5 | 6 | 7 |

    Sample eBook

    8 |

    This is a sample ebook, nothing more.

    9 |

    10 |

    11 | 12 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero.

    13 | 14 |

    Sed dignissim lacinia nunc. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nibh. Fusce nec tellus sed augue semper porta. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum.

    15 | 16 |

    Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Nam nec ante. Suspendisse in justo eu magna luctus suscipit. Sed lectus.

    17 | 18 |

    Sed convallis tristique sem. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Etiam ultrices. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Sed non quam. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa.

    19 | 20 |

    Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci.

    21 | 22 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc.

    23 | 24 |

    Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante.

    25 | 26 |

    Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.

    27 | 28 |

    Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor.

    29 | 30 |

    Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque.

    31 | 32 |

    Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa.

    33 | 34 |

    Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.

    35 | 36 |

    Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien.

    37 | 38 |

    Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.

    39 | 40 |

    Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante.

    41 | 42 |

    Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque. Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero.

    43 | 44 |

    Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc.

    45 | 46 |

    Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    47 | 48 |

    Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam.

    49 | 50 |

    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi.

    51 | 52 |

    Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam. Aenean laoreet. Vestibulum nisi lectus, commodo ac, facilisis ac, ultricies eu, pede. Ut orci risus, accumsan porttitor, cursus quis, aliquet eget, justo. Sed pretium blandit orci. Ut eu diam at pede suscipit sodales. Aenean lectus elit, fermentum non, convallis id, sagittis at, neque.

    53 | 54 |

    Nullam mauris orci, aliquet et, iaculis et, viverra vitae, ligula. Nulla ut felis in purus aliquam imperdiet. Maecenas aliquet mollis lectus. Vivamus consectetuer risus et tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.

    55 | 56 |

    Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem.

    57 | 58 |

    Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti.

    59 | 60 |

    Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices. Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet.

    61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /public/epubjs/font/epub-fontello.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2017 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /public/epubjs/js/reader.min.js: -------------------------------------------------------------------------------- 1 | EPUBJS.reader={},EPUBJS.reader.plugins={},function(a,b){var c=(a.ePubReader,a.ePubReader=function(a,b){return new EPUBJS.Reader(a,b)});"function"==typeof define&&define.amd?define(function(){return Reader}):"undefined"!=typeof module&&module.exports&&(module.exports=c)}(window,jQuery),EPUBJS.Reader=function(a,b){var c,d,e=this,f=$("#viewer");this.settings=EPUBJS.core.defaults(b||{},{bookPath:a,restore:!1,bookmarks:void 0,annotations:void 0,bookKey:void 0,styles:void 0,generatePagination:!1,history:!1}),this.setBookKey(this.settings.bookPath),this.settings.restore&&this.isSaved()&&this.applySavedSettings(),this.settings.styles=this.settings.styles||{fontSize:"100%"},this.book=c=new EPUBJS.Book(this.settings),this.settings.previousLocationCfi&&c.gotoCfi(this.settings.previousLocationCfi),this.offline=!1,this.sidebarOpen=!1,this.settings.bookmarks||(this.settings.bookmarks=[]),this.settings.annotations||(this.settings.annotations=[]),this.settings.generatePagination&&c.generatePagination(f.width(),f.height()),c.renderTo("viewer"),e.ReaderController=EPUBJS.reader.ReaderController.call(e,c),e.ControlsController=EPUBJS.reader.ControlsController.call(e,c),e.SidebarController=EPUBJS.reader.SidebarController.call(e,c),e.BookmarksController=EPUBJS.reader.BookmarksController.call(e,c),e.NotesController=EPUBJS.reader.NotesController.call(e,c);for(d in EPUBJS.reader.plugins)EPUBJS.reader.plugins.hasOwnProperty(d)&&(e[d]=EPUBJS.reader.plugins[d].call(e,c));return c.ready.all.then(function(){e.ReaderController.hideLoader()}),c.getMetadata().then(function(a){e.MetaController=EPUBJS.reader.MetaController.call(e,a)}),c.getToc().then(function(a){e.TocController=EPUBJS.reader.TocController.call(e,a)}),window.addEventListener("beforeunload",this.unload.bind(this),!1),window.addEventListener("hashchange",this.hashChanged.bind(this),!1),document.addEventListener("keydown",this.adjustFontSize.bind(this),!1),c.on("renderer:keydown",this.adjustFontSize.bind(this)),c.on("renderer:keydown",e.ReaderController.arrowKeys.bind(this)),c.on("renderer:selected",this.selectedRange.bind(this)),this},EPUBJS.Reader.prototype.adjustFontSize=function(a){var b,c=2,d=a.ctrlKey||a.metaKey;this.settings.styles&&(this.settings.styles.fontSize||(this.settings.styles.fontSize="100%"),b=parseInt(this.settings.styles.fontSize.slice(0,-1)),d&&187==a.keyCode&&(a.preventDefault(),this.book.setStyle("fontSize",b+c+"%")),d&&189==a.keyCode&&(a.preventDefault(),this.book.setStyle("fontSize",b-c+"%")),d&&48==a.keyCode&&(a.preventDefault(),this.book.setStyle("fontSize","100%")))},EPUBJS.Reader.prototype.addBookmark=function(a){this.isBookmarked(a)>-1||(this.settings.bookmarks.push(a),this.trigger("reader:bookmarked",a))},EPUBJS.Reader.prototype.removeBookmark=function(a){var b=this.isBookmarked(a);-1!==b&&(this.settings.bookmarks.splice(b,1),this.trigger("reader:unbookmarked",b))},EPUBJS.Reader.prototype.isBookmarked=function(a){return this.settings.bookmarks.indexOf(a)},EPUBJS.Reader.prototype.clearBookmarks=function(){this.settings.bookmarks=[]},EPUBJS.Reader.prototype.addNote=function(a){this.settings.annotations.push(a)},EPUBJS.Reader.prototype.removeNote=function(a){var b=this.settings.annotations.indexOf(a);-1!==b&&delete this.settings.annotations[b]},EPUBJS.Reader.prototype.clearNotes=function(){this.settings.annotations=[]},EPUBJS.Reader.prototype.setBookKey=function(a){return this.settings.bookKey||(this.settings.bookKey="epubjsreader:"+EPUBJS.VERSION+":"+window.location.host+":"+a),this.settings.bookKey},EPUBJS.Reader.prototype.isSaved=function(a){return!!localStorage&&null!==localStorage.getItem(this.settings.bookKey)},EPUBJS.Reader.prototype.removeSavedSettings=function(){if(!localStorage)return!1;localStorage.removeItem(this.settings.bookKey)},EPUBJS.Reader.prototype.applySavedSettings=function(){var a;if(!localStorage)return!1;try{a=JSON.parse(localStorage.getItem(this.settings.bookKey))}catch(a){return!1}return!!a&&(a.styles&&(this.settings.styles=EPUBJS.core.defaults(this.settings.styles||{},a.styles)),this.settings=EPUBJS.core.defaults(this.settings,a),!0)},EPUBJS.Reader.prototype.saveSettings=function(){if(this.book&&(this.settings.previousLocationCfi=this.book.getCurrentLocationCfi()),!localStorage)return!1;localStorage.setItem(this.settings.bookKey,JSON.stringify(this.settings))},EPUBJS.Reader.prototype.unload=function(){this.settings.restore&&localStorage&&this.saveSettings()},EPUBJS.Reader.prototype.hashChanged=function(){var a=window.location.hash.slice(1);this.book.goto(a)},EPUBJS.Reader.prototype.selectedRange=function(a){var b=new EPUBJS.EpubCFI,c=b.generateCfiFromRangeAnchor(a,this.book.renderer.currentChapter.cfiBase),d="#"+c;this.settings.history&&window.location.hash!=d&&(history.pushState({},"",d),this.currentLocationCfi=c)},RSVP.EventTarget.mixin(EPUBJS.Reader.prototype),EPUBJS.reader.BookmarksController=function(){var a=this.book,b=$("#bookmarksView"),c=b.find("#bookmarks"),d=document.createDocumentFragment(),e=function(){b.show()},f=function(){b.hide()},g=0,h=function(b){var c=document.createElement("li"),d=document.createElement("a");return c.id="bookmark-"+g,c.classList.add("list_item"),d.textContent=b,d.href=b,d.classList.add("bookmark_link"),d.addEventListener("click",function(b){var c=this.getAttribute("href");a.gotoCfi(c),b.preventDefault()},!1),c.appendChild(d),g++,c};return this.settings.bookmarks.forEach(function(a){var b=h(a);d.appendChild(b)}),c.append(d),this.on("reader:bookmarked",function(a){var b=h(a);c.append(b)}),this.on("reader:unbookmarked",function(a){$("#bookmark-"+a).remove()}),{show:e,hide:f}},EPUBJS.reader.ControlsController=function(a){var b=this,c=($("#store"),$("#fullscreen")),d=$("#menu"),e=$("#sidebar-closer"),f=($("#main"),$("#sidebar"),$("#bookmark")),g=function(){b.offline=!1},h=function(){b.offline=!0},i=!1;return a.on("book:online",g),a.on("book:offline",h),d.on("click",function(){b.sidebarOpen?(b.SidebarController.hide(),d.addClass("icon-menu"),d.removeClass("icon-cancel")):(b.SidebarController.show(),d.addClass("icon-cancel"),d.removeClass("icon-menu"))}),e.on("click",function(){b.SidebarController.hide(),d.addClass("icon-menu"),d.removeClass("icon-right")}),"undefined"!=typeof screenfull&&(c.on("click",function(){screenfull.toggle($("#container")[0])}),screenfull.raw&&document.addEventListener(screenfull.raw.fullscreenchange,function(){i=screenfull.isFullscreen,i?c.addClass("icon-resize-small").removeClass("icon-resize-full"):c.addClass("icon-resize-full").removeClass("icon-resize-small")})),f.on("click",function(){var a=b.book.getCurrentLocationCfi();-1===b.isBookmarked(a)?(b.addBookmark(a),f.addClass("icon-bookmark").removeClass("icon-bookmark-empty")):(b.removeBookmark(a),f.removeClass("icon-bookmark").addClass("icon-bookmark-empty"))}),a.on("renderer:locationChanged",function(a){var c="#"+a;-1===b.isBookmarked(a)?f.removeClass("icon-bookmark").addClass("icon-bookmark-empty"):f.addClass("icon-bookmark").removeClass("icon-bookmark-empty"),b.currentLocationCfi=a,b.settings.history&&window.location.hash!=c&&history.pushState({},"",c)}),a.on("book:pageChanged",function(a){}),{}},EPUBJS.reader.MetaController=function(a){var b=a.bookTitle,c=a.creator,d=$("#book-title"),e=$("#chapter-title"),f=$("#title-seperator");document.title=b+" – "+c,d.html(b),e.html(c),f.show()},EPUBJS.reader.NotesController=function(){var a=this.book,b=this,c=$("#notesView"),d=$("#notes"),e=$("#note-text"),f=$("#note-anchor"),g=b.settings.annotations,h=a.renderer,i=[],j=new EPUBJS.EpubCFI,k=function(){c.show()},l=function(){c.hide()},m=function(c){var d,g,h,i,k,l=a.renderer.doc;if(l.caretPositionFromPoint?(d=l.caretPositionFromPoint(c.clientX,c.clientY),g=d.offsetNode,h=d.offset):l.caretRangeFromPoint&&(d=l.caretRangeFromPoint(c.clientX,c.clientY),g=d.startContainer,h=d.startOffset),3!==g.nodeType)for(var p=0;pm/2.5&&(o=m/2.5,pop_content.style.maxHeight=o+"px"),popRect.height+l>=m-25?(b.style.top=l-popRect.height+"px",b.classList.add("above")):b.classList.remove("above"),k-popRect.width<=0?(b.style.left=k+"px",b.classList.add("left")):b.classList.remove("left"),k+popRect.width/2>=n?(b.style.left=k-300+"px",popRect=b.getBoundingClientRect(),b.style.left=k-popRect.width+"px",popRect.height+l>=m-25?(b.style.top=l-popRect.height+"px",b.classList.add("above")):b.classList.remove("above"),b.classList.add("right")):b.classList.remove("right")},f=function(){i[d].classList.add("on")},g=function(){i[d].classList.remove("on")},j=function(){setTimeout(function(){i[d].classList.remove("show")},100)},l=function(){b.ReaderController.slideOut(),k()};a.addEventListener("mouseover",e,!1),a.addEventListener("mouseout",j,!1),a.addEventListener("click",l,!1)};return f.on("click",function(b){f.text("Cancel"),e.prop("disabled","true"),a.on("renderer:click",m)}),g.forEach(function(a){n(a)}),h.registerHook("beforeChapterDisplay",function(a,b){var c=b.currentChapter;g.forEach(function(a){if(j.parse(a.anchor).spinePos===c.spinePos)try{o(a)}catch(b){console.log("anchoring failed",a.anchor)}}),a()},!0),{show:k,hide:l}},EPUBJS.reader.ReaderController=function(a){var b=$("#main"),c=($("#_main"),$("#divider")),d=$("#loader"),e=$("#next"),f=$("#prev"),a=this.book,g=!1,h=function(){b.removeClass("closed")},i=function(){b.addClass("closed")},j=function(){d.show(),c.hide()},k=function(){d.hide(),c.toggle(g)},l=function(){"rtl"===a.metadata.direction?a.prevPage():a.nextPage()},m=function(){"rtl"===a.metadata.direction?a.nextPage():a.prevPage()},n=function(a){a.addClass("active"),setTimeout(function(){a.removeClass("active")},100)},o=function(a){37==a.keyCode&&(m(),n(f),a.preventDefault()),39==a.keyCode&&(l(),n(e),a.preventDefault())},p=-1,q=function(){p>0&&clearTimeout(p),p=setTimeout(function(){j(),p=-1},300)},r=function(){p>0&&clearTimeout(p),p=-1,k()};return document.addEventListener("keydown",o,!1),e.on("click",function(a){l(),a.preventDefault()}),f.on("click",function(a){m(),a.preventDefault()}),a.on("renderer:spreads",function(a){var b=g!==a;g=a,b&&d.is(":hidden")&&c.toggle(a)}),a.on("book:displayingChapter",q),a.on("renderer:chapterDisplayed",r),$.fn.swipe&&(console.log("swipe enabled"),a.renderer.registerHook("beforeChapterDisplay",function(b,c){$(a.renderer.render.window).swipe({swipe:function(a,b){switch((b+"").toLowerCase()){case"down":case"right":m(),n(f);break;case"up":case"left":l(),n(e)}},threshold:75,triggerOnTouchEnd:!1,maxTimeThreshold:1e3,longTapthreshold:1e3,excludedElements:$.fn.swipe.defaults.excludedElements+", button, input, select, textarea, a[href]"}),b&&b()})),{slideOut:i,slideIn:h,hideLoader:k,arrowKeys:o}},EPUBJS.reader.SidebarController=function(a){var b=this,c=$("#sidebar"),d=$("#sidebar-buttons"),e="Toc",f=function(a){var c=a+"Controller";e!=a&&void 0!==b[c]&&(b[e+"Controller"].hide(),b[c].show(),e=a,d.find(".active").removeClass("active"),d.find("#show-"+a).addClass("active"))},g=function(){return e},h=function(){b.sidebarOpen=!0,b.ReaderController.slideOut(),c.addClass("open")},i=function(){b.sidebarOpen=!1,b.ReaderController.slideIn(),c.removeClass("open")};return d.find(".show_view").on("click",function(a){var b=$(this).data("view");f(b),a.preventDefault()}),{show:h,hide:i,getActivePanel:g,changePanelTo:f}},EPUBJS.reader.TocController=function(a){var b=this.book,c=$("#tocView"),d=document.createDocumentFragment(),e=!1,f=function(a,b){var c=document.createElement("ul");return b||(b=1),a.forEach(function(a){var d=document.createElement("li"),e=document.createElement("a");toggle=document.createElement("a");var g;d.id="toc-"+a.id,d.classList.add("list_item"),e.textContent=a.label,e.href=a.href,e.classList.add("toc_link"),d.appendChild(e),a.subitems.length>0&&(b++,g=f(a.subitems,b),toggle.classList.add("toc_toggle"),d.insertBefore(toggle,e),d.appendChild(g)),c.appendChild(d)}),c},g=function(){c.show()},h=function(){c.hide()},i=function(a){var b=a.id,d=c.find("#toc-"+b),f=c.find(".currentChapter");c.find(".openChapter");d.length&&(d!=f&&d.has(e).length>0&&f.removeClass("currentChapter"),d.addClass("currentChapter"),d.parents("li").addClass("openChapter"))};b.on("renderer:chapterDisplayed",i);var j=f(a);return d.appendChild(j),c.append(d),c.find(".toc_link").on("click",function(a){var d=this.getAttribute("href");a.preventDefault(),b.goto(d),c.find(".currentChapter").addClass("openChapter").removeClass("currentChapter"),$(this).parent("li").addClass("currentChapter")}),c.find(".toc_toggle").on("click",function(a){var b=$(this).parent("li"),c=b.hasClass("openChapter");a.preventDefault(),c?b.removeClass("openChapter"):b.addClass("openChapter")}),{show:g,hide:h}}; -------------------------------------------------------------------------------- /admin/class-epub-reader-admin.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Epub_Reader_Admin { 24 | 25 | /** 26 | * The ID of this plugin. 27 | * 28 | * @since 0.9.0 29 | * @access private 30 | * @var string $plugin_name The ID of this plugin. 31 | */ 32 | private $plugin_name; 33 | 34 | /** 35 | * The version of this plugin. 36 | * 37 | * @since 0.9.0 38 | * @access private 39 | * @var string $version The current version of this plugin. 40 | */ 41 | private $version; 42 | 43 | /** 44 | * Initialize the class and set its properties. 45 | * 46 | * @since 0.9.0 47 | * @param string $plugin_name The name of this plugin. 48 | * @param string $version The version of this plugin. 49 | */ 50 | public function __construct( $plugin_name, $version ) { 51 | 52 | $this->plugin_name = $plugin_name; 53 | $this->version = $version; 54 | 55 | } 56 | 57 | public function init( $loader) { 58 | $loader->add_action( 'admin_menu', $this, 'register_settings_page' );// CM 59 | $loader->add_action( 'admin_init', $this, 'register_settings' ); // CM 60 | $loader->add_action( 'admin_enqueue_scripts', $this, 'enqueue_styles' ); 61 | $loader->add_action( 'admin_enqueue_scripts', $this, 'enqueue_scripts' ); 62 | } 63 | 64 | /** 65 | * Register the stylesheets for the admin area. 66 | * 67 | * @since 0.9.0 68 | */ 69 | public function enqueue_styles() { 70 | 71 | /** 72 | * This function is provided for demonstration purposes only. 73 | * 74 | * An instance of this class should be passed to the run() function 75 | * defined in Epub_Reader_Loader as all of the hooks are defined 76 | * in that particular class. 77 | * 78 | * The Epub_Reader_Loader will then create the relationship 79 | * between the defined hooks and the functions defined in this 80 | * class. 81 | */ 82 | 83 | //if ( 'tools_page_epub-reader' != $hook ) 84 | // return; 85 | 86 | wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/epub-reader-admin.css', array(), $this->version, 'all' ); 87 | 88 | } 89 | 90 | /** 91 | * Register the JavaScript for the admin area. 92 | * 93 | * @since 0.9.0 94 | */ 95 | public function enqueue_scripts() { 96 | 97 | /** 98 | * This function is provided for demonstration purposes only. 99 | * 100 | * An instance of this class should be passed to the run() function 101 | * defined in Epub_Reader_Loader as all of the hooks are defined 102 | * in that particular class. 103 | * 104 | * The Epub_Reader_Loader will then create the relationship 105 | * between the defined hooks and the functions defined in this 106 | * class. 107 | */ 108 | //if ( 'tools_page_epub-reader' != $hook ) 109 | // return; 110 | 111 | wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/epub-reader-admin.js', array( 'jquery' ), $this->version, false ); 112 | 113 | } 114 | 115 | /** 116 | * Register the settings page for the admin area. 117 | * 118 | * @since 0.9.0 119 | */ 120 | public function register_settings_page() { 121 | // Create our settings page as a submenu page. 122 | add_submenu_page( 123 | 'tools.php', // parent slug 124 | __( 'ePub Reader', 'epub-reader' ), // page title 125 | __( 'ePub Reader', 'epub-reader' ), // menu title 126 | 'manage_options', // capability 127 | 'epub-reader', // menu_slug 128 | array( $this, 'display_settings_page' ) // callable function 129 | ); 130 | } 131 | 132 | /** 133 | * Display the settings page content for the page we have created. 134 | * 135 | * @since 0.9.0 136 | */ 137 | public function display_settings_page() { 138 | 139 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/epub-reader-admin-display.php'; 140 | 141 | } 142 | 143 | 144 | /** 145 | * Register the settings for our settings page. 146 | * 147 | * @since 0.9.0 148 | */ 149 | public function register_settings() { 150 | 151 | /* 152 | // Here we are going to register our setting. 153 | register_setting( 154 | $this->plugin_name . '-settings', 155 | $this->plugin_name . '-settings', 156 | array( $this, 'sandbox_register_setting' ) 157 | ); 158 | 159 | // Here we are going to add a section for our setting. 160 | add_settings_section( 161 | $this->plugin_name . '-settings-section', 162 | __( 'Settings', 'epub-reader' ), 163 | array( $this, 'sandbox_add_settings_section' ), 164 | $this->plugin_name . '-settings' 165 | ); 166 | 167 | // Here we are going to add fields to our section. 168 | add_settings_field( 169 | 'post-types', 170 | __( 'Post Types', 'epub-reader' ), 171 | array( $this, 'sandbox_add_settings_field_multiple_checkbox' ), 172 | $this->plugin_name . '-settings', 173 | $this->plugin_name . '-settings-section', 174 | array( 175 | 'label_for' => 'post-types', 176 | 'description' => __( 'Save button will be added only to the checked post types.', 'epub-reader' ) 177 | ) 178 | ); 179 | add_settings_field( 180 | 'toggle-content-override', 181 | __( 'Append Button', 'epub-reader' ), 182 | array( $this, 'sandbox_add_settings_field_single_checkbox' ), 183 | $this->plugin_name . '-settings', 184 | $this->plugin_name . '-settings-section', 185 | array( 186 | 'label_for' => 'toggle-content-override', 187 | 'description' => __( 'If checked, it will append save button to the content.', 'epub-reader' ) 188 | ) 189 | ); 190 | add_settings_field( 191 | 'toggle-status-override', 192 | __( 'Membership', 'epub-reader' ), 193 | array( $this, 'sandbox_add_settings_field_single_checkbox' ), 194 | $this->plugin_name . '-settings', 195 | $this->plugin_name . '-settings-section', 196 | array( 197 | 'label_for' => 'toggle-status-override', 198 | 'description' => __( 'If checked, this feature will be available only to logged in users. ', 'epub-reader' ) 199 | ) 200 | ); 201 | add_settings_field( 202 | 'toggle-css-override', 203 | __( 'Our Styles', 'epub-reader' ), 204 | array( $this, 'sandbox_add_settings_field_single_checkbox' ), 205 | $this->plugin_name . '-settings', 206 | $this->plugin_name . '-settings-section', 207 | array( 208 | 'label_for' => 'toggle-css-override', 209 | 'description' => __( 'If checked, our style will be used.', 'epub-reader' ) 210 | ) 211 | ); 212 | add_settings_field( 213 | 'text-save', 214 | __( 'Save Item', 'epub-reader' ), 215 | array( $this, 'sandbox_add_settings_field_input_text' ), 216 | $this->plugin_name . '-settings', 217 | $this->plugin_name . '-settings-section', 218 | array( 219 | 'label_for' => 'text-save', 220 | 'default' => __( 'Save Item', 'epub-reader' ) 221 | ) 222 | ); 223 | add_settings_field( 224 | 'text-unsave', 225 | __( 'Unsave Item', 'epub-reader' ), 226 | array( $this, 'sandbox_add_settings_field_input_text' ), 227 | $this->plugin_name . '-settings', 228 | $this->plugin_name . '-settings-section', 229 | array( 230 | 'label_for' => 'text-unsave', 231 | 'default' => __( 'Unsave Item', 'epub-reader' ) 232 | ) 233 | ); 234 | add_settings_field( 235 | 'text-saved', 236 | __( 'Saved. See saved items.', 'epub-reader' ), 237 | array( $this, 'sandbox_add_settings_field_input_text' ), 238 | $this->plugin_name . '-settings', 239 | $this->plugin_name . '-settings-section', 240 | array( 241 | 'label_for' => 'text-saved', 242 | 'default' => __( 'Saved. See saved items.', 'epub-reader' ) 243 | ) 244 | ); 245 | add_settings_field( 246 | 'text-no-saved', 247 | __( 'You don\'t have any saved items.', 'epub-reader' ), 248 | array( $this, 'sandbox_add_settings_field_input_text' ), 249 | $this->plugin_name . '-settings', 250 | $this->plugin_name . '-settings-section', 251 | array( 252 | 'label_for' => 'text-no-saved', 253 | 'default' => __( 'You don\'t have any saved items.', 'epub-reader' ) 254 | ) 255 | ); 256 | */ 257 | } 258 | 259 | /** 260 | * Sandbox our settings. 261 | * 262 | * @since 0.9.0 263 | */ 264 | public function sandbox_register_setting( $input ) { 265 | 266 | $new_input = array(); 267 | 268 | if ( isset( $input ) ) { 269 | // Loop trough each input and sanitize the value if the input id isn't post-types 270 | foreach ( $input as $key => $value ) { 271 | if ( $key == 'post-types' ) { 272 | $new_input[ $key ] = $value; 273 | } else { 274 | $new_input[ $key ] = sanitize_text_field( $value ); 275 | } 276 | } 277 | } 278 | 279 | return $new_input; 280 | 281 | } 282 | 283 | /** 284 | * Sandbox our section for the settings. 285 | * 286 | * @since 0.9.0 287 | */ 288 | public function sandbox_add_settings_section() { 289 | 290 | return; 291 | 292 | } 293 | 294 | /** 295 | * Sandbox our single checkboxes. 296 | * 297 | * @since 0.9.0 298 | */ 299 | public function sandbox_add_settings_field_single_checkbox( $args ) { 300 | 301 | $field_id = $args['label_for']; 302 | $field_description = $args['description']; 303 | 304 | $options = get_option( $this->plugin_name . '-settings' ); 305 | $option = 0; 306 | 307 | if ( ! empty( $options[ $field_id ] ) ) { 308 | 309 | $option = $options[ $field_id ]; 310 | 311 | } 312 | 313 | ?> 314 | 315 | 319 | 320 | plugin_name . '-settings' ); 335 | $option = array(); 336 | 337 | if ( ! empty( $options[ $field_id ] ) ) { 338 | $option = $options[ $field_id ]; 339 | } 340 | 341 | if ( $field_id == 'post-types' ) { 342 | 343 | $args = array( 344 | 'public' => true 345 | ); 346 | $post_types = get_post_types( $args, 'objects' ); 347 | 348 | foreach ( $post_types as $post_type ) { 349 | 350 | if ( $post_type->name != 'attachment' ) { 351 | 352 | if ( in_array( $post_type->name, $option ) ) { 353 | $checked = 'checked="checked"'; 354 | } else { 355 | $checked = ''; 356 | } 357 | 358 | ?> 359 | 360 |
    361 | 365 |
    366 | 367 | $field_arg_value ) { 378 | 379 | if ( in_array( $field_arg_key, $option ) ) { 380 | $checked = 'checked="checked"'; 381 | } else { 382 | $checked = ''; 383 | } 384 | 385 | ?> 386 | 387 |
    388 | 392 |
    393 | 394 | 401 | 402 |

    403 | 404 | plugin_name . '-settings' ); 419 | $option = $field_default; 420 | 421 | if ( ! empty( $options[ $field_id ] ) ) { 422 | 423 | $option = $options[ $field_id ]; 424 | 425 | } 426 | 427 | ?> 428 | 429 | 430 | 431 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. --------------------------------------------------------------------------------