Bug 1629113 - Move prompt classes to its own modules. r=snorp

Differential Revision: https://phabricator.services.mozilla.com/D75877
This commit is contained in:
Agi Sferro 2020-05-26 16:35:28 +00:00
Родитель 903fea5453
Коммит 7cdda27e40
7 изменённых файлов: 457 добавлений и 377 удалений

Просмотреть файл

@ -0,0 +1,46 @@
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["ColorPickerDelegate"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.jsm",
});
const { debug, warn } = GeckoViewUtils.initLogging("ColorPickerDelegate"); // eslint-disable-line no-unused-vars
class ColorPickerDelegate {
init(aParent, aTitle, aInitialColor) {
this._prompt = new GeckoViewPrompter(aParent);
this._msg = {
type: "color",
title: aTitle,
value: aInitialColor,
};
}
open(aColorPickerShownCallback) {
this._prompt.asyncShowPrompt(this._msg, result => {
// OK: result
// Cancel: !result
aColorPickerShownCallback.done((result && result.color) || "");
});
}
}
ColorPickerDelegate.prototype.classID = Components.ID(
"{aa0dd6fc-73dd-4621-8385-c0b377e02cee}"
);
ColorPickerDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsIColorPicker,
]);

Просмотреть файл

@ -0,0 +1,197 @@
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["FilePickerDelegate"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
FileUtils: "resource://gre/modules/FileUtils.jsm",
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.jsm",
Services: "resource://gre/modules/Services.jsm",
});
const { debug, warn } = GeckoViewUtils.initLogging("FilePickerDelegate"); // eslint-disable-line no-unused-vars
class FilePickerDelegate {
/* ---------- nsIFilePicker ---------- */
init(aParent, aTitle, aMode) {
if (
aMode === Ci.nsIFilePicker.modeGetFolder ||
aMode === Ci.nsIFilePicker.modeSave
) {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
this._prompt = new GeckoViewPrompter(aParent);
this._msg = {
type: "file",
title: aTitle,
mode: aMode === Ci.nsIFilePicker.modeOpenMultiple ? "multiple" : "single",
};
this._mode = aMode;
this._mimeTypes = [];
this._capture = 0;
}
get mode() {
return this._mode;
}
appendRawFilter(aFilter) {
this._mimeTypes.push(aFilter);
}
show() {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
open(aFilePickerShownCallback) {
this._msg.mimeTypes = this._mimeTypes;
this._msg.capture = this._capture;
this._prompt.asyncShowPrompt(this._msg, result => {
// OK: result
// Cancel: !result
if (!result || !result.files || !result.files.length) {
aFilePickerShownCallback.done(Ci.nsIFilePicker.returnCancel);
} else {
this._resolveFiles(result.files, aFilePickerShownCallback);
}
});
}
async _resolveFiles(aFiles, aCallback) {
const fileData = [];
try {
for (const file of aFiles) {
const domFile = await this._getDOMFile(file);
fileData.push({
file,
domFile,
});
}
} catch (ex) {
warn`Error resolving files from file picker: ${ex}`;
aCallback.done(Ci.nsIFilePicker.returnCancel);
return;
}
this._fileData = fileData;
aCallback.done(Ci.nsIFilePicker.returnOK);
}
get file() {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
const fileData = this._fileData[0];
if (!fileData) {
return null;
}
return new FileUtils.File(fileData.file);
}
get fileURL() {
return Services.io.newFileURI(this.file);
}
*_getEnumerator(aDOMFile) {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
for (const fileData of this._fileData) {
if (aDOMFile) {
yield fileData.domFile;
}
yield new FileUtils.File(fileData.file);
}
}
get files() {
return this._getEnumerator(/* aDOMFile */ false);
}
_getDOMFile(aPath) {
if (this._prompt.domWin) {
return this._prompt.domWin.File.createFromFileName(aPath);
}
return File.createFromFileName(aPath);
}
get domFileOrDirectory() {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
return this._fileData[0] ? this._fileData[0].domFile : null;
}
get domFileOrDirectoryEnumerator() {
return this._getEnumerator(/* aDOMFile */ true);
}
get defaultString() {
return "";
}
set defaultString(aValue) {}
get defaultExtension() {
return "";
}
set defaultExtension(aValue) {}
get filterIndex() {
return 0;
}
set filterIndex(aValue) {}
get displayDirectory() {
return null;
}
set displayDirectory(aValue) {}
get displaySpecialDirectory() {
return "";
}
set displaySpecialDirectory(aValue) {}
get addToRecentDocs() {
return false;
}
set addToRecentDocs(aValue) {}
get okButtonLabel() {
return "";
}
set okButtonLabel(aValue) {}
get capture() {
return this._capture;
}
set capture(aValue) {
this._capture = aValue;
}
}
FilePickerDelegate.prototype.classID = Components.ID(
"{e4565e36-f101-4bf5-950b-4be0887785a9}"
);
FilePickerDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsIFilePicker,
]);

