Extending firebug: Understanding Firebug.chrome.$(id) vs. FirebugChrome.$(id) vs $(id)

41 views
Skip to first unread message

Andrew R

unread,
Oct 8, 2009, 8:06:15 PM10/8/09
to Firebug
A user of my extension has realized that errors occur when firebug is
opened in a new window. The reason is that Firebug.chrome.$(id) was
returning null when I called a function during reattaching. Unlike the
firebug code, I haven't been keeping local variables around to point
to the DOM elements, but have instead have looked them up as needed
(perhaps I will have to change that).

In code like the commandLine.js, it seems that Firebug.chrome always
gets passed to "setMultiLine", but in syncFilterButtons in net.js,
initializeUI in the module uses FirebugChrome, where other code is
using Firebug.chrome.

What are the rules of thumb when using $(id) in terms of using with or
without the chrome and which chrome to use?

Thank you,
Andrew

johnjbarton

unread,
Oct 8, 2009, 8:45:45 PM10/8/09
to Firebug


On Oct 8, 5:06 pm, Andrew R <andrew.rw.robin...@gmail.com> wrote:
> A user of my extension has realized that errors occur when firebug is
> opened in a new window. The reason is that Firebug.chrome.$(id) was
> returning null when I called a function during reattaching. Unlike the
> firebug code, I haven't been keeping local variables around to point
> to the DOM elements, but have instead have looked them up as needed
> (perhaps I will have to change that).
>
> In code like the commandLine.js, it seems that Firebug.chrome always
> gets passed to "setMultiLine", but in syncFilterButtons in net.js,
> initializeUI in the module uses FirebugChrome, where other code is
> using Firebug.chrome.

Use Firebug.chrome. We are trying to get rid of FirebugChrome.

>
> What are the rules of thumb when using $(id) in terms of using with or
> without the chrome and which chrome to use?

chrome.js has XUL-window specific code; Firebug.chrome is the current
window's chrome object. When we detach the Firebug object is not
changed, but Firebug.chrome changes from in-browser to the firebug.xul
window (and vice versa).

I don't like the way $() works in Firebug, too mysterious, eg this is
the definition in chrome.js:
$: function(id)
{
return $(id);
},
So when you say Firebug.chrome.$("foo"), it calls the function above
in the scope of chrome.js where document resolves to what ever it was
when you compiled chrome.js. That can be in browser.xul or
firebug.xul.

If Firebug.chrome.$(id) returns null, then the most likely problem is
not $() or chrome, but rather that the document is not ready with the
element yet.

jjb

>
> Thank you,
> Andrew

Andrew R

unread,
Oct 9, 2009, 11:59:10 AM10/9/09
to Firebug
Thank you for that information, apparently something is askew with my
Firebug.chrome in my panel. I have this code:

