Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

screen grab triggered by command line (cont'd)

3 views
Skip to first unread message

miles zarathustra

unread,
Oct 31, 2006, 4:10:09 PM10/31/06
to
Hi again,

Once again, I've been trying to adapt the screengrab extension so that I
can pull up a URL from the command line and have an image of it saved to
file.

I have been exploring far and wide, and two approaches seem to stand out as
most likely to succeed.

In both, I plan to load a page that pops up a window and does the screen
grab of the contents in the popped window (so that the first window can
control the grab).

1st possible approach) access the screen grab functions from javascript, by
getting a handle somehow to the installed extension.

2nd ) access the screen grab functions from an XUL file.

I've run into roadblocks and confusion, and many hours of tedious and
minimally productive trial and error in both directions.

As for (1) ....

My first idea was to get its handle from the Components array.

I tried various strategeies for telling the security manager to keep its
nose out (even though it's a local file, thus theoretically the security
manager is supposed to let me do "unsafe" things, it still insists on
failing silently, a lot). I spent a lot of time trying various things in
prefs.js, e.g. user_pref("capability.policy.xxx", ...) from the example
page on mozilla.org. No luck. Finally after hours of effort, I found that
saying:

netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

let me access the Components array -- but then I found that the extension
was not listed there. The closest I could get to finding a handle to it
was through the ExtensionManager by using

Components.classes["@mozilla.org/extensions/manager;1"]

but none of its methods gave me an actual handle to the extension whereby I
could call the functions it defines. The best I got was a list of
information about it.

If anyone can tell me how to get at that handle (and how to convince the
security manager to butt out) I would be quite grateful.

as for (2)

I tried pulling out the XUL file and the associated JS file from screen
grab, and succeeded in getting them to connect together by rewriting the
URL's (and simplifying by getting rid of the localization) but the
javascript doesn't run correctly.

It fails on the line:

return document.getElementById("content").selectedBrowser;

It can't even seem to find an element with the ID "content," let alone a
selectedBrowser attribute of it. Now mind you, this purported "document"
object is quite a different animal from the one I am accustomed to.

I've been pulling my hair out trying to untangle the maze of API's listed
for AOM vs DOM or whatnot, and haven't found anything explaining why the
selectedBrowser line should even work in the first place, let alone why it
works when it's in the extension but fails otherwise.

I can find selectedBrowser on developer.mozilla.org/en/docs/XUL:Property
but no explanation of where it came from or how to get at it.

It seems like there are about a dozen different underlying object
structures for javascript, and none seem to be very well documented, aside
from the main DOM one finds in browsers which I have the O'Reilly book for.

If someone could direct me to documentation which would help me sort all of
these things out, and in particular tell me how to get this JS file that
runs perfectly under chrome to run under XUL as well, I would also be quite
grateful.


I lookead briefly at the docs for pearlcrescent pagesaver, but it uses the
'canvas' element, and I need to capture flash stuff as well.

Thanks in advance for your help!

-= miles =-

Eric H. Jung

unread,
Oct 31, 2006, 4:49:42 PM10/31/06
to miles zarathustra, dev-ext...@lists.mozilla.org
I don't have time to address all of your questions, but here's the answer to one. You can read about selectedBrowser here:
http://www.xulplanet.com/references/elemref/ref_tabbrowser.html#prop_selectedBrowser

FYI, it's my understanding Pearl Crescent ScreenSaver is closed-source and its EULA specifically prohibits reverse-engineering.

Good luck,
Eric

Hi again,

As for (1) ....

netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

Components.classes["@mozilla.org/extensions/manager;1"]

as for (2)

return document.getElementById("content").selectedBrowser;

-= miles =-

_______________________________________________
dev-extensions mailing list
dev-ext...@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-extensions

Nickolay Ponomarev

