Merge pull request #1118 from brendandahl/amowarnings
Address AMO Review Concerns
This commit is contained in:
commit
13f207424c
21
Makefile
21
Makefile
@ -209,11 +209,11 @@ pages-repo: | $(BUILD_DIR)
|
|||||||
# copy of the pdf.js source.
|
# copy of the pdf.js source.
|
||||||
CONTENT_DIR := content
|
CONTENT_DIR := content
|
||||||
BUILD_NUMBER := `git log --format=oneline $(EXTENSION_BASE_VERSION).. | wc -l | awk '{print $$1}'`
|
BUILD_NUMBER := `git log --format=oneline $(EXTENSION_BASE_VERSION).. | wc -l | awk '{print $$1}'`
|
||||||
PDF_WEB_FILES = \
|
EXTENSION_WEB_FILES = \
|
||||||
web/images \
|
web/images \
|
||||||
web/compatibility.js \
|
|
||||||
web/viewer.css \
|
web/viewer.css \
|
||||||
web/viewer.js \
|
web/viewer.js \
|
||||||
|
web/viewer.html \
|
||||||
web/viewer-production.html \
|
web/viewer-production.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
@ -251,8 +251,19 @@ extension: | production
|
|||||||
@cd extensions/firefox; cp -r $(FIREFOX_EXTENSION_FILES_TO_COPY) ../../$(FIREFOX_BUILD_DIR)/
|
@cd extensions/firefox; cp -r $(FIREFOX_EXTENSION_FILES_TO_COPY) ../../$(FIREFOX_BUILD_DIR)/
|
||||||
# Copy a standalone version of pdf.js inside the content directory
|
# Copy a standalone version of pdf.js inside the content directory
|
||||||
@cp $(BUILD_TARGET) $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/
|
@cp $(BUILD_TARGET) $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/
|
||||||
@cp -r $(PDF_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/
|
@cp -r $(EXTENSION_WEB_FILES) $(FIREFOX_BUILD_CONTENT)/web/
|
||||||
@mv -f $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html $(FIREFOX_BUILD_CONTENT)/web/viewer.html
|
@rm $(FIREFOX_BUILD_CONTENT)/web/viewer-production.html
|
||||||
|
# Copy over the firefox extension snippet so we can inline pdf.js in it
|
||||||
|
@cp web/viewer-snippet-firefox-extension.html $(FIREFOX_BUILD_CONTENT)/web/
|
||||||
|
# Modify the viewer so it does all the extension only stuff.
|
||||||
|
@cd $(FIREFOX_BUILD_CONTENT)/web; \
|
||||||
|
sed -i.bak '/PDFJSSCRIPT_INCLUDE_BUNDLE/ r ../build/pdf.js' viewer-snippet-firefox-extension.html; \
|
||||||
|
sed -i.bak '/PDFJSSCRIPT_REMOVE/d' viewer.html; \
|
||||||
|
sed -i.bak '/PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION/d' viewer.html; \
|
||||||
|
sed -i.bak '/PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION/ r viewer-snippet-firefox-extension.html' viewer.html; \
|
||||||
|
rm -f *.bak;
|
||||||
|
# We don't need pdf.js anymore since its inlined
|
||||||
|
@rm -Rf $(FIREFOX_BUILD_CONTENT)/$(BUILD_DIR)/;
|
||||||
# Update the build version number
|
# Update the build version number
|
||||||
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf
|
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/install.rdf
|
||||||
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/update.rdf
|
@sed -i.bak "s/PDFJSSCRIPT_BUILD/$(BUILD_NUMBER)/" $(FIREFOX_BUILD_DIR)/update.rdf
|
||||||
@ -274,7 +285,7 @@ extension: | production
|
|||||||
@cp -R $(CHROME_EXTENSION_FILES) $(CHROME_BUILD_DIR)/
|
@cp -R $(CHROME_EXTENSION_FILES) $(CHROME_BUILD_DIR)/
|
||||||
# Copy a standalone version of pdf.js inside the content directory
|
# Copy a standalone version of pdf.js inside the content directory
|
||||||
@cp $(BUILD_TARGET) $(CHROME_BUILD_CONTENT)/$(BUILD_DIR)/
|
@cp $(BUILD_TARGET) $(CHROME_BUILD_CONTENT)/$(BUILD_DIR)/
|
||||||
@cp -r $(PDF_WEB_FILES) $(CHROME_BUILD_CONTENT)/web/
|
@cp -r $(EXTENSION_WEB_FILES) $(CHROME_BUILD_CONTENT)/web/
|
||||||
@mv -f $(CHROME_BUILD_CONTENT)/web/viewer-production.html $(CHROME_BUILD_CONTENT)/web/viewer.html
|
@mv -f $(CHROME_BUILD_CONTENT)/web/viewer-production.html $(CHROME_BUILD_CONTENT)/web/viewer.html
|
||||||
|
|
||||||
# Create the crx
|
# Create the crx
|
||||||
|
7
extensions/firefox/bootstrap.js
vendored
7
extensions/firefox/bootstrap.js
vendored
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
|
||||||
|
const PDFJS_EVENT_ID = 'pdf.js.message';
|
||||||
let Cc = Components.classes;
|
let Cc = Components.classes;
|
||||||
let Ci = Components.interfaces;
|
let Ci = Components.interfaces;
|
||||||
let Cm = Components.manager;
|
let Cm = Components.manager;
|
||||||
@ -14,6 +16,7 @@ function log(str) {
|
|||||||
dump(str + '\n');
|
dump(str + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function startup(aData, aReason) {
|
function startup(aData, aReason) {
|
||||||
let manifestPath = 'chrome.manifest';
|
let manifestPath = 'chrome.manifest';
|
||||||
let manifest = Cc['@mozilla.org/file/local;1']
|
let manifest = Cc['@mozilla.org/file/local;1']
|
||||||
@ -34,13 +37,11 @@ function shutdown(aData, aReason) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function install(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);
|
|
||||||
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function uninstall(aData, aReason) {
|
function uninstall(aData, aReason) {
|
||||||
Services.prefs.clearUserPref('extensions.pdf.js.url');
|
|
||||||
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
||||||
|
application.prefs.setValue(EXT_PREFIX + '.database', '{}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
content pdf.js content/
|
resource pdf.js content/
|
||||||
|
|
||||||
component {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a} components/pdfContentHandler.js
|
component {6457a96b-2d68-439a-bcfa-44465fbcdbb1} components/PdfStreamConverter.js
|
||||||
contract @mozilla.org/uriloader/content-handler;1?type=application/pdf {2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}
|
contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {6457a96b-2d68-439a-bcfa-44465fbcdbb1}
|
||||||
|
|
||||||
|
159
extensions/firefox/components/PdfStreamConverter.js
Normal file
159
extensions/firefox/components/PdfStreamConverter.js
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* -*- 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 PDFJS_EVENT_ID = 'pdf.js.message';
|
||||||
|
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||||
|
const NS_ERROR_NOT_IMPLEMENTED = 0x80004001;
|
||||||
|
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
|
||||||
|
|
||||||
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
|
|
||||||
|
function log(aMsg) {
|
||||||
|
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||||
|
Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService)
|
||||||
|
.logStringMessage(msg);
|
||||||
|
dump(msg + '\n');
|
||||||
|
}
|
||||||
|
let application = Cc['@mozilla.org/fuel/application;1']
|
||||||
|
.getService(Ci.fuelIApplication);
|
||||||
|
let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
||||||
|
.getService(Ci.nsIPrivateBrowsingService);
|
||||||
|
let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
|
||||||
|
|
||||||
|
// All the priviledged actions.
|
||||||
|
function ChromeActions() {
|
||||||
|
this.inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
|
||||||
|
}
|
||||||
|
ChromeActions.prototype = {
|
||||||
|
download: function(data) {
|
||||||
|
Services.wm.getMostRecentWindow('navigator:browser').saveURL(data);
|
||||||
|
},
|
||||||
|
setDatabase: function(data) {
|
||||||
|
if (this.inPrivateBrowswing)
|
||||||
|
return;
|
||||||
|
application.prefs.setValue(EXT_PREFIX + '.database', data);
|
||||||
|
},
|
||||||
|
getDatabase: function() {
|
||||||
|
if (this.inPrivateBrowswing)
|
||||||
|
return '{}';
|
||||||
|
return application.prefs.getValue(EXT_PREFIX + '.database', '{}');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Event listener to trigger chrome privedged code.
|
||||||
|
function RequestListener(actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
// Receive an event and synchronously responds.
|
||||||
|
RequestListener.prototype.receive = function(event) {
|
||||||
|
var message = event.target;
|
||||||
|
var action = message.getUserData('action');
|
||||||
|
var data = message.getUserData('data');
|
||||||
|
var actions = this.actions;
|
||||||
|
if (!(action in actions)) {
|
||||||
|
log('Unknown action: ' + action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var response = actions[action].call(this.actions, data);
|
||||||
|
message.setUserData('response', response, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function PdfStreamConverter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
PdfStreamConverter.prototype = {
|
||||||
|
|
||||||
|
// properties required for XPCOM registration:
|
||||||
|
classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'),
|
||||||
|
classDescription: 'pdf.js Component',
|
||||||
|
contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',
|
||||||
|
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([
|
||||||
|
Ci.nsISupports,
|
||||||
|
Ci.nsIStreamConverter,
|
||||||
|
Ci.nsIStreamListener,
|
||||||
|
Ci.nsIRequestObserver
|
||||||
|
]),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This component works as such:
|
||||||
|
* 1. asyncConvertData stores the listener
|
||||||
|
* 2. onStartRequest creates a new channel, streams the viewer and cancels
|
||||||
|
* the request so pdf.js can do the request
|
||||||
|
* Since the request is cancelled onDataAvailable should not be called. The
|
||||||
|
* onStopRequest does nothing. The convert function just returns the stream,
|
||||||
|
* it's just the synchronous version of asyncConvertData.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// nsIStreamConverter::convert
|
||||||
|
convert: function(aFromStream, aFromType, aToType, aCtxt) {
|
||||||
|
return aFromStream;
|
||||||
|
},
|
||||||
|
|
||||||
|
// nsIStreamConverter::asyncConvertData
|
||||||
|
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||||
|
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
||||||
|
throw NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
// Store the listener passed to us
|
||||||
|
this.listener = aListener;
|
||||||
|
},
|
||||||
|
|
||||||
|
// nsIStreamListener::onDataAvailable
|
||||||
|
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||||
|
// Do nothing since all the data loading is handled by the viewer.
|
||||||
|
log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!');
|
||||||
|
},
|
||||||
|
|
||||||
|
// nsIRequestObserver::onStartRequest
|
||||||
|
onStartRequest: function(aRequest, aContext) {
|
||||||
|
|
||||||
|
// Setup the request so we can use it below.
|
||||||
|
aRequest.QueryInterface(Ci.nsIChannel);
|
||||||
|
// Cancel the request so the viewer can handle it.
|
||||||
|
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
|
||||||
|
// Create a new channel that is viewer loaded as a resource.
|
||||||
|
var ioService = Cc['@mozilla.org/network/io-service;1']
|
||||||
|
.getService(Ci.nsIIOService);
|
||||||
|
var channel = ioService.newChannel(
|
||||||
|
'resource://pdf.js/web/viewer.html', null, null);
|
||||||
|
|
||||||
|
// Keep the URL the same so the browser sees it as the same.
|
||||||
|
channel.originalURI = aRequest.originalURI;
|
||||||
|
channel.asyncOpen(this.listener, aContext);
|
||||||
|
|
||||||
|
// Setup a global listener waiting for the next DOM to be created and verfiy
|
||||||
|
// that its the one we want by its URL. When the correct DOM is found create
|
||||||
|
// an event listener on that window for the pdf.js events that require
|
||||||
|
// chrome priviledges.
|
||||||
|
var url = aRequest.originalURI.spec;
|
||||||
|
var gb = Services.wm.getMostRecentWindow('navigator:browser');
|
||||||
|
var domListener = function domListener(event) {
|
||||||
|
var doc = event.originalTarget;
|
||||||
|
var win = doc.defaultView;
|
||||||
|
if (doc.location.href === url) {
|
||||||
|
gb.removeEventListener('DOMContentLoaded', domListener);
|
||||||
|
var requestListener = new RequestListener(new ChromeActions());
|
||||||
|
win.addEventListener(PDFJS_EVENT_ID, function(event) {
|
||||||
|
requestListener.receive(event);
|
||||||
|
}, false, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gb.addEventListener('DOMContentLoaded', domListener, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
// nsIRequestObserver::onStopRequest
|
||||||
|
onStopRequest: function(aRequest, aContext, aStatusCode) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfStreamConverter]);
|
@ -1,67 +0,0 @@
|
|||||||
/* -*- 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');
|
|
||||||
|
|
||||||
function log(aMsg) {
|
|
||||||
let msg = 'pdfContentHandler.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
|
||||||
Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService)
|
|
||||||
.logStringMessage(msg);
|
|
||||||
dump(msg + '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
|
|
||||||
function pdfContentHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
pdfContentHandler.prototype = {
|
|
||||||
handleContent: function handleContent(aMimetype, aContext, aRequest) {
|
|
||||||
if (aMimetype != PDF_CONTENT_TYPE)
|
|
||||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
|
||||||
|
|
||||||
if (!(aRequest instanceof Ci.nsIChannel))
|
|
||||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
|
||||||
|
|
||||||
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
|
||||||
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
|
||||||
|
|
||||||
let window = null;
|
|
||||||
let callbacks = aRequest.notificationCallbacks ||
|
|
||||||
aRequest.loadGroup.notificationCallbacks;
|
|
||||||
if (!callbacks)
|
|
||||||
return;
|
|
||||||
|
|
||||||
window = callbacks.getInterface(Ci.nsIDOMWindow);
|
|
||||||
|
|
||||||
let url = null;
|
|
||||||
try {
|
|
||||||
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', encodeURIComponent(targetUrl));
|
|
||||||
},
|
|
||||||
|
|
||||||
classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
|
|
||||||
};
|
|
||||||
|
|
||||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]);
|
|
||||||
|
|
20
src/core.js
20
src/core.js
@ -624,9 +624,19 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Some versions of FF can't create a worker on localhost, see:
|
var worker;
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
|
if (PDFJS.isFirefoxExtension) {
|
||||||
var worker = new Worker(workerSrc);
|
// The firefox extension can't load the worker from the resource://
|
||||||
|
// url so we have to inline the script and then use the blob loader.
|
||||||
|
var bb = new MozBlobBuilder();
|
||||||
|
bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent);
|
||||||
|
var blobUrl = window.URL.createObjectURL(bb.getBlob());
|
||||||
|
worker = new Worker(blobUrl);
|
||||||
|
} else {
|
||||||
|
// Some versions of FF can't create a worker on localhost, see:
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280
|
||||||
|
worker = new Worker(workerSrc);
|
||||||
|
}
|
||||||
|
|
||||||
var messageHandler = new MessageHandler('main', worker);
|
var messageHandler = new MessageHandler('main', worker);
|
||||||
|
|
||||||
@ -645,7 +655,9 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
// serializing the typed array.
|
// serializing the typed array.
|
||||||
messageHandler.send('test', testObj);
|
messageHandler.send('test', testObj);
|
||||||
return;
|
return;
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
warn('The worker has been disabled.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Either workers are disabled, not supported or have thrown an exception.
|
// Either workers are disabled, not supported or have thrown an exception.
|
||||||
// Thus, we fallback to a faked worker.
|
// Thus, we fallback to a faked worker.
|
||||||
|
14
web/viewer-snippet-firefox-extension.html
Normal file
14
web/viewer-snippet-firefox-extension.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!-- This snippet is used in firefox extension, see Makefile -->
|
||||||
|
<base href="resource://pdf.js/web/" />
|
||||||
|
<script type="text/javascript" id="PDFJS_SCRIPT_TAG">
|
||||||
|
<!--
|
||||||
|
// pdf.js is inlined here because resource:// urls won't work
|
||||||
|
// for loading workers.
|
||||||
|
/* PDFJSSCRIPT_INCLUDE_BUNDLE */
|
||||||
|
-->
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// This specifies the location of the pdf.js file.
|
||||||
|
PDFJS.isFirefoxExtension = true;
|
||||||
|
PDFJS.workerSrc = 'none';
|
||||||
|
</script>
|
@ -9,7 +9,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === Toolbar === */
|
/* === Toolbar === */
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Simple pdf.js page viewer</title>
|
<title>Simple pdf.js page viewer</title>
|
||||||
|
<!-- PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION -->
|
||||||
|
|
||||||
<link rel="stylesheet" href="viewer.css"/>
|
<link rel="stylesheet" href="viewer.css"/>
|
||||||
|
|
||||||
<script type="text/javascript" src="compatibility.js"></script>
|
<script type="text/javascript" src="compatibility.js"></script> <!-- PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION -->
|
||||||
|
|
||||||
<!-- PDFJSSCRIPT_INCLUDE_BUILD -->
|
<!-- PDFJSSCRIPT_INCLUDE_BUILD -->
|
||||||
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
@ -91,7 +93,7 @@
|
|||||||
|
|
||||||
<input id="fileInput" type="file" oncontextmenu="return false;"/>
|
<input id="fileInput" type="file" oncontextmenu="return false;"/>
|
||||||
|
|
||||||
<div class="separator"></div>
|
<div id="fileInputSeperator" class="separator"></div>
|
||||||
|
|
||||||
<a href="#" id="viewBookmark" title="Bookmark (or copy) current location">
|
<a href="#" id="viewBookmark" title="Bookmark (or copy) current location">
|
||||||
<img src="images/bookmark.svg" alt="Bookmark" align="top" height="16"/>
|
<img src="images/bookmark.svg" alt="Bookmark" align="top" height="16"/>
|
||||||
|
122
web/viewer.js
122
web/viewer.js
@ -62,6 +62,31 @@ var RenderingQueue = (function RenderingQueueClosure() {
|
|||||||
return RenderingQueue;
|
return RenderingQueue;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var FirefoxCom = (function FirefoxComClosure() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Creates an event that hopefully the extension is listening for and will
|
||||||
|
* synchronously respond to.
|
||||||
|
* @param {String} action The action to trigger.
|
||||||
|
* @param {String} data Optional data to send.
|
||||||
|
* @return {*} The response.
|
||||||
|
*/
|
||||||
|
request: function(action, data) {
|
||||||
|
var request = document.createTextNode('');
|
||||||
|
request.setUserData('action', action, null);
|
||||||
|
request.setUserData('data', data, null);
|
||||||
|
document.documentElement.appendChild(request);
|
||||||
|
|
||||||
|
var sender = document.createEvent('Events');
|
||||||
|
sender.initEvent('pdf.js.message', true, false);
|
||||||
|
request.dispatchEvent(sender);
|
||||||
|
var response = request.getUserData('response');
|
||||||
|
document.documentElement.removeChild(request);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
// Settings Manager - This is a utility for saving settings
|
// Settings Manager - This is a utility for saving settings
|
||||||
// First we see if localStorage is available, FF bug #495747
|
// First we see if localStorage is available, FF bug #495747
|
||||||
// If not, we use FUEL in FF
|
// If not, we use FUEL in FF
|
||||||
@ -74,22 +99,14 @@ var Settings = (function SettingsClosure() {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})();
|
})();
|
||||||
var extPrefix = 'extensions.uriloader@pdf.js';
|
|
||||||
var isExtension = location.protocol == 'chrome:' && !isLocalStorageEnabled;
|
var isFirefoxExtension = PDFJS.isFirefoxExtension;
|
||||||
var inPrivateBrowsing = false;
|
|
||||||
if (isExtension) {
|
|
||||||
var pbs = Components.classes['@mozilla.org/privatebrowsing;1']
|
|
||||||
.getService(Components.interfaces.nsIPrivateBrowsingService);
|
|
||||||
inPrivateBrowsing = pbs.privateBrowsingEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Settings(fingerprint) {
|
function Settings(fingerprint) {
|
||||||
var database = null;
|
var database = null;
|
||||||
var index;
|
var index;
|
||||||
if (inPrivateBrowsing)
|
if (isFirefoxExtension)
|
||||||
return false;
|
database = FirefoxCom.request('getDatabase', null);
|
||||||
else if (isExtension)
|
|
||||||
database = Application.prefs.getValue(extPrefix + '.database', '{}');
|
|
||||||
else if (isLocalStorageEnabled)
|
else if (isLocalStorageEnabled)
|
||||||
database = localStorage.getItem('database') || '{}';
|
database = localStorage.getItem('database') || '{}';
|
||||||
else
|
else
|
||||||
@ -111,31 +128,23 @@ var Settings = (function SettingsClosure() {
|
|||||||
index = database.files.push({fingerprint: fingerprint}) - 1;
|
index = database.files.push({fingerprint: fingerprint}) - 1;
|
||||||
this.file = database.files[index];
|
this.file = database.files[index];
|
||||||
this.database = database;
|
this.database = database;
|
||||||
if (isExtension)
|
if (isLocalStorageEnabled)
|
||||||
Application.prefs.setValue(extPrefix + '.database',
|
|
||||||
JSON.stringify(database));
|
|
||||||
else if (isLocalStorageEnabled)
|
|
||||||
localStorage.setItem('database', JSON.stringify(database));
|
localStorage.setItem('database', JSON.stringify(database));
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.prototype = {
|
Settings.prototype = {
|
||||||
set: function settingsSet(name, val) {
|
set: function settingsSet(name, val) {
|
||||||
if (inPrivateBrowsing)
|
|
||||||
return false;
|
|
||||||
var file = this.file;
|
var file = this.file;
|
||||||
file[name] = val;
|
file[name] = val;
|
||||||
if (isExtension)
|
var database = JSON.stringify(this.database);
|
||||||
Application.prefs.setValue(extPrefix + '.database',
|
if (isFirefoxExtension)
|
||||||
JSON.stringify(this.database));
|
FirefoxCom.request('setDatabase', database);
|
||||||
else if (isLocalStorageEnabled)
|
else if (isLocalStorageEnabled)
|
||||||
localStorage.setItem('database', JSON.stringify(this.database));
|
localStorage.setItem('database', database);
|
||||||
},
|
},
|
||||||
|
|
||||||
get: function settingsGet(name, defaultValue) {
|
get: function settingsGet(name, defaultValue) {
|
||||||
if (inPrivateBrowsing)
|
return this.file[name] || defaultValue;
|
||||||
return defaultValue;
|
|
||||||
else
|
|
||||||
return this.file[name] || defaultValue;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -258,7 +267,7 @@ var PDFView = {
|
|||||||
},
|
},
|
||||||
error: function getPdfError(e) {
|
error: function getPdfError(e) {
|
||||||
var loadingIndicator = document.getElementById('loading');
|
var loadingIndicator = document.getElementById('loading');
|
||||||
loadingIndicator.innerHTML = 'Error';
|
loadingIndicator.textContent = 'Error';
|
||||||
var moreInfo = {
|
var moreInfo = {
|
||||||
message: 'Unexpected server response of ' + e.target.status + '.'
|
message: 'Unexpected server response of ' + e.target.status + '.'
|
||||||
};
|
};
|
||||||
@ -273,7 +282,13 @@ var PDFView = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
download: function pdfViewDownload() {
|
download: function pdfViewDownload() {
|
||||||
window.open(this.url + '#pdfjs.action=download', '_parent');
|
var url = this.url.split('#')[0];
|
||||||
|
if (PDFJS.isFirefoxExtension) {
|
||||||
|
FirefoxCom.request('download', url);
|
||||||
|
} else {
|
||||||
|
url += '#pdfjs.action=download', '_parent';
|
||||||
|
window.open(url, '_parent');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
navigateTo: function pdfViewNavigateTo(dest) {
|
navigateTo: function pdfViewNavigateTo(dest) {
|
||||||
@ -294,14 +309,14 @@ var PDFView = {
|
|||||||
|
|
||||||
getDestinationHash: function pdfViewGetDestinationHash(dest) {
|
getDestinationHash: function pdfViewGetDestinationHash(dest) {
|
||||||
if (typeof dest === 'string')
|
if (typeof dest === 'string')
|
||||||
return '#' + escape(dest);
|
return PDFView.getAnchorUrl('#' + escape(dest));
|
||||||
if (dest instanceof Array) {
|
if (dest instanceof Array) {
|
||||||
var destRef = dest[0]; // see navigateTo method for dest format
|
var destRef = dest[0]; // see navigateTo method for dest format
|
||||||
var pageNumber = destRef instanceof Object ?
|
var pageNumber = destRef instanceof Object ?
|
||||||
this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
|
this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
|
||||||
(destRef + 1);
|
(destRef + 1);
|
||||||
if (pageNumber) {
|
if (pageNumber) {
|
||||||
var pdfOpenParams = '#page=' + pageNumber;
|
var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber);
|
||||||
var destKind = dest[1];
|
var destKind = dest[1];
|
||||||
if ('name' in destKind && destKind.name == 'XYZ') {
|
if ('name' in destKind && destKind.name == 'XYZ') {
|
||||||
var scale = (dest[4] || this.currentScale);
|
var scale = (dest[4] || this.currentScale);
|
||||||
@ -316,6 +331,17 @@ var PDFView = {
|
|||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the firefox extension we prefix the full url on anchor links so they
|
||||||
|
* don't come up as resource:// urls and so open in new tab/window works.
|
||||||
|
* @param {String} anchor The anchor hash include the #.
|
||||||
|
*/
|
||||||
|
getAnchorUrl: function getAnchorUrl(anchor) {
|
||||||
|
if (PDFJS.isFirefoxExtension)
|
||||||
|
return this.url.split('#')[0] + anchor;
|
||||||
|
return anchor;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the error box.
|
* Show the error box.
|
||||||
* @param {String} message A message that is human readable.
|
* @param {String} message A message that is human readable.
|
||||||
@ -328,7 +354,7 @@ var PDFView = {
|
|||||||
errorWrapper.removeAttribute('hidden');
|
errorWrapper.removeAttribute('hidden');
|
||||||
|
|
||||||
var errorMessage = document.getElementById('errorMessage');
|
var errorMessage = document.getElementById('errorMessage');
|
||||||
errorMessage.innerHTML = message;
|
errorMessage.textContent = message;
|
||||||
|
|
||||||
var closeButton = document.getElementById('errorClose');
|
var closeButton = document.getElementById('errorClose');
|
||||||
closeButton.onclick = function() {
|
closeButton.onclick = function() {
|
||||||
@ -363,7 +389,7 @@ var PDFView = {
|
|||||||
progress: function pdfViewProgress(level) {
|
progress: function pdfViewProgress(level) {
|
||||||
var percent = Math.round(level * 100);
|
var percent = Math.round(level * 100);
|
||||||
var loadingIndicator = document.getElementById('loading');
|
var loadingIndicator = document.getElementById('loading');
|
||||||
loadingIndicator.innerHTML = 'Loading... ' + percent + '%';
|
loadingIndicator.textContent = 'Loading... ' + percent + '%';
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function pdfViewLoad(data, scale) {
|
load: function pdfViewLoad(data, scale) {
|
||||||
@ -403,7 +429,7 @@ var PDFView = {
|
|||||||
var pagesCount = pdf.numPages;
|
var pagesCount = pdf.numPages;
|
||||||
var id = pdf.fingerprint;
|
var id = pdf.fingerprint;
|
||||||
var storedHash = null;
|
var storedHash = null;
|
||||||
document.getElementById('numPages').innerHTML = pagesCount;
|
document.getElementById('numPages').textContent = pagesCount;
|
||||||
document.getElementById('pageNumber').max = pagesCount;
|
document.getElementById('pageNumber').max = pagesCount;
|
||||||
PDFView.documentFingerprint = id;
|
PDFView.documentFingerprint = id;
|
||||||
var store = PDFView.store = new Settings(id);
|
var store = PDFView.store = new Settings(id);
|
||||||
@ -655,7 +681,15 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
|||||||
if (!item.content) {
|
if (!item.content) {
|
||||||
content.setAttribute('hidden', true);
|
content.setAttribute('hidden', true);
|
||||||
} else {
|
} else {
|
||||||
text.innerHTML = item.content.replace('\n', '<br />');
|
var e = document.createElement('span');
|
||||||
|
var lines = item.content.split('\n');
|
||||||
|
for (var i = 0, ii = lines.length; i < ii; ++i) {
|
||||||
|
var line = lines[i];
|
||||||
|
e.appendChild(document.createTextNode(line));
|
||||||
|
if (i < (ii - 1))
|
||||||
|
e.appendChild(document.createElement('br'));
|
||||||
|
}
|
||||||
|
text.appendChild(e);
|
||||||
image.addEventListener('mouseover', function annotationImageOver() {
|
image.addEventListener('mouseover', function annotationImageOver() {
|
||||||
this.nextSibling.removeAttribute('hidden');
|
this.nextSibling.removeAttribute('hidden');
|
||||||
}, false);
|
}, false);
|
||||||
@ -831,13 +865,13 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
|||||||
var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render;
|
var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render;
|
||||||
var str = 'Time to compile/fonts/render: ' +
|
var str = 'Time to compile/fonts/render: ' +
|
||||||
(t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms';
|
(t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms';
|
||||||
document.getElementById('info').innerHTML = str;
|
document.getElementById('info').textContent = str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var ThumbnailView = function thumbnailView(container, page, id, pageRatio) {
|
var ThumbnailView = function thumbnailView(container, page, id, pageRatio) {
|
||||||
var anchor = document.createElement('a');
|
var anchor = document.createElement('a');
|
||||||
anchor.href = '#' + id;
|
anchor.href = PDFView.getAnchorUrl('#page=' + id);
|
||||||
anchor.onclick = function stopNivigation() {
|
anchor.onclick = function stopNivigation() {
|
||||||
PDFView.page = id;
|
PDFView.page = id;
|
||||||
return false;
|
return false;
|
||||||
@ -1045,12 +1079,18 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var scale = ('scale' in params) ? params.scale : 0;
|
var scale = ('scale' in params) ? params.scale : 0;
|
||||||
PDFView.open(params.file || kDefaultURL, parseFloat(scale));
|
var file = PDFJS.isFirefoxExtension ?
|
||||||
|
window.location.toString() : params.file || kDefaultURL;
|
||||||
|
PDFView.open(file, parseFloat(scale));
|
||||||
|
|
||||||
if (!window.File || !window.FileReader || !window.FileList || !window.Blob)
|
if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader ||
|
||||||
|
!window.FileList || !window.Blob) {
|
||||||
document.getElementById('fileInput').setAttribute('hidden', 'true');
|
document.getElementById('fileInput').setAttribute('hidden', 'true');
|
||||||
else
|
document.getElementById('fileInputSeperator')
|
||||||
|
.setAttribute('hidden', 'true');
|
||||||
|
} else {
|
||||||
document.getElementById('fileInput').value = null;
|
document.getElementById('fileInput').value = null;
|
||||||
|
}
|
||||||
|
|
||||||
if ('disableWorker' in params)
|
if ('disableWorker' in params)
|
||||||
PDFJS.disableWorker = (params['disableWorker'] === 'true');
|
PDFJS.disableWorker = (params['disableWorker'] === 'true');
|
||||||
@ -1135,8 +1175,8 @@ function updateViewarea() {
|
|||||||
store.set('zoom', normalizedScaleValue);
|
store.set('zoom', normalizedScaleValue);
|
||||||
store.set('scrollLeft', Math.round(topLeft.x));
|
store.set('scrollLeft', Math.round(topLeft.x));
|
||||||
store.set('scrollTop', Math.round(topLeft.y));
|
store.set('scrollTop', Math.round(topLeft.y));
|
||||||
|
var href = PDFView.getAnchorUrl(pdfOpenParams);
|
||||||
document.getElementById('viewBookmark').href = pdfOpenParams;
|
document.getElementById('viewBookmark').href = href;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', function webViewerScroll(evt) {
|
window.addEventListener('scroll', function webViewerScroll(evt) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user