зеркало из https://github.com/mozilla/gecko-dev.git
Bug 792062 - Make the tabNavigated notification reusable by the Web Console; r=past
This commit is contained in:
Родитель
aae3f29d7b
Коммит
11c5a3ad68
|
@ -103,64 +103,26 @@ function DeviceTabActor(connection, browser) {
|
|||
|
||||
DeviceTabActor.prototype = new BrowserTabActor();
|
||||
|
||||
DeviceTabActor.prototype.grip = function DTA_grip() {
|
||||
dbg_assert(!this.exited,
|
||||
'grip() should not be called on exited browser actor.');
|
||||
dbg_assert(this.actorID,
|
||||
'tab should have an actorID.');
|
||||
Object.defineProperty(DeviceTabActor.prototype, "title", {
|
||||
get: function() {
|
||||
return this.browser.title;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
let response = {
|
||||
'actor': this.actorID,
|
||||
'title': this.browser.title,
|
||||
'url': this.browser.document.documentURI
|
||||
};
|
||||
Object.defineProperty(DeviceTabActor.prototype, "url", {
|
||||
get: function() {
|
||||
return this.browser.document.documentURI;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
||||
// Walk over tab actors added by extensions and add them to a new ActorPool.
|
||||
let actorPool = new ActorPool(this.conn);
|
||||
this._createExtraActors(DebuggerServer.tabActorFactories, actorPool);
|
||||
if (!actorPool.isEmpty()) {
|
||||
this._tabActorPool = actorPool;
|
||||
this.conn.addActorPool(this._tabActorPool);
|
||||
}
|
||||
|
||||
this._appendExtraActors(response);
|
||||
return response;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a thread actor and a pool for context-lifetime actors. It then sets
|
||||
* up the content window for debugging.
|
||||
*/
|
||||
DeviceTabActor.prototype._pushContext = function DTA_pushContext() {
|
||||
dbg_assert(!this._contextPool, "Can't push multiple contexts");
|
||||
|
||||
this._contextPool = new ActorPool(this.conn);
|
||||
this.conn.addActorPool(this._contextPool);
|
||||
|
||||
this.threadActor = new ThreadActor(this, this.browser.wrappedJSObject);
|
||||
this._contextPool.addActor(this.threadActor);
|
||||
};
|
||||
|
||||
// Protocol Request Handlers
|
||||
|
||||
/**
|
||||
* Prepare to enter a nested event loop by disabling debuggee events.
|
||||
*/
|
||||
DeviceTabActor.prototype.preNest = function DTA_preNest() {
|
||||
let windowUtils = this.browser
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.suppressEventHandling(true);
|
||||
windowUtils.suspendTimeouts();
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepare to exit a nested event loop by enabling debuggee events.
|
||||
*/
|
||||
DeviceTabActor.prototype.postNest = function DTA_postNest(aNestData) {
|
||||
let windowUtils = this.browser
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.resumeTimeouts();
|
||||
windowUtils.suppressEventHandling(false);
|
||||
};
|
||||
Object.defineProperty(DeviceTabActor.prototype, "contentWindow", {
|
||||
get: function() {
|
||||
return this.browser;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: false
|
||||
});
|
||||
|
|
|
@ -215,9 +215,18 @@ let DebuggerController = {
|
|||
|
||||
/**
|
||||
* Called for each location change in the debugged tab.
|
||||
*
|
||||
* @param string aType
|
||||
* Packet type.
|
||||
* @param object aPacket
|
||||
* Packet received from the server.
|
||||
*/
|
||||
_onTabNavigated: function DC__onTabNavigated() {
|
||||
DebuggerView._handleTabNavigation();
|
||||
_onTabNavigated: function DC__onTabNavigated(aType, aPacket) {
|
||||
if (aPacket.state == "start") {
|
||||
DebuggerView._handleTabNavigation();
|
||||
return;
|
||||
}
|
||||
|
||||
this.ThreadState._handleTabNavigation();
|
||||
this.StackFrames._handleTabNavigation();
|
||||
this.SourceScripts._handleTabNavigation();
|
||||
|
|
|
@ -40,7 +40,14 @@ function testInitialLoad() {
|
|||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
@ -59,7 +66,14 @@ function testLocationChange()
|
|||
|
||||
function testBack()
|
||||
{
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired after going back.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
@ -79,7 +93,14 @@ function testBack()
|
|||
|
||||
function testForward()
|
||||
{
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired after going forward.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
|
|
@ -73,7 +73,13 @@ function testSimpleCall() {
|
|||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
|
|
@ -73,7 +73,13 @@ function testSimpleCall() {
|
|||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
|
|
@ -50,7 +50,13 @@ function testSimpleCall() {
|
|||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gDebugger.DebuggerController.client.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("tabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
gDebugger.DebuggerController.client.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
|
|
|
@ -26,7 +26,13 @@ function get_tab()
|
|||
get_tab_actor_for_url(gClient, TAB1_URL, function(aGrip) {
|
||||
gTab1Actor = aGrip.actor;
|
||||
gClient.request({ to: aGrip.actor, type: "attach" }, function(aResponse) {
|
||||
gClient.addOneTimeListener("tabNavigated", function(aEvent, aPacket) {
|
||||
gClient.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("onTabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
gClient.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
is(aPacket.url, TAB2_URL, "Got a tab navigation notification.");
|
||||
gClient.addOneTimeListener("tabDetached", function (aEvent, aPacket) {
|
||||
ok(true, "Got a tab detach notification.");
|
||||
|
|
|
@ -370,8 +370,12 @@ function RemoteTarget(form, client, chrome) {
|
|||
this.destroy = this.destroy.bind(this);
|
||||
this.client.addListener("tabDetached", this.destroy);
|
||||
|
||||
this._onTabNavigated = function onRemoteTabNavigated() {
|
||||
this.emit("navigate");
|
||||
this._onTabNavigated = function onRemoteTabNavigated(aType, aPacket) {
|
||||
if (aPacket.state == "start") {
|
||||
this.emit("will-navigate", aPacket);
|
||||
} else {
|
||||
this.emit("navigate", aPacket);
|
||||
}
|
||||
}.bind(this);
|
||||
this.client.addListener("tabNavigated", this._onTabNavigated);
|
||||
}
|
||||
|
@ -384,9 +388,9 @@ RemoteTarget.prototype = {
|
|||
|
||||
get chrome() this._chrome,
|
||||
|
||||
get name() this._form._title,
|
||||
get name() this._form.title,
|
||||
|
||||
get url() this._form._url,
|
||||
get url() this._form.url,
|
||||
|
||||
get client() this._client,
|
||||
|
||||
|
|
|
@ -378,6 +378,7 @@ WebConsoleFrame.prototype = {
|
|||
timeout, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
||||
this.proxy.connect(function() {
|
||||
// Don't complete connection if the connection timed-out.
|
||||
if (this._connectTimer) {
|
||||
this._connectTimer.cancel();
|
||||
this._connectTimer = null;
|
||||
|
@ -4045,7 +4046,7 @@ function WebConsoleConnectionProxy(aWebConsole, aTarget)
|
|||
this._onNetworkEvent = this._onNetworkEvent.bind(this);
|
||||
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
|
||||
this._onFileActivity = this._onFileActivity.bind(this);
|
||||
this._onLocationChange = this._onLocationChange.bind(this);
|
||||
this._onTabNavigated = this._onTabNavigated.bind(this);
|
||||
}
|
||||
|
||||
WebConsoleConnectionProxy.prototype = {
|
||||
|
@ -4057,6 +4058,12 @@ WebConsoleConnectionProxy.prototype = {
|
|||
*/
|
||||
owner: null,
|
||||
|
||||
/**
|
||||
* The target that the console connects to.
|
||||
* @type RemoteTarget
|
||||
*/
|
||||
target: null,
|
||||
|
||||
/**
|
||||
* The DebuggerClient object.
|
||||
*
|
||||
|
@ -4073,6 +4080,12 @@ WebConsoleConnectionProxy.prototype = {
|
|||
*/
|
||||
webConsoleClient: null,
|
||||
|
||||
/**
|
||||
* The TabClient instance we use.
|
||||
* @type object
|
||||
*/
|
||||
tabClient: null,
|
||||
|
||||
/**
|
||||
* Tells if the connection is established.
|
||||
* @type boolean
|
||||
|
@ -4087,6 +4100,14 @@ WebConsoleConnectionProxy.prototype = {
|
|||
*/
|
||||
_consoleActor: null,
|
||||
|
||||
/**
|
||||
* The TabActor ID.
|
||||
*
|
||||
* @private
|
||||
* @type string
|
||||
*/
|
||||
_tabActor: null,
|
||||
|
||||
/**
|
||||
* Tells if the window.console object of the remote web page is the native
|
||||
* object or not.
|
||||
|
@ -4131,23 +4152,24 @@ WebConsoleConnectionProxy.prototype = {
|
|||
client.addListener("networkEvent", this._onNetworkEvent);
|
||||
client.addListener("networkEventUpdate", this._onNetworkEventUpdate);
|
||||
client.addListener("fileActivity", this._onFileActivity);
|
||||
client.addListener("locationChange", this._onLocationChange);
|
||||
client.addListener("tabNavigated", this._onTabNavigated);
|
||||
|
||||
if (this.target.isRemote) {
|
||||
this._consoleActor = this.target.form.consoleActor;
|
||||
if (!this.target.chrome) {
|
||||
this.owner.onLocationChange(this.target.url, this.target.name);
|
||||
// target.form is a TabActor grip
|
||||
this._attachTab(this.target.form, aCallback);
|
||||
}
|
||||
else {
|
||||
// target.form is a RootActor grip
|
||||
this._consoleActor = this.target.form.consoleActor;
|
||||
this._attachConsole(aCallback);
|
||||
}
|
||||
|
||||
let listeners = ["PageError", "ConsoleAPI", "NetworkActivity",
|
||||
"FileActivity", "LocationChange"];
|
||||
this.client.attachConsole(this._consoleActor, listeners,
|
||||
this._onAttachConsole.bind(this, aCallback));
|
||||
return;
|
||||
}
|
||||
client.connect(function(aType, aTraits) {
|
||||
client.listTabs(this._onListTabs.bind(this, aCallback));
|
||||
}.bind(this));
|
||||
else {
|
||||
client.connect(function(aType, aTraits) {
|
||||
client.listTabs(this._onListTabs.bind(this, aCallback));
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -4161,19 +4183,67 @@ WebConsoleConnectionProxy.prototype = {
|
|||
*/
|
||||
_onListTabs: function WCCP__onListTabs(aCallback, aResponse)
|
||||
{
|
||||
let selectedTab = aResponse.tabs[aResponse.selected];
|
||||
if (selectedTab) {
|
||||
this._consoleActor = selectedTab.consoleActor;
|
||||
this.owner.onLocationChange(selectedTab.url, selectedTab.title);
|
||||
}
|
||||
else {
|
||||
this._consoleActor = aResponse.consoleActor;
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("listTabs failed: " + aResponse.error + " " +
|
||||
aResponse.message);
|
||||
return;
|
||||
}
|
||||
|
||||
this.owner._resetConnectionTimeout();
|
||||
this._attachTab(aResponse.tabs[aResponse.selected], aCallback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach to the tab actor.
|
||||
*
|
||||
* @private
|
||||
* @param object aTab
|
||||
* Grip for the tab to attach to.
|
||||
* @param function aCallback
|
||||
* Function to invoke when the connection is established.
|
||||
*/
|
||||
_attachTab: function WCCP__attachTab(aTab, aCallback)
|
||||
{
|
||||
this._consoleActor = aTab.consoleActor;
|
||||
this._tabActor = aTab.actor;
|
||||
this.owner.onLocationChange(aTab.url, aTab.title);
|
||||
this.client.attachTab(this._tabActor,
|
||||
this._onAttachTab.bind(this, aCallback));
|
||||
},
|
||||
|
||||
/**
|
||||
* The "attachTab" response handler.
|
||||
*
|
||||
* @private
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the connection is established.
|
||||
* @param object aResponse
|
||||
* The JSON response object received from the server.
|
||||
* @param object aTabClient
|
||||
* The TabClient instance for the attached tab.
|
||||
*/
|
||||
_onAttachTab: function WCCP__onAttachTab(aCallback, aResponse, aTabClient)
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("attachTab failed: " + aResponse.error + " " +
|
||||
aResponse.message);
|
||||
return;
|
||||
}
|
||||
|
||||
this.tabClient = aTabClient;
|
||||
this._attachConsole(aCallback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach to the Web Console actor.
|
||||
*
|
||||
* @private
|
||||
* @param function aCallback
|
||||
* Function to invoke when the connection is established.
|
||||
*/
|
||||
_attachConsole: function WCCP__attachConsole(aCallback)
|
||||
{
|
||||
let listeners = ["PageError", "ConsoleAPI", "NetworkActivity",
|
||||
"FileActivity", "LocationChange"];
|
||||
"FileActivity"];
|
||||
this.client.attachConsole(this._consoleActor, listeners,
|
||||
this._onAttachConsole.bind(this, aCallback));
|
||||
},
|
||||
|
@ -4322,7 +4392,7 @@ WebConsoleConnectionProxy.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* The "locationChange" message type handler. We redirect any message to
|
||||
* The "tabNavigated" message type handler. We redirect any message to
|
||||
* the UI for displaying.
|
||||
*
|
||||
* @private
|
||||
|
@ -4331,13 +4401,16 @@ WebConsoleConnectionProxy.prototype = {
|
|||
* @param object aPacket
|
||||
* The message received from the server.
|
||||
*/
|
||||
_onLocationChange: function WCCP__onLocationChange(aType, aPacket)
|
||||
_onTabNavigated: function WCCP__onTabNavigated(aType, aPacket)
|
||||
{
|
||||
if (!this.owner || aPacket.from != this._consoleActor) {
|
||||
if (!this.owner || aPacket.from != this._tabActor) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.owner.onLocationChange(aPacket.uri, aPacket.title);
|
||||
if (aPacket.url) {
|
||||
this.owner.onLocationChange(aPacket.url, aPacket.title);
|
||||
}
|
||||
|
||||
if (aPacket.state == "stop" && !aPacket.nativeConsoleAPI) {
|
||||
this.owner.logWarningAboutReplacedAPI();
|
||||
}
|
||||
|
@ -4381,7 +4454,8 @@ WebConsoleConnectionProxy.prototype = {
|
|||
};
|
||||
|
||||
let timer = null;
|
||||
if (aOnDisconnect) {
|
||||
let remoteTarget = this.target.isRemote;
|
||||
if (aOnDisconnect && !remoteTarget) {
|
||||
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback(onDisconnect, 1500, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
@ -4391,11 +4465,20 @@ WebConsoleConnectionProxy.prototype = {
|
|||
this.client.removeListener("networkEvent", this._onNetworkEvent);
|
||||
this.client.removeListener("networkEventUpdate", this._onNetworkEventUpdate);
|
||||
this.client.removeListener("fileActivity", this._onFileActivity);
|
||||
this.client.removeListener("locationChange", this._onLocationChange);
|
||||
this.client.removeListener("tabNavigated", this._onTabNavigated);
|
||||
|
||||
let client = this.client;
|
||||
|
||||
this.client = null;
|
||||
this.webConsoleClient = null;
|
||||
this.tabClient = null;
|
||||
this.target = null;
|
||||
this.connected = false;
|
||||
this.owner = null;
|
||||
|
||||
try {
|
||||
if (!this.target.isRemote) {
|
||||
this.client.close(onDisconnect);
|
||||
if (!remoteTarget) {
|
||||
client.close(onDisconnect);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
|
@ -4404,10 +4487,9 @@ WebConsoleConnectionProxy.prototype = {
|
|||
onDisconnect();
|
||||
}
|
||||
|
||||
this.client = null;
|
||||
this.webConsoleClient = null;
|
||||
this.connected = false;
|
||||
this.owner = null;
|
||||
if (remoteTarget) {
|
||||
onDisconnect();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -480,9 +480,10 @@ DebuggerClient.prototype = {
|
|||
this._threadClients[aPacket.from]._onThreadState(aPacket);
|
||||
}
|
||||
// On navigation the server resumes, so the client must resume as well.
|
||||
// We achive that by generating a fake resumption packet that triggers
|
||||
// We achieve that by generating a fake resumption packet that triggers
|
||||
// the client's thread state change listeners.
|
||||
if (aPacket.type == UnsolicitedNotifications.tabNavigated &&
|
||||
if (this.activeThread &&
|
||||
aPacket.type == UnsolicitedNotifications.tabNavigated &&
|
||||
aPacket.from in this._tabClients) {
|
||||
let resumption = { from: this.activeThread._actor, type: "resumed" };
|
||||
this.activeThread._onThreadState(resumption);
|
||||
|
|
|
@ -354,24 +354,51 @@ BrowserTabActor.prototype = {
|
|||
// A constant prefix that will be used to form the actor ID by the server.
|
||||
actorPrefix: "tab",
|
||||
|
||||
grip: function BTA_grip() {
|
||||
dbg_assert(!this.exited,
|
||||
"grip() shouldn't be called on exited browser actor.");
|
||||
dbg_assert(this.actorID,
|
||||
"tab should have an actorID.");
|
||||
|
||||
/**
|
||||
* Getter for the tab title.
|
||||
* @return string
|
||||
* Tab title.
|
||||
*/
|
||||
get title() {
|
||||
let title = this.browser.contentTitle;
|
||||
// If contentTitle is empty (e.g. on a not-yet-restored tab), but there is a
|
||||
// tabbrowser (i.e. desktop Firefox, but not Fennec), we can use the label
|
||||
// as the title.
|
||||
if (!title && this._tabbrowser) {
|
||||
title = this._tabbrowser
|
||||
._getTabForContentWindow(this.browser.contentWindow).label;
|
||||
._getTabForContentWindow(this.contentWindow).label;
|
||||
}
|
||||
return title;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter for the tab URL.
|
||||
* @return string
|
||||
* Tab URL.
|
||||
*/
|
||||
get url() {
|
||||
return this.browser.currentURI.spec;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter for the tab content window.
|
||||
* @return nsIDOMWindow
|
||||
* Tab content window.
|
||||
*/
|
||||
get contentWindow() {
|
||||
return this.browser.contentWindow;
|
||||
},
|
||||
|
||||
grip: function BTA_grip() {
|
||||
dbg_assert(!this.exited,
|
||||
"grip() shouldn't be called on exited browser actor.");
|
||||
dbg_assert(this.actorID,
|
||||
"tab should have an actorID.");
|
||||
|
||||
let response = {
|
||||
actor: this.actorID,
|
||||
title: title,
|
||||
url: this.browser.currentURI.spec
|
||||
title: this.title,
|
||||
url: this.url,
|
||||
};
|
||||
|
||||
// Walk over tab actors added by extensions and add them to a new ActorPool.
|
||||
|
@ -391,10 +418,6 @@ BrowserTabActor.prototype = {
|
|||
*/
|
||||
disconnect: function BTA_disconnect() {
|
||||
this._detach();
|
||||
|
||||
if (this._progressListener) {
|
||||
this._progressListener.destroy();
|
||||
}
|
||||
this._extraActors = null;
|
||||
},
|
||||
|
||||
|
@ -412,9 +435,6 @@ BrowserTabActor.prototype = {
|
|||
type: "tabDetached" });
|
||||
}
|
||||
|
||||
if (this._progressListener) {
|
||||
this._progressListener.destroy();
|
||||
}
|
||||
this._browser = null;
|
||||
this._tabbrowser = null;
|
||||
},
|
||||
|
@ -455,7 +475,7 @@ BrowserTabActor.prototype = {
|
|||
this._contextPool = new ActorPool(this.conn);
|
||||
this.conn.addActorPool(this._contextPool);
|
||||
|
||||
this.threadActor = new ThreadActor(this, this.browser.contentWindow.wrappedJSObject);
|
||||
this.threadActor = new ThreadActor(this, this.contentWindow.wrappedJSObject);
|
||||
this._contextPool.addActor(this.threadActor);
|
||||
},
|
||||
|
||||
|
@ -480,6 +500,10 @@ BrowserTabActor.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this._progressListener) {
|
||||
this._progressListener.destroy();
|
||||
}
|
||||
|
||||
this.browser.removeEventListener("DOMWindowCreated", this._onWindowCreated, true);
|
||||
this.browser.removeEventListener("pageshow", this._onWindowCreated, true);
|
||||
|
||||
|
@ -489,7 +513,7 @@ BrowserTabActor.prototype = {
|
|||
this.conn.removeActorPool(this._tabPool);
|
||||
this._tabPool = null;
|
||||
if (this._tabActorPool) {
|
||||
this.conn.removeActorPool(this._tabActorPool);
|
||||
this.conn.removeActorPool(this._tabActorPool, true);
|
||||
this._tabActorPool = null;
|
||||
}
|
||||
|
||||
|
@ -515,10 +539,6 @@ BrowserTabActor.prototype = {
|
|||
|
||||
this._detach();
|
||||
|
||||
if (this._progressListener) {
|
||||
this._progressListener.destroy();
|
||||
}
|
||||
|
||||
return { type: "detached" };
|
||||
},
|
||||
|
||||
|
@ -530,7 +550,7 @@ BrowserTabActor.prototype = {
|
|||
// The tab is already closed.
|
||||
return;
|
||||
}
|
||||
let windowUtils = this.browser.contentWindow
|
||||
let windowUtils = this.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.suppressEventHandling(true);
|
||||
|
@ -545,7 +565,7 @@ BrowserTabActor.prototype = {
|
|||
// The tab is already closed.
|
||||
return;
|
||||
}
|
||||
let windowUtils = this.browser.contentWindow
|
||||
let windowUtils = this.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.resumeTimeouts();
|
||||
|
@ -572,11 +592,6 @@ BrowserTabActor.prototype = {
|
|||
if (this.threadActor.dbg) {
|
||||
this.threadActor.dbg.enabled = true;
|
||||
}
|
||||
if (this._progressListener) {
|
||||
delete this._progressListener._needsTabNavigated;
|
||||
}
|
||||
this.conn.send({ from: this.actorID, type: "tabNavigated",
|
||||
url: this.browser.contentDocument.URL });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,7 +601,26 @@ BrowserTabActor.prototype = {
|
|||
this.threadActor.findGlobals();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the window.console object is native or overwritten by script in
|
||||
* the page.
|
||||
*
|
||||
* @param nsIDOMWindow aWindow
|
||||
* The window object you want to check.
|
||||
* @return boolean
|
||||
* True if the window.console object is native, or false otherwise.
|
||||
*/
|
||||
hasNativeConsoleAPI: function BTA_hasNativeConsoleAPI(aWindow) {
|
||||
let isNative = false;
|
||||
try {
|
||||
let console = aWindow.wrappedJSObject.console;
|
||||
isNative = "__mozillaConsole__" in console;
|
||||
}
|
||||
catch (ex) { }
|
||||
return isNative;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -622,33 +656,45 @@ DebuggerProgressListener.prototype = {
|
|||
let isWindow = aFlag & Ci.nsIWebProgressListener.STATE_IS_WINDOW;
|
||||
|
||||
// Skip non-interesting states.
|
||||
if (isStart && isDocument && isRequest && isNetwork) {
|
||||
if (!isWindow || !isNetwork ||
|
||||
aProgress.DOMWindow != this._tabActor.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isStart && aRequest instanceof Ci.nsIChannel) {
|
||||
// If the request is about to happen in a new window, we are not concerned
|
||||
// about the request.
|
||||
if (aProgress.DOMWindow != this._tabActor.browser.contentWindow) {
|
||||
return;
|
||||
|
||||
// Proceed normally only if the debuggee is not paused.
|
||||
if (this._tabActor.threadActor.state == "paused") {
|
||||
aRequest.suspend();
|
||||
this._tabActor.threadActor.onResume();
|
||||
this._tabActor.threadActor.dbg.enabled = false;
|
||||
this._tabActor._pendingNavigation = aRequest;
|
||||
}
|
||||
|
||||
// If the debuggee is not paused, then proceed normally.
|
||||
if (this._tabActor.threadActor.state != "paused") {
|
||||
return;
|
||||
}
|
||||
|
||||
aRequest.suspend();
|
||||
this._tabActor.threadActor.onResume();
|
||||
this._tabActor.threadActor.dbg.enabled = false;
|
||||
this._tabActor._pendingNavigation = aRequest;
|
||||
this._needsTabNavigated = true;
|
||||
} else if (isStop && isWindow && isNetwork && this._needsTabNavigated) {
|
||||
delete this._needsTabNavigated;
|
||||
this._tabActor.threadActor.dbg.enabled = true;
|
||||
this._tabActor.conn.send({
|
||||
from: this._tabActor.actorID,
|
||||
type: "tabNavigated",
|
||||
url: this._tabActor.browser.contentDocument.URL
|
||||
url: aRequest.URI.spec,
|
||||
title: "",
|
||||
nativeConsoleAPI: true,
|
||||
state: "start",
|
||||
});
|
||||
} else if (isStop) {
|
||||
if (this._tabActor.threadActor.state == "running") {
|
||||
this._tabActor.threadActor.dbg.enabled = true;
|
||||
}
|
||||
|
||||
this.destroy();
|
||||
let window = this._tabActor.contentWindow;
|
||||
this._tabActor.conn.send({
|
||||
from: this._tabActor.actorID,
|
||||
type: "tabNavigated",
|
||||
url: this._tabActor.url,
|
||||
title: this._tabActor.title,
|
||||
nativeConsoleAPI: this._tabActor.hasNativeConsoleAPI(window),
|
||||
state: "stop",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -657,7 +703,11 @@ DebuggerProgressListener.prototype = {
|
|||
*/
|
||||
destroy: function DPL_destroy() {
|
||||
if (this._tabActor._tabbrowser.removeProgressListener) {
|
||||
this._tabActor._tabbrowser.removeProgressListener(this);
|
||||
try {
|
||||
this._tabActor._tabbrowser.removeProgressListener(this);
|
||||
} catch (ex) {
|
||||
// This can throw during browser shutdown.
|
||||
}
|
||||
}
|
||||
this._tabActor._progressListener = null;
|
||||
this._tabActor = null;
|
||||
|
|
|
@ -541,11 +541,20 @@ DebuggerServerConnection.prototype = {
|
|||
|
||||
/**
|
||||
* Remove a previously-added pool of actors to the connection.
|
||||
*
|
||||
* @param ActorPool aActorPool
|
||||
* The ActorPool instance you want to remove.
|
||||
* @param boolean aCleanup
|
||||
* True if you want to disconnect each actor from the pool, false
|
||||
* otherwise.
|
||||
*/
|
||||
removeActorPool: function DSC_removeActorPool(aActorPool) {
|
||||
removeActorPool: function DSC_removeActorPool(aActorPool, aCleanup) {
|
||||
let index = this._extraPools.lastIndexOf(aActorPool);
|
||||
if (index > -1) {
|
||||
this._extraPools.splice(index, 1);
|
||||
let pool = this._extraPools.splice(index, 1);
|
||||
if (aCleanup) {
|
||||
pool.map(function(p) { p.cleanup(); });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -160,23 +160,7 @@ WebConsoleActor.prototype =
|
|||
return { actor: this.actorID };
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the window.console object is native or overwritten by script in
|
||||
* the page.
|
||||
*
|
||||
* @return boolean
|
||||
* True if the window.console object is native, or false otherwise.
|
||||
*/
|
||||
hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI()
|
||||
{
|
||||
let isNative = false;
|
||||
try {
|
||||
let consoleObject = WebConsoleUtils.unwrap(this.window).console;
|
||||
isNative = "__mozillaConsole__" in consoleObject;
|
||||
}
|
||||
catch (ex) { }
|
||||
return isNative;
|
||||
},
|
||||
hasNativeConsoleAPI: BrowserTabActor.prototype.hasNativeConsoleAPI,
|
||||
|
||||
/**
|
||||
* Destroy the current WebConsoleActor instance.
|
||||
|
@ -336,20 +320,11 @@ WebConsoleActor.prototype =
|
|||
MONITOR_FILE_ACTIVITY);
|
||||
startedListeners.push(listener);
|
||||
break;
|
||||
case "LocationChange":
|
||||
if (!this.consoleProgressListener) {
|
||||
this.consoleProgressListener =
|
||||
new ConsoleProgressListener(this.window, this);
|
||||
}
|
||||
this.consoleProgressListener.startMonitor(this.consoleProgressListener.
|
||||
MONITOR_LOCATION_CHANGE);
|
||||
startedListeners.push(listener);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
startedListeners: startedListeners,
|
||||
nativeConsoleAPI: this.hasNativeConsoleAPI(),
|
||||
nativeConsoleAPI: this.hasNativeConsoleAPI(this.window),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -370,7 +345,7 @@ WebConsoleActor.prototype =
|
|||
// listeners.
|
||||
let toDetach = aRequest.listeners ||
|
||||
["PageError", "ConsoleAPI", "NetworkActivity",
|
||||
"FileActivity", "LocationChange"];
|
||||
"FileActivity"];
|
||||
|
||||
while (toDetach.length > 0) {
|
||||
let listener = toDetach.shift();
|
||||
|
@ -403,13 +378,6 @@ WebConsoleActor.prototype =
|
|||
}
|
||||
stoppedListeners.push(listener);
|
||||
break;
|
||||
case "LocationChange":
|
||||
if (this.consoleProgressListener) {
|
||||
this.consoleProgressListener.stopMonitor(this.consoleProgressListener.
|
||||
MONITOR_LOCATION_CHANGE);
|
||||
}
|
||||
stoppedListeners.push(listener);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -737,34 +705,6 @@ WebConsoleActor.prototype =
|
|||
this.conn.send(packet);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for location changes. This method sends the new browser location
|
||||
* to the remote Web Console client.
|
||||
*
|
||||
* @see ConsoleProgressListener
|
||||
* @param string aState
|
||||
* Tells the location change state:
|
||||
* - "start" means a load has begun.
|
||||
* - "stop" means load completed.
|
||||
* @param string aURI
|
||||
* The new browser URI.
|
||||
* @param string aTitle
|
||||
* The new page title URI.
|
||||
*/
|
||||
onLocationChange: function WCA_onLocationChange(aState, aURI, aTitle)
|
||||
{
|
||||
// TODO: Bug 792062 - Make the tabNavigated notification reusable by the Web Console
|
||||
let packet = {
|
||||
from: this.actorID,
|
||||
type: "locationChange",
|
||||
uri: aURI,
|
||||
title: aTitle,
|
||||
state: aState,
|
||||
nativeConsoleAPI: this.hasNativeConsoleAPI(),
|
||||
};
|
||||
this.conn.send(packet);
|
||||
},
|
||||
|
||||
//////////////////
|
||||
// End of event handlers for various listeners.
|
||||
//////////////////
|
||||
|
|
Загрузка…
Ссылка в новой задаче