Просмотреть файл

@ -3,13 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = [
"ColorPickerDelegate",
"FilePickerDelegate",
"LoginStorageDelegate",
"PromptFactory",
"ShareDelegate",
];
var EXPORTED_SYMBOLS = ["PromptFactory"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
@ -20,18 +14,10 @@ const { XPCOMUtils } = ChromeUtils.import(
);
XPCOMUtils.defineLazyModuleGetters(this, {
FileUtils: "resource://gre/modules/FileUtils.jsm",
GeckoViewAutocomplete: "resource://gre/modules/GeckoViewAutocomplete.jsm",
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.jsm",
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
LoginEntry: "resource://gre/modules/GeckoViewAutocomplete.jsm",
Services: "resource://gre/modules/Services.jsm",
});
const domBundle = Services.strings.createBundle(
"chrome://global/locale/dom/dom.properties"
);
const { debug, warn } = GeckoViewUtils.initLogging("GeckoViewPrompt"); // eslint-disable-line no-unused-vars
function PromptFactory() {
@ -911,361 +897,3 @@ PromptDelegate.prototype = {
return { displayHost, realm };
},
};
class FilePickerDelegate {
/* ---------- nsIFilePicker ---------- */
init(aParent, aTitle, aMode) {
if (
aMode === Ci.nsIFilePicker.modeGetFolder ||
aMode === Ci.nsIFilePicker.modeSave
) {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
this._prompt = new GeckoViewPrompter(aParent);
this._msg = {
type: "file",
title: aTitle,
mode: aMode === Ci.nsIFilePicker.modeOpenMultiple ? "multiple" : "single",
};
this._mode = aMode;
this._mimeTypes = [];
this._capture = 0;
}
get mode() {
return this._mode;
}
appendRawFilter(aFilter) {
this._mimeTypes.push(aFilter);
}
show() {
throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
}
open(aFilePickerShownCallback) {
this._msg.mimeTypes = this._mimeTypes;
this._msg.capture = this._capture;
this._prompt.asyncShowPrompt(this._msg, result => {
// OK: result
// Cancel: !result
if (!result || !result.files || !result.files.length) {
aFilePickerShownCallback.done(Ci.nsIFilePicker.returnCancel);
} else {
this._resolveFiles(result.files, aFilePickerShownCallback);
}
});
}
async _resolveFiles(aFiles, aCallback) {
const fileData = [];
try {
for (const file of aFiles) {
const domFile = await this._getDOMFile(file);
fileData.push({
file,
domFile,
});
}
} catch (ex) {
warn`Error resolving files from file picker: ${ex}`;
aCallback.done(Ci.nsIFilePicker.returnCancel);
return;
}
this._fileData = fileData;
aCallback.done(Ci.nsIFilePicker.returnOK);
}
get file() {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
const fileData = this._fileData[0];
if (!fileData) {
return null;
}
return new FileUtils.File(fileData.file);
}
get fileURL() {
return Services.io.newFileURI(this.file);
}
*_getEnumerator(aDOMFile) {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
for (const fileData of this._fileData) {
if (aDOMFile) {
yield fileData.domFile;
}
yield new FileUtils.File(fileData.file);
}
}
get files() {
return this._getEnumerator(/* aDOMFile */ false);
}
_getDOMFile(aPath) {
if (this._prompt.domWin) {
return this._prompt.domWin.File.createFromFileName(aPath);
}
return File.createFromFileName(aPath);
}
get domFileOrDirectory() {
if (!this._fileData) {
throw Components.Exception("", Cr.NS_ERROR_NOT_AVAILABLE);
}
return this._fileData[0] ? this._fileData[0].domFile : null;
}
get domFileOrDirectoryEnumerator() {
return this._getEnumerator(/* aDOMFile */ true);
}
get defaultString() {
return "";
}
set defaultString(aValue) {}
get defaultExtension() {
return "";
}
set defaultExtension(aValue) {}
get filterIndex() {
return 0;
}
set filterIndex(aValue) {}
get displayDirectory() {
return null;
}
set displayDirectory(aValue) {}
get displaySpecialDirectory() {
return "";
}
set displaySpecialDirectory(aValue) {}
get addToRecentDocs() {
return false;
}
set addToRecentDocs(aValue) {}
get okButtonLabel() {
return "";
}
set okButtonLabel(aValue) {}
get capture() {
return this._capture;
}
set capture(aValue) {
this._capture = aValue;
}
}
FilePickerDelegate.prototype.classID = Components.ID(
"{e4565e36-f101-4bf5-950b-4be0887785a9}"
);
FilePickerDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsIFilePicker,
]);
class ColorPickerDelegate {
init(aParent, aTitle, aInitialColor) {
this._prompt = new GeckoViewPrompter(aParent);
this._msg = {
type: "color",
title: aTitle,
value: aInitialColor,
};
}
open(aColorPickerShownCallback) {
this._prompt.asyncShowPrompt(this._msg, result => {
// OK: result
// Cancel: !result
aColorPickerShownCallback.done((result && result.color) || "");
});
}
}
ColorPickerDelegate.prototype.classID = Components.ID(
"{aa0dd6fc-73dd-4621-8385-c0b377e02cee}"
);
ColorPickerDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsIColorPicker,
]);
class ShareDelegate {
init(aParent) {
this._openerWindow = aParent;
}
get openerWindow() {
return this._openerWindow;
}
async share(aTitle, aText, aUri) {
const ABORT = 2;
const FAILURE = 1;
const SUCCESS = 0;
const msg = {
type: "share",
title: aTitle,
text: aText,
uri: aUri ? aUri.displaySpec : null,
};
const prompt = new GeckoViewPrompter(this._openerWindow);
const result = await new Promise(resolve => {
prompt.asyncShowPrompt(msg, resolve);
});
if (!result) {
// A null result is treated as a dismissal in GeckoViewPrompter.
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Aborted"),
"AbortError"
);
}
const res = result && result.response;
switch (res) {
case FAILURE:
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Failed"),
"DataError"
);
case ABORT: // Handle aborted attempt and invalid responses the same.
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Aborted"),
"AbortError"
);
case SUCCESS:
return;
default:
throw new DOMException("Unknown error.", "UnknownError");
}
}
}
ShareDelegate.prototype.classID = Components.ID(
"{1201d357-8417-4926-a694-e6408fbedcf8}"
);
ShareDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsISharePicker,
]);
// Sync with LoginSaveOption.Hint in Autocomplete.java.
const LoginStorageHint = {
NONE: 0,
GENERATED: 1 << 0,
LOW_CONFIDENCE: 1 << 1,
};
class LoginStorageDelegate {
_createMessage({ dismissed, autoSavedLoginGuid }, aLogins) {
let hint = LoginStorageHint.NONE;
if (dismissed) {
hint |= LoginStorageHint.LOW_CONFIDENCE;
}
if (autoSavedLoginGuid) {
hint |= LoginStorageHint.GENERATED;
}
return {
// Sync with GeckoSession.handlePromptEvent.
type: "Autocomplete:Save:Login",
hint,
logins: aLogins,
};
}
promptToSavePassword(
aBrowser,
aLogin,
dismissed = false,
notifySaved = false
) {
const prompt = new GeckoViewPrompter(aBrowser.ownerGlobal);
prompt.asyncShowPrompt(
this._createMessage({ dismissed }, [LoginEntry.fromLoginInfo(aLogin)]),
result => {
const selectedLogin = result?.selection?.value;
if (!selectedLogin) {
return;
}
const loginInfo = LoginEntry.parse(selectedLogin).toLoginInfo();
Services.obs.notifyObservers(loginInfo, "passwordmgr-prompt-save");
GeckoViewAutocomplete.onLoginSave(selectedLogin);
}
);
}
promptToChangePassword(
aBrowser,
aOldLogin,
aNewLogin,
dismissed = false,
notifySaved = false,
autoSavedLoginGuid = ""
) {
const newLogin = LoginEntry.fromLoginInfo(aOldLogin || aNewLogin);
const oldGuid = (aOldLogin && newLogin.guid) || null;
newLogin.origin = aNewLogin.origin;
newLogin.formActionOrigin = aNewLogin.formActionOrigin;
newLogin.password = aNewLogin.password;
newLogin.username = aNewLogin.username;
const prompt = new GeckoViewPrompter(aBrowser.ownerGlobal);
prompt.asyncShowPrompt(
this._createMessage({ dismissed, autoSavedLoginGuid }, [newLogin]),
result => {
const selectedLogin = result?.selection?.value;
if (!selectedLogin) {
return;
}
GeckoViewAutocomplete.onLoginSave(selectedLogin);
const loginInfo = LoginEntry.parse(selectedLogin).toLoginInfo();
Services.obs.notifyObservers(
loginInfo,
"passwordmgr-prompt-change",
oldGuid
);
}
);
}
promptToChangePasswordWithUsernames(aBrowser, aLogins, aNewLogin) {
this.promptToChangePassword(aBrowser, null /* oldLogin */, aNewLogin);
}
}
LoginStorageDelegate.prototype.classID = Components.ID(
"{3d765750-1c3d-11ea-aaef-0800200c9a66}"
);
LoginStorageDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsILoginManagerPrompter,
]);

