forked from mirrors/gecko-dev
257 lines
7.9 KiB
JavaScript
257 lines
7.9 KiB
JavaScript
/* 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/. */
|
|
|
|
/* global ExtensionAPI, ExtensionCommon */
|
|
|
|
"use strict";
|
|
|
|
const { XPCOMUtils } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
|
);
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
|
Preferences: "resource://gre/modules/Preferences.sys.mjs",
|
|
UrlbarProviderExtension:
|
|
"resource:///modules/UrlbarProviderExtension.sys.mjs",
|
|
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
|
|
UrlbarView: "resource:///modules/UrlbarView.sys.mjs",
|
|
});
|
|
|
|
XPCOMUtils.defineLazyGetter(
|
|
this,
|
|
"defaultPreferences",
|
|
() => new Preferences({ defaultBranch: true })
|
|
);
|
|
|
|
let { EventManager } = ExtensionCommon;
|
|
|
|
this.experiments_urlbar = class extends ExtensionAPI {
|
|
getAPI(context) {
|
|
return {
|
|
experiments: {
|
|
urlbar: {
|
|
addDynamicResultType: (name, type) => {
|
|
this._addDynamicResultType(name, type);
|
|
},
|
|
|
|
addDynamicViewTemplate: (name, viewTemplate) => {
|
|
this._addDynamicViewTemplate(name, viewTemplate);
|
|
},
|
|
|
|
attributionURL: this._getDefaultSettingsAPI(
|
|
"browser.partnerlink.attributionURL"
|
|
),
|
|
|
|
clearInput() {
|
|
let window = BrowserWindowTracker.getTopWindow();
|
|
window.gURLBar.value = "";
|
|
window.gURLBar.setPageProxyState("invalid");
|
|
},
|
|
|
|
engagementTelemetry: this._getDefaultSettingsAPI(
|
|
"browser.urlbar.eventTelemetry.enabled"
|
|
),
|
|
|
|
extensionTimeout: this._getDefaultSettingsAPI(
|
|
"browser.urlbar.extension.timeout"
|
|
),
|
|
|
|
onViewUpdateRequested: new EventManager({
|
|
context,
|
|
name: "experiments.urlbar.onViewUpdateRequested",
|
|
register: (fire, providerName) => {
|
|
let provider = UrlbarProviderExtension.getOrCreate(providerName);
|
|
provider.setEventListener(
|
|
"getViewUpdate",
|
|
(result, idsByName) => {
|
|
return fire.async(result.payload, idsByName).catch(error => {
|
|
throw context.normalizeError(error);
|
|
});
|
|
}
|
|
);
|
|
return () => provider.setEventListener("getViewUpdate", null);
|
|
},
|
|
}).api(),
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
onShutdown() {
|
|
// Reset the default prefs. This is necessary because
|
|
// ExtensionPreferencesManager doesn't properly reset prefs set on the
|
|
// default branch. See bug 1586543, bug 1578513, bug 1578508.
|
|
if (this._initialDefaultPrefs) {
|
|
for (let [pref, value] of this._initialDefaultPrefs.entries()) {
|
|
defaultPreferences.set(pref, value);
|
|
}
|
|
}
|
|
|
|
this._removeDynamicViewTemplates();
|
|
this._removeDynamicResultTypes();
|
|
}
|
|
|
|
_getDefaultSettingsAPI(pref) {
|
|
return {
|
|
get: details => {
|
|
return {
|
|
value: Preferences.get(pref),
|
|
|
|
// Nothing actually uses this, but on debug builds there are extra
|
|
// checks enabled in Schema.sys.mjs that fail if it's not present. The
|
|
// value doesn't matter.
|
|
levelOfControl: "controllable_by_this_extension",
|
|
};
|
|
},
|
|
set: details => {
|
|
if (!this._initialDefaultPrefs) {
|
|
this._initialDefaultPrefs = new Map();
|
|
}
|
|
if (!this._initialDefaultPrefs.has(pref)) {
|
|
this._initialDefaultPrefs.set(pref, defaultPreferences.get(pref));
|
|
}
|
|
defaultPreferences.set(pref, details.value);
|
|
return true;
|
|
},
|
|
clear: details => {
|
|
if (this._initialDefaultPrefs && this._initialDefaultPrefs.has(pref)) {
|
|
defaultPreferences.set(pref, this._initialDefaultPrefs.get(pref));
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
};
|
|
}
|
|
|
|
// We use the following four properties as bookkeeping to keep track of
|
|
// dynamic result types and view templates registered by extensions so that
|
|
// they can be properly removed on extension shutdown.
|
|
|
|
// Names of dynamic result types added by this extension.
|
|
_dynamicResultTypeNames = new Set();
|
|
|
|
// Names of dynamic result type view templates added by this extension.
|
|
_dynamicViewTemplateNames = new Set();
|
|
|
|
// Maps dynamic result type names to Sets of IDs of extensions that have
|
|
// registered those types.
|
|
static extIDsByDynamicResultTypeName = new Map();
|
|
|
|
// Maps dynamic result type view template names to Sets of IDs of extensions
|
|
// that have registered those view templates.
|
|
static extIDsByDynamicViewTemplateName = new Map();
|
|
|
|
/**
|
|
* Adds a dynamic result type and includes it in our bookkeeping. See
|
|
* UrlbarResult.addDynamicResultType().
|
|
*
|
|
* @param {string} name
|
|
* The name of the dynamic result type.
|
|
* @param {object} type
|
|
* The type.
|
|
*/
|
|
_addDynamicResultType(name, type) {
|
|
this._dynamicResultTypeNames.add(name);
|
|
this._addExtIDToDynamicResultTypeMap(
|
|
experiments_urlbar.extIDsByDynamicResultTypeName,
|
|
name
|
|
);
|
|
UrlbarResult.addDynamicResultType(name, type);
|
|
}
|
|
|
|
/**
|
|
* Removes all dynamic result types added by the extension.
|
|
*/
|
|
_removeDynamicResultTypes() {
|
|
for (let name of this._dynamicResultTypeNames) {
|
|
let allRemoved = this._removeExtIDFromDynamicResultTypeMap(
|
|
experiments_urlbar.extIDsByDynamicResultTypeName,
|
|
name
|
|
);
|
|
if (allRemoved) {
|
|
UrlbarResult.removeDynamicResultType(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a dynamic result type view template and includes it in our
|
|
* bookkeeping. See UrlbarView.addDynamicViewTemplate().
|
|
*
|
|
* @param {string} name
|
|
* The view template will be registered for the dynamic result type with
|
|
* this name.
|
|
* @param {object} viewTemplate
|
|
* The view template.
|
|
*/
|
|
_addDynamicViewTemplate(name, viewTemplate) {
|
|
this._dynamicViewTemplateNames.add(name);
|
|
this._addExtIDToDynamicResultTypeMap(
|
|
experiments_urlbar.extIDsByDynamicViewTemplateName,
|
|
name
|
|
);
|
|
if (viewTemplate.stylesheet) {
|
|
viewTemplate.stylesheet = this.extension.baseURI.resolve(
|
|
viewTemplate.stylesheet
|
|
);
|
|
}
|
|
UrlbarView.addDynamicViewTemplate(name, viewTemplate);
|
|
}
|
|
|
|
/**
|
|
* Removes all dynamic result type view templates added by the extension.
|
|
*/
|
|
_removeDynamicViewTemplates() {
|
|
for (let name of this._dynamicViewTemplateNames) {
|
|
let allRemoved = this._removeExtIDFromDynamicResultTypeMap(
|
|
experiments_urlbar.extIDsByDynamicViewTemplateName,
|
|
name
|
|
);
|
|
if (allRemoved) {
|
|
UrlbarView.removeDynamicViewTemplate(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a dynamic result type name and this extension's ID to a bookkeeping
|
|
* map.
|
|
*
|
|
* @param {Map} map
|
|
* Either extIDsByDynamicResultTypeName or extIDsByDynamicViewTemplateName.
|
|
* @param {string} dynamicTypeName
|
|
* The dynamic result type name.
|
|
*/
|
|
_addExtIDToDynamicResultTypeMap(map, dynamicTypeName) {
|
|
let extIDs = map.get(dynamicTypeName);
|
|
if (!extIDs) {
|
|
extIDs = new Set();
|
|
map.set(dynamicTypeName, extIDs);
|
|
}
|
|
extIDs.add(this.extension.id);
|
|
}
|
|
|
|
/**
|
|
* Removes a dynamic result type name and this extension's ID from a
|
|
* bookkeeping map.
|
|
*
|
|
* @param {Map} map
|
|
* Either extIDsByDynamicResultTypeName or extIDsByDynamicViewTemplateName.
|
|
* @param {string} dynamicTypeName
|
|
* The dynamic result type name.
|
|
* @returns {boolean}
|
|
* True if no other extension IDs are in the map under the same
|
|
* dynamicTypeName, and false otherwise.
|
|
*/
|
|
_removeExtIDFromDynamicResultTypeMap(map, dynamicTypeName) {
|
|
let extIDs = map.get(dynamicTypeName);
|
|
extIDs.delete(this.extension.id);
|
|
if (!extIDs.size) {
|
|
map.delete(dynamicTypeName);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|