diff --git a/extensions/firefox/components/pdfContentHandler.js b/extensions/firefox/components/pdfContentHandler.js index 9186bfd8a..7746e41b6 100644 --- a/extensions/firefox/components/pdfContentHandler.js +++ b/extensions/firefox/components/pdfContentHandler.js @@ -20,115 +20,17 @@ function log(aMsg) { dump(msg + '\n'); } -function fireEventTo(aName, aData, aWindow) { - let window = aWindow.wrappedJSObject; - let evt = window.document.createEvent('CustomEvent'); - evt.initCustomEvent('pdf' + aName, false, false, aData); - window.document.dispatchEvent(evt); -} - -function loadDocument(aWindow, aDocumentUrl) { - let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'] - .createInstance(Ci.nsIXMLHttpRequest); - xhr.onprogress = function updateProgress(evt) { - if (evt.lengthComputable) - fireEventTo(evt.type, evt.loaded / evt.total, aWindow); - }; - - xhr.onerror = function error(evt) { - fireEventTo(evt.type, false, aWindow); - }; - - xhr.onload = function load(evt) { - let data = (xhr.mozResponseArrayBuffer || xhr.mozResponse || - xhr.responseArrayBuffer || xhr.response); - try { - let view = new Uint8Array(data); - - let window = aWindow.wrappedJSObject; - let arrayBuffer = new window.ArrayBuffer(data.byteLength); - let view2 = new window.Uint8Array(arrayBuffer); - view2.set(view); - - fireEventTo(evt.type, arrayBuffer, aWindow); - } catch (e) { - log('Error - ' + e); - } - }; - - xhr.open('GET', aDocumentUrl); - xhr.responseType = 'arraybuffer'; - xhr.send(null); -} - -let WebProgressListener = { - init: function WebProgressListenerInit(aWindow, aUrl) { - this._locationHasChanged = false; - this._documentUrl = aUrl; - - let flags = Ci.nsIWebProgress.NOTIFY_LOCATION | - Ci.nsIWebProgress.NOTIFY_STATE_NETWORK | - Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT; - - let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell); - let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebProgress); - try { - webProgress.removeProgressListener(this); - } catch (e) {} - webProgress.addProgressListener(this, flags); - }, - - onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, - aStatus) { - const complete = Ci.nsIWebProgressListener.STATE_IS_WINDOW + - Ci.nsIWebProgressListener.STATE_STOP; - if ((aStateFlags & complete) == complete && this._locationHasChanged) { - aWebProgress.removeProgressListener(this); - loadDocument(aWebProgress.DOMWindow, this._documentUrl); - } - }, - - onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, - aMaxSelf, aCurTotal, aMaxTotal) { - }, - - onLocationChange: function onLocationChange(aWebProgress, aRequest, - aLocationURI) { - this._locationHasChanged = true; - }, - - onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, - aMessage) { - }, - - onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) { - }, - - QueryInterface: function QueryInterface(aIID) { - if (aIID.equals(Ci.nsIWebProgressListener) || - aIID.equals(Ci.nsISupportsWeakReference) || - aIID.equals(Ci.nsISupports)) { - return this; - } - - throw Components.results.NS_ERROR_NO_INTERFACE; - } -}; - - +const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; function pdfContentHandler() { } pdfContentHandler.prototype = { handleContent: function handleContent(aMimetype, aContext, aRequest) { if (aMimetype != PDF_CONTENT_TYPE) - throw Cr.NS_ERROR_WONT_HANDLE_CONTENT; + throw NS_ERROR_WONT_HANDLE_CONTENT; if (!(aRequest instanceof Ci.nsIChannel)) - throw Cr.NS_ERROR_WONT_HANDLE_CONTENT; + throw NS_ERROR_WONT_HANDLE_CONTENT; let window = null; let callbacks = aRequest.notificationCallbacks || @@ -136,19 +38,22 @@ pdfContentHandler.prototype = { if (!callbacks) return; - aRequest.cancel(Cr.NS_BINDING_ABORTED); - let uri = aRequest.URI; - window = callbacks.getInterface(Ci.nsIDOMWindow); - WebProgressListener.init(window, uri.spec); + let url = null; try { - let url = Services.prefs.getCharPref('extensions.pdf.js.url'); - url = url.replace('%s', uri.spec); - window.location = url; + url = Services.prefs.getCharPref('extensions.pdf.js.url'); } catch (e) { log('Error retrieving the pdf.js base url - ' + e); + throw NS_ERROR_WONT_HANDLE_CONTENT; } + + let targetUrl = aRequest.URI.spec; + if (targetUrl.indexOf('?pdfjs.action=download') >= 0) + throw NS_ERROR_WONT_HANDLE_CONTENT; + + aRequest.cancel(Cr.NS_BINDING_ABORTED); + window.location = url.replace('%s', targetUrl); }, classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'), @@ -157,4 +62,3 @@ pdfContentHandler.prototype = { var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]); - diff --git a/pdf.js b/pdf.js index 2ee61ada6..378c17580 100644 --- a/pdf.js +++ b/pdf.js @@ -2021,6 +2021,25 @@ var CCITTFaxStream = (function ccittFaxStream() { return EOF; }; + var findTableCode = function ccittFaxStreamFindTableCode(start, end, table, + limit) { + for (var i = start; i <= end; ++i) { + var code = this.lookBits(i); + if (code == EOF) + return [true, 1]; + if (i < end) + code <<= end - i; + if (code >= limit) { + var p = table[code - ((limit == ccittEOL) ? 0 : limit)]; + if (p[0] == i) { + this.eatBits(i); + return [true, p[1]]; + } + } + } + return [false, 0]; + }; + constructor.prototype.getWhiteCode = function ccittFaxStreamGetWhiteCode() { var code = 0; var p; @@ -2040,31 +2059,13 @@ var CCITTFaxStream = (function ccittFaxStream() { return p[1]; } } else { - for (var n = 1; n <= 9; ++n) { - code = this.lookBits(n); - if (code == EOF) - return 1; + var result = findTableCode(1, 9, whiteTable2, ccittEOL); + if (result[0]) + return result[1]; - if (n < 9) - code <<= 9 - n; - p = whiteTable2[code]; - if (p[0] == n) { - this.eatBits(n); - return p[0]; - } - } - for (var n = 11; n <= 12; ++n) { - code = this.lookBits(n); - if (code == EOF) - return 1; - if (n < 12) - code <<= 12 - n; - p = whiteTable1[code]; - if (p[0] == n) { - this.eatBits(n); - return p[1]; - } - } + result = findTableCode(11, 12, whiteTable1, ccittEOL); + if (result[0]) + return result[1]; } warn('bad white code'); this.eatBits(1); @@ -2089,45 +2090,17 @@ var CCITTFaxStream = (function ccittFaxStream() { return p[1]; } } else { - var n; - for (n = 2; n <= 6; ++n) { - code = this.lookBits(n); - if (code == EOF) - return 1; - if (n < 6) - code <<= 6 - n; - p = blackTable3[code]; - if (p[0] == n) { - this.eatBits(n); - return p[1]; - } - } - for (n = 7; n <= 12; ++n) { - code = this.lookBits(n); - if (code == EOF) - return 1; - if (n < 12) - code <<= 12 - n; - if (code >= 64) { - p = blackTable2[code - 64]; - if (p[0] == n) { - this.eatBits(n); - return p[1]; - } - } - } - for (n = 10; n <= 13; ++n) { - code = this.lookBits(n); - if (code == EOF) - return 1; - if (n < 13) - code <<= 13 - n; - p = blackTable1[code]; - if (p[0] == n) { - this.eatBits(n); - return p[1]; - } - } + var result = findTableCode(2, 6, blackTable3, ccittEOL); + if (result[0]) + return result[1]; + + result = findTableCode(7, 12, blackTable2, 64); + if (result[0]) + return result[1]; + + result = findTableCode(10, 13, blackTable1, ccittEOL); + if (result[0]) + return result[1]; } warn('bad black code'); this.eatBits(1); @@ -3634,8 +3607,8 @@ var Page = (function pagePage() { gfx.execute(this.code, xref, resources); gfx.endDrawing(); }, - rotatePoint: function pageRotatePoint(x, y) { - var rotate = this.rotate; + rotatePoint: function pageRotatePoint(x, y, reverse) { + var rotate = reverse ? (360 - this.rotate) : this.rotate; switch (rotate) { case 180: return {x: this.width - x, y: y}; @@ -3643,6 +3616,7 @@ var Page = (function pagePage() { return {x: this.width - y, y: this.height - x}; case 270: return {x: y, y: x}; + case 360: case 0: default: return {x: x, y: this.height - y}; diff --git a/test/driver.js b/test/driver.js index 7f5aef733..4b42c40b5 100644 --- a/test/driver.js +++ b/test/driver.js @@ -66,7 +66,8 @@ function nextTask() { cleanup(); if (currentTaskIdx == manifest.length) { - return done(); + done(); + return; } var task = manifest[currentTaskIdx]; task.round = 0; @@ -86,7 +87,11 @@ function nextTask() { } function isLastPage(task) { - return task.pageNum > task.pdfDoc.numPages || task.pageNum > task.pageLimit; + var limit = task.pageLimit || 0; + if (!limit || limit > task.pdfDoc.numPages) + limit = task.pdfDoc.numPages; + + return task.pageNum > limit; } function canvasToDataURL() { diff --git a/web/images/bookmark.svg b/web/images/bookmark.svg new file mode 100644 index 000000000..2c1fa130d --- /dev/null +++ b/web/images/bookmark.svg @@ -0,0 +1,661 @@ + + + + diff --git a/web/images/download.svg b/web/images/download.svg new file mode 100644 index 000000000..2922c4331 --- /dev/null +++ b/web/images/download.svg @@ -0,0 +1,619 @@ + + + diff --git a/web/viewer.css b/web/viewer.css index e72bdc286..040b87bdf 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -8,6 +8,10 @@ body { padding: 0px; } +[hidden] { + display: none; +} + /* === Toolbar === */ #controls { background-color: #eee; @@ -34,6 +38,10 @@ body { margin: 4px; } +#controls > a > img { + margin: 2px; +} + #controls > button { line-height: 32px; } diff --git a/web/viewer.html b/web/viewer.html index 160c5ce57..f348b6c58 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -17,12 +17,12 @@