@@ -41,3 +41,233 @@ Include `viewer.html` using [SSI](http://httpd.apache.org/docs/2.4/howto/ssi.htm
41
41
</html >
42
42
```
43
43
44
+ ## Upgrading the source
45
+
46
+ Normally mozilla's PDF js viewer, will only run as standalone. This version is patched so you can include it within a
47
+ page.
48
+
49
+ To update this version, get the pdf.js source code and build the project
50
+
51
+ git clone https://github.com/mozilla/pdf.js.git
52
+ cd pdf.js
53
+ npm install
54
+ node make generic
55
+ cd ..
56
+
57
+ And update the files from source and patch them
58
+
59
+ cd pdf.js-viewer
60
+ npm install
61
+ ./build.sh ../pdf.js/build/generic/
62
+
63
+ ### Manual patching
64
+
65
+ When updating to a new minor (or major) version, it's likely than one or more of the chunks can't be applied. This
66
+ means you need to do these modifications manually.
67
+
68
+
69
+ #### function getL10nData()
70
+
71
+ The viewer uses ` l10n.js ` with a ` <link rel="resource" type="application/l10n"> ` header for internationalization. This
72
+ chunk makes using that optional.
73
+
74
+ function getL10nData(key, args, fallback) {
75
+ var data = gL10nData[key];
76
+ if (!data) {
77
+ - console.warn('#' + key + ' is undefined.');
78
+ + if (Object.keys(gL10nData).length > 0) {
79
+ + console.warn('#' + key + ' is undefined.');
80
+ + }
81
+ if (!fallback) {
82
+ return null;
83
+ }
84
+
85
+ #### Dynamic paths
86
+
87
+ The viewer uses relative paths to JavaScript files. This doesn't work when the viewer is embedded on a web page.
88
+ Instead the paths are determined based on the path of the current JavaScript file.
89
+
90
+ -PDFJS.imageResourcesPath = './images/';
91
+ - PDFJS.workerSrc = '../build/pdf.worker.js';
92
+ - PDFJS.cMapUrl = '../web/cmaps/';
93
+ - PDFJS.cMapPacked = true;
94
+ +var scriptTagContainer = document.body ||
95
+ + document.getElementsByTagName('head')[0];
96
+ +var pdfjsSrc = scriptTagContainer.lastChild.src;
97
+ +
98
+ +if (pdfjsSrc) {
99
+ + PDFJS.imageResourcesPath = pdfjsSrc.replace(/pdf\.js$/i, 'images/');
100
+ + PDFJS.workerSrc = pdfjsSrc.replace(/pdf\.js$/i, 'pdf.worker.js');
101
+ + PDFJS.cMapUrl = pdfjsSrc.replace(/pdf\.js$/i, 'cmaps/');
102
+ +}
103
+ +
104
+ +PDFJS.cMapPacked = true;
105
+
106
+ #### Explicitly load a PDF document
107
+
108
+ The viewer shouldn't start loading a (default) document when it's loaded. Instead we want to expose the initialization,
109
+ so it can be called in JavaScript with ` PDFJS.webViewerLoad() ` .
110
+
111
+ -document.addEventListener('DOMContentLoaded', webViewerLoad, true);
112
+ +// document.addEventListener('DOMContentLoaded', webViewerLoad, true);
113
+ +PDFJS.webViewerLoad = function (src) {
114
+ + if (src) DEFAULT_URL = src;
115
+ +
116
+ + webViewerLoad();
117
+ +}
118
+
119
+ On several places the code assumes that a PDF is loaded, which (because of the explicit load) might not be the case. We
120
+ need to check if ` pdfDocument ` is set before using it.
121
+
122
+ ##### PDFViewerApplication.pagesCount() and PDFLinkService.pagesCount()
123
+
124
+ get pagesCount() {
125
+ - return this.pdfDocument.numPages;
126
+ + return this.pdfDocument ? this.pdfDocument.numPages : 0;
127
+ },
128
+
129
+ _ The pagesCount method for both ` PDFViewerApplication ` and ` PDFLinkService ` . Both need to be patched._
130
+
131
+ ##### PDFViewerApplication.cleanup()
132
+
133
+ cleanup: function pdfViewCleanup() {
134
+ this.pdfViewer.cleanup();
135
+ this.pdfThumbnailViewer.cleanup();
136
+ - this.pdfDocument.cleanup();
137
+ + if (this.pdfDocument) {
138
+ + this.pdfDocument.cleanup();
139
+ + }
140
+ },
141
+
142
+ #### overlayManagerRegister
143
+
144
+ The overlay is registered when the viewer is loaded. The original code will only do this once and give an error on each
145
+ subsequent call. Escpecially with single-page applications (eg an Angular app), the viewer may be loaded multiple times.
146
+ This patch causes pdf.js to unregister an unusued (closed) overlay.
147
+
148
+ register: function overlayManagerRegister(name, callerCloseMethod, canForceClose) {
149
+ return new Promise(function (resolve) {
150
+ var element, container;
151
+ if (!name || !(element = document.getElementById(name)) ||
152
+ !(container = element.parentNode)) {
153
+ throw new Error('Not enough parameters.');
154
+ } else if (this.overlays[name]) {
155
+ - throw new Error('The overlay is already registered.');
156
+ + if (this.active !== name) {
157
+ + this.unregister(name);
158
+ + } else {
159
+ + throw new Error('The overlay is already registered and active.');
160
+ + }
161
+ }
162
+
163
+ #### webViewerChange trigger on file upload dialog
164
+
165
+ Whenever a file dialog is used (so with any ` <input type="file"> ` on the page), the file is loaded into the pdf.js
166
+ viewer. We don't want this behaviour, so comment it out.
167
+
168
+ -window.addEventListener('change', function webViewerChange(evt) {
169
+ +/*window.addEventListener('change', function webViewerChange(evt) {
170
+ var files = evt.target.files;
171
+ if (!files || files.length === 0) {
172
+ return;
173
+ @@ -17627,7 +17647,7 @@
174
+ setAttribute('hidden', 'true');
175
+ document.getElementById('download').setAttribute('hidden', 'true');
176
+ document.getElementById('secondaryDownload').setAttribute('hidden', 'true');
177
+ -}, true);
178
+ +}, true);*/
179
+
180
+ #### handleMouseWheel()
181
+
182
+ The JavaScript pdf.js file might be loaded while the viewer isn't being displayed. This causes an error on mouse move.
183
+ We need to check if the viewer is initialized, before handling the event.
184
+
185
+ function handleMouseWheel(evt) {
186
+ + // Ignore mousewheel event if pdfViewer isn't loaded
187
+ + if (!PDFViewerApplication.pdfViewer) return;
188
+
189
+ #### Load code for worker using AJAX if needed
190
+
191
+ A [ Web Worker] ( https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers ) can't use code from
192
+ a same-origin domain. The CORS headers don't apply.
193
+
194
+ he patch will cause pdf.js to first try to create the Worker the regular way, with a URL to the JavaScript source. If
195
+ this fails, the source if fetched using AJAX and used to create an
196
+ [ object url] ( https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL ) . If this also fails, pdf.js will go
197
+ onto it's last resort by calling ` setupFakeWorker() ` .
198
+
199
+ + /**
200
+ + * Needed because workers cannot load scripts outside of the current origin (as of firefox v45).
201
+ + * This patch does require the worker script to be served with a (Access-Control-Allow-Origin: *) header
202
+ + * @patch
203
+ + */
204
+ + var loadWorkerXHR = function(){
205
+ + var url = PDFJS.workerSrc;
206
+ + var jsdfd = PDFJS.createPromiseCapability();
207
+ +
208
+ + if (url.match(/^blob:/) || typeof URL.createObjectURL === 'undefined') {
209
+ + jsdfd.reject(); // Failed loading using blob
210
+ + }
211
+ +
212
+ + var xmlhttp;
213
+ + xmlhttp = new XMLHttpRequest();
214
+ +
215
+ + xmlhttp.onreadystatechange = function(){
216
+ + if (xmlhttp.readyState != 4) return;
217
+ +
218
+ + if (xmlhttp.status == 200) {
219
+ + info('Loaded worker source through XHR.');
220
+ + var workerJSBlob = new Blob([xmlhttp.responseText], { type: 'text/javascript' });
221
+ + jsdfd.resolve(window.URL.createObjectURL(workerJSBlob));
222
+ + } else {
223
+ + jsdfd.reject();
224
+ + }
225
+ + };
226
+ +
227
+ + xmlhttp.open('GET', url, true);
228
+ + xmlhttp.send();
229
+ + return jsdfd.promise;
230
+ + }
231
+ +
232
+ + var workerError = function() {
233
+ + loadWorkerXHR().then(function(blob) {
234
+ + PDFJS.workerSrc = blob;
235
+ + loadWorker();
236
+ + }, function() {
237
+ + this.setupFakeWorker();
238
+ + }.bind(this));
239
+ + }.bind(this);
240
+ +
241
+
242
+ - if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
243
+ + var loadWorker = function() {
244
+ var workerSrc = PDFJS.workerSrc;
245
+ if (!workerSrc) {
246
+ error('No PDFJS.workerSrc specified');
247
+ @@ -3559,6 +3603,8 @@
248
+ // Some versions of FF can't create a worker on localhost, see:
249
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
250
+ var worker = new Worker(workerSrc);
251
+ + worker.onerror = workerError;
252
+ +
253
+ var messageHandler = new MessageHandler('main', worker);
254
+ this.messageHandler = messageHandler;
255
+
256
+ @@ -3589,11 +3635,16 @@
257
+ return;
258
+ } catch (e) {
259
+ info('The worker has been disabled.');
260
+ + workerError();
261
+ }
262
+ - }
263
+ + }.bind(this);
264
+ // Either workers are disabled, not supported or have thrown an exception.
265
+ // Thus, we fallback to a faked worker.
266
+ - this.setupFakeWorker();
267
+ + if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
268
+ + loadWorker();
269
+ + } else {
270
+ + this.setupFakeWorker();
271
+ + }
272
+ }
273
+
0 commit comments