UNPKG

11.2 kBJavaScriptView Raw
1/**
2 * @licstart The following is the entire license notice for the
3 * JavaScript code in this page
4 *
5 * Copyright 2022 Mozilla Foundation
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * @licend The above is the entire license notice for the
20 * JavaScript code in this page
21 */
22"use strict";
23
24Object.defineProperty(exports, "__esModule", {
25 value: true
26});
27exports.FirefoxCom = exports.DownloadManager = void 0;
28
29require("../extensions/firefox/tools/l10n.js");
30
31var _app = require("./app.js");
32
33var _pdf = require("../pdf");
34
35var _preferences = require("./preferences.js");
36
37var _ui_utils = require("./ui_utils.js");
38
39var _l10n_utils = require("./l10n_utils.js");
40
41{
42 throw new Error('Module "./firefoxcom.js" shall not be used outside MOZCENTRAL builds.');
43}
44
45class FirefoxCom {
46 static requestSync(action, data) {
47 const request = document.createTextNode("");
48 document.documentElement.append(request);
49 const sender = document.createEvent("CustomEvent");
50 sender.initCustomEvent("pdf.js.message", true, false, {
51 action,
52 data,
53 sync: true
54 });
55 request.dispatchEvent(sender);
56 const response = sender.detail.response;
57 request.remove();
58 return response;
59 }
60
61 static requestAsync(action, data) {
62 return new Promise(resolve => {
63 this.request(action, data, resolve);
64 });
65 }
66
67 static request(action, data, callback = null) {
68 const request = document.createTextNode("");
69
70 if (callback) {
71 request.addEventListener("pdf.js.response", event => {
72 const response = event.detail.response;
73 event.target.remove();
74 callback(response);
75 }, {
76 once: true
77 });
78 }
79
80 document.documentElement.append(request);
81 const sender = document.createEvent("CustomEvent");
82 sender.initCustomEvent("pdf.js.message", true, false, {
83 action,
84 data,
85 sync: false,
86 responseExpected: !!callback
87 });
88 request.dispatchEvent(sender);
89 }
90
91}
92
93exports.FirefoxCom = FirefoxCom;
94
95class DownloadManager {
96 constructor() {
97 this._openBlobUrls = new WeakMap();
98 }
99
100 downloadUrl(url, filename) {
101 FirefoxCom.request("download", {
102 originalUrl: url,
103 filename
104 });
105 }
106
107 downloadData(data, filename, contentType) {
108 const blobUrl = URL.createObjectURL(new Blob([data], {
109 type: contentType
110 }));
111 FirefoxCom.request("download", {
112 blobUrl,
113 originalUrl: blobUrl,
114 filename,
115 isAttachment: true
116 });
117 }
118
119 openOrDownloadData(element, data, filename) {
120 const isPdfData = (0, _pdf.isPdfFile)(filename);
121 const contentType = isPdfData ? "application/pdf" : "";
122
123 if (isPdfData) {
124 let blobUrl = this._openBlobUrls.get(element);
125
126 if (!blobUrl) {
127 blobUrl = URL.createObjectURL(new Blob([data], {
128 type: contentType
129 }));
130
131 this._openBlobUrls.set(element, blobUrl);
132 }
133
134 const viewerUrl = blobUrl + "#filename=" + encodeURIComponent(filename);
135
136 try {
137 window.open(viewerUrl);
138 return true;
139 } catch (ex) {
140 console.error(`openOrDownloadData: ${ex}`);
141 URL.revokeObjectURL(blobUrl);
142
143 this._openBlobUrls.delete(element);
144 }
145 }
146
147 this.downloadData(data, filename, contentType);
148 return false;
149 }
150
151 download(blob, url, filename) {
152 const blobUrl = URL.createObjectURL(blob);
153 FirefoxCom.request("download", {
154 blobUrl,
155 originalUrl: url,
156 filename
157 });
158 }
159
160}
161
162exports.DownloadManager = DownloadManager;
163
164class FirefoxPreferences extends _preferences.BasePreferences {
165 async _writeToStorage(prefObj) {
166 return FirefoxCom.requestAsync("setPreferences", prefObj);
167 }
168
169 async _readFromStorage(prefObj) {
170 const prefStr = await FirefoxCom.requestAsync("getPreferences", prefObj);
171 return JSON.parse(prefStr);
172 }
173
174}
175
176class MozL10n {
177 constructor(mozL10n) {
178 this.mozL10n = mozL10n;
179 }
180
181 async getLanguage() {
182 return this.mozL10n.getLanguage();
183 }
184
185 async getDirection() {
186 return this.mozL10n.getDirection();
187 }
188
189 async get(key, args = null, fallback = (0, _l10n_utils.getL10nFallback)(key, args)) {
190 return this.mozL10n.get(key, args, fallback);
191 }
192
193 async translate(element) {
194 this.mozL10n.translate(element);
195 }
196
197}
198
199(function listenFindEvents() {
200 const events = ["find", "findagain", "findhighlightallchange", "findcasesensitivitychange", "findentirewordchange", "findbarclose", "finddiacriticmatchingchange"];
201 const findLen = "find".length;
202
203 const handleEvent = function ({
204 type,
205 detail
206 }) {
207 if (!_app.PDFViewerApplication.initialized) {
208 return;
209 }
210
211 if (type === "findbarclose") {
212 _app.PDFViewerApplication.eventBus.dispatch(type, {
213 source: window
214 });
215
216 return;
217 }
218
219 _app.PDFViewerApplication.eventBus.dispatch("find", {
220 source: window,
221 type: type.substring(findLen),
222 query: detail.query,
223 phraseSearch: true,
224 caseSensitive: !!detail.caseSensitive,
225 entireWord: !!detail.entireWord,
226 highlightAll: !!detail.highlightAll,
227 findPrevious: !!detail.findPrevious,
228 matchDiacritics: !!detail.matchDiacritics
229 });
230 };
231
232 for (const event of events) {
233 window.addEventListener(event, handleEvent);
234 }
235})();
236
237(function listenZoomEvents() {
238 const events = ["zoomin", "zoomout", "zoomreset"];
239
240 const handleEvent = function ({
241 type,
242 detail
243 }) {
244 if (!_app.PDFViewerApplication.initialized) {
245 return;
246 }
247
248 if (type === "zoomreset" && _app.PDFViewerApplication.pdfViewer.currentScaleValue === _ui_utils.DEFAULT_SCALE_VALUE) {
249 return;
250 }
251
252 _app.PDFViewerApplication.eventBus.dispatch(type, {
253 source: window
254 });
255 };
256
257 for (const event of events) {
258 window.addEventListener(event, handleEvent);
259 }
260})();
261
262(function listenSaveEvent() {
263 const handleEvent = function ({
264 type,
265 detail
266 }) {
267 if (!_app.PDFViewerApplication.initialized) {
268 return;
269 }
270
271 _app.PDFViewerApplication.eventBus.dispatch("download", {
272 source: window
273 });
274 };
275
276 window.addEventListener("save", handleEvent);
277})();
278
279(function listenEditingEvent() {
280 const handleEvent = function ({
281 detail
282 }) {
283 if (!_app.PDFViewerApplication.initialized) {
284 return;
285 }
286
287 _app.PDFViewerApplication.eventBus.dispatch("editingaction", {
288 source: window,
289 name: detail.name
290 });
291 };
292
293 window.addEventListener("editingaction", handleEvent);
294})();
295
296class FirefoxComDataRangeTransport extends _pdf.PDFDataRangeTransport {
297 requestDataRange(begin, end) {
298 FirefoxCom.request("requestDataRange", {
299 begin,
300 end
301 });
302 }
303
304 abort() {
305 FirefoxCom.requestSync("abortLoading", null);
306 }
307
308}
309
310class FirefoxScripting {
311 static async createSandbox(data) {
312 const success = await FirefoxCom.requestAsync("createSandbox", data);
313
314 if (!success) {
315 throw new Error("Cannot create sandbox.");
316 }
317 }
318
319 static async dispatchEventInSandbox(event) {
320 FirefoxCom.request("dispatchEventInSandbox", event);
321 }
322
323 static async destroySandbox() {
324 FirefoxCom.request("destroySandbox", null);
325 }
326
327}
328
329class FirefoxExternalServices extends _app.DefaultExternalServices {
330 static updateFindControlState(data) {
331 FirefoxCom.request("updateFindControlState", data);
332 }
333
334 static updateFindMatchesCount(data) {
335 FirefoxCom.request("updateFindMatchesCount", data);
336 }
337
338 static initPassiveLoading(callbacks) {
339 let pdfDataRangeTransport;
340 window.addEventListener("message", function windowMessage(e) {
341 if (e.source !== null) {
342 console.warn("Rejected untrusted message from " + e.origin);
343 return;
344 }
345
346 const args = e.data;
347
348 if (typeof args !== "object" || !("pdfjsLoadAction" in args)) {
349 return;
350 }
351
352 switch (args.pdfjsLoadAction) {
353 case "supportsRangedLoading":
354 if (args.done && !args.data) {
355 callbacks.onError();
356 break;
357 }
358
359 pdfDataRangeTransport = new FirefoxComDataRangeTransport(args.length, args.data, args.done, args.filename);
360 callbacks.onOpenWithTransport(args.pdfUrl, args.length, pdfDataRangeTransport);
361 break;
362
363 case "range":
364 pdfDataRangeTransport.onDataRange(args.begin, args.chunk);
365 break;
366
367 case "rangeProgress":
368 pdfDataRangeTransport.onDataProgress(args.loaded);
369 break;
370
371 case "progressiveRead":
372 pdfDataRangeTransport.onDataProgressiveRead(args.chunk);
373 pdfDataRangeTransport.onDataProgress(args.loaded, args.total);
374 break;
375
376 case "progressiveDone":
377 pdfDataRangeTransport?.onDataProgressiveDone();
378 break;
379
380 case "progress":
381 callbacks.onProgress(args.loaded, args.total);
382 break;
383
384 case "complete":
385 if (!args.data) {
386 callbacks.onError(args.errorCode);
387 break;
388 }
389
390 callbacks.onOpenWithData(args.data, args.filename);
391 break;
392 }
393 });
394 FirefoxCom.requestSync("initPassiveLoading", null);
395 }
396
397 static reportTelemetry(data) {
398 FirefoxCom.request("reportTelemetry", JSON.stringify(data));
399 }
400
401 static createDownloadManager(options) {
402 return new DownloadManager();
403 }
404
405 static createPreferences() {
406 return new FirefoxPreferences();
407 }
408
409 static updateEditorStates(data) {
410 FirefoxCom.request("updateEditorStates", data);
411 }
412
413 static createL10n(options) {
414 const mozL10n = document.mozL10n;
415 return new MozL10n(mozL10n);
416 }
417
418 static createScripting(options) {
419 return FirefoxScripting;
420 }
421
422 static get supportsIntegratedFind() {
423 const support = FirefoxCom.requestSync("supportsIntegratedFind");
424 return (0, _pdf.shadow)(this, "supportsIntegratedFind", support);
425 }
426
427 static get supportsDocumentFonts() {
428 const support = FirefoxCom.requestSync("supportsDocumentFonts");
429 return (0, _pdf.shadow)(this, "supportsDocumentFonts", support);
430 }
431
432 static get supportedMouseWheelZoomModifierKeys() {
433 const support = FirefoxCom.requestSync("supportedMouseWheelZoomModifierKeys");
434 return (0, _pdf.shadow)(this, "supportedMouseWheelZoomModifierKeys", support);
435 }
436
437 static get isInAutomation() {
438 const isInAutomation = FirefoxCom.requestSync("isInAutomation");
439 return (0, _pdf.shadow)(this, "isInAutomation", isInAutomation);
440 }
441
442}
443
444_app.PDFViewerApplication.externalServices = FirefoxExternalServices;
445document.mozL10n.setExternalLocalizerServices({
446 getLocale() {
447 return FirefoxCom.requestSync("getLocale", null);
448 },
449
450 getStrings(key) {
451 return FirefoxCom.requestSync("getStrings", null);
452 }
453
454});
\No newline at end of file