/* 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";
/** * NOTE: If you change the globals in this file, you must check if the globals * list in mobile/android/.eslintrc.js also needs updating.
*/
// We need let to break cyclic dependency /* eslint-disable-next-line prefer-const */
let windowTracker;
/** * A nsIWebProgressListener for a specific XUL browser, which delegates the * events that it receives to a tab progress listener, and prepends the browser * to their arguments list. * * @param {XULElement} browser * A XUL browser element. * @param {object} listener * A tab progress listener object. * @param {integer} flags * The web progress notification flags with which to filter events.
*/ class BrowserProgressListener {
constructor(browser, listener, flags) { this.listener = listener; this.browser = browser; this.filter = new BrowserStatusFilter(this, flags); this.browser.addProgressListener(this.filter, flags);
}
/** * Destroy the listener, and perform any necessary cleanup.
*/
destroy() { this.browser.removeProgressListener(this.filter); this.filter.removeProgressListener(this);
}
/** * Calls the appropriate listener in the wrapped tab progress listener, with * the wrapped XUL browser object as its first argument, and the additional * arguments in `args`. * * @param {string} method * The name of the nsIWebProgressListener method which is being * delegated. * @param {*} args * The arguments to pass to the delegated listener. * @private
*/
delegate(method, ...args) { if (this.listener[method]) { this.listener[method](this.browser, ...args);
}
}
onLocationChange(webProgress, request, locationURI, flags) { const window = this.browser.ownerGlobal; // GeckoView windows can become popups at any moment, so we need to check // here if (!windowTracker.isBrowserWindow(window)) { return;
}
class ProgressListenerWrapper {
constructor(window, listener) { this.listener = new BrowserProgressListener(
window.browser,
listener,
PROGRESS_LISTENER_FLAGS
);
}
destroy() { this.listener.destroy();
}
}
class WindowTracker extends WindowTrackerBase {
constructor(...args) { super(...args);
this.progressListeners = new DefaultWeakMap(() => new WeakMap());
}
getCurrentWindow(context) { // In GeckoView the popup is on a separate window so getCurrentWindow for // the popup should return whatever is the topWindow. if (context?.viewType === "popup") { returnthis.topWindow;
} returnsuper.getCurrentWindow(context);
}
get topWindow() { return mobileWindowTracker.topWindow;
}
get topNonPBWindow() { return mobileWindowTracker.topNonPBWindow;
}
/** * Helper to create an event manager which listens for an event in the Android * global EventDispatcher, and calls the given listener function whenever the * event is received. That listener function receives a `fire` object, * which it can use to dispatch events to the extension, and an object * detailing the EventDispatcher event that was received. * * @param {BaseContext} context * The extension context which the event manager belongs to. * @param {string} name * The API name of the event manager, e.g.,"runtime.onMessage". * @param {string} event * The name of the EventDispatcher event to listen for. * @param {Function} listener * The listener function to call when an EventDispatcher event is * recieved. * * @returns {object} An injectable api for the new event.
*/
global.makeGlobalEvent = function makeGlobalEvent(
context,
name,
event,
listener
) { returnnew EventManager({
context,
name,
register: fire => { const listener2 = {
onEvent(event, data) {
listener(fire, data);
},
};
windowTracker.addCloseListener(window => { const { tab: nativeTab, browser } = window; const { windowId, tabId } = this.getBrowserData(browser); this.emit("tab-removed", {
nativeTab,
tabId,
windowId, // In GeckoView, it is not meaningful to speak of "window closed", because a tab is a window. // Until we have a meaningful way to group tabs (and close multiple tabs at once), // let's use isWindowClosing: false
isWindowClosing: false,
});
});
}
get autoDiscardable() { // This property reflects whether the browser is allowed to auto-discard. // Since extensions cannot do so on Android, we return true here. returntrue;
}
// Manages tab-specific context data and dispatches tab select and close events. class TabContext extends EventEmitter {
constructor(getDefaultPrototype) { super();
windowTracker.addListener("progress", this);
this.getDefaultPrototype = getDefaultPrototype; this.tabData = new Map();
}
onLocationChange(browser, webProgress, request, locationURI, flags) { if (!webProgress.isTopLevel) { // Only pageAction and browserAction are consuming the "location-change" event // to update their per-tab status, and they should only do so in response of // location changes related to the top level frame (See Bug 1493470 for a rationale). return;
} const { tab } = browser.ownerGlobal; // fromBrowse will be false in case of e.g. a hash change or history.pushState const fromBrowse = !(
flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT
); this.emit( "location-change",
{
id: tab.id,
linkedBrowser: browser, // TODO: we don't support selected so we just alway say we are
selected: true,
},
fromBrowse
);
}
get(tabId) { if (!this.tabData.has(tabId)) { const data = Object.create(this.getDefaultPrototype(tabId)); this.tabData.set(tabId, data);
}
class Window extends WindowBase {
get focused() { returnthis.window.document.hasFocus();
}
isCurrentFor(context) { // In GeckoView the popup is on a separate window so the current window for // the popup is whatever is the topWindow. if (context?.viewType === "popup") { return mobileWindowTracker.topWindow == this.window;
} returnsuper.isCurrentFor(context);
}
get top() { returnthis.window.screenY;
}
get left() { returnthis.window.screenX;
}
get width() { returnthis.window.outerWidth;
}
get height() { returnthis.window.outerHeight;
}
get incognito() { return PrivateBrowsingUtils.isWindowPrivate(this.window);
}
get alwaysOnTop() { returnfalse;
}
get isLastFocused() { returnthis.window === windowTracker.topWindow;
}
if (optionsPageProperties.open_in_tab) { // Delegate new tab creation and open the options page in the new tab. const tab = await GeckoViewTabBridge.createNewTab({
extensionId,
createProperties: {
url: optionsPageProperties.page,
active: true,
},
});
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.