Bug 792062 - Make the tabNavigated notification reusable by the Web Console; r=past

This commit is contained in:
Mihai Sucan 2012-12-17 22:06:13 +02:00
parent aae3f29d7b
commit 11c5a3ad68
13 changed files with 324 additions and 222 deletions

View File

@ -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
});

View File

@ -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();

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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.");

View File

@ -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,

View File

@ -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();
}
},
};

View File

@ -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);

View File

@ -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;

View File

@ -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(); });
}
}
},

View File

@ -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.
//////////////////