unread,
Oct 31, 2006, 4:51:35 PM10/31/06
to miles zarathustra, dev-ext...@lists.mozilla.org
On 11/1/06, miles zarathustra <nob...@nomail.com> wrote:
> netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
>
That's correct. You should use this if you need to run privileged code
from a local file. I'm not sure I understand -why- you need it though
(I confess I didn't read your rather long message carefully).

> but none of its methods gave me an actual handle to the extension whereby I

There's no such thing as an "extension handle". Extension's functions
can be defined in windows of certain type (e.g. browser.xul windows),
in which case you need to get the window you need, e.g. using
nsIWindowMediator.

Alternatively they can be defined in an XPCOM component, in which case
you have to get your component via its contract id and either
a) call a method on one of (IDL-defined) interfaces your component
implements (you may need to create your own interface) or
b) use the wrappedJSObject trick, which is, weirdly, not documented,
but you can see it in the code on
http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol

If Components.classes["@your.name/yourcontractid"] returns null, your
component wasn't registered. I don't think we have troubleshooting
guide for XPCOM components registration, but you should at least check
that you put the component's JS file in your extension's components/
folder, that it has a proper XPCOM registration code (copy it from
http://forums.mozillazine.org/viewtopic.php?p=1694347&sid=518e2773c6c0d9182e6ec30adc5eb899#1694347
if you don't understand it), and that there are no errors in the error
console.

> It fails on the line:
> return document.getElementById("content").selectedBrowser;
>
> It can't even seem to find an element with the ID "content," let alone a

Where does the code run?

> I've been pulling my hair out trying to untangle the maze of API's listed
> for AOM vs DOM or whatnot, and haven't found anything explaining why the
> selectedBrowser line should even work in the first place, let alone why it

http://www.xulplanet.com/references/elemref/ref_tabbrowser.html#prop_selectedBrowser
http://developer.mozilla.org/en/docs/XUL:Property:selectedBrowser

> works when it's in the extension but fails otherwise.
>
> I can find selectedBrowser on developer.mozilla.org/en/docs/XUL:Property
> but no explanation of where it came from or how to get at it.
>

Yeah, the migrated XUL reference has this problem. You can use the
"What links to this page" link in the sidebar to work around the
issue.

> It seems like there are about a dozen different underlying object
> structures for javascript, and none seem to be very well documented, aside
> from the main DOM one finds in browsers which I have the O'Reilly book for.
>

XUL is more or less documented in xulplanet.com's reference, which is
being(?) migrated to MDC. Unfortunately, there's indeed not as much
documentation as there could be, and certain parts of XUL are poorly
documented.

Nickolay

miles zarathustra

unread,
Oct 31, 2006, 6:08:13 PM10/31/06
to
Eric H. Jung wrote:

> I don't have time to address all of your questions, but here's the answer
> to one. You can read about selectedBrowser here:
>
http://www.xulplanet.com/references/elemref/ref_tabbrowser.html#prop_selectedBrowser

Interesting, though it doesn't quite explain the code I'm looking at:

document.getElementByID("content").selectedBrowser

Does that mean that the "content" element is a tabbrowser object? How
would I discover that it was? Not to mention, every time *I* try it,
document.getElementById('content') is null.

I find myself with more questions than answers...

-= miles =-


miles zarathustra

unread,
Oct 31, 2006, 6:38:29 PM10/31/06
to

Thanks for getting back again! As you can see, I've moved away from the
xpcom idea.

Nickolay Ponomarev wrote:

> On 11/1/06, miles zarathustra <nob...@nomail.com> wrote:
>> netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
>>
> That's correct. You should use this if you need to run privileged code
> from a local file. I'm not sure I understand -why- you need it though
> (I confess I didn't read your rather long message carefully).

Yes, it's been arduous; difficult to summarize.

The first reason I needed (I thought) to use privileges was to get at the
Component.classesByID object, though it didn't give me what I wanted.

Eventually, I need to write to the filesystem (the image file to be saved).

Incidentally, though the enablePrivilege() function gave me access, it
forced me to press a button in a dialog box (even after I said "remember
this decision") which is unsatisfactory for an unattended commandline
application.

>
>> but none of its methods gave me an actual handle to the extension whereby
>> I
> There's no such thing as an "extension handle". Extension's functions
> can be defined in windows of certain type (e.g. browser.xul windows),
> in which case you need to get the window you need, e.g. using
> nsIWindowMediator.

Interesting. I wonder how I figure out which window (some hidden window?)
might be the right one.


>
> Alternatively they can be defined in an XPCOM component, in which case
> you have to get your component via its contract id and either

It's not currently cast in XPCOM, and given what I've seen of the
complexity of that framework, I'd rather avoid it if I can.


> If Components.classes["@your.name/yourcontractid"] returns null, your
> component wasn't registered. I don't think we have troubleshooting
> guide for XPCOM components registration, but you should at least check
> that you put the component's JS file in your extension's components/
> folder, that it has a proper XPCOM registration code (copy it from
>

Apparently an "Extension" is a different animal from a "Component," because
the extension is installed successfully and does in fact work when called
from its popup menu. But it's clsid is not listed in the componentsByID
hash.


>
>> It fails on the line:
>> return document.getElementById("content").selectedBrowser;
>>
>> It can't even seem to find an element with the ID "content," let alone a
>
> Where does the code run?

It's in an extension, so the code exists in a .js file in

{<uuid>}/content/screengrab

It's referenced by a .xul file in the same directory, which basically binds
it to a context-menu addition, along with localizations.

I've pulled it out of the .jar file, rearranging the configuration to
adjust for the switch. In its original form, as a packaged extension, the
structure is a bit different. (this is standard extension development
procedure, from what I understand)

>
>> I've been pulling my hair out trying to untangle the maze of API's listed
>> for AOM vs DOM or whatnot, and haven't found anything explaining why the
>> selectedBrowser line should even work in the first place, let alone why
>> it
>
>
http://www.xulplanet.com/references/elemref/ref_tabbrowser.html#prop_selectedBrowser

Repeating what I said in the last message, it's true that one can find
"selectedBrowser" on this page, but I still don't see how it relates to:


document.getElementById("content").selectedBrowser


> http://developer.mozilla.org/en/docs/XUL:Property:selectedBrowser
>
>> works when it's in the extension but fails otherwise.
>>
>> I can find selectedBrowser on developer.mozilla.org/en/docs/XUL:Property
>> but no explanation of where it came from or how to get at it.
>>
> Yeah, the migrated XUL reference has this problem. You can use the
> "What links to this page" link in the sidebar to work around the
> issue.

interesting, though I'm still not seeing a connection between tabbrowser
and document.getElementById("content");

I can't convince document.getElementById("content") to yield a non-null
result.


>
>> It seems like there are about a dozen different underlying object
>> structures for javascript, and none seem to be very well documented,
>> aside from the main DOM one finds in browsers which I have the O'Reilly
>> book for.
>>
> XUL is more or less documented in xulplanet.com's reference, which is
> being(?) migrated to MDC. Unfortunately, there's indeed not as much
> documentation as there could be, and certain parts of XUL are poorly
> documented.


The odd thing is that it seems there is a different object structure when
running an XUL file as a standalone, from when it's running "inside of"
chrome as an extension. Or maybe there's some other factor that's
different -- but the code that runs perfectly from inside an extension
gives me much grief as a standalone.

Thanks again for your expertise,

-= miles =-

Nickolay Ponomarev

unread,
Oct 31, 2006, 6:57:35 PM10/31/06
to miles zarathustra, dev-ext...@lists.mozilla.org
On 11/1/06, miles zarathustra <nob...@nomail.com> wrote:
> Nickolay Ponomarev wrote:
>
> > On 11/1/06, miles zarathustra <nob...@nomail.com> wrote:
> >> netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
> >>
> > That's correct. You should use this if you need to run privileged code
> > from a local file. I'm not sure I understand -why- you need it though
> > (I confess I didn't read your rather long message carefully).
>
> Yes, it's been arduous; difficult to summarize.
>
> The first reason I needed (I thought) to use privileges was to get at the
> Component.classesByID object, though it didn't give me what I wanted.
>
> Eventually, I need to write to the filesystem (the image file to be saved).
>
I mean, why you need to do all that from an untrusted page.

> Incidentally, though the enablePrivilege() function gave me access, it
> forced me to press a button in a dialog box (even after I said "remember
> this decision") which is unsatisfactory for an unattended commandline
> application.
>

Yes, you're not really supposed to do this.

> >
> >> but none of its methods gave me an actual handle to the extension whereby
> >> I
> > There's no such thing as an "extension handle". Extension's functions
> > can be defined in windows of certain type (e.g. browser.xul windows),
> > in which case you need to get the window you need, e.g. using
> > nsIWindowMediator.
>
> Interesting. I wonder how I figure out which window (some hidden window?)
> might be the right one.
>

By looking at the extension - what file the functions are defined in
and where that file is referenced from. In your case it looks like
you're saying the JS file is referenced from a XUL overlay (correct?).
To figure out what window the JS file gets loaded in, you'll need to
figure to which documents the overlay referencing the JS gets applied.
Probably it's chrome://browser/content/browser.xul, in which case the
extension's variables should be defined in all browser windows.

>
> >
> > Alternatively they can be defined in an XPCOM component, in which case
> > you have to get your component via its contract id and either
>
> It's not currently cast in XPCOM, and given what I've seen of the
> complexity of that framework, I'd rather avoid it if I can.
>

Heh, good luck with that.

>
> > If Components.classes["@your.name/yourcontractid"] returns null, your
> > component wasn't registered. I don't think we have troubleshooting
> > guide for XPCOM components registration, but you should at least check
> > that you put the component's JS file in your extension's components/
> > folder, that it has a proper XPCOM registration code (copy it from
> >
>
> Apparently an "Extension" is a different animal from a "Component," because
> the extension is installed successfully and does in fact work when called
> from its popup menu. But it's clsid is not listed in the componentsByID
> hash.
>

An extension is a bundle, which can provide various things, including
chrome packages and components:
http://developer.mozilla.org/en/docs/Bundles

After the extension is installed, mozilla will attempt to register its
components on restart. It may fail to register them, in which case
you'll indeed have the extension registered, but not the component.

What is the component's contract ID? Where is the file defining the
component? Did you try troubleshooting the registration as I
suggested?

>
> >
> >> It fails on the line:
> >> return document.getElementById("content").selectedBrowser;
> >>
> >> It can't even seem to find an element with the ID "content," let alone a
> >
> > Where does the code run?
>
> It's in an extension, so the code exists in a .js file in
>
> {<uuid>}/content/screengrab
>
> It's referenced by a .xul file in the same directory, which basically binds
> it to a context-menu addition, along with localizations.
>

As I said, you also need to know what the overlay get applies to in
order to give a meaningful answer to my question. From what you said
I'm guessing it's the browser.xul document, in which case the code
really ought to work. The common reason for such problems is described
here: http://developer.mozilla.org/en/docs/Extension_FAQ#Why_doesn.27t_my_script_run_properly.3F

> I've pulled it out of the .jar file, rearranging the configuration to
> adjust for the switch. In its original form, as a packaged extension, the
> structure is a bit different. (this is standard extension development
> procedure, from what I understand)
>

Are you sure you didn't break anything? Does the extension itself
still work after repackaging?

Actually... are you sure the code that tries to get the tabbrowser
doesn't run in the content page?

>
>
> >
> >> I've been pulling my hair out trying to untangle the maze of API's listed
> >> for AOM vs DOM or whatnot, and haven't found anything explaining why the
> >> selectedBrowser line should even work in the first place, let alone why
> >> it
> >
> >
> http://www.xulplanet.com/references/elemref/ref_tabbrowser.html#prop_selectedBrowser
>
> Repeating what I said in the last message, it's true that one can find
> "selectedBrowser" on this page, but I still don't see how it relates to:
>
>
> document.getElementById("content").selectedBrowser
>

Once you know what 'document' refers to (browser.xul, which we figured
out by walking from the JS file to the XUL overlay referencing it, to
the browser.xul document which is probably overlayed in
chrome.manifest), it's pretty easy to find out. Open the DOMi, inspect
the browser window and look for an element with id "content". You'll
see it's a tabbrowser element.

[snip]


> >
> >> It seems like there are about a dozen different underlying object
> >> structures for javascript, and none seem to be very well documented,
> >> aside from the main DOM one finds in browsers which I have the O'Reilly
> >> book for.
> >>
> > XUL is more or less documented in xulplanet.com's reference, which is
> > being(?) migrated to MDC. Unfortunately, there's indeed not as much
> > documentation as there could be, and certain parts of XUL are poorly
> > documented.
>
>
> The odd thing is that it seems there is a different object structure when
> running an XUL file as a standalone, from when it's running "inside of"
> chrome as an extension. Or maybe there's some other factor that's
> different -- but the code that runs perfectly from inside an extension
> gives me much grief as a standalone.
>

Of course, overlays are different from 'standalone' XUL files,
whatever you mean. The overlays are merged into specified master
documents (browser.xul in your case), while "standalone" XUL files
have their own documents.

The <tabbrowser id="content"> is declared in browser.xul and not in
your standalone XUL, which explains why document.getElementById can't
find it.

Nickolay

> Thanks again for your expertise,
>
> -= miles =-
>
>
>

miles zarathustra

unread,
Oct 31, 2006, 9:14:06 PM10/31/06
to
Nickolay Ponomarev wrote:


>>
> I mean, why you need to do all that from an untrusted page.

I don't really care where I do it from, as long as I can get it to work.

However, I am in the dark about how to convince the browser that my page is
"trusted."

I have stumbled through various long, scary documents about "signed
javascript" which mostly seem to be way out of date and filled with broken
links to the "netscape" site.


What I want to do is pass the following information to the extension:

1) a URL
2) a filename to save to.

One way I figured to do that was by generating, on the fly, a static file
that would contain javascript which would call the screen grab function
with the two arguments.

Not an elegant solution, I know. I'm open to doing it in whatever way will
work. But the bottom line is that I need to pass those two arguments from
an application which invokes firefox on the command line to the screengrab
extension (or the screen grab functions, wherever they live).

The application has to be able to write to the filesystem.


Because of memory issues with the screen grab, I figure I will shut down
the browser between each. I need to do about 8000 of them (on a dedicated
machine).


>
>> >
>> >> but none of its methods gave me an actual handle to the extension
>> >> whereby I
>> > There's no such thing as an "extension handle". Extension's functions
>> > can be defined in windows of certain type (e.g. browser.xul windows),
>> > in which case you need to get the window you need, e.g. using
>> > nsIWindowMediator.
>>
>> Interesting. I wonder how I figure out which window (some hidden
>> window?) might be the right one.
>>
> By looking at the extension - what file the functions are defined in
> and where that file is referenced from. In your case it looks like
> you're saying the JS file is referenced from a XUL overlay (correct?).

Yes, apparently. The screengrabOverly.xul file says
<overlay id="screengrabOverlay" ...

and then has a <script> tag which imports the screengrabOverly.js file.

> To figure out what window the JS file gets loaded in, you'll need to
> figure to which documents the overlay referencing the JS gets applied.
> Probably it's chrome://browser/content/browser.xul, in which case the
> extension's variables should be defined in all browser windows.

yes (browser.xul). (see below)

The context menu that the extension installs appears successfully in all
the browser windows.

However, if I try to directly access the functions defined in the
extension, from a browser window, using javascript, they are undefined.


>>
>> > If Components.classes["@your.name/yourcontractid"] returns null, your
>> > component wasn't registered. I don't think we have troubleshooting
>> > guide for XPCOM components registration, but you should at least check
>> > that you put the component's JS file in your extension's components/
>> > folder, that it has a proper XPCOM registration code (copy it from
>> >

Not sure how to find the contractid. (or what name is "your.name", or how
it decides what it is).

However, I dumped the enumeration of Components.classes to a window and
didn't see anything that looked like "my" extension (or the one I borrowed
at any rate).

So the short answer would be, I guess it didn't get 'properly' registered,
although it works just fine from the context menu it defines.


> An extension is a bundle, which can provide various things, including
> chrome packages and components:
> http://developer.mozilla.org/en/docs/Bundles
>

It's got chrome.manifest and install.rdf, and a bunch of directories. Most
of the stuff is in 'content' with localization stuff in 'locale.' Looks
pretty standard, from the descriptions I've seen.

chrome.manifest defines the overlay (see below)

> After the extension is installed, mozilla will attempt to register its
> components on restart. It may fail to register them, in which case
> you'll indeed have the extension registered, but not the component.
>
> What is the component's contract ID? Where is the file defining the
> component? Did you try troubleshooting the registration as I
> suggested?
>

I'm not sure what the contract ID is, but I didn't see anything in
Components.classes that looked like it. The name of it is screengrab, and
that seems to be used as an identifier a lot.

> As I said, you also need to know what the overlay get applies to in
> order to give a meaningful answer to my question.


I think it's browser.xul, as you were guessing. (see below)


> From what you said
> I'm guessing it's the browser.xul document, in which case the code
> really ought to work. The common reason for such problems is described
> here:
>
http://developer.mozilla.org/en/docs/Extension_FAQ#Why_doesn.27t_my_script_run_properly.3F


Now I think I'm getting it -- the code doesn't work from a standalone .xul
file, because it's got to overlay the browser.xul file, thus inheriting its
"attributes" (methods, data, whatever terminology one prefers)

I'm still not sure what the best way to do that is, for what I'm trying to
do.

>
>> I've pulled it out of the .jar file, rearranging the configuration to
>> adjust for the switch. In its original form, as a packaged extension,
>> the
>> structure is a bit different. (this is standard extension development
>> procedure, from what I understand)
>>
> Are you sure you didn't break anything? Does the extension itself
> still work after repackaging?

Yes it does. I've tested it many times, and it's fine.


>
> Actually... are you sure the code that tries to get the tabbrowser
> doesn't run in the content page?

I'm not sure of much, when it comes to all of this!

I do know that it's triggered by a context menu that pops up from the window you're grabbing.


When I do an alert to display the objects, I get this:
document.getElementById("content") == XULElement
document.getElementById("content").selectedBrowser == XULElement

When I enumerate the fields of the former, I get a whole huge page of
stuff, with tons of methods and data fields.

>> Repeating what I said in the last message, it's true that one can find
>> "selectedBrowser" on this page, but I still don't see how it relates to:
>>
>>
>> document.getElementById("content").selectedBrowser
>>
> Once you know what 'document' refers to (browser.xul, which we figured
> out by walking from the JS file to the XUL overlay referencing it, to
> the browser.xul document which is probably overlayed in
> chrome.manifest),

The chrome.manifest mentions both
chrome://browser/content/browser.xul and
chrome://navigator/content/navigator.xul

here are the lines: (each broken into two for usenet)

overlay chrome://browser/content/browser.xul
chrome://screengrab/content/screengrabOverlay.xul
overlay chrome://navigator/content/navigator.xul
chrome://screengrab/content/screengrabOverlay.xul

>
> it's pretty easy to find out. Open the DOMi, inspect
> the browser window and look for an element with id "content". You'll
> see it's a tabbrowser element.
>

I don't know DOMi


> Of course, overlays are different from 'standalone' XUL files,
> whatever you mean.

By "standalone," I mean, when I have a file with the extension .xul and I
just open it with the browser using "file / open"


> The overlays are merged into specified master
> documents (browser.xul in your case), while "standalone" XUL files
> have their own documents.

So the installed extension is inheriting from the browser.xul object(s) ...
that starts to make sense.


>
> The <tabbrowser id="content"> is declared in browser.xul and not in
> your standalone XUL, which explains why document.getElementById can't
> find it.


OK, now I'm starting to see. Which still doesn't tell me how to get what I
want, but I'm starting to understand why the standalone version runs
differently.

Thanks again for your help ....

0 new messages