Просмотреть файл

@ -0,0 +1,120 @@
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["LoginStorageDelegate"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
GeckoViewAutocomplete: "resource://gre/modules/GeckoViewAutocomplete.jsm",
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.jsm",
LoginEntry: "resource://gre/modules/GeckoViewAutocomplete.jsm",
Services: "resource://gre/modules/Services.jsm",
});
const { debug, warn } = GeckoViewUtils.initLogging("LoginStorageDelegate"); // eslint-disable-line no-unused-vars
// Sync with LoginSaveOption.Hint in Autocomplete.java.
const LoginStorageHint = {
NONE: 0,
GENERATED: 1 << 0,
LOW_CONFIDENCE: 1 << 1,
};
class LoginStorageDelegate {
_createMessage({ dismissed, autoSavedLoginGuid }, aLogins) {
let hint = LoginStorageHint.NONE;
if (dismissed) {
hint |= LoginStorageHint.LOW_CONFIDENCE;
}
if (autoSavedLoginGuid) {
hint |= LoginStorageHint.GENERATED;
}
return {
// Sync with GeckoSession.handlePromptEvent.
type: "Autocomplete:Save:Login",
hint,
logins: aLogins,
};
}
promptToSavePassword(
aBrowser,
aLogin,
dismissed = false,
notifySaved = false
) {
const prompt = new GeckoViewPrompter(aBrowser.ownerGlobal);
prompt.asyncShowPrompt(
this._createMessage({ dismissed }, [LoginEntry.fromLoginInfo(aLogin)]),
result => {
const selectedLogin = result?.selection?.value;
if (!selectedLogin) {
return;
}
const loginInfo = LoginEntry.parse(selectedLogin).toLoginInfo();
Services.obs.notifyObservers(loginInfo, "passwordmgr-prompt-save");
GeckoViewAutocomplete.onLoginSave(selectedLogin);
}
);
}
promptToChangePassword(
aBrowser,
aOldLogin,
aNewLogin,
dismissed = false,
notifySaved = false,
autoSavedLoginGuid = ""
) {
const newLogin = LoginEntry.fromLoginInfo(aOldLogin || aNewLogin);
const oldGuid = (aOldLogin && newLogin.guid) || null;
newLogin.origin = aNewLogin.origin;
newLogin.formActionOrigin = aNewLogin.formActionOrigin;
newLogin.password = aNewLogin.password;
newLogin.username = aNewLogin.username;
const prompt = new GeckoViewPrompter(aBrowser.ownerGlobal);
prompt.asyncShowPrompt(
this._createMessage({ dismissed, autoSavedLoginGuid }, [newLogin]),
result => {
const selectedLogin = result?.selection?.value;
if (!selectedLogin) {
return;
}
GeckoViewAutocomplete.onLoginSave(selectedLogin);
const loginInfo = LoginEntry.parse(selectedLogin).toLoginInfo();
Services.obs.notifyObservers(
loginInfo,
"passwordmgr-prompt-change",
oldGuid
);
}
);
}
promptToChangePasswordWithUsernames(aBrowser, aLogins, aNewLogin) {
this.promptToChangePassword(aBrowser, null /* oldLogin */, aNewLogin);
}
}
LoginStorageDelegate.prototype.classID = Components.ID(
"{3d765750-1c3d-11ea-aaef-0800200c9a66}"
);
LoginStorageDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsILoginManagerPrompter,
]);

