Skip to content

Commit aca2a13

Browse files
committed
Implement jQuerify command
1 parent 781b199 commit aca2a13

File tree

4 files changed

+174
-16
lines changed

4 files changed

+174
-16
lines changed

chrome.manifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
content firequery chrome/content/
2-
content firequery-resources chrome/resources/
2+
content firequery-resources chrome/resources/ contentaccessible=yes
33
skin firequery classic/1.0 chrome/skin/classic/shared/
44

55
locale firequery en-US chrome/locale/en-US/

lib/console-overlay.js

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ module.metadata = {
66
"stability": "stable"
77
};
88

9+
// Add-on SDK
910
const options = require("@loader/options");
10-
1111
const { Cu, Ci } = require("chrome");
1212
const { on, off, emit } = require("sdk/event/core");
13-
const { defer } = require("sdk/core/promise");
13+
const { defer, resolve } = require("sdk/core/promise");
1414
const { Class } = require("sdk/core/heritage");
1515
const { loadSheet, removeSheet } = require("sdk/stylesheet/utils");
1616

@@ -20,14 +20,15 @@ const { PanelOverlay } = require("firebug.sdk/lib/panel-overlay.js");
2020
const { ToolbarButton } = require("firebug.sdk/lib/toolbar-button.js");
2121
const { Rdp } = require("firebug.sdk/lib/core/rdp.js");
2222

23-
// FireQuery
24-
const { FireQueryFront } = require("./firequery-front.js");
25-
const { JQueryRenderer } = require("./jquery-renderer");
26-
2723
// DevTools
2824
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
2925
const { makeInfallible } = devtools["require"]("devtools/toolkit/DevToolsUtils.js");
3026

27+
// FireQuery
28+
const { FireQueryFront } = require("./firequery-front");
29+
const { JQueryRenderer } = require("./jquery-renderer");
30+
const { getJQuerifyScript } = require("./jquerify-code");
31+
3132
// URL of the {@FireQueryActor} module. This module will be
3233
// installed and loaded on the backend.
3334
const actorModuleUrl = options.prefixURI + "lib/firequery-actor.js";
@@ -107,14 +108,18 @@ const ConsoleOverlay = Class(
107108
attach: makeInfallible(function() {
108109
Trace.sysout("ConsoleOverlay.attach;");
109110

111+
if (this.deferredAttach) {
112+
return this.deferredAttach.promise;
113+
}
114+
110115
let config = {
111116
prefix: FireQueryFront.prototype.typeName,
112117
actorClass: "FireQueryActor",
113118
frontClass: FireQueryFront,
114119
moduleUrl: actorModuleUrl
115120
};
116121

117-
let deferred = defer();
122+
this.deferredAttach = defer();
118123
let client = this.toolbox.target.client;
119124

120125
// Register as tab actor.
@@ -129,10 +134,12 @@ const ConsoleOverlay = Class(
129134
// Emit an event indicating that the attach process is done. This
130135
// can be used e.g. by tests.
131136
emit(this, "attached", front);
132-
deferred.resolve(front);
137+
138+
// Resolve the 'attach promise'.
139+
this.deferredAttach.resolve(front);
133140
});
134141

135-
return deferred.promise;
142+
return this.deferredAttach.promise;
136143
}),
137144

138145
detach: function() {
@@ -141,12 +148,44 @@ const ConsoleOverlay = Class(
141148
// xxxHonza: TODO
142149
},
143150

151+
getJQueryFront: function() {
152+
return this.attach();
153+
},
154+
144155
// Commands
145156

146157
onJQuerify: function() {
147-
// xxxHonza: TODO
158+
// xxxHonza: webConsoleClient should be available at this point,
159+
// but safer would be to call attachConsole.
160+
let webConsoleClient = getConsoleClient(this.panel);
161+
if (!webConsoleClient) {
162+
return;
163+
}
164+
165+
let script = getJQuerifyScript();
166+
webConsoleClient.evaluateJSAsync(script, response => {
167+
if (response.error) {
168+
TraceError.sysout("ConsoleOverlay.onJQuerify; ERROR " +
169+
response.error, response);
170+
}
171+
else if (response.exception !== null) {
172+
TraceError.sysout("ConsoleOverlay.onJQuerify; EXCEPTION " +
173+
response.exception, response);
174+
}
175+
else {
176+
Trace.sysout("ConsoleOverlay.onJQuerify; DONE " +
177+
response.result, response);
178+
}
179+
});
148180
}
149181
});
150182

183+
// Helpers
184+
185+
function getConsoleClient(panel) {
186+
return panel && panel.hud && panel.hud.ui ?
187+
panel.hud.ui.webConsoleClient : null;
188+
}
189+
151190
// Exports from this module
152191
exports.ConsoleOverlay = ConsoleOverlay;

