Bug 1060188 - [App Manager] Cannot use Inspector to view app's DOM on Flame r=paul

This commit is contained in:
Michael Ratcliffe 2014-08-29 13:44:59 +01:00
parent de2965fbbf
commit da361adf4e
4 changed files with 116 additions and 102 deletions

View File

@ -29,7 +29,6 @@ const MAX_ORDINAL = 99;
this.DevTools = function DevTools() {
this._tools = new Map(); // Map<toolId, tool>
this._themes = new Map(); // Map<themeId, theme>
this._eventParsers = new Map(); // Map<parserID, [handlers]>
this._toolboxes = new Map(); // Map<target, toolbox>
// destroy() is an observer's handler so we need to preserve context.
@ -42,7 +41,7 @@ this.DevTools = function DevTools() {
Services.obs.addObserver(this._teardown, "devtools-unloaded", false);
Services.obs.addObserver(this.destroy, "quit-application", false);
}
};
DevTools.prototype = {
/**
@ -66,10 +65,6 @@ DevTools.prototype = {
}
},
get eventParsers() {
return this._eventParsers;
},
/**
* Register a new developer tool.
*
@ -145,85 +140,6 @@ DevTools.prototype = {
}
},
/**
* Register a new event parser to be used in the processing of event info.
*
* @param {Object} parserObj
* Each parser must contain the following properties:
* - parser, which must take the following form:
* {
* id {String}: "jQuery events", // Unique id.
* getListeners: function(node) { }, // Function that takes a node and
* // returns an array of eventInfo
* // objects (see below).
*
* hasListeners: function(node) { }, // Optional function that takes a
* // node and returns a boolean
* // indicating whether a node has
* // listeners attached.
*
* normalizeHandler: function(fnDO) { }, // Optional function that takes a
* // Debugger.Object instance and
* // climbs the scope chain to get
* // the function that should be
* // displayed in the event bubble
* // see the following url for
* // details:
* // https://developer.mozilla.org/
* // docs/Tools/Debugger-API/
* // Debugger.Object
* }
*
* An eventInfo object should take the following form:
* {
* type {String}: "click",
* handler {Function}: event handler,
* tags {String}: "jQuery,Live", // These tags will be displayed as
* // attributes in the events popup.
* hide: { // Hide or show fields:
* debugger: false, // Debugger icon
* type: false, // Event type e.g. click
* filename: false, // Filename
* capturing: false, // Capturing
* dom0: false // DOM 0
* },
*
* override: { // The following can be overridden:
* type: "click",
* origin: "http://www.mozilla.com",
* searchString: 'onclick="doSomething()"',
* DOM0: true,
* capturing: true
* }
* }
*/
registerEventParser: function(parserObj) {
let parserId = parserObj.id;
if (!parserId) {
throw new Error("Cannot register new event parser with id " + parserId);
}
if (this._eventParsers.has(parserId)) {
throw new Error("Duplicate event parser id " + parserId);
}
this._eventParsers.set(parserId, {
getListeners: parserObj.getListeners,
hasListeners: parserObj.hasListeners,
normalizeHandler: parserObj.normalizeHandler
});
},
/**
* Removes parser that matches a given parserId.
*
* @param {String} parserId
* id of the event parser to unregister.
*/
unregisterEventParser: function(parserId) {
this._eventParsers.delete(parserId);
},
/**
* Sorting function used for sorting tools based on their ordinals.
*/
@ -555,10 +471,6 @@ DevTools.prototype = {
this.unregisterTool(key, true);
}
for (let [id] of this._eventParsers) {
this.unregisterEventParser(id, true);
}
// Cleaning down the toolboxes: i.e.
// for (let [target, toolbox] of this._toolboxes) toolbox.destroy();
// Is taken care of by the gDevToolsBrowser.forgetBrowserWindow

View File

@ -21,8 +21,6 @@ loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getS
let events = require("sdk/system/events");
require("devtools/toolkit/event-parsers");
// Panels
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel);
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel);

View File