Просмотреть файл

@ -0,0 +1,85 @@
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["ShareDelegate"];
const { GeckoViewUtils } = ChromeUtils.import(
"resource://gre/modules/GeckoViewUtils.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.jsm",
Services: "resource://gre/modules/Services.jsm",
});
const domBundle = Services.strings.createBundle(
"chrome://global/locale/dom/dom.properties"
);
const { debug, warn } = GeckoViewUtils.initLogging("ShareDelegate"); // eslint-disable-line no-unused-vars
class ShareDelegate {
init(aParent) {
this._openerWindow = aParent;
}
get openerWindow() {
return this._openerWindow;
}
async share(aTitle, aText, aUri) {
const ABORT = 2;
const FAILURE = 1;
const SUCCESS = 0;
const msg = {
type: "share",
title: aTitle,
text: aText,
uri: aUri ? aUri.displaySpec : null,
};
const prompt = new GeckoViewPrompter(this._openerWindow);
const result = await new Promise(resolve => {
prompt.asyncShowPrompt(msg, resolve);
});
if (!result) {
// A null result is treated as a dismissal in GeckoViewPrompter.
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Aborted"),
"AbortError"
);
}
const res = result && result.response;
switch (res) {
case FAILURE:
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Failed"),
"DataError"
);
case ABORT: // Handle aborted attempt and invalid responses the same.
throw new DOMException(
domBundle.GetStringFromName("WebShareAPI_Aborted"),
"AbortError"
);
case SUCCESS:
return;
default:
throw new DOMException("Unknown error.", "UnknownError");
}
}
}
ShareDelegate.prototype.classID = Components.ID(
"{1201d357-8417-4926-a694-e6408fbedcf8}"
);
ShareDelegate.prototype.QueryInterface = ChromeUtils.generateQI([
Ci.nsISharePicker,
]);

