Skip to content

Commit 7323960

Browse files
committed
Ignore event-parser's module calls to data API
1 parent 866b901 commit 7323960

File tree

2 files changed

+94
-27
lines changed

2 files changed

+94
-27
lines changed

lib/firequery-actor.js

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
// Add-on SDK
12-
const { Cu } = require("chrome");
12+
const { Cu, components } = require("chrome");
1313

1414
// DevTools
1515
const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
@@ -21,6 +21,7 @@ const { makeInfallible } = devtools["require"]("devtools/toolkit/DevToolsUtils.j
2121
const DevToolsUtils = devtools["require"]("devtools/toolkit/DevToolsUtils");
2222
const { NodeActor } = devtools["require"]("devtools/server/actors/inspector");
2323

24+
// Constants
2425
const Previewers = DebuggerServer.ObjectActorPreviewers;
2526

2627
// Number of items to preview in objects, arrays, maps, sets, lists,
@@ -96,8 +97,16 @@ var FireQueryActor = ActorClass(
9697
this.parent = parent;
9798
this.state = "detached";
9899

100+
// DevTools events
99101
this.onNodeActorForm = this.onNodeActorForm.bind(this);
100102
this.onNavigate = this.onNavigate.bind(this);
103+
104+
// jQuery events
105+
this.onDataModified = this.onDataModified.bind(this);
106+
this.onJQueryDetected = this.onJQueryDetected.bind(this);
107+
108+
// Console customization
109+
this.onBuildPreview = this.onBuildPreview.bind(this);
101110
},
102111

103112
/**
@@ -135,7 +144,7 @@ var FireQueryActor = ActorClass(
135144

136145
this.state = "attached";
137146

138-
Previewers.Object.unshift(this.onBuildPreview.bind(this));
147+
Previewers.Object.unshift(this.onBuildPreview);
139148

140149
Events.on(this.parent, "navigate", this.onNavigate);
141150
Events.on(NodeActor, "form", this.onNodeActorForm);
@@ -158,7 +167,13 @@ var FireQueryActor = ActorClass(
158167
Events.off(this.parent, "navigate", this.onNavigate);
159168
Events.off(NodeActor, "form", this.onNodeActorForm);
160169

161-
// xxxHonza: remove previewer
170+
// Remove (content) window listeners.
171+
let win = this.parent.window.wrappedJSObject;
172+
win.removeEventListener("jQueryDetected", this.onJQueryDetected, true);
173+
win.removeEventListener("firequery-event", this.onDataModified, true);
174+
175+
// Remove previewer listener (web console).
176+
removeItem(Previewers.Object, this.onBuildPreview);
162177
}), {
163178
request: {},
164179
response: {
@@ -258,28 +273,8 @@ var FireQueryActor = ActorClass(
258273
this.walkerActorID = walkerActorID || this.walkerActorID;
259274

260275
let win = this.parent.window.wrappedJSObject;
261-
262-
win.addEventListener("jQueryDetected", event => {
263-
win.eval(this.patch);
264-
}, true);
265-
266-
win.addEventListener("firequery-event", event => {
267-
let walkerActor = this.conn.getActor(this.walkerActorID);
268-
if (!walkerActor) {
269-
return;
270-
}
271-
272-
let data = walkerActor.attachElement(event.target);
273-
let jQueryData = hasJQueryData(event.target);
274-
275-
Trace.sysout("FireQueryActor.fireQueryEvent;", {
276-
data: data,
277-
jQueryData: jQueryData
278-
});
279-
280-
Events.emit(this, "data-modified", data, jQueryData);
281-
}, true);
282-
276+
win.addEventListener("jQueryDetected", this.onJQueryDetected, true);
277+
win.addEventListener("firequery-event", this.onDataModified, true);
283278
win.eval(this.watcher);
284279
}), {
285280
request: {
@@ -292,11 +287,49 @@ var FireQueryActor = ActorClass(
292287
}
293288
}),
294289

290+
onJQueryDetected: makeInfallible(function(event) {
291+
let win = this.parent.window.wrappedJSObject;
292+
293+
Trace.sysout("FireQueryActor.onJQueryDetected; " + win.location, event);
294+
295+
win.eval(this.patch);
296+
}),
297+
298+
onDataModified: makeInfallible(function(event) {
299+
let win = this.parent.window.wrappedJSObject;
300+
301+
Trace.sysout("FireQueryActor.onDataModified; " + win.location, event);
302+
303+
if (ignoreEventParsers()) {
304+
return;
305+
}
306+
307+
let walkerActor = this.conn.getActor(this.walkerActorID);
308+
if (!walkerActor) {
309+
return;
310+
}
311+
312+
let data = walkerActor.attachElement(event.target);
313+
let jQueryData = hasJQueryData(event.target);
314+
315+
Trace.sysout("FireQueryActor.onDataModified;", {
316+
data: data,
317+
jQueryData: jQueryData
318+
});
319+
320+
try {
321+
Events.emit(this, "data-modified", data, jQueryData);
322+
} catch(err) {
323+
Trace.sysout("FireQueryActor.onDataModified; ERROR " + err, err);
324+
}
325+
}),
326+
295327
/**
296328
* Returns jQuery data for given node.
297329
*/
298330
getJQueryData: method(expectState("attached", function(node) {
299331
Trace.sysout("FireQueryActor.getJQueryData;", node);
332+
300333
return {
301334
jQueryData: hasJQueryData(node.rawNode)
302335
}
@@ -334,7 +367,6 @@ var FireQueryActor = ActorClass(
334367
form.setFormProperty("hasJQueryData", !!data);
335368

336369
let json = data ? JSON.stringify(data) : "";
337-
Trace.sysout("FireQueryActor.onNodeActorForm; " + json, arguments);
338370
})
339371
});
340372

@@ -417,5 +449,39 @@ NodeActor.prototype.form = function(detail) {
417449
return form;
418450
}
419451

452+
// Helpers
453+
454+
/**
455+
* Remove an item from specified array. Copied from Firebug.sdk
456+
* (since the SDK isn't available on the backend).
457+
*/
458+
function removeItem(list, item) {
459+
for (let i = 0; i < list.length; i++) {
460+
if (list[i] == item) {
461+
list.splice(i, 1);
462+
return true;
463+
}
464+
}
465+
return false;
466+
};
467+
468+
/**
469+
* EventParser module in DevTools is internally executing jQuery.data
470+
* function. Ignore these calls.
471+
*/
472+
function ignoreEventParsers() {
473+
var eventParser = "resource://gre/modules/devtools/event-parsers.js";
474+
var counter = 0;
475+
var stack = components.stack;
476+
while (stack && counter++ < 10) {
477+
var url = stack.filename;
478+
if (url.indexOf(eventParser) != -1) {
479+
return true;
480+
}
481+
stack = stack.caller;
482+
}
483+
return false;
484+
}
485+
420486
// Exports from this module
421487
exports.FireQueryActor = FireQueryActor;

lib/jquery-watcher-code.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module.metadata = {
1010
const { prefs } = require("sdk/simple-prefs");
1111

1212
/**
13-
* xxxHonza TODO docs
13+
* Wait till jQuery is initialized on the current page and send
14+
* an event when it happens.
1415
*/
1516
const jQueryWatcherCode = "\
1617
(function() {\

0 commit comments

Comments
 (0)