tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FilePickerHandler.sys.mjs (3055B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const FILE_PICKER_HANDLER_CID = Services.uuid.generateUUID();
      6 const FILE_PICKER_CONTRACT_ID = "@mozilla.org/filepicker;1";
      7 
      8 /**
      9 * The FilePickerHandler can override the default component factory for the file
     10 * picker to prevent showing file pickers if needed.
     11 */
     12 class FilePickerHandlerClass {
     13  #callers;
     14  #originalFilePickerCID;
     15  #registrar;
     16  #registeredFactory;
     17 
     18  constructor() {
     19    this.#registeredFactory = null;
     20 
     21    this.#registrar = Components.manager.QueryInterface(
     22      Ci.nsIComponentRegistrar
     23    );
     24    this.#originalFilePickerCID = this.#registrar.contractIDToCID(
     25      FILE_PICKER_CONTRACT_ID
     26    );
     27 
     28    // Set to keep track of all callers which requested to handle file pickers.
     29    this.#callers = new Set();
     30  }
     31 
     32  /**
     33   * Stop requesting to dismiss all file pickers on behalf of the provided
     34   * caller.
     35   * Note that file pickers will only be displayed again once all callers
     36   * called allowFilePickers.
     37   *
     38   * @param {object} caller
     39   *     A reference to identify the caller which requested to dismiss pickers.
     40   */
     41  allowFilePickers(caller) {
     42    if (!this.#callers.has(caller)) {
     43      return;
     44    }
     45 
     46    this.#callers.delete(caller);
     47 
     48    if (this.#callers.size || !this.#registeredFactory) {
     49      return;
     50    }
     51 
     52    // Unregister our proxy factory.
     53    this.#registrar.unregisterFactory(
     54      FILE_PICKER_HANDLER_CID,
     55      this.#registeredFactory
     56    );
     57    this.#registeredFactory = null;
     58 
     59    // Restore the original factory.
     60    this.#registrar.registerFactory(
     61      this.#originalFilePickerCID,
     62      "",
     63      FILE_PICKER_CONTRACT_ID,
     64      null
     65    );
     66  }
     67 
     68  /**
     69   * Request to dismiss all file picker dialogs by registering a custom file
     70   * picker factory instead of the default one.
     71   *
     72   * @param {object} caller
     73   *     A reference to identify the caller which requested to dismiss pickers.
     74   */
     75  dismissFilePickers(caller) {
     76    this.#callers.add(caller);
     77 
     78    if (this.#registeredFactory) {
     79      return;
     80    }
     81 
     82    this.#registeredFactory = {
     83      createInstance(iid) {
     84        const filePickerProxy = {
     85          init() {},
     86          open: openCallback => {
     87            openCallback.done(Ci.nsIFilePicker.returnCancel);
     88          },
     89          displayDirectory: null,
     90          file: null,
     91          QueryInterface: ChromeUtils.generateQI(["nsIFilePicker"]),
     92        };
     93        return filePickerProxy.QueryInterface(iid);
     94      },
     95      QueryInterface: ChromeUtils.generateQI(["nsIFactory"]),
     96    };
     97 
     98    this.#registrar.registerFactory(
     99      FILE_PICKER_HANDLER_CID,
    100      "WebDriver FilePicker handler",
    101      FILE_PICKER_CONTRACT_ID,
    102      this.#registeredFactory
    103    );
    104  }
    105 }
    106 
    107 // Expose a singleton shared by all WebDriver sessions.
    108 // The FilePickerHandler factory should only be registered once at most.
    109 export const FilePickerHandler = new FilePickerHandlerClass();