mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-11 21:58:41 +02:00
There is still some tight connection between ThreadClient and Target,
- Target.threadClient, which should ideally disappear in favor of
target.getFront("thread")
- Target.threadClient is manually nullified from ThreadClient.detach,
but that should disappear as well thanks to getFront.
Differential Revision: https://phabricator.services.mozilla.com/D18813
--HG--
extra : moz-landing-system : lando
152 lines
4.7 KiB
JavaScript
152 lines
4.7 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/. */
|
|
"use strict";
|
|
|
|
const {browsingContextTargetSpec} = require("devtools/shared/specs/targets/browsing-context");
|
|
const { FrontClassWithSpec, registerFront } = require("devtools/shared/protocol");
|
|
const { TargetMixin } = require("./target-mixin");
|
|
|
|
class BrowsingContextTargetFront extends
|
|
TargetMixin(FrontClassWithSpec(browsingContextTargetSpec)) {
|
|
constructor(client) {
|
|
super(client);
|
|
|
|
// Cache the value of some target properties that are being returned by `attach`
|
|
// request and then keep them up-to-date in `reconfigure` request.
|
|
this.configureOptions = {
|
|
javascriptEnabled: null,
|
|
};
|
|
|
|
// RootFront.listTabs is going to update this state via `setIsSelected` method
|
|
this._selected = false;
|
|
|
|
this._onTabNavigated = this._onTabNavigated.bind(this);
|
|
this._onFrameUpdate = this._onFrameUpdate.bind(this);
|
|
}
|
|
|
|
form(json) {
|
|
this.actorID = json.actor;
|
|
|
|
// Save the full form for Target class usage.
|
|
// Do not use `form` name to avoid colliding with protocol.js's `form` method
|
|
this.targetForm = json;
|
|
|
|
this.outerWindowID = json.outerWindowID;
|
|
this.favicon = json.favicon;
|
|
this._title = json.title;
|
|
this._url = json.url;
|
|
}
|
|
|
|
// Reports if the related tab is selected. Only applies to BrowsingContextTarget
|
|
// issued from RootFront.listTabs.
|
|
get selected() {
|
|
return this._selected;
|
|
}
|
|
|
|
// This is called by RootFront.listTabs, to update the currently selected tab.
|
|
setIsSelected(selected) {
|
|
this._selected = selected;
|
|
}
|
|
|
|
/**
|
|
* Event listener for `frameUpdate` event.
|
|
*/
|
|
_onFrameUpdate(packet) {
|
|
this.emit("frame-update", packet);
|
|
}
|
|
|
|
/**
|
|
* Event listener for `tabNavigated` event.
|
|
*/
|
|
_onTabNavigated(packet) {
|
|
const event = Object.create(null);
|
|
event.url = packet.url;
|
|
event.title = packet.title;
|
|
event.nativeConsoleAPI = packet.nativeConsoleAPI;
|
|
event.isFrameSwitching = packet.isFrameSwitching;
|
|
|
|
// Keep the title unmodified when a developer toolbox switches frame
|
|
// for a tab (Bug 1261687), but always update the title when the target
|
|
// is a WebExtension (where the addon name is always included in the title
|
|
// and the url is supposed to be updated every time the selected frame changes).
|
|
if (!packet.isFrameSwitching || this.isWebExtension) {
|
|
this._url = packet.url;
|
|
this._title = packet.title;
|
|
}
|
|
|
|
// Send any stored event payload (DOMWindow or nsIRequest) for backwards
|
|
// compatibility with non-remotable tools.
|
|
if (packet.state == "start") {
|
|
this.emit("will-navigate", event);
|
|
} else {
|
|
this.emit("navigate", event);
|
|
}
|
|
}
|
|
|
|
async attach() {
|
|
if (this._attach) {
|
|
return this._attach;
|
|
}
|
|
this._attach = (async () => {
|
|
// All Browsing context inherited target emit a few event that are being
|
|
// translated on the target class. Listen for them before attaching as they
|
|
// can start firing on attach call.
|
|
this.on("tabNavigated", this._onTabNavigated);
|
|
this.on("frameUpdate", this._onFrameUpdate);
|
|
|
|
const response = await super.attach();
|
|
|
|
this._threadActor = response.threadActor;
|
|
this.configureOptions.javascriptEnabled = response.javascriptEnabled;
|
|
this.traits = response.traits || {};
|
|
|
|
// xpcshell tests from devtools/server/tests/unit/ are implementing
|
|
// fake BrowsingContextTargetActor which do not expose any console actor.
|
|
if (this.targetForm.consoleActor) {
|
|
await this.attachConsole();
|
|
}
|
|
})();
|
|
return this._attach;
|
|
}
|
|
|
|
async reconfigure({ options }) {
|
|
const response = await super.reconfigure({ options });
|
|
|
|
if (typeof options.javascriptEnabled != "undefined") {
|
|
this.configureOptions.javascriptEnabled = options.javascriptEnabled;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
async detach() {
|
|
let response;
|
|
try {
|
|
response = await super.detach();
|
|
} catch (e) {
|
|
console.warn(
|
|
`Error while detaching the browsing context target front: ${e.message}`);
|
|
}
|
|
|
|
// Remove listeners set in attach
|
|
this.off("tabNavigated", this._onTabNavigated);
|
|
this.off("frameUpdate", this._onFrameUpdate);
|
|
|
|
return response;
|
|
}
|
|
|
|
destroy() {
|
|
const promise = super.destroy();
|
|
|
|
// As detach isn't necessarily called on target's destroy
|
|
// (it isn't for local tabs), ensure removing listeners set in attach.
|
|
this.off("tabNavigated", this._onTabNavigated);
|
|
this.off("frameUpdate", this._onFrameUpdate);
|
|
|
|
return promise;
|
|
}
|
|
}
|
|
|
|
exports.BrowsingContextTargetFront = BrowsingContextTargetFront;
|
|
registerFront(exports.BrowsingContextTargetFront);
|