Просмотреть файл

@ -23,28 +23,28 @@ Classes = [
{
'cid': '{aa0dd6fc-73dd-4621-8385-c0b377e02cee}',
'contract_ids': ['@mozilla.org/colorpicker;1'],
'jsm': 'resource://gre/modules/GeckoViewPrompt.jsm',
'jsm': 'resource://gre/modules/ColorPickerDelegate.jsm',
'constructor': 'ColorPickerDelegate',
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},
{
'cid': '{e4565e36-f101-4bf5-950b-4be0887785a9}',
'contract_ids': ['@mozilla.org/filepicker;1'],
'jsm': 'resource://gre/modules/GeckoViewPrompt.jsm',
'jsm': 'resource://gre/modules/FilePickerDelegate.jsm',
'constructor': 'FilePickerDelegate',
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},
{
'cid': '{1201d357-8417-4926-a694-e6408fbedcf8}',
'contract_ids': ['@mozilla.org/sharepicker;1'],
'jsm': 'resource://gre/modules/GeckoViewPrompt.jsm',
'jsm': 'resource://gre/modules/ShareDelegate.jsm',
'constructor': 'ShareDelegate',
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},
{
'cid': '{3d765750-1c3d-11ea-aaef-0800200c9a66}',
'contract_ids': ['@mozilla.org/login-manager/prompter;1'],
'jsm': 'resource://gre/modules/GeckoViewPrompt.jsm',
'jsm': 'resource://gre/modules/LoginStorageDelegate.jsm',
'constructor': 'LoginStorageDelegate',
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},

Просмотреть файл

@ -28,9 +28,13 @@ EXTRA_COMPONENTS += [
]
EXTRA_JS_MODULES += [
'ColorPickerDelegate.jsm',
'FilePickerDelegate.jsm',
'GeckoViewPrompt.jsm',
'GeckoViewPrompter.jsm',
'LoginStorageDelegate.jsm',
'PromptCollection.jsm',
'ShareDelegate.jsm',
]
FINAL_LIBRARY = 'xul'