diff --git a/examples/basic-dev.html b/examples/basic-dev.html index b820365..a977804 100644 --- a/examples/basic-dev.html +++ b/examples/basic-dev.html @@ -8,11 +8,14 @@ + + + + + + + +
+ + + + + + + diff --git a/lib/epub.js b/lib/epub.js index 18a87f0..55dbe08 100644 --- a/lib/epub.js +++ b/lib/epub.js @@ -3,7 +3,7 @@ if (typeof EPUBJS === 'undefined') { } EPUBJS.VERSION = "0.3.0"; - +EPUBJS.Render = {}; (function(root) { "use strict"; diff --git a/lib/epubjs/book.js b/lib/epubjs/book.js index c20e4e2..5b881c3 100644 --- a/lib/epubjs/book.js +++ b/lib/epubjs/book.js @@ -2,6 +2,7 @@ EPUBJS.Book = function(_url){ // Promises this.opening = new RSVP.defer(); this.opened = this.opening.promise; + this.isOpen = false; this.url = undefined; @@ -25,17 +26,11 @@ EPUBJS.Book = function(_url){ pageList: this.loading.pageList.promise }; - this.loaders = []; - for(var promise in this.loaded){ - this.loaders.push(this.loaded[promise]); - } + this.ready = RSVP.hash(this.loaded); - this.ready = RSVP.all(this.loaders); - - // this.pageList = []; - - - // this.ready.all.then(this._ready.bind(this)); + // Queue for methods used before opening + this.isRendered = false; + this._q = EPUBJS.core.queue(this); if(_url) { this.open(_url); @@ -48,6 +43,7 @@ EPUBJS.Book.prototype.open = function(_url){ var epubPackage; var book = this; var containerPath = "META-INF/container.xml"; + var location; // Reuse parsed url or create a new uri object if(typeof(_url) === "object") { @@ -64,6 +60,9 @@ EPUBJS.Book.prototype.open = function(_url){ if(uri.origin) { this.url = uri.origin + "/" + uri.directory; + } else if(window){ + location = EPUBJS.core.uri(window.location.href); + this.url = EPUBJS.core.resolveUrl(location.base, uri.directory); } else { this.url = uri.directory; } @@ -111,11 +110,13 @@ EPUBJS.Book.prototype.open = function(_url){ book.loading.spine.resolve(book.spine); book.loading.cover.resolve(book.cover); - // Resolve book opened promise - book.opening.resolve(book); + this.isOpen = true; // Clear queue of any waiting book request + // Resolve book opened promise + book.opening.resolve(book); + }).catch(function(error) { // handle errors in parsing the book console.error(error.message, error.stack); @@ -152,6 +153,13 @@ EPUBJS.Book.prototype.section = function(target) { return this.spine.get(target); }; +// Sugar to render a book +EPUBJS.Book.prototype.renderTo = function(element, options) { + var rendition = new EPUBJS.Renderer(this, options); + rendition.attachTo(element); + return rendition; +}; + EPUBJS.Book.prototype.request = function(_url) { // Switch request methods if(this.archived) { diff --git a/lib/epubjs/core.js b/lib/epubjs/core.js index 9ce9f0c..2d65ce0 100644 --- a/lib/epubjs/core.js +++ b/lib/epubjs/core.js @@ -153,4 +153,108 @@ EPUBJS.core.folder = function(url){ return folder; +}; + + +EPUBJS.core.queue = function(_scope){ + var _q = []; + var scope = _scope; + // Add an item to the queue + var enqueue = function(funcName, args, context) { + _q.push({ + "funcName" : funcName, + "args" : args, + "context" : context + }); + return _q; + }; + // Run one item + var dequeue = function(){ + var inwait; + if(_q.length) { + inwait = _q.shift(); + // Defer to any current tasks + // setTimeout(function(){ + scope[inwait.funcName].apply(inwait.context || scope, inwait.args); + // }, 0); + } + }; + + // Run All + var flush = function(){ + while(_q.length) { + dequeue(); + } + }; + // Clear all items in wait + var clear = function(){ + _q = []; + }; + + var length = function(){ + return _q.length; + }; + + return { + "enqueue" : enqueue, + "dequeue" : dequeue, + "flush" : flush, + "clear" : clear, + "length" : length + }; +}; + +EPUBJS.core.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); +}; + +// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript +EPUBJS.core.uuid = function() { + var d = new Date().getTime(); + var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = (d + Math.random()*16)%16 | 0; + d = Math.floor(d/16); + return (c=='x' ? r : (r&0x7|0x8)).toString(16); + }); + return uuid; +}; + +// From Lodash +EPUBJS.core.values = function(object) { + var index = -1, + props = Object.keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; +}; + +EPUBJS.core.resolveUrl = function(base, path) { + var url, + segments = [], + // uri = EPUBJS.core.uri(path), + folders = base.split("/"), + paths; + + // if(uri.host) { + // return path; + // } + + folders.pop(); + + paths = path.split("/"); + paths.forEach(function(p){ + if(p === ".."){ + folders.pop(); + }else{ + segments.push(p); + } + }); + + url = folders.concat(segments); + + return url.join("/"); }; \ No newline at end of file diff --git a/lib/epubjs/hooks.js b/lib/epubjs/hooks.js new file mode 100644 index 0000000..e2a7a7e --- /dev/null +++ b/lib/epubjs/hooks.js @@ -0,0 +1,87 @@ +EPUBJS.hooks = {}; +EPUBJS.Hooks = (function(){ + function hooks(){} + + //-- Get pre-registered hooks + hooks.prototype.getHooks = function(){ + var plugs, hooks; + this.hooks = {}; + Array.prototype.slice.call(arguments).forEach(function(arg){ + this.hooks[arg] = []; + }, this); + + for (var plugType in this.hooks) { + hooks = EPUBJS.hooks[plugType]; + if(hooks){ + plugs = EPUBJS.core.values(); + + plugs.forEach(function(hook){ + this.registerHook(plugType, hook); + }, this); + } + } + }; + + //-- Hooks allow for injecting async functions that must all complete before continuing + // Functions must have a callback as their first argument. + hooks.prototype.registerHook = function(type, toAdd, toFront){ + + if(typeof(this.hooks[type]) != "undefined"){ + + if(typeof(toAdd) === "function"){ + if(toFront) { + this.hooks[type].unshift(toAdd); + }else{ + this.hooks[type].push(toAdd); + } + }else if(Array.isArray(toAdd)){ + toAdd.forEach(function(hook){ + if(toFront) { + this.hooks[type].unshift(hook); + }else{ + this.hooks[type].push(hook); + } + }, this); + } + }else{ + //-- Allows for undefined hooks, but maybe this should error? + this.hooks[type] = [func]; + } + }; + + hooks.prototype.triggerHooks = function(type, callback, passed){ + var hooks, count; + + if(typeof(this.hooks[type]) == "undefined") return false; + + hooks = this.hooks[type]; + + count = hooks.length; + if(count === 0 && callback) { + callback(); + } + + function countdown(){ + count--; + if(count <= 0 && callback) callback(); + } + + hooks.forEach(function(hook){ + hook(countdown, passed); + }); + }; + + return { + register: function(name) { + if(EPUBJS.hooks[name] === undefined) { EPUBJS.hooks[name] = {}; } + if(typeof EPUBJS.hooks[name] !== 'object') { throw "Already registered: "+name; } + return EPUBJS.hooks[name]; + }, + mixin: function(object) { + for (var prop in hooks.prototype) { + object[prop] = hooks.prototype[prop]; + } + } + }; +})(); + diff --git a/lib/epubjs/infinite.js b/lib/epubjs/infinite.js new file mode 100644 index 0000000..256b76e --- /dev/null +++ b/lib/epubjs/infinite.js @@ -0,0 +1,97 @@ +EPUBJS.Infinite = function(container, renderer){ + this.container = container; + this.windowHeight = window.innerHeight; + this.tick = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; + this.scrolled = false; + this.displaying = false; + this.offset = 250; + this.views = []; + this.renderer = renderer; +}; + +EPUBJS.Infinite.prototype.start = function(first_argument) { + + window.addEventListener("scroll", function(){ + this.scrolled = true; + }.bind(this)); + + this.tick.call(window, this.check.bind(this)); + + // Fill Screen + this.scrolled = false; + +}; + +EPUBJS.Infinite.prototype.forwards = function() { + this.trigger("forwards"); + +}; + +EPUBJS.Infinite.prototype.backwards = function() { + this.trigger("backwards"); + +}; + +/* + +// Manage Views +EPUBJS.Infinite.prototype.jump = function(view){ + this.views.push(view); +}; + +EPUBJS.Infinite.prototype.append = function(view){ + this.views.push(view); + view.appendTo(this.container); +}; + +EPUBJS.Infinite.prototype.prepend = function(view){ + this.views.unshift(view); + view.prependTo(this.container); +}; + +// Simple Insert +EPUBJS.Infinite.prototype.insert = function(view, index){ + + var position; + var distanceFront = index - this.positions[0]; + var distanceRear = index - this.positions[this.positions.length-1]; + + if(distanceFront >= 0 || !this.positions.length) { + position = this.append(view); + this.positions.push(index); + } else if(distanceRear <= 0) { + position = this.prepend(view); + this.positions.unshift(index); + } + + + + return position; +}; + +*/ + +EPUBJS.Infinite.prototype.check = function(){ + + if(this.scrolled && !this.displaying) { + + var scrollTop = document.body.scrollTop;//TODO: make document.body a variable + var scrollHeight = document.body.scrollHeight; + // console.log(scrollTop, this.windowHeight - (scrollHeight - scrollTop) ) + if(this.windowHeight - (scrollHeight - scrollTop) > -this.offset) { + this.forwards(); + } + else if(scrollTop < this.offset) { + this.backwards(); + } + + // console.log(document.body.scrollTop) + + + this.scrolled = false; + } + + this.tick.call(window, this.check.bind(this)); +} + +RSVP.EventTarget.mixin(EPUBJS.Infinite.prototype); \ No newline at end of file diff --git a/lib/epubjs/layout.js b/lib/epubjs/layout.js new file mode 100644 index 0000000..7f200e3 --- /dev/null +++ b/lib/epubjs/layout.js @@ -0,0 +1,95 @@ +/** +* Reconciles the current chapters layout properies with +* the global layout properities. +* Takes: global layout settings object, chapter properties string +* Returns: Object with layout properties +*/ +EPUBJS.Renderer.prototype.reconcileLayoutSettings = function(global, chapter){ + var settings = {}; + + //-- Get the global defaults + for (var attr in global) { + if (global.hasOwnProperty(attr)){ + settings[attr] = global[attr]; + } + } + //-- Get the chapter's display type + chapter.forEach(function(prop){ + var rendition = prop.replace("rendition:", ''); + var split = rendition.indexOf("-"); + var property, value; + + if(split != -1){ + property = rendition.slice(0, split); + value = rendition.slice(split+1); + + settings[property] = value; + } + }); + return settings; +}; + +/** +* Uses the settings to determine which Layout Method is needed +* Triggers events based on the method choosen +* Takes: Layout settings object +* Returns: String of appropriate for EPUBJS.Layout function +*/ +EPUBJS.Renderer.prototype.determineLayout = function(settings){ + // Default is layout: reflowable & spread: auto + var spreads = this.determineSpreads(this.minSpreadWidth); + var layoutMethod = spreads ? "ReflowableSpreads" : "Reflowable"; + var scroll = false; + + if(settings.layout === "pre-paginated") { + layoutMethod = "Fixed"; + scroll = true; + spreads = false; + } + + if(settings.layout === "reflowable" && settings.spread === "none") { + layoutMethod = "Reflowable"; + scroll = false; + spreads = false; + } + + if(settings.layout === "reflowable" && settings.spread === "both") { + layoutMethod = "ReflowableSpreads"; + scroll = false; + spreads = true; + } + + this.spreads = spreads; + this.render.scroll(scroll); + this.trigger("renderer:spreads", spreads); + return layoutMethod; +}; + +//-- STYLES + +EPUBJS.Renderer.prototype.applyStyles = function(styles) { + for (var style in styles) { + for (var view in this.views) { + view.setStyle(style, styles[style]); + } + } +}; + +EPUBJS.Renderer.prototype.setStyle = function(style, val, prefixed){ + for (var view in this.views) { + view.setStyle(style, val, prefixed); + } +}; + +EPUBJS.Renderer.prototype.removeStyle = function(style){ + for (var view in this.views) { + view.removeStyle(style); + } +}; + +//-- HEAD TAGS +EPUBJS.Renderer.prototype.applyHeadTags = function(headTags) { + for ( var headTag in headTags ) { + this.render.addHeadTag(headTag, headTags[headTag]); + } +}; \ No newline at end of file diff --git a/lib/epubjs/listeners.js b/lib/epubjs/listeners.js new file mode 100644 index 0000000..cc23dad --- /dev/null +++ b/lib/epubjs/listeners.js @@ -0,0 +1,70 @@ +EPUBJS.Renderer.prototype.listeners = function(){ + // Dom events to listen for + this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click"]; + this.upEvent = "mouseup"; + this.downEvent = "mousedown"; + if('ontouchstart' in document.documentElement) { + this.listenedEvents.push("touchstart", "touchend"); + this.upEvent = "touchend"; + this.downEvent = "touchstart"; + } + + // Resize events + // this.resized = _.debounce(this.onResized.bind(this), 100); + +}; + +//-- Listeners for events in the frame + +EPUBJS.Renderer.prototype.onResized = function(e) { + var width = this.container.clientWidth; + var height = this.container.clientHeight; + + this.resize(width, height, false); +}; + +EPUBJS.Renderer.prototype.addEventListeners = function(){ + if(!this.render.document) { + return; + } + this.listenedEvents.forEach(function(eventName){ + this.render.document.addEventListener(eventName, this.triggerEvent.bind(this), false); + }, this); + +}; + +EPUBJS.Renderer.prototype.removeEventListeners = function(){ + if(!this.render.document) { + return; + } + this.listenedEvents.forEach(function(eventName){ + this.render.document.removeEventListener(eventName, this.triggerEvent, false); + }, this); + +}; + +// Pass browser events +EPUBJS.Renderer.prototype.triggerEvent = function(e){ + this.trigger("renderer:"+e.type, e); +}; + +EPUBJS.Renderer.prototype.addSelectionListeners = function(){ + this.render.document.addEventListener("selectionchange", this.onSelectionChange.bind(this), false); +}; + +EPUBJS.Renderer.prototype.removeSelectionListeners = function(){ + if(!this.render.document) { + return; + } + this.doc.removeEventListener("selectionchange", this.onSelectionChange, false); +}; + +EPUBJS.Renderer.prototype.onSelectionChange = function(e){ + if (this.selectionEndTimeout) { + clearTimeout(this.selectionEndTimeout); + } + this.selectionEndTimeout = setTimeout(function() { + this.selectedRange = this.render.window.getSelection(); + this.trigger("renderer:selected", this.selectedRange); + }.bind(this), 500); +}; \ No newline at end of file diff --git a/lib/epubjs/render/paginated.js b/lib/epubjs/render/paginated.js new file mode 100644 index 0000000..ef5524b --- /dev/null +++ b/lib/epubjs/render/paginated.js @@ -0,0 +1,63 @@ +EPUBJS.Render.Paginated = function(book, options){ + + // Dom events to listen for + this.listenedEvents = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click"]; + this.upEvent = "mouseup"; + this.downEvent = "mousedown"; + if('ontouchstart' in document.documentElement) { + this.listenedEvents.push("touchstart", "touchend"); + this.upEvent = "touchend"; + this.downEvent = "touchstart"; + } + +}; + +//-- Takes a string or a element +EPUBJS.Render.Paginated.prototype.initialize = function(elem){ + var book = this; + var rendered; + + if(EPUBJS.core.isElement(elem)) { + this.element = elem; + } else if (typeof elem == "string") { + this.element = document.getElementById(elem); + } else { + console.error("Pass an Element or Element Id"); + return; + } + + rendered = this.opened. + then(function(){ + // book.render = new EPUBJS.Renderer[this.settings.renderer](book); + book.renderer.initialize(book.element, book.settings.width, book.settings.height); + book._rendered(); + return book.startDisplay(); + }); + + // rendered.then(null, function(error) { console.error(error); }); + + return rendered; +}; + + +// epub.renderTo("elementID", _type); +// rendition = epub.renderer(book, _type); +// rendition.attachTo("elementID"); +// epub.display(); +// return rendition; + +// epub.display(); +// epub.display(1); +// epub.display("chapt1.html#something"); +// epub.display("epubcfi(/6/30[id-id2640702]!2/4/1:0)"); +// section = book.section(_arg); +// rendition.display(section); +// section.render(); +// section.load(); +// return rendition; + +// epub.rendition.backwards(); +// epub.rendition.forwards(); + +// epub.rendition.addStyle(); +// epub.rendition.addStyles(); diff --git a/lib/epubjs/renderer.js b/lib/epubjs/renderer.js new file mode 100644 index 0000000..37c78ca --- /dev/null +++ b/lib/epubjs/renderer.js @@ -0,0 +1,220 @@ +EPUBJS.Renderer = function(book, _options) { + var options = _options || {}; + var settings = { + hidden: options.hidden || false, + viewLimit: 3, + width: options.width || false, + height: options.height || false, + }; + + this.book = book; + + // Listen for load events + // this.on("render:loaded", this.loaded.bind(this)); + + // Blank Cfi for Parsing + this.epubcfi = new EPUBJS.EpubCFI(); + // this.resized = _.debounce(this.onResized.bind(this), 100); + + this.layoutSettings = {}; + + //-- Adds Hook methods to the Book prototype + // Hooks will all return before triggering the callback. + EPUBJS.Hooks.mixin(this); + + //-- Get pre-registered hooks for events + this.getHooks("beforeChapterDisplay"); + + //-- Queue up page changes if page map isn't ready + this._q = EPUBJS.core.queue(this); + + this.position = 1; + + this.initialize({ + "width" : settings.width, + "height" : settings.height, + "hidden" : true + }); + + this.displaying = false; + this.views = []; + this.positions = []; + +}; + +/** +* Creates an element to render to. +* Resizes to passed width and height or to the elements size +*/ +EPUBJS.Renderer.prototype.initialize = function(_options){ + var options = _options || {}; + var height = options.height || "100%"; + var width = options.width || "100%"; + var hidden = options.hidden || false; + + + this.container = document.createElement("div"); + this.infinite = new EPUBJS.Infinite(this.container, this); + + this.container.style.width = height; + this.container.style.height = width; + this.container.style.overflow = "scroll"; + + if(options.hidden) { + this.wrapper = document.createElement("div"); + this.wrapper.style.visibility = "hidden"; + this.wrapper.style.overflow = "hidden"; + this.wrapper.style.width = "0"; + this.wrapper.style.height = "0"; + + this.wrapper.appendChild(this.container); + return this.wrapper; + } + + return this.container; +}; + + +EPUBJS.Renderer.prototype.attachTo = function(_element){ + var element; + + if(EPUBJS.core.isElement(_element)) { + element = _element; + } else if (typeof _element === "string") { + element = document.getElementById(_element); + } + + if(!element){ + console.error("Not an Element"); + return; + } + + element.appendChild(this.container); + + this.infinite.start(); + + this.infinite.on("forwards", this.forwards.bind(this)); + this.infinite.on("backwards", this.backwards.bind(this)); + +}; + + +EPUBJS.Renderer.prototype.display = function(what){ + var displaying = new RSVP.defer(); + var displayed = displaying.promise; + var view = new EPUBJS.View(); + + this.book.opened.then(function(){ + var section = this.book.spine.get(what); + var rendered; + + if(!section) { + displaying.reject(); + return; + }; + + rendered = section.render(); + + view.index = section.index; + + rendered.then(function(contents){ + return view.load(contents); + }).then(function(){ + displaying.resolve(this); + }.bind(this)); + + // Place view in correct position + this.insert(view, section.index); + + }.bind(this)); + + return displayed; +}; + + +EPUBJS.Renderer.prototype.forwards = function(){ + var next; + var displayed; + + if(this.displaying) return; + + next = this.last().index + 1; + + if(next === this.book.spine.length){ + return; + } + + displayed = this.display(next); + this.displaying = true; + + displayed.then(function(){ + this.displaying = false; + }.bind(this)); + + return displayed; +}; + +EPUBJS.Renderer.prototype.backwards = function(view){ + var prev; + var displayed; + + if(this.displaying) return; + + prev = this.first().index - 1; + if(prev < 0){ + return; + } + + displayed = this.display(prev); + this.displaying = true; + + displayed.then(function(){ + this.displaying = false; + window.scrollBy(0, this.first().height + 20); + }.bind(this)); + + return displayed; +}; + + +// Manage Views +EPUBJS.Renderer.prototype.jump = function(view){ + this.views.push(view); +}; + +EPUBJS.Renderer.prototype.append = function(view){ + this.views.push(view); + view.appendTo(this.container); +}; + +EPUBJS.Renderer.prototype.prepend = function(view){ + this.views.unshift(view); + view.prependTo(this.container); +}; + +// Simple Insert +EPUBJS.Renderer.prototype.insert = function(view, index){ + + if(!this.first()) { + this.append(view); + } else if(index - this.first().index >= 0) { + this.append(view); + } else if(index - this.last().index <= 0) { + this.prepend(view); + } + + // return position; +}; + +// Remove the render element and clean up listeners +EPUBJS.Renderer.prototype.destroy = function() { + +}; + +EPUBJS.Renderer.prototype.first = function() { + return this.views[0]; +}; + +EPUBJS.Renderer.prototype.last = function() { + return this.views[this.views.length-1]; +}; \ No newline at end of file diff --git a/lib/epubjs/spine.js b/lib/epubjs/spine.js index 14a5042..5589b4b 100644 --- a/lib/epubjs/spine.js +++ b/lib/epubjs/spine.js @@ -37,13 +37,13 @@ EPUBJS.Spine = function(_package, _request){ // book.spine.get("chap1.html"); // book.spine.get("#id1234"); EPUBJS.Spine.prototype.get = function(target) { - var index = 1; + var index = 0; - if(typeof target === "number" || isNaN(target) === false){ - index = target-1; - } else if(target.indexOf("#") === 0) { + if(target && (typeof target === "number" || isNaN(target) === false)){ + index = target; + } else if(target && target.indexOf("#") === 0) { index = this.spineById[target.substring(1)]; - } else { + } else if(target) { index = this.spineByHref[target]; } @@ -71,7 +71,13 @@ EPUBJS.SpineItem.prototype.load = function(_request){ loading.resolve(this.contents); } else { request(this.url, 'xml').then(function(xml){ + var base; + var directory = EPUBJS.core.folder(this.url); + this.document = xml; this.contents = xml.documentElement; + + this.replacements(this.document); + loading.resolve(this.contents); }.bind(this)); } @@ -79,11 +85,23 @@ EPUBJS.SpineItem.prototype.load = function(_request){ return loaded; }; +EPUBJS.SpineItem.prototype.replacements = function(_document){ + var base = _document.createElement("base"); + base.setAttribute("href", this.url); + _document.head.insertBefore(base, _document.head.firstChild); +}; + EPUBJS.SpineItem.prototype.render = function(){ - return this.load().then(function(contents){ + var rendering = new RSVP.defer(); + var rendered = rendering.promise; + + this.load().then(function(contents){ var serializer = new XMLSerializer(); - return serializer.serializeToString(contents); + var output = serializer.serializeToString(contents); + rendering.resolve(output); }); + + return rendered; }; EPUBJS.SpineItem.prototype.find = function(_query){ diff --git a/lib/epubjs/view.js b/lib/epubjs/view.js new file mode 100644 index 0000000..9e22058 --- /dev/null +++ b/lib/epubjs/view.js @@ -0,0 +1,87 @@ +EPUBJS.View = function(options) { + this.id = "epubjs-view:" + EPUBJS.core.uuid(); + this.loading = new RSVP.defer(); + this.loaded = this.loading.promise; + this.iframe = this.create(); + this.height; + this.width; +}; + +// EPUBJS.View.prototype.load = function(section) { +// var contents = section.render(); +// var loading = new RSVP.defer(); +// var loaded = loading.promise; + +// this.section = section; + +// contents.then(function(contents) { +// //TODO: Add a more generic set contents +// this.iframe.srcdoc = contents; +// this.layout(); + +// loading.resolve(this); +// }.bind(this)); + +// return loaded; +// }; + +EPUBJS.View.prototype.load = function(contents) { + var loading = new RSVP.defer(); + var loaded = loading.promise; + + this.document = this.iframe.contentDocument; + + // this.iframe.srcdoc = contents; + this.document.open(); + this.document.write(contents); + this.document.close(); + + this.iframe.onload = function(e) { + this.iframe.style.display = "block"; + this.layout(); + this.iframe.style.visibility = "visible"; + loading.resolve(this); + this.loading.resolve(this); + }.bind(this); + + return loaded; +}; + + +EPUBJS.View.prototype.unload = function() { + +}; + +EPUBJS.View.prototype.create = function() { + this.iframe = document.createElement('iframe'); + this.iframe.id = this.id; + this.iframe.scrolling = "no"; + this.iframe.seamless = "seamless"; + // Back up if seamless isn't supported + this.iframe.style.border = "none"; + this.iframe.width = "100%"; + this.iframe.height = "100%"; + // this.iframe.addEventListener("load", this.loaded.bind(this), false); + this.iframe.style.display = "none"; + this.iframe.style.visibility = "hidden"; + + return this.iframe; +}; + +EPUBJS.View.prototype.layout = function() { + this.height = this.document.documentElement.getBoundingClientRect().height; + this.width = this.document.documentElement.getBoundingClientRect().width; + this.iframe.style.height = this.height + "px"; +}; + +EPUBJS.View.prototype.appendTo = function(element) { + element.appendChild(this.iframe); +}; + +EPUBJS.View.prototype.prependTo = function(element) { + element.insertBefore(this.iframe, element.firstChild); +}; + +EPUBJS.View.prototype.destroy = function() { + +}; \ No newline at end of file diff --git a/test/index.html b/test/index.html index 8ccc079..75b525a 100644 --- a/test/index.html +++ b/test/index.html @@ -12,18 +12,22 @@ + + +
- + + diff --git a/test/tests/rendering.js b/test/tests/rendering.js new file mode 100644 index 0000000..40d6e17 --- /dev/null +++ b/test/tests/rendering.js @@ -0,0 +1,15 @@ +module('Rendering'); + +asyncTest("Render To", 1, function() { + + var book = ePub("../books/moby-dick/OPS/package.opf"); + var rendition = book.renderTo("qunit-fixture"); + var displayed = rendition.display(); + + displayed.then(function(){ + equal( $( "iframe", "#qunit-fixture" ).length, 1, "iframe added successfully" ); + start(); + }); + + +}); \ No newline at end of file