Well, i guess that in order to be accurate one must answer they are
not "added" to the web page. They are executed in a sandbox built
around a XPCNWrapper of the page's window:
var safeWin = new XPCNativeWrapper(window);
var sandbox = new Components.utils.Sandbox(safeWin);
sandbox.__proto__ = safeWin;
Components.utils.evalInSandbox(scriptSourceCode, sandbox);
As of now, there is nowhere FB could grab a reference to such a
sandbox or the running script source code. However, i'm thinking about
providing them (script source+sandbox) to FB somehow from the GM code.
As i see it so far, i'd like to be able to browse the running GM
scripts source code from FB scripts tab, as well as poke around in
these scripts sandboxes in the FB console tab after a cd(sandbox). In
a perfect world, i'd love to achieve that via a simple FB extension
included in the GM add-on, but it probably is over-optimistic... :-)
--
Olivier
On Tue, Jul 28, 2009 at 21:53, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> Run Firebug with tracing and set up for your page. Then use Tracing
> option FBS_CREATION and FBS_SRCUNITS. Run the Greasemonkey code and
> look for the jsdIScript creation messages. (You will want to turn off
> these tracing options, they have high overhead).
So, i did run FB-1.4X.1 with FBS_CREATION and FBS_SRCUNITS.
I guess the following output is what i'm looking for: traces for the
GM script (#178), from creation to destruction:
85. [extensions.firebug] onScriptCreated:
178@(302-314)file:/home/olivier/dev/webmonkey/src/components/webmonkey.js
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1512)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### webmonkey.js:302 is indeed where
Components.utils.evalInSandbox(scriptSource, sandbox) is located.
86. [extensions.firebug] onScriptCreated: ''
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1514)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### Here, Object->data shows the GM script source code.
87. [extensions.firebug] createdScriptHasCaller 4 FF3.1:false
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1600)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1524)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
88. [extensions.firebug] createdScriptHasCaller null
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1525)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### Looking at the code, i suppose from these last 2 that the
script is considered as having "no caller" (FYI,
createdScriptHasCaller() returns on line 1617).
89. [extensions.firebug] onScriptCreated: set BP at PC 0 in top level
tag=178:file:/home/olivier/dev/webmonkey/src/components/webmonkey.js
jsd depth:1
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1538)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
90. [extensions.firebug] onBreakpoint frame.script.tag=178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1169)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)
91. [extensions.firebug] FBS.onTopLevelScriptCreated no debuggr for 178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1446)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1181)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)
### It seems fbs.findDebugger(frame):1435 fails to find the
associated context (see below).
92. [extensions.firebug] fbs.onTopLevelScriptCreated script.tag:178
href: no sourceFile
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1456)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1181)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)
93. [extensions.firebug] Top Scripts Uncleared:
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1190)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)
94. [extensions.firebug] fbs.onScriptDestroyed 178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1634)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
From here, i turned on FBS_FINDDEBUGGER to get more feedback on
why/how findDebugger() failed. It yielded:
[extensions.firebug] fbs.getFrameScopeWindowAncestor found scope chain
bottom, not Window: Sandbox
[extensions.firebug] fbs.findDebugger no frame Window, looking down the stack
[extensions.firebug] fbs.findDebugger fell thru bottom of stack
As it seems a Sandbox is not a "supported" scope, i tried this
quick-&-dirty-hack(TM) in getFrameScopeWindowAncestor():
--- firebug-service.js~ 2009-07-29 13:25:51.913450368 +0200
+++ firebug-service.js 2009-07-29 13:26:42.293449931 +0200
@@ -2573,7 +2573,7 @@
while(scope.jsParent)
scope = scope.jsParent;
- if (scope.jsClassName == "Window" || scope.jsClassName ==
"ChromeWindow")
+ if (scope.jsClassName == "Window" || scope.jsClassName ==
"ChromeWindow" || scope.jsClassName == "Sandbox")
return scope.getWrappedValue();
if (FBTrace.DBG_FBS_FINDDEBUGGER)
Apart of the fact that this throws "too much recursion" errors at
firebug-service:2559 (hook()), webmonkey.js (the add-on XPCOM, not the
script unfortunately) appears in FB scripts tab. Nevertheless, it's a
tiny progress. :-p
> Once you figure out what jsd things of the GM scripts, you need to
> convince Firebug to add them to the context for the web page. After
> that I guess Firebug will work for you.
I'm not there yet! I guess i'll have to keep on working in this
direction... Any hint will be much appreciated. :-)
I guess one of my problems at this stage will be that
getFrameScopeWindowAncestor() is expected to return an object that is
_both_ a Window and a JS scope: in the context of a GM script, these
are two different things (the scope is the Sandbox).
Patched as shown above, the console tab does not work (it doesn't
answer commands). If i return the associated window instead of the
sandbox, the console works... in the scope of the window, i.e. scripts
vars are unreachable (and, as a side note, entered console commands
show up in the scripts tab as evals -- is that normal?).
--
Olivier
More precisely, the error is logged by notifyObservers() at
firebug-trace-service.js:181.
It's consistently thrown, unless there is an opened FB Tracing window.
--
Olivier
Do you think i should browse Chromebug code for inspiration, then?
>> Apart of the fact that this throws "too much recursion" errors at
>> firebug-service:2559 (hook()), webmonkey.js (the add-on XPCOM, not the
>> script unfortunately) appears in FB scripts tab. Nevertheless, it's a
>> tiny progress. :-p
>
> I don't understand "the addon XPCOM".
I meant it's a GM XPCOM service source file (like Firebug's firebug-service.js).
>> I guess one of my problems at this stage will be that
>> getFrameScopeWindowAncestor() is expected to return an object that is
>> _both_ a Window and a JS scope: in the context of a GM script, these
>> are two different things (the scope is the Sandbox).
>
> Well getFrameScopeWindowAncestor() must return a nsIDOMWindow for
> Firebug. In particular it needs to return the window that the GM
> script was applied to. But I think you want to know that the compile
> was in a Sandbox.
>
> I think that at this stage in the processing the only thing we are
> trying to do is create a "SourceFile", that is Firebug's metadata for
> a compilation unit, and put that SourceFile in the correct context.
> The scope analysis is only a means to that end. Firefox mixes up all
> of the scripts from web pages and xul: we are just trying to sort out
> where this particular script belongs. For that we need the window
> then we can use getContextByWindow() to get the context we want to
> attach to.
Alright. In the specific case of a GM script Sandbox, it's quite
straightforward to extract a reference back to the target nsiDOMWindow
(it holds several of them). In other words, it should be easy to find
the right context (/me is checking that box).
> But we also need to know that the compile was in a Sandbox so we can
> create a SandboxSourceFile (which by the way is not defined yet ;-).
> This would be returned from onTopLevelScriptCreated. You don't need
> the sandbox itself, just a way to know that you need to get the source
> from GM (well I assume you have a way to get the source...).
As noted in my previous mail, the source code run in the Sandbox
appears at some point in the Firebug trace (step #86):
script.functionSource logged by onScriptCreated() on line 1514.
It is not the script source in its exact original form though (it
lacks some metadata/comments, etc), so it might still be a good idea
to make this original source available from GM somehow.
> With a SandboxSourceFile and the correct context, I guess the rest
> will come together.
I guess that, if we rely on GM to provide the Sandbox source, that
would be a GMSandboxSourceFile (as opposed to a general Sandbox
mechanism)?
> You won't see any of the GM script's top level objects this way, I
> suppose they are in the sandbox object. But you can't reach them from
> the web page anyway. You will see stuff when you hit a breakpoint in a
> GM script.
That'd be excellent already. :-)
Then i'd just like to add a way for users to poke around in a script
Sandbox/scope from the Firebug console tab, which implies a mean for
users to select said scope -- cd(scope)?
> Does this give you enough hints?
That's a lot -- more than i was expecting! It's great, thanks again
for that. :-)
I guess i've got the big picture now, i just to work a bit more on the
specifics...
Anyway, i've got enough to move forward significantly. Back to work!
--
Olivier
FB-1.4X.1 so far.
I'll switch to the current SVN branch from now on...
--
Olivier
That's right: it's true there's a real value in showing the script
exactly as it is on-disk.
This raises another question: a running script can actually be a
bundle of JS files glued together thanks to a PHP-like @include
directive. In other words, we're potentially dealing with a bunch of
SourceFiles to be "spawned" out of a single jsdIScript.
As, i guess, there usually is a one-to-one relationship between
SourceFile and jsdIScript in Firebug, do you think this can be an
issue?
>> I guess that, if we rely on GM to provide the Sandbox source, that
>> would be a GMSandboxSourceFile (as opposed to a general Sandbox
>> mechanism)?
>
> Sure. I suppose the correct distinction would be by how the SourceFile
> object differs from other SourceFile objects, but GMSandbox is fine.
SandboxSourceFile is good, especially if Firebug defines some kind of
interface allowing tiers components to provide sources for their
Sandboxed scripts (and GM complies to that). ;-)
>> Then i'd just like to add a way for users to poke around in a script
>> Sandbox/scope from the Firebug console tab, which implies a mean for
>> users to select said scope -- cd(scope)?
>
> Strictly speaking you can't poke around in the scope of a function X
> unless X is being compiled or run. I suppose you would allow users to
> examine the properties of the Sandbox object.
Yes: as script global vars are Sandbox properties, i thought it could
be helpful to explore their values...
--
Olivier
Well, my question was more: how is the jsdIScript/SourceFile relation
constrained in the Firebug framework? But i should probably get more
familiar with Firebug SourceFiles before going there...
Just to make it clearer though, i meant: as i understand it, it
usually is about linking "spawned" jsdIScripts to a SourceFile, while
in the GM-script discovery step it is about creating several
SourceFiles objects in the context of one on(JsdI)Script handler.
>> SandboxSourceFile is good, especially if Firebug defines some kind of
>> interface allowing tiers components to provide sources for their
>> Sandboxed scripts (and GM complies to that). ;-)
>
> You lost me here. Firefox compile, we watch.
We watch but i understand we don't usually watch sandboxes which, i
suppose, are particular.
I'm assuming Firebug usually builds SourceFiles out of JS script DOM
elements. In the case of a Sandbox (i.e. without corresponding DOM
element), there seem to be no way for Firebug to build a proper
SourceFile alone, when one is needed as is the case with GM scripts.
It can only do so if it's provided with proper data by the Sandbox
owner -- GM here.
If that's the case, why not take it as an opportunity for Firebug to
support Sandbox debugging? The idea being to provide an interface
tiers chrome code can use to register Sandboxes they want to debug.
I understand Firebug is focused on web page debugging (as opposed to
chrome debugging), yet it makes sense to include chrome code
dynamically altering said page, doesn't it?
> You could try to see if Chromebug will show you the sandbox values.
> Firebug is not really set up to deal with them. I suppose we could go
> in that direction, but honestly I don't expect to do that.
I've been unlucky with Chromebug: i tried to install it once but it
was making FF crash (FF could not even start, iirc).
But i did some (limited) testing of script Sandbox values poking
around: it worked as mentioned.
--
Olivier
Thank you, the whole process is much clearer after this. :-)
> SourceFiles are then used to map jsdIScripts to source that is shown
> to the user. (SourceFiles are defined in lib.js)
Alright. I'm still unsure as to how i am going to deal with the fact
that a single GM script may be composed of several JS source files
(glued and run in the same sandbox), which i'd like to show separately
in Firebug's script tab. But this can be dealt with later...
> Since GM is also an extension it could easily help by providing a
> method that returns the source so Firebug can copy it into its cache
> and point from the SourceFile into the cache.
Yes. And the file name seems to be needed as well, at least for the
GUI: so far it shows webmonkey.js, which is the JS code creating the
sandbox, not the script code running inside it.
I guess this GM method should return the needed script's details,
whatever they end up being. As far as i can see, the only reference to
the running script we share between GM and FB is the Sandbox object
it's running in -- that should be the method parameter.
Overall, here is how i'm proceeding: i patch
firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
right debugger for a GM script sandbox. It then flows as usual up to
debugger.js:onTopLevelScriptCreated(), patched in order to delegate
the work to onSandboxScriptCreated() in case of a Sandbox scope.
Finally, this last method returns a lib.js:SandboxSourceFile object.
Does it look ok so far?
>> Just to make it clearer though, i meant: as i understand it, it
>> usually is about linking "spawned" jsdIScripts to a SourceFile, while
>> in the GM-script discovery step it is about creating several
>> SourceFiles objects in the context of one on(JsdI)Script handler.
>
> The GM script is compiled in a sandbox, so the entire compile will be
> one SourceFile.
It's fine as long as we show all the JS source files composing a GM
script as one big source file. I guess that, if we wanted to show them
separately, Firebug.Debugger#onSandboxScriptCreated() should return an
array of SourceFiles...
>> But i did some (limited) testing of script Sandbox values poking
>> around: it worked as mentioned.
>
> And did you find the content of the sandbox to be critical for
> debugging the GM script or only helpful in understanding sandboxes?
Well, i just tested that it worked, i haven't used it for real
debugging. I kinda thought: "well, i could have a JS console to poke
in that thing just the way FB allows poking in a window... hey, let's
use FB's console for that!". :-)
As i see it, what makes poking in Windows or Sandboxes (equally)
interesting is that you actually are poking in a "top-level" JS scope.
But i might be wrong...
> I think you can get 80% of the value of Firebug for GM without viewing
> the sandbox; viewing the sandbox will be 80% of a complete job. I'd
> push on the first 20%.
No problem: let's focus on the debugger then. :-)
--
Olivier
It's somewhat reassuring to realize there's been some misunderstanding
around this at some point... :-p
>> Yes. And the file name seems to be needed as well, at least for the
>> GUI: so far it shows webmonkey.js, which is the JS code creating the
>> sandbox, not the script code running inside it.
>
> Yes, that is all the compiler knows, because that is what GM told it.
I take it this is happening behind the scene: i'm not aware of any GM
code specifically providing this kind of information to the compiler.
>> I guess this GM method should return the needed script's details,
>> whatever they end up being. As far as i can see, the only reference to
>> the running script we share between GM and FB is the Sandbox object
>> it's running in -- that should be the method parameter.
>
> You will need the line numbers for points of concatenation, eg. a.js
> 1-150, b.js 151-213, c.js 213-end.
Yes. From what i see, i guess line numbers should be taken care of in
SandboxSourceFile...
> You might return a sourcefile representing the webmonkey.js with a
> single script, the outer script representing the body of the function
> that run the sandbox global method (called outerScript in Firebug).
>
> (...) just jam the other ones on the context and return one representing
> the outerScript.
> To create the others you need to walk the list of innerScripts and
> compare the source ranges (baseLineNumber, lineExtent) to the
> webmonkey.js and your list of actual sources with their line ranges.
> Divvy them up.
Alright. Haven't dealt with line numbers specifics yet but i suppose
it'll make sense when i do.
--
Olivier
Thanks, that's always good to hear... :-)
If you keep following this thread you'll be notified when there's code
up for testing.
> It would be great if someone could write an article that will show the
> steps to flollow to "hack" FB to be able to debug GM.
> Thanks a lot !
I'm not sure how these features may be integrated in FB actually.
Eventually, it'd be nice to get them without hacking FB...
--
Olivier
Considering the amount of FB code patching that seems necessary so far
(firebug-service, debugger, lib...), will this be doable using a FB
extension only?
That would be excellent...
On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>> > You will need the line numbers for points of concatenation, eg. a.js
>> > 1-150, b.js 151-213, c.js 213-end.
>>
>> Yes. From what i see, i guess line numbers should be taken care of in
>> SandboxSourceFile...
>
> Yes, it has to translate the line number the user wants to see back
> and forth to the ones the compiler assigns.
Alright. Frankly, i'm still quite puzzled at how the line mangling
between jsdIScript and SourceFile work...
That is, even when sticking to the simple case: one GM script file run
in its Sandbox (i'm temporarily putting aside the complex case: many
files concatenated and run into a single GM script sandbox).
I've been able to make GM scripts proper name and source code appear
in FB's "Scripts" tab. It is possible to set a breakpoint and the
debugger will properly stop on it on page reload. Restarting execution
also works (i haven't really tested stepping). But there are a few
problems (for example, the breakpoint's red dot in the script margin
does not change state when the debugger stops on it).
The only line mangling i've done though is:
SandboxSourceFile.prototype.getBaseLineOffset
this.SandboxSourceFile.prototype.getBaseLineOffset = function()
{
return 304; // TODO depends on number of script tags
https://bugzilla.mozilla.org/show_bug.cgi?id=396568
}
So far i've been able to set a breakpoint in
I'm trying to solve the simple case first, that is:
I suppose the line-nb related methods inherited from SourceFile are
enough in this case.
As a reminder, this is what i do:
>> i patch
>> firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
>> right debugger for a GM script sandbox. It then flows as usual up to
>> debugger.js:onTopLevelScriptCreated(), patched in order to delegate
>> the work to onSandboxScriptCreated() in case of a Sandbox scope.
>> Finally, this last method returns a lib.js:SandboxSourceFile object.
onSandboxScriptCreated() calls a GM method to get details on the
script running in this sandbox. It can thus create a SandboxSourceFile
object with the proper file URL.
As a consequence, the GM script name and source now appear correctly
in FB's Scripts tab; i can set breakpoints in the GM script... :-)
...However breakpoints do not work: on page reload, script execution
is not halted, breakpoints seem disabled (light-red UI dot, unchecked
UI box).
I haven't found out why yet.
--
Olivier
On Tue, Aug 18, 2009 at 19:56, Olivier Cornu<o.c...@gmail.com> wrote:
> On Tue, Aug 11, 2009 at 17:38, johnjbarton<johnj...@johnjbarton.com> wrote:
>>
>> We would be happy to help you create a GM extension for Firebug.
>
> Considering the amount of FB code patching that seems necessary so far
> (firebug-service, debugger, lib...), will this be doable using a FB
> extension only?
> That would be excellent...
That's still a question i wanted to ask. :p
> On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>>> > You will need the line numbers for points of concatenation, eg. a.js
>>> > 1-150, b.js 151-213, c.js 213-end.
>>>
>>> Yes. From what i see, i guess line numbers should be taken care of in
>>> SandboxSourceFile...
>>
>> Yes, it has to translate the line number the user wants to see back
>> and forth to the ones the compiler assigns.
>
> Alright. Frankly, i'm still quite puzzled at how the line mangling
> between jsdIScript and SourceFile work...
> That is, even when sticking to the simple case: one GM script file run
> in its Sandbox (i'm temporarily putting aside the complex case: many
> files concatenated and run into a single GM script sandbox).
> I've been able to make GM scripts proper name and source code appear
> in FB's "Scripts" tab. It is possible to set a breakpoint and the
> debugger will properly stop on it on page reload. Restarting execution
> also works (i haven't really tested stepping). But there are a few
> problems (for example, the breakpoint's red dot in the script margin
> does not change state when the debugger stops on it).
The only line mangling i've done though is:
SandboxSourceFile.prototype.getBaseLineOffset = function()
{
return 304; // webmonkey.js:evalInSandbox() line
}
...which is a dirty hack. :)
> As a reminder, this is what i do:
>>> i patch
>>> firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
>>> right debugger for a GM script sandbox. It then flows as usual up to
>>> debugger.js:onTopLevelScriptCreated(), patched in order to delegate
>>> the work to onSandboxScriptCreated() in case of a Sandbox scope.
>>> Finally, this last method returns a lib.js:SandboxSourceFile object.
>
> onSandboxScriptCreated() calls a GM method to get details on the
> script running in this sandbox. It can thus create a SandboxSourceFile
> object with the proper file URL.
Sorry again for the inconvenience.
--
Olivier
Alright. Perhaps it's too soon to talk about how to split the code
between FB and a FB extension for GM...
Yet i'm pleased to learn that your are willing to adapt FB to this
purpose, if needed -- and i'm quite sure GM script developers feel the
same. :-)
> For the rest perhaps you can try again?
Sure! Sorry about that, let me try again...
So far i've been working on the _simple_ case: the GM script is
considered to always be a single file. In other words, i temporarily
left aside the _complex_ case we already talked about, where a GM
script is a concatenation of several files (see: Greasemonkey @require
header tag [1]).
I've made some progress: GM scripts correctly appear (name and source
code) in Firebug's debugger tab. I can set breakpoints and correctly
use the debugger stepping functionalities.
I still have a few issues, though, that i'd like to fix before working
on the _complex_ case. For example, the "this" object in the right
side of the debugger seems to be wrong/empty (see attached
screenshot); is that a problem of context? Or scope?
As a reminder, i'm patching Firebug pretty much as we have have
discussed (see attached patch against Firebug 1.5 branch, rev 4035):
* getFrameScopeWindowAncestor() is patched to find the nsIDOMWindow
associated with a (GM) Sandbox scope. This happens both in
firebug-service.js and debugger.js because
getFrameScopeWindowAncestor() is defined -- and used -- in both of
them.
* onTopLevelScriptCreated() is patched to delegate SourceFile
creation to a new onSandboxScriptCreated() method when the top scope
is a Sandbox (debugger.js).
* this new onSandboxScriptCreated() calls a GM method returning the
GM-script file URL running in that Sandbox, and returns a new
SandboxSourceFile object for this script.
* SandboxSourceFile is a cut-&-paste of TopLevelSourceFile (with a
new "sandbox" compilation_unit_type) except that line-related methods
are tweaked for dealing with Sandboxes (lib.js).
--
Olivier
But it's empty (notice "this" has been developed).
There usually is more stuff in there, for example when i debug a JS
script embedded in this same page.
Also, i suppose "this" should be the Sandbox in order to see things as
the debugged script does.
--
Olivier
Probably.
I have troubles finding where in the code is "this" set. Would you be
so kind as to give me a clue?
> I don't know whether or not the sandbox should be "this", since the
> whole sandbox model makes not sense to me. I never could figure out
> what it did which is why we took it out of Firebug.
I'm no sandbox expert, but i understand it allows evaling code with
limited privileges.
A GM script sandbox uses the underlying window, wrapped into a XPCNW,
as its prototype. It seems there's more value in showing this rather
than the target window.
--
Olivier
Nevermind. Think i found it.
--
Olivier
As i've found out, "this" refers to the script scope. It usually is a
Window but in case of a sandboxed script it's a Sandbox. It's fine
like that.
For the sake of completion: the empty "this" issue was because the
Sandbox object has no hasOwnProperty(), __lookupGetter___() and
__lookupSetter__() methods -- dom.js needs them to correctly print the
object hierarchy. If i put dummy implementations of these methods
everything works fine. :-)
Also, very interestingly: "As of Firefox 3.5/Gecko 1.9.1, it's
possible to optionally specify the JS version, filename, and line
number of the code being evaluated" [1].
This means it seems possible for the Firebug-1.5 to support sandboxed
scripts debugging (when they provide such information) without too
many changes: they pretty much look like other top-level scripts. The
only thing needed is a way for getFrameScopeWindowAncestor() to
discover which window the script should be attached to (if any).
The most generic test i've found (also working with GM) is the
following: if the sandbox prototype is a Window (or a XPCNW of a
Window) return it, otherwise the sandboxed script is ignored. It
probably makes sense to debug sandboxed scripts which are as tied to a
Window as that, although it's not a perfect test to filter relevant
sandboxed scripts...
--
Olivier
[1] https://developer.mozilla.org/en/Components.utils.evalInSandbox
I kind of remember i read somewhere there was a point it, though...
Whatever: it works. :-)
>> Also, very interestingly: "As of Firefox 3.5/Gecko 1.9.1, it's
>> possible to optionally specify the JS version, filename, and line
>> number of the code being evaluated" [1].
>> This means it seems possible for the Firebug-1.5 to support sandboxed
>> scripts debugging (when they provide such information) without too
>> many changes: they pretty much look like other top-level scripts. The
>> only thing needed is a way for getFrameScopeWindowAncestor() to
>> discover which window the script should be attached to (if any).
I can confirm patching getFrameScopeWindowAncestor() is enough to
correctly debug GM scripts: no need to mess further with Firebug core
code (no need for a onSandboxScriptCreated() handler nor a new
SandboxSourceFile object). Sandboxed scripts are successfully treated
like other top-level scripts.
>> The most generic test i've found (also working with GM) is the
>> following: if the sandbox prototype is a Window (or a XPCNW of a
>> Window) return it, otherwise the sandboxed script is ignored. It
>> probably makes sense to debug sandboxed scripts which are as tied to a
>> Window as that, although it's not a perfect test to filter relevant
>> sandboxed scripts...
>
> But that assumes a specific model for how the sandbox is used. On the
> other hand, as far as I know GM is the only user of the sandbox, so
> why not.
Yes, it's not generic enough to cover every Window-mangling sandboxed
script possible. In fact, it's probably impossible to detect all
Window-mangling sandboxed scripts without "prior knowledge": somehow,
FB and tiers chrome code will have to share common assumptions about
where in the sandbox is the Window reference. In which case i suppose
we have to rely on "obvious" locations if we want to keep it simple:
the sandbox prototype, a sandbox property called "window"...
An alternative would be for FB to offer an API tiers code can use to
register their own getWindowFromSandbox() handler.
Back to debugging GM in particular, the new evalInSandbox() signature
is a blessing, even more so in case of concatenated scripts (the
so-called complex case -- GM @require tag). GM used to evalInSandbox()
a single string which was the concatenation of all needed source
files. If, instead, GM does evalInSandbox() each one of them in turn,
passing the proper filename/line number of the code being evaled,
everything works perfectly: all files appear in the debugger tab and
you can set breakpoints, etc, in anyone of them.
In other words, our original goal is reached with a very simple FB
core patch (attached)! :-)
--
Olivier
Thank you for your help and support, John. :-)
Will do. By the way, there is a 2-years old bug report about this
topic (although it's tagged "chromebug") [1].
--
Olivier
Follow-up and updates on this topic on this bug ticket:
http://code.google.com/p/fbug/issues/detail?id=83
--
Olivier