Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
EventEmitter: "resource://gre/modules/EventEmitter.sys.mjs",
});
const OBSERVER_TOPIC_FILE_INPUT_PICKER_OPENING = "file-input-picker-opening";
/**
* The FilePickerListener can be used to listen for file picker dialog openings
* triggered by input type=file elements.
*
* Note that the actual file picker might not open if it is automatically
* dismissed as part of the defined user prompt behavior.
*
* Example:
* ```
* const listener = new FilePickerListener();
* listener.on("file-picker-opening", onFilePickerOpened);
* listener.startListening();
*
* const onFilePickerOpened = (eventName, data) => {
* const { element } = data;
* console.log("File picker opened:", element.multiple);
* };
* ```
*
* @fires FilePickerListener#"file-picker-opening"
* The FilePickerListener emits the following event:
* - "file-picker-opening" when a file picker is requested to be opened,
* with the following object as payload:
* - {Element} element
* The DOM element which triggered the file picker to open.
*/
export class FilePickerListener {
#listening;
constructor() {
lazy.EventEmitter.decorate(this);
this.#listening = false;
}
destroy() {
this.stopListening();
}
observe(subject, topic) {
switch (topic) {
case OBSERVER_TOPIC_FILE_INPUT_PICKER_OPENING: {
this.emit("file-picker-opening", {
element: subject,
});
break;
}
}
}
startListening() {
if (this.#listening) {
return;
}
Services.obs.addObserver(this, OBSERVER_TOPIC_FILE_INPUT_PICKER_OPENING);
this.#listening = true;
}
stopListening() {
if (!this.#listening) {
return;
}
Services.obs.removeObserver(this, OBSERVER_TOPIC_FILE_INPUT_PICKER_OPENING);
this.#listening = false;
}
}