lib/firequery-actor.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,23 @@ function makeDebuggeeValueIfNeeded(obj, value) {
205205

206206
function evalJQueryCache(object) {
207207
try {
208-
var forceInternals = true;//Firebug.FireQuery.getPref("showInternalData") ? true : undefined;
208+
var forceInternals = true;
209209
var win = object.ownerDocument.defaultView;
210210
var wrapper = win.wrappedJSObject || win;
211211
var jQuery = wrapper.jQuery;
212212
// jQuery 1.4 breaking changes (http://jquery14.com/day-01/jquery-14):
213-
// jQuery.data(elem) no longer returns an id, it returns the element’s object cache instead.
214-
var idOrCache = jQuery.data(object.wrappedJSObject || object, undefined, undefined, forceInternals);
213+
// jQuery.data(elem) no longer returns an id, it returns the
214+
// element's object cache instead.
215+
var idOrCache = jQuery.data(object.wrappedJSObject || object,
216+
undefined, undefined, forceInternals);
217+
215218
if (typeof idOrCache == "object") {
216-
return idOrCache; // jQuery 1.4+ path
219+
// jQuery 1.4+ path
220+
return idOrCache;
217221
}
218222

219-
return jQuery.cache[idOrCache]; // jQuery 1.3- path
223+
// jQuery 1.3- path
224+
return jQuery.cache[idOrCache];
220225
} catch (ex) {
221226
}
222227
};

lib/jquerify-code.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/* See license.txt for terms of usage */
2+
3+
"use strict";
4+
5+
module.metadata = {
6+
"stability": "stable"
7+
};
8+
9+
// Add-on SDK
10+
const { prefs } = require("sdk/simple-prefs");
11+
12+
/**
13+
* jQuerify by Karl Swedberg, taken from:
14+
* http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet
15+
* and slightly modified styles
16+
*/
17+
const jQuerifyCode = "\
18+
(function() {\
19+
var el = document.createElement('div');\
20+
var b = document.getElementsByTagName('body')[0];\
21+
var otherlib = false;\
22+
var msg = '';\
23+
el.style.fontFamily = 'Arial, Verdana';\
24+
el.style.position = 'fixed';\
25+
el.style.padding = '5px 10px 5px 10px';\
26+
el.style.margin = '0';\
27+
el.style.zIndex = 1001;\
28+
el.style.lineHeight = '46px';\
29+
el.style.fontSize = '40px';\
30+
el.style.fontWeight = 'bold';\
31+
el.style.color = '#444';\
32+
el.style.backgroundColor = '#FFFB00';\
33+
el.style.MozBorderRadius = '8px';\
34+
el.style.opacity = '0.8';\
35+
el.style.textAlign = 'center';\
36+
if (typeof jQuery != 'undefined') {\
37+
msg = 'This page already using jQuery v' + jQuery.fn.jquery;\
38+
if (typeof $jq == 'function') {\
39+
msg += ' and noConflict().<br/>Use $jq(), not $().';\
40+
}\
41+
return showMsg();\
42+
} else if (typeof $ == 'function') {\
43+
otherlib = true;\
44+
}\
45+
function getScript(url, success, failure) {\
46+
var script = document.createElement('script');\
47+
script.src = url;\
48+
var head = document.getElementsByTagName('head')[0],\
49+
done = false;\
50+
var timeout = setTimeout(function() { failure(); }, {{jQueryURLTimeout}});\
51+
script.onload = script.onreadystatechange = function() {\
52+
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {\
53+
done = true;\
54+
clearTimeout(timeout);\
55+
success();\
56+
}\
57+
};\
58+
head.appendChild(script);\
59+
}\
60+
getScript('{{jQueryURL}}', \
61+
function() {\
62+
if (typeof jQuery == 'undefined') {\
63+
msg = 'Sorry, but jQuery wasn\\'t able to load';\
64+
return showMsg(true);\
65+
} else {\
66+
msg = 'This page is now jQuerified with v' + jQuery.fn.jquery;\
67+
if (otherlib) {\
68+
msg += ' and noConflict().<br/>Use $jq(), not $().';\
69+
}\
70+
}\
71+
return showMsg();\
72+
}, function() {\
73+
msg = 'Unable to load jQuery from:<br/>{{jQueryURL}}';\
74+
return showMsg(true);\
75+
});\
76+
function showMsg(isError) {\
77+
el.innerHTML = msg;\
78+
if (isError) el.style.backgroundColor = '#FF4444';\
79+
b.appendChild(el);\
80+
el.style.left = Math.floor((window.innerWidth - el.clientWidth) / 2) + 'px';\
81+
el.style.top = Math.floor((window.innerHeight - el.clientHeight) / 2) + 'px';\
82+
window.setTimeout(function() {\
83+
if (typeof jQuery == 'undefined') {\
84+
b.removeChild(el);\
85+
} else {\
86+
b.removeChild(el);\
87+
if (otherlib) {\
88+
$jq = jQuery.noConflict();\
89+
}\
90+
}\
91+
},\
92+
2500);\
93+
}\
94+
})();\
95+
";
96+
97+
/**
98+
* xxxHonza TODO docs
99+
*
100+
* @returns
101+
*/
102+
function getJQuerifyScript() {
103+
let defaultUrl = "chrome://firequery-resources/content/jquery.js";
104+
let jQueryUrl = prefs.jQueryURL || defaultUrl;
105+
let jQueryUrlTimeout = prefs.jQueryURLTimeout || 5000;
106+
107+
var code = jQuerifyCode;
108+
code = code.replace(/\{\{jQueryURL\}\}/g, jQueryUrl.replace("'", "\\'"));
109+
code = code.replace(/\{\{jQueryURLTimeout\}\}/g, jQueryUrlTimeout + "");
110+
return code;
111+
}
112+
113+
// Exports from this module
114+
exports.getJQuerifyScript = getJQuerifyScript;

0 commit comments

Comments
 (0)