const superClass = Firebug.ActivablePanel;
OAdfvPanel.prototype = extend(superClass,
{
...
reattach: function (doc)
{
logger.trace('OAdfvPanel.reattach: %s', doc);
try
{

superClass.reattach.apply(this, arguments);
logger.info('Menu using firebug.chrome: %s', Firebug.chrome.$
('fbAdfvTypeMenu'));
logger.info('Menu using document: %s', document.getElementById
('fbAdfvTypeMenu'));
...

Firebug.chrome.$('fbAdfvTypeMenu')
Is returning null

document.getElementById('fbAdfvTypeMenu')
Is returning my element in the XUL toolbar

The relevant portion of my XUL is this:
...
<toolbox
id="fbToolbox">
<toolbar
id="fbToolbar">
<hbox
id="fbToolbarInner"
class="innerToolbar"
insertbefore="fbDetachButton"
align="center">
<hbox
id="fbAdfvFbButtons"
insertafter="fbNetButtons"
collapsed="true">
<toolbaritem align="center">
<label
class="oadfv-toolbar-label"
value="&oadfv.typelabel;"
tooltiptext="&oadfv.typemenu.tt;" />
</toolbaritem>
<toolbarbutton
id="fbAdfvTypeMenu"
type="menu"
role="button"
tooltiptext="&oadfv.typemenu.tt;"
aria-haspopup="true"
oncommand="return Firebug.OAdfvModule.onTypeMenuCommand
(event, FirebugContext)">
...

any idea why the Firebug.chrome is not finding the toolbarbutton by
ID, but a plain old document.getElementById is working? Makes me
wonder if I should just use document.getElementById instead of $ in my
extension. Is it possible that I am doing something that would cause
the Firebug.chrome.$ to see the wrong document but the global document
in my panel to be the correct one (I have a lot of code in my
extension, so it is very plausible that I have a bug causing this
behavior)?

johnjbarton

unread,
Oct 9, 2009, 1:18:35 PM10/9/09
to Firebug


On Oct 9, 8:59 am, Andrew R <andrew.rw.robin...@gmail.com> wrote:
> Thank you for that information, apparently something is askew with my
> Firebug.chrome in my panel. I have this code:
...
> Firebug.chrome.$('fbAdfvTypeMenu')
> Is returning null

So the |document| in the scope that chrome.js was compiled in has no
element with that id.

>
> document.getElementById('fbAdfvTypeMenu')
> Is returning my element in the XUL toolbar

Then the |document| in the scope of this statement does have the
element.

I guess the code is included via a script tag in your overlay's .xul
file. I guess you are overlaying browser.xul but I think you need to
overlay firebug.xul?

jjb

Andrew R

unread,
Oct 9, 2009, 4:26:18 PM10/9/09
to Firebug
This is what I have:

My chrome.manifest:

content oracleadfv content/
resource oracleadfvdocs docs/
locale oracleadfv en-US locale/en-US/
skin oracleadfv classic/1.0 skin/
overlay chrome://firebug/content/firebugOverlay.xul
chrome://oracleadfv/content/FirebugOverlay.xul
style chrome://firebug/content/firebugOverlay.xul chrome://oracleadfv/skin/overlay.css

The start of my chrome://oracleadfv/content/FirebugOverlay.xul:

<?xml version="1.0"?>
<!DOCTYPE oadflocal SYSTEM "chrome://oracleadfv/locale/mainPanel.dtd">
<overlay
xmlns="http://www.mozilla.org/keymaster/gatekeeper/
there.is.only.xul">
...
<script type="application/x-javascript"
src="mainModule.js"/>
<script type="application/x-javascript"
src="mainPanel.js"/>
...
<toolbox
id="fbToolbox">
...


I went off of the Firebug blog posts when I changed my extension to
start extending firebug:
http://www.softwareishard.com/blog/firebug-tutorial/extending-firebug-hello-world-part-i/

So I should not have anything that is overlaying firefox at this
point, only firebug.

Here is some of the start of my panel:
FBL.ns(function () { with (FBL) {
if (!Firebug.OAdfvModule) { return; }

const utils = Firebug.OAdfvUtil;
const logger = Firebug.OAdfvLogger;

//
************************************************************************************************
const superClass = Firebug.ActivablePanel;
const adfvext = Firebug.OAdfvModule;
const panelName = 'adfvMainPanel';
// Local STR function that adds the panel name and uses our bundle
function $LSTR(name)
{
return $STR(panelName + '.' + name, utils.bundleName);
}
function $LSTRF(name, args)
{
return $STRF(panelName + '.' + name, args, utils.bundleName);
}
try{
function OAdfvPanel()
{
logger.debug('OAdfvPanel created');
}
...
Firebug.registerPanel(OAdfvPanel);
Firebug.OAdfvPanel = OAdfvPanel;

} catch (e) {
//Firebug.Console.log(e);
logger.error(e);
}
}});

johnjbarton

unread,
Oct 9, 2009, 6:05:24 PM10/9/09
to Firebug


On Oct 9, 1:26 pm, Andrew R <andrew.rw.robin...@gmail.com> wrote:

Roughly speaking I don't see anything obvious.

I would add

FBTrace.sysout("lib.$ document: "+(doc?
doc.location:document.location) );

in lib.js this.$ function and see where it thinks you are when you get
null values for elements.

jjb
Message has been deleted

Andrew R

unread,
Oct 9, 2009, 6:41:14 PM10/9/09
to Firebug
Okay, this is really odd.

After adding the logging in both lib.$ and chrome.$ in the firebug
code, I found something really odd. When firebug is inside firefox,
everything is cool and the global "$" as seen by chrome.$ is the same
as FBL.$, but when I open firebug in a window, I get a different "$"
in chrome.js.

I changed the $ function in chrome.$ to this:
$: function(id)
{
FBTrace.sysout("chrome.$ document: "+(document.location) + " for ID: "
+ id + " and $ is: " + $ + " FBL.$ = " + FBL.$);
return $(id);
},

And $ in lib.js to this:
this.$ = function(id, doc)
{
FBTrace.sysout("lib.$ document: "+(doc?
doc.location:document.location) + " for ID: " + id);

if (doc)
return doc.getElementById(id);
else
return document.getElementById(id);
};


But when I have firebug in its own window I see this output in the
console:


FTS0: chrome.$ document: chrome://firebug/content/firebug.xul for ID:
fbAdfvTypeMenu and $ is: function $(id, doc) {
if (doc) {
return doc.getElementById(id);
} else {
return document.getElementById(id);
}
} FBL.$ = function (id, doc) {
FBTrace.sysout("lib.$ document: " + (doc ? doc.location :
document.location) + " for ID: " + id);
if (doc) {
return doc.getElementById(id);
} else {
return document.getElementById(id);
}
}


As you can see, the global "$" function is different than "FBL.$"
function. I tried disabling all my extensions except for firebug and
mine, and so far I do not see who is overwriting the "$" in chrome's
namespace or window object. Quite odd. Don't suppose you know what is
going on?

If it matters, I am using firefox 3.5.3 shipped by Ubuntu in Jaunty
and Firebug 1.4.3

Thanks for all your help.

Andrew R

unread,
Oct 9, 2009, 7:00:28 PM10/9/09
to Firebug
Got to stop for today, but I see that chrome.js has its own global $
function that is the same code as lib.js's $ function.

Comparing all of the documents, I get this:
FTS0: chrome.$ global function document: chrome://firebug/content/firebug.xul
for ID: fbAdfvTypeMenu
FTS0: reattach document: chrome://browser/content/browser.xul
FTS0: lib.$ document: chrome://firebug/content/panel.html for ID:
fbAdfvTypeMenu

So for some reason it is not finding my XUL element is the
chrome://firebug/content/firebug.xul file, but it is finding it in
chrome://browser/content/browser.xul. Using the "DOM Inspector"
plugin, I do see my toolbar in the firebug window though, and this is
working:

Firebug.chrome.$('fbPanelSplitter')

But not
Firebug.chrome.$('fbAdfvTypeMenu')

So it seems that something is amiss with my XUL when it is in the new
window. I recently added a bindings.xml file to use XBL for some of my
elements, I wonder if that could have caused any problems.

johnjbarton

unread,
Oct 9, 2009, 7:29:45 PM10/9/09
to Firebug
I think these are the same function being accessed two different ways.

At the top of chrome.js you will see
(function() { with (fbXPCOMUtils) {
and at the top of lib.js:
var FBL = fbXPCOMUtils;
So all of the functions defined in lib.js are global functions in
chrome.js. This is generally true through out firebug source. The
only reason we use FBL.foo() is if we are in an event handler called
by something in Firefox that does not include our lib.js scope.

So "$" in chrome.js resolves to a global from the with(fbXPCOMUtils)
and FBL.$ resolves to the same method as a property of FBL.

jjb

johnjbarton

unread,
Oct 9, 2009, 7:33:02 PM10/9/09
to Firebug


On Oct 9, 4:00 pm, Andrew R <andrew.rw.robin...@gmail.com> wrote:
> Got to stop for today, but I see that chrome.js has its own global $
> function that is the same code as lib.js's $ function.
>
> Comparing all of the documents, I get this:
> FTS0: chrome.$ global function document: chrome://firebug/content/firebug.xul
> for ID: fbAdfvTypeMenu
> FTS0: reattach document: chrome://browser/content/browser.xul
> FTS0: lib.$ document: chrome://firebug/content/panel.html for ID:
> fbAdfvTypeMenu

panel.html is the content of the panel (an HTML document inside of a
browser element). So you won't find your id in there, it is either in
browser.xul or firebug.xul. So either you are executing this statement
in the wrong window or passing in a |doc| object that is for the panel
not the toolbar.

jjb
Message has been deleted
Message has been deleted
Message has been deleted

Andrew R

unread,
Oct 19, 2009, 7:05:34 PM10/19/09
to Firebug
Apparently XUL got a little unhappy with me with overlaying too many
elements. I removed some of the fb* elements that weren't necessary in
my overlay and it started working again, thanks for you help.

Andrew R

unread,
Oct 19, 2009, 7:20:44 PM10/19/09
to Firebug
Okay, there is more to it than that. Firebug's XUL, when opened in a
new window has 2 toolbox's with the ID fbToolbox

There is one as a direct child of the window object that contains the
menubar and there is another that is in the vbox in the box with id
fbPanelPane. I started adding my own toolbar to the inside of the
fbToolbox so that I could add a 2nd toolbox "row" and that XUL was
unhappy since I was overlaying an element that appears twice in the
document.

Using grep, I see these hits:

firebugOverlay.xul:129: <toolbox
id="fbToolbox">
firebug.xul:61: <toolbox id="fbToolbox">

So I think the fix is to rename the ID for the fbToolbox at line 61 of
firebug.xul to something else so it will not clash with the one in the
firebugOverlay.xul file.

Andrew R

unread,
Oct 20, 2009, 1:37:56 PM10/20/09
to Firebug
Reply all
Reply to author
Forward
0 new messages