UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

245 lines (194 loc) 6.03 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>EPUB.js Basic Example</title> <script src="../dist/epub.js"></script> <style type="text/css"> body { margin: 0; background: #fafafa; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #333; } #viewer { display: block; margin: 0; width: 100%; height: 100%; } #viewer iframe { background: white; box-shadow: 0 0 4px #ccc; width: 590px; margin: 10px auto; } #prev { left: 40px; } #next { right: 40px; } .arrow { position: fixed; top: 50%; margin-top: -32px; font-size: 64px; color: #E2E2E2; font-family: arial, sans-serif; font-weight: bold; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; user-select: none; } .arrow:hover { color: #777; } .arrow:active { color: #000; } #toc { display: block; margin: 10px auto; } </style> </head> <body> <div id="viewer"></div> <script type="text/javascript"> var OReader = OReader || {}; OReader.Stitcher = {}; OReader.Stitcher.resolver = function(prefix) { var ns = { 'xhtml' : 'http://www.w3.org/1999/xhtml', 'mathml': 'http://www.w3.org/1998/Math/MathML' }; return ns[prefix] || null; }; OReader.Stitcher.parsePart = function(partString) { var tokens = partString.split("["); // Split string into element and other var attributes = {}; var part = { "string" : "xhtml:" + partString, "attributes" : attributes, "node" : tokens[0], "offset" : 1 }; var attrString; var re = /\@([^=]+)=[\'\"]([^\'^\"]+)[\'\"]/g; var match; // Part muight have additional information such as id or offset if(tokens[1]){ // remove the last part attrString = tokens[1].replace(']', ''); // If there is an offset it will be numerical if(!isNaN(parseFloat(attrString)) && isFinite(attrString)){ // is a number part.offset = parseInt(attrString); } else { // Run through string looking for @key=value paris do { match = re.exec(attrString); if (match) { // Add pairs to attributes object attributes[match[1]] = match[2]; } } while (match); } } return part; }; OReader.Stitcher.parseXpath = function(_xpath){ // Split path into parts var parts = _xpath.substring(1).split("/"); var xpath = []; // Parse each part and add to xpath array parts.forEach(function(part){ var parsed = OReader.Stitcher.parsePart(part); xpath.push(parsed); }); return xpath; }; OReader.Stitcher.createElement = function(part, _doc){ var doc = _doc || document; var element = doc.createElement(part.node); for (var attribute in part.attributes){ if (part.attributes.hasOwnProperty(attribute)) { element.setAttribute(attribute, part.attributes[attribute]); } } return element; }; OReader.Stitcher.rebuild = function(_xpath, doc, payload){ var xpath = OReader.Stitcher.parseXpath(_xpath); var walked = []; var fragment = document.createDocumentFragment(); var prevElement; var existingElement; // Process xpath parts xpath.forEach(function(part){ var present; var element; walked.push(part.string); // Check if part is present in DOM present = doc.evaluate("./"+walked.join('/'), doc, OReader.Stitcher.resolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if(!present) { // Create the element, add attributes element = OReader.Stitcher.createElement(part, doc); if(prevElement) { // Add to previously created element prevElement.appendChild(element); } else { fragment.appendChild(element); } // Continue prevElement = element; } else { // Continue, adding to existingElement = present; } }); // // Add the wrapper last if(prevElement) { // wrap the current payload in element while (payload.childNodes.length > 0) { if(payload.childNodes[0] != prevElement){ prevElement.appendChild(payload.childNodes[0]); } } } if(existingElement) { existingElement.appendChild(fragment); } return fragment; }; </script> <script> 'use strict'; // Load the opf var book = ePub("../books/9781565922259/content.opf"); // Where to render to var element = document.getElementById("viewer"); // Give the renderer an id or element to render to - takes an options such as size {width: 400, height: 600} var rendition = book.renderTo(element); // Display a section -> takes spineIndex, #id or chapter.html var displayed = rendition.display("7.xhtml"); // Register the hook for rebuilding the dom rendition.hooks.display.register(function(view){ var task = new RSVP.defer(); // Create a defer to return // Get the orginal xpath of the chunk var chunk = view.document.body; var pathElement = view.document.head.querySelector("meta[name='data-origPath']"); var path = pathElement.getAttribute('value'); if(path){ // Rebuild the DOM, insert current chunk to orginal position OReader.Stitcher.rebuild(path, view.document, chunk); } // Resolve defer since all tasks are finished task.resolve(); // Hook must return a promise return task.promise; }); </script> </body> </html>