Browse Source

fix merge conflicts

= 14 years ago
parent
commit
ff2dea38ec
  1. 7
      Makefile
  2. 73
      README.md
  3. 6
      crypto.js
  4. 4
      examples/helloworld/README.md
  5. 32
      examples/helloworld/hello.js
  6. 27
      extensions/firefox/bootstrap.js
  7. 93
      extensions/firefox/components/pdfContentHandler.js
  8. 2
      extensions/firefox/install.rdf
  9. 8
      fonts.js
  10. 459
      pdf.js
  11. 14
      test/driver.js
  12. 1
      test/pdfs/unix01.pdf.link
  13. 6
      test/test_manifest.json
  14. 2
      utils/fonts_utils.js
  15. 2
      web/viewer.html
  16. 146
      web/viewer.js

7
Makefile

@ -88,7 +88,8 @@ browser-test: @@ -88,7 +88,8 @@ browser-test:
# To install gjslint, see:
#
# <http://code.google.com/closure/utilities/docs/linter_howto.html>
SRC_DIRS := . utils worker web test
SRC_DIRS := . utils worker web test examples/helloworld extensions/firefox \
extensions/firefox/components
GJSLINT_FILES = $(foreach DIR,$(SRC_DIRS),$(wildcard $(DIR)/*.js))
lint:
gjslint $(GJSLINT_FILES)
@ -165,9 +166,9 @@ PDF_WEB_FILES = \ @@ -165,9 +166,9 @@ PDF_WEB_FILES = \
extension:
# Copy a standalone version of pdf.js inside the content directory
@rm -Rf $(EXTENSION_SRC)/$(CONTENT_DIR)/
@mkdir $(EXTENSION_SRC)/$(CONTENT_DIR)/
@mkdir -p $(EXTENSION_SRC)/$(CONTENT_DIR)/web
@cp $(PDF_JS_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/
@cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/
@cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/web/
# Create the xpi
@cd $(EXTENSION_SRC); zip -r $(EXTENSION_NAME) *

73
README.md

@ -18,46 +18,42 @@ successful. @@ -18,46 +18,42 @@ successful.
## Getting started
**Online demo**
### Online demo
For an online demo, visit:
http://andreasgal.github.com/pdf.js/web/viewer.html
+ http://andreasgal.github.com/pdf.js/web/viewer.html
This demo provides an interactive interface for displaying and browsing PDFs
using the pdf.js API.
**Getting the code**
### Getting the code
To get a local copy of the current code, clone it using git:
```bash
git clone git://github.com/andreasgal/pdf.js.git pdfjs
cd pdfjs
```
$ git clone git://github.com/andreasgal/pdf.js.git pdfjs
$ cd pdfjs
Next, you need to start a local web server as some browsers don't allow opening
PDF files for a file:// url:
```bash
make server
```
$ make server
If everything worked out, you can now serve
http://localhost:8888/web/viewer.html
+ http://localhost:8888/web/viewer.html
You can also view all the test pdf files on the right side serving
http://localhost:8888/test/pdfs/?frame
+ http://localhost:8888/test/pdfs/?frame
**Hello world**
### Hello world
For a "hello world" example, take a look at:
examples/helloworld/
+ [examples/helloworld/hello.js](https://github.com/andreasgal/pdf.js/blob/master/examples/helloworld/hello.js)
This example illustrates the bare minimum ingredients for integrating pdf.js
in a custom project.
@ -66,16 +62,22 @@ in a custom project. @@ -66,16 +62,22 @@ in a custom project.
## Contributing
pdf.js is a community-driver project, so contributors are always welcome.
pdf.js is a community-driven project, so contributors are always welcome.
Simply fork our repo and contribute away. A great place to start is our
open issues. For better consistency and long-term stability, please do look around the
code and try to follow our conventions.
[open issues](https://github.com/andreasgal/pdf.js/issues). For better consistency and
long-term stability, please do look around the code and try to follow our conventions.
If you __don't want to hack__ on the project or have short spare times, you still
can help! Just open PDFs in the
If you don't want to hack on the project or have short spare times, __you still
can help!__ Just open PDFs in the
[online demo](http://andreasgal.github.com/pdf.js/web/viewer.html) and report
any breakage in rendering.
Our Github contributors so far:
+ https://github.com/andreasgal/pdf.js/contributors
You can add your name to it! :)
## Running the Tests
@ -108,47 +110,46 @@ raising any errors. @@ -108,47 +110,46 @@ raising any errors.
Our demo site is here:
http://andreasgal.github.com/pdf.js/web/viewer.html
+ http://andreasgal.github.com/pdf.js/web/viewer.html
You can read more about pdf.js here:
http://andreasgal.com/2011/06/15/pdf-js/
+ http://andreasgal.com/2011/06/15/pdf-js/
+ http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/
http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/
Follow us on twitter: @pdfjs
Talk to us on IRC:
http://twitter.com/#!/pdfjs
+ #pdfjs on irc.mozilla.org
Join our mailing list:
dev-pdf-js@lists.mozilla.org
+ dev-pdf-js@lists.mozilla.org
Subscribe either using lists.mozilla.org or Google Groups:
https://lists.mozilla.org/listinfo/dev-pdf-js
+ https://lists.mozilla.org/listinfo/dev-pdf-js
+ https://groups.google.com/group/mozilla.dev.pdf-js/topics
https://groups.google.com/group/mozilla.dev.pdf-js/topics
Follow us on twitter: @pdfjs
+ http://twitter.com/#!/pdfjs
Talk to us on IRC:
#pdfjs on irc.mozilla.org
## Additional resources to understand the structure of PDF
A really basic overview of PDF is described here:
http://partners.adobe.com/public/developer/en/livecycle/lc_pdf_overview_format.pdf
+ http://partners.adobe.com/public/developer/en/livecycle/lc_pdf_overview_format.pdf
A more detailed file example:
http://gnupdf.org/Introduction_to_PDF
+ http://gnupdf.org/Introduction_to_PDF
The PDF specification itself is an ISO and not free available. However, there is
The PDF specification itself is an ISO and not freely available. However, there is
a "PDF Reference" from Adobe:
http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf
+ http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf
Recommanded chapters to read: "2. Overview", "3.4 File Structure",
Recommended chapters to read: "2. Overview", "3.4 File Structure",
"4.1 Graphics Objects" that lists the PDF commands.

6
crypto.js

@ -493,16 +493,16 @@ var CipherTransformFactory = (function cipherTransformFactory() { @@ -493,16 +493,16 @@ var CipherTransformFactory = (function cipherTransformFactory() {
function constructor(dict, fileId, password) {
var filter = dict.get('Filter');
if (!IsName(filter) || filter.name != 'Standard')
if (!isName(filter) || filter.name != 'Standard')
error('unknown encryption method');
this.dict = dict;
var algorithm = dict.get('V');
if (!IsInt(algorithm) ||
if (!isInt(algorithm) ||
(algorithm != 1 && algorithm != 2 && algorithm != 4))
error('unsupported encryption algorithm');
this.algorithm = algorithm;
var keyLength = dict.get('Length') || 40;
if (!IsInt(keyLength) ||
if (!isInt(keyLength) ||
keyLength < 40 || (keyLength % 8) != 0)
error('invalid key length');
// prepare keys

4
examples/helloworld/README.md

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
## "Hello World" overview
This example is a minimalistic application of the pdf.js project. The file
`helloworld.pdf` is from the GNUpdf project (see [Introduction to PDF at GNUpdf](http://gnupdf.org/Introduction_to_PDF), and contains a simple and
`helloworld.pdf` is from the GNUpdf project (see [Introduction to PDF at
GNUpdf] (http://gnupdf.org/Introduction_to_PDF)), and contains a simple and
human-readable PDF.
@ -14,3 +15,4 @@ how to make basic calls to `pdf.js`. @@ -14,3 +15,4 @@ how to make basic calls to `pdf.js`.
## Additional resources
+ [GNUpdf - Introduction to PDF](http://gnupdf.org/Introduction_to_PDF)

32
examples/helloworld/hello.js

@ -1,36 +1,17 @@ @@ -1,36 +1,17 @@
//
// See README for overview
//
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
//
// Ajax GET request, for binary files
// (like jQuery's $.get(), but supports the binary type ArrayBuffer)
// See README for overview
//
var ajaxGet = function(url, callback){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
xhr.responseArrayBuffer || xhr.response);
callback(data);
}
};
xhr.send(null);
}
'use strict';
//
// This is where the fun happens
//
ajaxGet('helloworld.pdf', function(data){
getPdf('helloworld.pdf', function getPdfHelloWorld(data) {
//
// Instantiate PDFDoc with PDF data
//
var pdf = new PDFDoc(new Stream(data));
var pdf = new PDFDoc(data);
var page = pdf.getPage(1);
var scale = 1.5;
@ -47,3 +28,4 @@ ajaxGet('helloworld.pdf', function(data){ @@ -47,3 +28,4 @@ ajaxGet('helloworld.pdf', function(data){
//
page.startRendering(context);
});

27
extensions/firefox/bootstrap.js vendored

@ -1,31 +1,36 @@ @@ -1,31 +1,36 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict';
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cm = Components.manager;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import('resource://gre/modules/Services.jsm');
function log(str) {
dump(str + "\n");
};
dump(str + '\n');
}
function startup(aData, aReason) {
let manifestPath = "chrome.manifest";
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
let manifestPath = 'chrome.manifest';
let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
try {
file.initWithPath(aData.installPath.path);
file.append(manifestPath);
Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file);
} catch(e) {
} catch (e) {
log(e);
}
};
}
function shutdown(aData, aReason) {
};
}
function install(aData, aReason) {
let url = "chrome://pdf.js/content/web/viewer.html?file=%s";
Services.prefs.setCharPref("extensions.pdf.js.url", url);
};
let url = 'chrome://pdf.js/content/web/viewer.html?file=%s';
Services.prefs.setCharPref('extensions.pdf.js.url', url);
}

93
extensions/firefox/components/pdfContentHandler.js

@ -1,52 +1,65 @@ @@ -1,52 +1,65 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict';
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const PDF_CONTENT_TYPE = "application/pdf";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const PDF_CONTENT_TYPE = 'application/pdf';
// TODO
// Add some download progress event
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
function log(aMsg) {
let msg = "pdfContentHandler.js: " + (aMsg.join ? aMsg.join("") : aMsg);
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
let msg = 'pdfContentHandler.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService)
.logStringMessage(msg);
dump(msg + "\n");
};
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"]
let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1']
.createInstance(Ci.nsIXMLHttpRequest);
xhr.open("GET", aDocumentUrl);
xhr.mozResponseType = xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
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 {
var view = new Uint8Array(data);
let view = new Uint8Array(data);
// I think accessing aWindow.wrappedJSObject returns a
// XPCSafeJSObjectWrapper and so it is safe but mrbkap can confirm that
let window = aWindow.wrappedJSObject;
var arrayBuffer = new window.ArrayBuffer(data.byteLength);
var view2 = new window.Uint8Array(arrayBuffer);
let arrayBuffer = new window.ArrayBuffer(data.byteLength);
let view2 = new window.Uint8Array(arrayBuffer);
view2.set(view);
let evt = window.document.createEvent("CustomEvent");
evt.initCustomEvent("pdfloaded", false, false, arrayBuffer);
window.document.dispatchEvent(evt);
} catch(e) {
log("Error - " + e);
}
fireEventTo(evt.type, arrayBuffer, aWindow);
} catch (e) {
log('Error - ' + e);
}
};
xhr.open('GET', aDocumentUrl);
xhr.responseType = 'arraybuffer';
xhr.send(null);
};
}
let WebProgressListener = {
init: function(aWindow, aUrl) {
@ -64,11 +77,12 @@ let WebProgressListener = { @@ -64,11 +77,12 @@ let WebProgressListener = {
.getInterface(Ci.nsIWebProgress);
try {
webProgress.removeProgressListener(this);
} catch(e) {}
} catch (e) {}
webProgress.addProgressListener(this, flags);
},
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags,
aStatus) {
const complete = Ci.nsIWebProgressListener.STATE_IS_WINDOW +
Ci.nsIWebProgressListener.STATE_STOP;
if ((aStateFlags & complete) == complete && this._locationHasChanged) {
@ -77,14 +91,17 @@ let WebProgressListener = { @@ -77,14 +91,17 @@ let WebProgressListener = {
}
},
onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf,
aMaxSelf, aCurTotal, aMaxTotal) {
},
onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI) {
onLocationChange: function onLocationChange(aWebProgress, aRequest,
aLocationURI) {
this._locationHasChanged = true;
},
onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus,
aMessage) {
},
onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) {
@ -127,16 +144,16 @@ pdfContentHandler.prototype = { @@ -127,16 +144,16 @@ pdfContentHandler.prototype = {
WebProgressListener.init(window, uri.spec);
try {
let url = Services.prefs.getCharPref("extensions.pdf.js.url");
url = url.replace("%s", uri.spec);
let url = Services.prefs.getCharPref('extensions.pdf.js.url');
url = url.replace('%s', uri.spec);
window.location = url;
} catch(e) {
log("Error - " + e);
} catch (e) {
log('Error retrieving the pdf.js base url - ' + e);
}
},
classID: Components.ID("{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler]),
classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]);

2
extensions/firefox/install.rdf

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>6.0</em:minVersion>
<em:maxVersion>9.0.*</em:maxVersion>
<em:maxVersion>10.0.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:bootstrap>true</em:bootstrap>

8
fonts.js

@ -1222,7 +1222,7 @@ var Font = (function Font() { @@ -1222,7 +1222,7 @@ var Font = (function Font() {
encoding[i] = {
unicode: i <= 0x1f || (i >= 127 && i <= 255) ?
i + kCmapGlyphOffset : i,
width: IsNum(width) ? width : properties.defaultWidth
width: isNum(width) ? width : properties.defaultWidth
};
}
} else {
@ -2212,7 +2212,7 @@ CFF.prototype = { @@ -2212,7 +2212,7 @@ CFF.prototype = {
var cmd = map[command];
assert(cmd, 'Unknow command: ' + command);
if (IsArray(cmd))
if (isArray(cmd))
charstring.splice(i++, 1, cmd[0], cmd[1]);
else
charstring[i] = cmd;
@ -2338,7 +2338,7 @@ CFF.prototype = { @@ -2338,7 +2338,7 @@ CFF.prototype = {
continue;
var value = properties.private[field];
if (IsArray(value)) {
if (isArray(value)) {
data += self.encodeNumber(value[0]);
for (var i = 1; i < value.length; i++)
data += self.encodeNumber(value[i] - value[i - 1]);
@ -2497,7 +2497,7 @@ var Type2CFF = (function type2CFF() { @@ -2497,7 +2497,7 @@ var Type2CFF = (function type2CFF() {
var width = mapping.width;
properties.glyphs[glyph] = properties.encoding[index] = {
unicode: code,
width: IsNum(width) ? width : defaultWidth
width: isNum(width) ? width : defaultWidth
};
charstrings.push({

459
pdf.js

File diff suppressed because it is too large Load Diff

14
test/driver.js

@ -73,26 +73,16 @@ function nextTask() { @@ -73,26 +73,16 @@ function nextTask() {
log('Loading file "' + task.file + '"\n');
var r = new XMLHttpRequest();
r.open('GET', task.file);
r.mozResponseType = r.responseType = 'arraybuffer';
r.onreadystatechange = function nextTaskOnreadystatechange() {
getPdf(task.file, function nextTaskGetPdf(data) {
var failure;
if (r.readyState == 4) {
var data = r.mozResponseArrayBuffer || r.mozResponse ||
r.responseArrayBuffer || r.response;
try {
task.pdfDoc = new PDFDoc(data);
} catch (e) {
failure = 'load PDF doc : ' + e.toString();
}
task.pageNum = 1;
nextPage(task, failure);
}
};
r.send(null);
});
}
function isLastPage(task) {

1
test/pdfs/unix01.pdf.link

@ -0,0 +1 @@ @@ -0,0 +1 @@
https://docs.rice.edu/confluence/download/attachments/4588376/unix01.pdf?version=1

6
test/test_manifest.json

@ -128,6 +128,12 @@ @@ -128,6 +128,12 @@
"rounds": 1,
"type": "eq"
},
{ "id": "unix01",
"file": "pdfs/unix01.pdf",
"link": true,
"rounds": 1,
"type": "eq"
},
{ "id": "fips197",
"file": "pdfs/fips197.pdf",
"link": true,

2
utils/fonts_utils.js

@ -258,7 +258,7 @@ var Type2Parser = function(aFilePath) { @@ -258,7 +258,7 @@ var Type2Parser = function(aFilePath) {
var count = decoded.length;
for (var i = 0; i < count; i++) {
var token = decoded[i];
if (IsNum(token)) {
if (isNum(token)) {
stack.push(token);
} else {
switch (token.operand) {

2
web/viewer.html

@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
<div class="separator"></div>
<input type="text" id="pageNumber" onchange="PDFView.page = this.value;" value="1" size="4"/>
<input type="number" id="pageNumber" onchange="PDFView.page = this.value;" value="1" size="4" min="1" />
<span>/</span>
<span id="numPages">--</span>

146
web/viewer.js

@ -9,6 +9,8 @@ var kDefaultScaleDelta = 1.1; @@ -9,6 +9,8 @@ var kDefaultScaleDelta = 1.1;
var kCacheSize = 20;
var kCssUnits = 96.0 / 72.0;
var kScrollbarPadding = 40;
var kMinScale = 0.25;
var kMaxScale = 4.0;
var Cache = function(size) {
@ -21,11 +23,13 @@ var Cache = function(size) { @@ -21,11 +23,13 @@ var Cache = function(size) {
};
var cache = new Cache(kCacheSize);
var currentPageNumber = 1;
var PDFView = {
pages: [],
thumbnails: [],
currentScale: kDefaultScale,
initialBookmark: document.location.hash.substring(1),
setScale: function(val, resetAutoSettings) {
var pages = this.pages;
@ -33,11 +37,8 @@ var PDFView = { @@ -33,11 +37,8 @@ var PDFView = {
pages[i].update(val * kCssUnits);
this.currentScale = val;
if (document.location.hash == '#' + this.page)
this.pages[this.page - 1].scrollIntoView();
this.pages[this.page - 1].draw();
else
// Jump the scroll position to the correct page.
document.location.hash = this.page;
var event = document.createEvent('UIEvents');
event.initUIEvent('scalechange', false, false, window, 0);
@ -72,11 +73,13 @@ var PDFView = { @@ -72,11 +73,13 @@ var PDFView = {
},
zoomIn: function() {
this.setScale(this.currentScale * kDefaultScaleDelta, true);
var newScale = Math.min(kMaxScale, this.currentScale * kDefaultScaleDelta);
this.setScale(newScale, true);
},
zoomOut: function() {
this.setScale(this.currentScale / kDefaultScaleDelta, true);
var newScale = Math.max(kMinScale, this.currentScale / kDefaultScaleDelta);
this.setScale(newScale, true);
},
set page(val) {
@ -87,18 +90,18 @@ var PDFView = { @@ -87,18 +90,18 @@ var PDFView = {
return;
}
document.location.hash = val;
currentPageNumber = val;
document.getElementById('previous').disabled = (val == 1);
document.getElementById('next').disabled = (val == pages.length);
if (input.value == val)
return;
if (input.value != val) {
input.value = val;
pages[val - 1].draw();
}
pages[val - 1].scrollIntoView();
},
get page() {
return parseInt(document.location.hash.substring(1), 10) || 1;
return currentPageNumber;
},
open: function(url, scale) {
@ -107,28 +110,18 @@ var PDFView = { @@ -107,28 +110,18 @@ var PDFView = {
document.title = url;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
xhr.onprogress = PDFView.progressLevel;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
xhr.responseArrayBuffer || xhr.response);
document.getElementById('loading').style.display = 'none';
PDFView.load(data, scale);
}
};
xhr.send(null);
getPdf(
{
url: url,
progress: function getPdfProgress(evt) {
if (evt.lengthComputable)
PDFView.progress(evt.loaded / evt.total);
},
progressLevel: function(evt) {
var p = Math.round((evt.loaded / evt.total) * 100);
document.getElementById('loading').innerHTML = 'Loading... ' + p + '%';
error: PDFView.error
},
function getPdfLoad(data) {
PDFView.load(data, scale);
});
},
navigateTo: function(dest) {
@ -147,7 +140,36 @@ var PDFView = { @@ -147,7 +140,36 @@ var PDFView = {
}
},
getDestinationHash: function(dest) {
if (typeof dest === 'string')
return '#' + escape(dest);
if (dest instanceof Array) {
var destRef = dest[0]; // see nevigateTo method for dest format
var pageNumber = destRef instanceof Object ?
this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
(destRef + 1);
if (pageNumber) {
return '#page=' + pageNumber + '&dest=' + dest.slice(1).join(',');
}
}
return '';
},
error: function() {
var loadingIndicator = document.getElementById('loading');
loadingIndicator.innerHTML = 'Error';
},
progress: function(level) {
var percent = Math.round(level * 100);
var loadingIndicator = document.getElementById('loading');
loadingIndicator.innerHTML = 'Loading... ' + percent + '%';
},
load: function(data, scale) {
var loadingIndicator = document.getElementById('loading');
loadingIndicator.style.display = 'none';
var sidebar = document.getElementById('sidebarView');
sidebar.parentNode.scrollTop = 0;
@ -162,6 +184,7 @@ var PDFView = { @@ -162,6 +184,7 @@ var PDFView = {
var pdf = new PDFDoc(data);
var pagesCount = pdf.numPages;
document.getElementById('numPages').innerHTML = pagesCount;
document.getElementById('pageNumber').max = pagesCount;
var pages = this.pages = [];
var pagesRefMap = {};
@ -177,7 +200,7 @@ var PDFView = { @@ -177,7 +200,7 @@ var PDFView = {
}
this.setScale(scale || kDefaultScale, true);
this.page = parseInt(document.location.hash.substring(1), 10) || 1;
this.pagesRefMap = pagesRefMap;
this.destinations = pdf.catalog.destinations;
if (pdf.catalog.documentOutline) {
@ -186,6 +209,28 @@ var PDFView = { @@ -186,6 +209,28 @@ var PDFView = {
outlineSwitchButton.removeAttribute('disabled');
this.switchSidebarView('outline');
}
if (this.initialBookmark) {
this.setHash(this.initialBookmark);
this.initialBookmark = null;
}
else
this.page = 1;
},
setHash: function(hash) {
if (!hash)
return;
if (hash.indexOf('=') >= 0) {
// TODO more complex hashes, for now catching page=XX only
var m = /\bpage=(\d+)/.exec(hash);
if (m && m[1] > 0)
this.page = m[1];
} else if (/^\d+$/.test(hash)) // page number
this.page = hash;
else // named destination
PDFView.navigateTo(unescape(hash));
},
switchSidebarView: function(view) {
@ -270,6 +315,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight, @@ -270,6 +315,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
function setupLinks(content, scale) {
function bindLink(link, dest) {
link.href = PDFView.getDestinationHash(dest);
link.onclick = function() {
if (dest)
PDFView.navigateTo(dest);
@ -292,6 +338,11 @@ var PageView = function(container, content, id, pageWidth, pageHeight, @@ -292,6 +338,11 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
}
this.scrollIntoView = function(dest) {
if (!dest) {
div.scrollIntoView(true);
return;
}
var x = 0, y = 0;
var width = 0, height = 0, widthScale, heightScale;
var scale = 0;
@ -401,6 +452,10 @@ var PageView = function(container, content, id, pageWidth, pageHeight, @@ -401,6 +452,10 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
var ThumbnailView = function(container, page, id, pageRatio) {
var anchor = document.createElement('a');
anchor.href = '#' + id;
anchor.onclick = function stopNivigation() {
PDFView.page = id;
return false;
};
var div = document.createElement('div');
div.id = 'thumbnailContainer' + id;
@ -448,7 +503,7 @@ var DocumentOutlineView = function(outline) { @@ -448,7 +503,7 @@ var DocumentOutlineView = function(outline) {
var outlineView = document.getElementById('outlineView');
function bindItemLink(domObj, item) {
domObj.href = '';
domObj.href = PDFView.getDestinationHash(item.dest);
domObj.onclick = function(e) {
PDFView.navigateTo(item.dest);
return false;
@ -495,10 +550,18 @@ window.addEventListener('load', function(evt) { @@ -495,10 +550,18 @@ window.addEventListener('load', function(evt) {
document.getElementById('fileInput').value = null;
}, true);
window.addEventListener('pdfloaded', function(evt) {
window.addEventListener('pdfload', function(evt) {
PDFView.load(evt.detail);
}, true);
window.addEventListener('pdfprogress', function(evt) {
PDFView.progress(evt.detail);
}, true);
window.addEventListener('pdferror', function(evt) {
PDFView.error();
}, true);
function updateViewarea() {
var visiblePages = PDFView.getVisiblePages();
for (var i = 0; i < visiblePages.length; i++) {
@ -531,7 +594,7 @@ window.addEventListener('resize', function onscroll(evt) { @@ -531,7 +594,7 @@ window.addEventListener('resize', function onscroll(evt) {
});
window.addEventListener('hashchange', function(evt) {
PDFView.page = PDFView.page;
PDFView.setHash(document.location.hash.substring(1));
});
window.addEventListener('change', function(evt) {
@ -557,7 +620,6 @@ window.addEventListener('change', function(evt) { @@ -557,7 +620,6 @@ window.addEventListener('change', function(evt) {
fileReader.readAsBinaryString(file);
document.title = file.name;
document.location.hash = 1;
}, true);
window.addEventListener('transitionend', function(evt) {
@ -609,13 +671,19 @@ window.addEventListener('scalechange', function scalechange(evt) { @@ -609,13 +671,19 @@ window.addEventListener('scalechange', function scalechange(evt) {
window.addEventListener('pagechange', function pagechange(evt) {
var page = evt.detail;
document.location.hash = page;
document.getElementById('pageNumber').value = page;
document.getElementById('previous').disabled = (page == 1);
document.getElementById('next').disabled = (page == PDFView.pages.length);
}, true);
window.addEventListener('keydown', function keydown(evt) {
var curElement = document.activeElement;
var controlsElement = document.getElementById('controls');
while (curElement) {
if (curElement === controlsElement)
return; // ignoring if the 'controls' element is focused
curElement = curElement.parentNode;
}
switch (evt.keyCode) {
case 61: // FF/Mac '='
case 107: // FF '+' and '='

Loading…
Cancel
Save