[api-minor] Support the Content-Disposition filename in the Firefox PDF Viewer (bug 1694556, PR 9379 follow-up)
As can be seen [in the mozilla-central code](https://searchfox.org/mozilla-central/rev/a6db3bd67367aa9ddd9505690cab09b47e65a762/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#1222-1225), we're already getting the Content-Disposition filename. However, that data isn't passed through to the viewer nor to the `PDFDataTransportStream`-implementation, which explains why it's currently being ignored. *Please note:* This will also require a small mozilla-central patch, see https://bugzilla.mozilla.org/show_bug.cgi?id=1694556, to forward the necessary data to the viewer.
This commit is contained in:
		
							parent
							
								
									061637d3f4
								
							
						
					
					
						commit
						6fd899dc44
					
				@ -334,6 +334,7 @@ function getDocument(src) {
 | 
				
			|||||||
              length: params.length,
 | 
					              length: params.length,
 | 
				
			||||||
              initialData: params.initialData,
 | 
					              initialData: params.initialData,
 | 
				
			||||||
              progressiveDone: params.progressiveDone,
 | 
					              progressiveDone: params.progressiveDone,
 | 
				
			||||||
 | 
					              contentDispositionFilename: params.contentDispositionFilename,
 | 
				
			||||||
              disableRange: params.disableRange,
 | 
					              disableRange: params.disableRange,
 | 
				
			||||||
              disableStream: params.disableStream,
 | 
					              disableStream: params.disableStream,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
@ -401,6 +402,8 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
 | 
				
			|||||||
    source.length = pdfDataRangeTransport.length;
 | 
					    source.length = pdfDataRangeTransport.length;
 | 
				
			||||||
    source.initialData = pdfDataRangeTransport.initialData;
 | 
					    source.initialData = pdfDataRangeTransport.initialData;
 | 
				
			||||||
    source.progressiveDone = pdfDataRangeTransport.progressiveDone;
 | 
					    source.progressiveDone = pdfDataRangeTransport.progressiveDone;
 | 
				
			||||||
 | 
					    source.contentDispositionFilename =
 | 
				
			||||||
 | 
					      pdfDataRangeTransport.contentDispositionFilename;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return worker.messageHandler
 | 
					  return worker.messageHandler
 | 
				
			||||||
    .sendWithPromise("GetDocRequest", {
 | 
					    .sendWithPromise("GetDocRequest", {
 | 
				
			||||||
@ -554,11 +557,18 @@ class PDFDataRangeTransport {
 | 
				
			|||||||
   * @param {number} length
 | 
					   * @param {number} length
 | 
				
			||||||
   * @param {Uint8Array} initialData
 | 
					   * @param {Uint8Array} initialData
 | 
				
			||||||
   * @param {boolean} [progressiveDone]
 | 
					   * @param {boolean} [progressiveDone]
 | 
				
			||||||
 | 
					   * @param {string} [contentDispositionFilename]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  constructor(length, initialData, progressiveDone = false) {
 | 
					  constructor(
 | 
				
			||||||
 | 
					    length,
 | 
				
			||||||
 | 
					    initialData,
 | 
				
			||||||
 | 
					    progressiveDone = false,
 | 
				
			||||||
 | 
					    contentDispositionFilename = null
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
    this.length = length;
 | 
					    this.length = length;
 | 
				
			||||||
    this.initialData = initialData;
 | 
					    this.initialData = initialData;
 | 
				
			||||||
    this.progressiveDone = progressiveDone;
 | 
					    this.progressiveDone = progressiveDone;
 | 
				
			||||||
 | 
					    this.contentDispositionFilename = contentDispositionFilename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this._rangeListeners = [];
 | 
					    this._rangeListeners = [];
 | 
				
			||||||
    this._progressListeners = [];
 | 
					    this._progressListeners = [];
 | 
				
			||||||
 | 
				
			|||||||
@ -451,6 +451,10 @@ function addLinkAttributes(link, { url, target, rel, enabled = true } = {}) {
 | 
				
			|||||||
  link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
 | 
					  link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function isPdfFile(filename) {
 | 
				
			||||||
 | 
					  return typeof filename === "string" && /\.pdf$/i.test(filename);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Gets the file name from a given URL.
 | 
					 * Gets the file name from a given URL.
 | 
				
			||||||
 * @param {string} url
 | 
					 * @param {string} url
 | 
				
			||||||
@ -652,6 +656,7 @@ export {
 | 
				
			|||||||
  DOMSVGFactory,
 | 
					  DOMSVGFactory,
 | 
				
			||||||
  getFilenameFromUrl,
 | 
					  getFilenameFromUrl,
 | 
				
			||||||
  isFetchSupported,
 | 
					  isFetchSupported,
 | 
				
			||||||
 | 
					  isPdfFile,
 | 
				
			||||||
  isValidFetchUrl,
 | 
					  isValidFetchUrl,
 | 
				
			||||||
  LinkTarget,
 | 
					  LinkTarget,
 | 
				
			||||||
  loadScript,
 | 
					  loadScript,
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ import {
 | 
				
			|||||||
  UnexpectedResponseException,
 | 
					  UnexpectedResponseException,
 | 
				
			||||||
} from "../shared/util.js";
 | 
					} from "../shared/util.js";
 | 
				
			||||||
import { getFilenameFromContentDispositionHeader } from "./content_disposition.js";
 | 
					import { getFilenameFromContentDispositionHeader } from "./content_disposition.js";
 | 
				
			||||||
 | 
					import { isPdfFile } from "./display_utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function validateRangeRequestCapabilities({
 | 
					function validateRangeRequestCapabilities({
 | 
				
			||||||
  getResponseHeader,
 | 
					  getResponseHeader,
 | 
				
			||||||
@ -70,7 +71,7 @@ function extractFilenameFromHeader(getResponseHeader) {
 | 
				
			|||||||
        filename = decodeURIComponent(filename);
 | 
					        filename = decodeURIComponent(filename);
 | 
				
			||||||
      } catch (ex) {}
 | 
					      } catch (ex) {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (/\.pdf$/i.test(filename)) {
 | 
					    if (isPdfFile(filename)) {
 | 
				
			||||||
      return filename;
 | 
					      return filename;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -82,11 +83,7 @@ function createResponseStatusError(status, url) {
 | 
				
			|||||||
    return new MissingPDFException('Missing PDF "' + url + '".');
 | 
					    return new MissingPDFException('Missing PDF "' + url + '".');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return new UnexpectedResponseException(
 | 
					  return new UnexpectedResponseException(
 | 
				
			||||||
    "Unexpected server response (" +
 | 
					    `Unexpected server response (${status}) while retrieving PDF "${url}".`,
 | 
				
			||||||
      status +
 | 
					 | 
				
			||||||
      ') while retrieving PDF "' +
 | 
					 | 
				
			||||||
      url +
 | 
					 | 
				
			||||||
      '".',
 | 
					 | 
				
			||||||
    status
 | 
					    status
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { assert, createPromiseCapability } from "../shared/util.js";
 | 
					import { assert, createPromiseCapability } from "../shared/util.js";
 | 
				
			||||||
 | 
					import { isPdfFile } from "./display_utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @implements {IPDFStream} */
 | 
					/** @implements {IPDFStream} */
 | 
				
			||||||
class PDFDataTransportStream {
 | 
					class PDFDataTransportStream {
 | 
				
			||||||
@ -25,6 +26,8 @@ class PDFDataTransportStream {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this._queuedChunks = [];
 | 
					    this._queuedChunks = [];
 | 
				
			||||||
    this._progressiveDone = params.progressiveDone || false;
 | 
					    this._progressiveDone = params.progressiveDone || false;
 | 
				
			||||||
 | 
					    this._contentDispositionFilename =
 | 
				
			||||||
 | 
					      params.contentDispositionFilename || null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const initialData = params.initialData;
 | 
					    const initialData = params.initialData;
 | 
				
			||||||
    if (initialData?.length > 0) {
 | 
					    if (initialData?.length > 0) {
 | 
				
			||||||
@ -125,7 +128,8 @@ class PDFDataTransportStream {
 | 
				
			|||||||
    return new PDFDataTransportStreamReader(
 | 
					    return new PDFDataTransportStreamReader(
 | 
				
			||||||
      this,
 | 
					      this,
 | 
				
			||||||
      queuedChunks,
 | 
					      queuedChunks,
 | 
				
			||||||
      this._progressiveDone
 | 
					      this._progressiveDone,
 | 
				
			||||||
 | 
					      this._contentDispositionFilename
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -153,10 +157,17 @@ class PDFDataTransportStream {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/** @implements {IPDFStreamReader} */
 | 
					/** @implements {IPDFStreamReader} */
 | 
				
			||||||
class PDFDataTransportStreamReader {
 | 
					class PDFDataTransportStreamReader {
 | 
				
			||||||
  constructor(stream, queuedChunks, progressiveDone = false) {
 | 
					  constructor(
 | 
				
			||||||
 | 
					    stream,
 | 
				
			||||||
 | 
					    queuedChunks,
 | 
				
			||||||
 | 
					    progressiveDone = false,
 | 
				
			||||||
 | 
					    contentDispositionFilename = null
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
    this._stream = stream;
 | 
					    this._stream = stream;
 | 
				
			||||||
    this._done = progressiveDone || false;
 | 
					    this._done = progressiveDone || false;
 | 
				
			||||||
    this._filename = null;
 | 
					    this._filename = isPdfFile(contentDispositionFilename)
 | 
				
			||||||
 | 
					      ? contentDispositionFilename
 | 
				
			||||||
 | 
					      : null;
 | 
				
			||||||
    this._queuedChunks = queuedChunks || [];
 | 
					    this._queuedChunks = queuedChunks || [];
 | 
				
			||||||
    this._loaded = 0;
 | 
					    this._loaded = 0;
 | 
				
			||||||
    for (const chunk of this._queuedChunks) {
 | 
					    for (const chunk of this._queuedChunks) {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ import {
 | 
				
			|||||||
  addLinkAttributes,
 | 
					  addLinkAttributes,
 | 
				
			||||||
  getFilenameFromUrl,
 | 
					  getFilenameFromUrl,
 | 
				
			||||||
  isFetchSupported,
 | 
					  isFetchSupported,
 | 
				
			||||||
 | 
					  isPdfFile,
 | 
				
			||||||
  isValidFetchUrl,
 | 
					  isValidFetchUrl,
 | 
				
			||||||
  LinkTarget,
 | 
					  LinkTarget,
 | 
				
			||||||
  loadScript,
 | 
					  loadScript,
 | 
				
			||||||
@ -128,6 +129,7 @@ export {
 | 
				
			|||||||
  // From "./display/display_utils.js":
 | 
					  // From "./display/display_utils.js":
 | 
				
			||||||
  addLinkAttributes,
 | 
					  addLinkAttributes,
 | 
				
			||||||
  getFilenameFromUrl,
 | 
					  getFilenameFromUrl,
 | 
				
			||||||
 | 
					  isPdfFile,
 | 
				
			||||||
  LinkTarget,
 | 
					  LinkTarget,
 | 
				
			||||||
  loadScript,
 | 
					  loadScript,
 | 
				
			||||||
  PDFDateString,
 | 
					  PDFDateString,
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,7 @@ import {
 | 
				
			|||||||
  getFilenameFromUrl,
 | 
					  getFilenameFromUrl,
 | 
				
			||||||
  GlobalWorkerOptions,
 | 
					  GlobalWorkerOptions,
 | 
				
			||||||
  InvalidPDFException,
 | 
					  InvalidPDFException,
 | 
				
			||||||
 | 
					  isPdfFile,
 | 
				
			||||||
  LinkTarget,
 | 
					  LinkTarget,
 | 
				
			||||||
  loadScript,
 | 
					  loadScript,
 | 
				
			||||||
  MissingPDFException,
 | 
					  MissingPDFException,
 | 
				
			||||||
@ -727,7 +728,10 @@ const PDFViewerApplication = {
 | 
				
			|||||||
      onOpenWithTransport: (url, length, transport) => {
 | 
					      onOpenWithTransport: (url, length, transport) => {
 | 
				
			||||||
        this.open(url, { length, range: transport });
 | 
					        this.open(url, { length, range: transport });
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      onOpenWithData: data => {
 | 
					      onOpenWithData: (data, contentDispositionFilename) => {
 | 
				
			||||||
 | 
					        if (isPdfFile(contentDispositionFilename)) {
 | 
				
			||||||
 | 
					          this._contentDispositionFilename = contentDispositionFilename;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.open(data);
 | 
					        this.open(data);
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      onOpenWithURL: (url, length, originalUrl) => {
 | 
					      onOpenWithURL: (url, length, originalUrl) => {
 | 
				
			||||||
@ -1744,7 +1748,7 @@ const PDFViewerApplication = {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.documentInfo = info;
 | 
					    this.documentInfo = info;
 | 
				
			||||||
    this.metadata = metadata;
 | 
					    this.metadata = metadata;
 | 
				
			||||||
    this._contentDispositionFilename = contentDispositionFilename;
 | 
					    this._contentDispositionFilename ??= contentDispositionFilename;
 | 
				
			||||||
    this._contentLength ??= contentLength; // See `getDownloadInfo`-call above.
 | 
					    this._contentLength ??= contentLength; // See `getDownloadInfo`-call above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Provides some basic debug information
 | 
					    // Provides some basic debug information
 | 
				
			||||||
 | 
				
			|||||||
@ -13,8 +13,7 @@
 | 
				
			|||||||
 * limitations under the License.
 | 
					 * limitations under the License.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { createObjectURL, createValidAbsoluteUrl } from "pdfjs-lib";
 | 
					import { createObjectURL, createValidAbsoluteUrl, isPdfFile } from "pdfjs-lib";
 | 
				
			||||||
import { PdfFileRegExp } from "./ui_utils.js";
 | 
					 | 
				
			||||||
import { viewerCompatibilityParams } from "./viewer_compatibility.js";
 | 
					import { viewerCompatibilityParams } from "./viewer_compatibility.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("CHROME || GENERIC")) {
 | 
					if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("CHROME || GENERIC")) {
 | 
				
			||||||
@ -68,10 +67,10 @@ class DownloadManager {
 | 
				
			|||||||
   * @returns {boolean} Indicating if the data was opened.
 | 
					   * @returns {boolean} Indicating if the data was opened.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  openOrDownloadData(element, data, filename) {
 | 
					  openOrDownloadData(element, data, filename) {
 | 
				
			||||||
    const isPdfFile = PdfFileRegExp.test(filename);
 | 
					    const isPdfData = isPdfFile(filename);
 | 
				
			||||||
    const contentType = isPdfFile ? "application/pdf" : "";
 | 
					    const contentType = isPdfData ? "application/pdf" : "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isPdfFile && !viewerCompatibilityParams.disableCreateObjectURL) {
 | 
					    if (isPdfData && !viewerCompatibilityParams.disableCreateObjectURL) {
 | 
				
			||||||
      let blobUrl = this._openBlobUrls.get(element);
 | 
					      let blobUrl = this._openBlobUrls.get(element);
 | 
				
			||||||
      if (!blobUrl) {
 | 
					      if (!blobUrl) {
 | 
				
			||||||
        blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
 | 
					        blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,10 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "../extensions/firefox/tools/l10n.js";
 | 
					import "../extensions/firefox/tools/l10n.js";
 | 
				
			||||||
import { DEFAULT_SCALE_VALUE, PdfFileRegExp } from "./ui_utils.js";
 | 
					 | 
				
			||||||
import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
 | 
					import { DefaultExternalServices, PDFViewerApplication } from "./app.js";
 | 
				
			||||||
import { PDFDataRangeTransport, shadow } from "pdfjs-lib";
 | 
					import { isPdfFile, PDFDataRangeTransport, shadow } from "pdfjs-lib";
 | 
				
			||||||
import { BasePreferences } from "./preferences.js";
 | 
					import { BasePreferences } from "./preferences.js";
 | 
				
			||||||
 | 
					import { DEFAULT_SCALE_VALUE } from "./ui_utils.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
					if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
 | 
				
			||||||
  throw new Error(
 | 
					  throw new Error(
 | 
				
			||||||
@ -129,10 +129,10 @@ class DownloadManager {
 | 
				
			|||||||
   * @returns {boolean} Indicating if the data was opened.
 | 
					   * @returns {boolean} Indicating if the data was opened.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  openOrDownloadData(element, data, filename) {
 | 
					  openOrDownloadData(element, data, filename) {
 | 
				
			||||||
    const isPdfFile = PdfFileRegExp.test(filename);
 | 
					    const isPdfData = isPdfFile(filename);
 | 
				
			||||||
    const contentType = isPdfFile ? "application/pdf" : "";
 | 
					    const contentType = isPdfData ? "application/pdf" : "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isPdfFile) {
 | 
					    if (isPdfData) {
 | 
				
			||||||
      let blobUrl = this._openBlobUrls.get(element);
 | 
					      let blobUrl = this._openBlobUrls.get(element);
 | 
				
			||||||
      if (!blobUrl) {
 | 
					      if (!blobUrl) {
 | 
				
			||||||
        blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
 | 
					        blobUrl = URL.createObjectURL(new Blob([data], { type: contentType }));
 | 
				
			||||||
@ -332,7 +332,8 @@ class FirefoxExternalServices extends DefaultExternalServices {
 | 
				
			|||||||
          pdfDataRangeTransport = new FirefoxComDataRangeTransport(
 | 
					          pdfDataRangeTransport = new FirefoxComDataRangeTransport(
 | 
				
			||||||
            args.length,
 | 
					            args.length,
 | 
				
			||||||
            args.data,
 | 
					            args.data,
 | 
				
			||||||
            args.done
 | 
					            args.done,
 | 
				
			||||||
 | 
					            args.filename
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          callbacks.onOpenWithTransport(
 | 
					          callbacks.onOpenWithTransport(
 | 
				
			||||||
@ -367,7 +368,7 @@ class FirefoxExternalServices extends DefaultExternalServices {
 | 
				
			|||||||
            callbacks.onError(args.errorCode);
 | 
					            callbacks.onError(args.errorCode);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          callbacks.onOpenWithData(args.data);
 | 
					          callbacks.onOpenWithData(args.data, args.filename);
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
@ -119,8 +119,8 @@ class PDFAttachmentViewer extends BaseTreeViewer {
 | 
				
			|||||||
    let attachmentsCount = 0;
 | 
					    let attachmentsCount = 0;
 | 
				
			||||||
    for (const name of names) {
 | 
					    for (const name of names) {
 | 
				
			||||||
      const item = attachments[name];
 | 
					      const item = attachments[name];
 | 
				
			||||||
      const content = item.content;
 | 
					      const content = item.content,
 | 
				
			||||||
      const filename = getFilenameFromUrl(item.filename);
 | 
					        filename = getFilenameFromUrl(item.filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const div = document.createElement("div");
 | 
					      const div = document.createElement("div");
 | 
				
			||||||
      div.className = "treeItem";
 | 
					      div.className = "treeItem";
 | 
				
			||||||
 | 
				
			|||||||
@ -69,9 +69,6 @@ const SpreadMode = {
 | 
				
			|||||||
// Used by `PDFViewerApplication`, and by the API unit-tests.
 | 
					// Used by `PDFViewerApplication`, and by the API unit-tests.
 | 
				
			||||||
const AutoPrintRegExp = /\bprint\s*\(/;
 | 
					const AutoPrintRegExp = /\bprint\s*\(/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Used by the (various) `DownloadManager`-implementations.
 | 
					 | 
				
			||||||
const PdfFileRegExp = /\.pdf$/i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Replaces {{arguments}} with their values.
 | 
					// Replaces {{arguments}} with their values.
 | 
				
			||||||
function formatL10nValue(text, args) {
 | 
					function formatL10nValue(text, args) {
 | 
				
			||||||
  if (!args) {
 | 
					  if (!args) {
 | 
				
			||||||
@ -1062,7 +1059,6 @@ export {
 | 
				
			|||||||
  normalizeWheelEventDirection,
 | 
					  normalizeWheelEventDirection,
 | 
				
			||||||
  NullL10n,
 | 
					  NullL10n,
 | 
				
			||||||
  parseQueryString,
 | 
					  parseQueryString,
 | 
				
			||||||
  PdfFileRegExp,
 | 
					 | 
				
			||||||
  PresentationModeState,
 | 
					  PresentationModeState,
 | 
				
			||||||
  ProgressBar,
 | 
					  ProgressBar,
 | 
				
			||||||
  RendererType,
 | 
					  RendererType,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user