@ -8,14 +8,13 @@
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
loader.lazyGetter(this, "eventListenerService", () => {
return Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService);
});
let eventParsers = [
let parsers = [
{
id: "jQuery events",
getListeners: function(node) {
@ -184,10 +183,6 @@ let eventParsers = [
}
];
for (let parserObj of eventParsers) {
gDevTools.registerEventParser(parserObj);
}
function jQueryLiveGetListeners(node, boolOnEventFound) {
let global = node.ownerGlobal.wrappedJSObject;
let hasJQuery = global.jQuery && global.jQuery.fn && global.jQuery.fn.jquery;
@ -260,3 +255,109 @@ function jQueryLiveGetListeners(node, boolOnEventFound) {
}
return handlers;
}
this.EventParsers = function EventParsers() {
if (this._eventParsers.size === 0) {
for (let parserObj of parsers) {
this.registerEventParser(parserObj);
}
}
};
exports.EventParsers = EventParsers;
EventParsers.prototype = {
_eventParsers: new Map(), // NOTE: This is shared amongst all instances.
get parsers() {
return this._eventParsers;
},
/**
* Register a new event parser to be used in the processing of event info.
*
* @param {Object} parserObj
* Each parser must contain the following properties:
* - parser, which must take the following form:
* {
* id {String}: "jQuery events", // Unique id.
* getListeners: function(node) { }, // Function that takes a node and
* // returns an array of eventInfo
* // objects (see below).
*
* hasListeners: function(node) { }, // Optional function that takes a
* // node and returns a boolean
* // indicating whether a node has
* // listeners attached.
*
* normalizeHandler: function(fnDO) { }, // Optional function that takes a
* // Debugger.Object instance and
* // climbs the scope chain to get
* // the function that should be
* // displayed in the event bubble
* // see the following url for
* // details:
* // https://developer.mozilla.org/
* // docs/Tools/Debugger-API/
* // Debugger.Object
* }
*
* An eventInfo object should take the following form:
* {
* type {String}: "click",
* handler {Function}: event handler,
* tags {String}: "jQuery,Live", // These tags will be displayed as
* // attributes in the events popup.
* hide: { // Hide or show fields:
* debugger: false, // Debugger icon
* type: false, // Event type e.g. click
* filename: false, // Filename
* capturing: false, // Capturing
* dom0: false // DOM 0
* },
*
* override: { // The following can be overridden:
* type: "click",
* origin: "http://www.mozilla.com",
* searchString: 'onclick="doSomething()"',
* DOM0: true,
* capturing: true
* }
* }
*/
registerEventParser: function(parserObj) {
let parserId = parserObj.id;
if (!parserId) {
throw new Error("Cannot register new event parser with id " + parserId);
}
if (this._eventParsers.has(parserId)) {
throw new Error("Duplicate event parser id " + parserId);
}
this._eventParsers.set(parserId, {
getListeners: parserObj.getListeners,
hasListeners: parserObj.hasListeners,
normalizeHandler: parserObj.normalizeHandler
});
},
/**
* Removes parser that matches a given parserId.
*
* @param {String} parserId
* id of the event parser to unregister.
*/
unregisterEventParser: function(parserId) {
this._eventParsers.delete(parserId);
},
/**
* Tidy up parsers.
*/
destroy: function() {
for (let [id] of this._eventParsers) {
this.unregisterEventParser(id, true);
}
}
};

View File

@ -69,6 +69,8 @@ const {
const {getLayoutChangesObserver, releaseLayoutChangesObserver} =
require("devtools/server/actors/layout");
const {EventParsers} = require("devtools/toolkit/event-parsers");
const FONT_FAMILY_PREVIEW_TEXT = "The quick brown fox jumps over the lazy dog";
const FONT_FAMILY_PREVIEW_TEXT_SIZE = 20;
const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
@ -188,6 +190,7 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({
protocol.Actor.prototype.initialize.call(this, null);
this.walker = walker;
this.rawNode = node;
this._eventParsers = new EventParsers().parsers;
// Storing the original display of the node, to track changes when reflows
// occur
@ -291,11 +294,11 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({
/**
* Are there event listeners that are listening on this node? This method
* uses all parsers registered via gDevTools.registerEventParser() to check if
* there are any event listeners.
* uses all parsers registered via event-parsers.js.registerEventParser() to
* check if there are any event listeners.
*/
get _hasEventListeners() {
let parsers = gDevTools.eventParsers;
let parsers = this._eventParsers;
for (let [,{hasListeners}] of parsers) {
if (hasListeners && hasListeners(this.rawNode)) {
return true;
@ -333,7 +336,7 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({
* Node for which we are to get listeners.
*/
getEventListeners: function(node) {
let parsers = gDevTools.eventParsers;
let parsers = this._eventParsers;
let dbg = this.parent().tabActor.makeDebugger();
let events = [];
@ -367,7 +370,7 @@ var NodeActor = exports.NodeActor = protocol.ActorClass({
* @param {Debugger} dbg
* JSDebugger instance.
* @param {Object} eventInfo
* See gDevTools.registerEventParser() for a description of the
* See event-parsers.js.registerEventParser() for a description of the
* eventInfo object.
*
* @return {Array}