why can't i do something before the page is rendered?

296 views
Skip to first unread message

keb...@gmail.com

unread,
Jul 10, 2009, 3:12:51 PM7/10/09
to greasemonkey-users
this is something that is bugging me, everywhere i look the response
is usually the same, which is no

firefox renders as its loading the content and i can even understand
why greasemonkey needs to have the full page before doing something,
but i've seen extensions that do something before rendering the page,
for example, adblock does it, why can't greasemonkey do it to? can't
there be some sort of GM function that lets you do that?

this bugs me because some sites take a while to load and i only see
the result at the end, actually most of the time the page is fully
loaded and it's just some sort of ad related content that it's taking
a while to load

Matt Sargent

unread,
Jul 12, 2009, 1:37:09 AM7/12/09
to greasemon...@googlegroups.com

metzgerite

unread,
Jul 14, 2009, 12:40:44 AM7/14/09
to greasemonkey-users
That wiki page doesn't really answer the question. It has a section
entitled Workaround, that says:

"Generally, flicker is a problem that should be ignored. If, however,
a script author decides that it must be avoided there is at least one
technique.

Using a combination of userContent.css [ http://kb.mozillazine.org/UserContent.css
] and -moz-document() [ https://developer.mozilla.org/CSS:@-moz-document/en
] rules, the page can be hidden completely. The Greasemonkey script
would then be crafted to undo this CSS rule, after altering it,
thereby never showing the page in its pre-greased state."

The first link describes changing the userContent.css file, and the
second goes to a blank page. A quick search finds: [
https://developer.mozilla.org/en/CSS/@-moz-document ], which
describes an @ (at-rule) that you can add to Gecko specific
userContent.css files. Asking users of your script to edit their own
userContent file is probably a very bad idea.

So to clarify, you can either write your own extension, or you can
accept that the answer is, in fact, no.

Matt Sargent

unread,
Jul 14, 2009, 5:45:42 PM7/14/09
to greasemon...@googlegroups.com
Actually, it does answer the question, in the very first sentence:
"The code in a Greasemonkey user script gets invoked when the
DOMContentLoaded event fires."

Obviously, if you want to do something before the content is loaded,
Greasemonkey is not the answer.

BD

unread,
Jul 14, 2009, 7:22:15 PM7/14/09
to greasemon...@googlegroups.com, greasemo...@googlegroups.com
It's due to the event hierarchy and the way mozilla performs content rendering.

The DOMContentLoaded event is the closest (and "best", if not only, in effect or actuality) event that can be used to perform Gm processing.

There is no "call me when the DOM is loaded, but BEFORE rendering begins (and don't start rendering until I return and/or am ready)" event in mozilla. If there was, that event would probably be used by Gm. There is also no "btw, don't start rendering yet" flag that can be set, or anything like that. Gm can only use what mozilla provides. (thereby the work-arounds suggested by people using userContent.css, etc., which are not automatic and require some manual labor by people if you want them to use those processes for your script)

Also, content rendering is an asynchronous process. After the DOM is loaded, rendering "begins" (in effect or actuality) and any processes (plural!) that have registered themselves with the DOMContentLoaded event are called. I don't know if it is on a "first come, first served" basis, or not, but that would be my guess. (but I could be wrong) AND I believe the calls to ALL of the processes who have registered themselves with that event are also called asynchronously, as well. So who knows how many functions get called before Gm. And what processing, and how much, is performed before Gm is called, or while Gm itself is executing. (depending on how threaded it all is, and how much "parallel processing" (if any, I'm not exactly sure how the internals work) is being performed by the Javascript processor, and the mozilla system) At that level things start getting a little complex as to what happens when, etc. (there are probably only a few people working on mozilla that understand and can answer these internals questions accurately with absolute knowledge)

And then there is the issue of what GmScript is called at what point, as well. Afaik, there is no way to say "ME FIRST!" for any script. (although I think the client (not the script creator) can tweak it manually) I forget how they are called. (probably either according to how they were added to Gm, or perhaps alphabetically, or maybe something else) This had been discussed before. So any number of GmScripts could also have been called and executed (and are executing, and used up some amount of time) before your script is called (all the while, rendering is occurring, and the time is in milliseconds or microseconds). I believe there is some amount of "parallel processing" involved there, as well. But, again, I don't know how all of that very low internal processing works in the mozilla JS system. (using sandboxes, etc.)

I don't know how some of the other addons do stuff before rendering occurs. Remember that there are also a bunch of addons that are called and executing in there, as well. (all of which are written in JS and XUL) I don't know when the addons are called, but probably "immediately" whenever mozilla thinks it's time for them to be called. But GmScripts need to execute AFTER the DOM is loaded (doing so otherwise, or before then, makes no sense, really), so that is when GmScripts are called, if not Gm itself. (I forget how that all works now, too)

Afaik, the above is fairly correct and true, but your mileage may vary.

Something like the above should be added to the wiki, but I'm not going to do it. In part because I don't know exactly how true and accurate my information is. (but I think it's pretty close, if not mostly right on, or thereabouts)

metzgerite

unread,
Jul 15, 2009, 8:33:34 PM7/15/09
to greasemonkey-users
Yes, you are correct, it does answer the question.

Perhaps I should have said, it doesn't answer the question *well*.

Due to the number of programming layers involved, dealing with
greasemonkey scripts is not a trivial issue. I dealt with the same
page flicker question when I first started out, and I got really tired
of being given a link to that stupid f'in wiki page that seemed to say
that there was a workaround.

Sure, there's a workaround, but it's not really feasible to ask
everyone installing your script to screw with their usercontent file.
Would have saved me hours of frustration if someone had just said NO
instead of linking to that stupid f'in wiki page.

So I apologize if it seemed I was saying your answer was wrong, it
wasn't. I have no issues with your answer, but I obviously have
issues with that stupid f'in wiki page =]

Oh and I'm on board with BD... I have no problem wasting my time
reading and posting comments on forums, but I've never edited a wiki
page in my life and I'm not about to start.

qufighter

unread,
Jul 16, 2009, 3:09:52 PM7/16/09
to greasemonkey-users
I think that since this problem (at least for me) is only a flash
problem, that writing an extension to disable certain

embed{display:none}

until DOMContentLoaded (after userscripts, or just before)

embed{display:block}

(or body element) would very likely solve any sort of problem.... of
flash playing, then being removed, and played again (rare but
annoying=)

it would speed up dom mods too (body{display:none}) I believe since
changes would not have to be rendered until you said "go" effectively,
though unfortunately certain calls do not work (you cannot measure the
width/position of display:none things)

would a http://userstyles.org/ possibly execute early enough? (tested,
seems to) Then your GM script just has to set the display to be
something visible for the things you want visible (at the right
moment). Unfortunately complicated way to solve this. Google Chrome
has a pre-DOMContentLoaded "early injection" option for userscripts,
which would possibly be perfect for injecting CSS (you define your own
contentloaded listener). Not sure exactly when stylish operates
(other than before contentloaded), it does not modify UserContent.css
http://forums.mozillazine.org/viewtopic.php?f=19&t=824685&start=0&st=0&sk=t&sd=a

Still requiring people to install both is not something I want to do
(unless it works, and no alternative in sight). Installing one
extension is complex enough, still its possible to add an enhanced
functionality through an additional extension plugin... without
negatively effecting your gm scripts functionality. Of course the
added "benefit" (horrible consequence) of doing some dual-plugin model
is that when they disable GM or your script, then the site breaks....
unless they disable the style too

This is more of an issue on slow internet connections, but its a huge
issue certainly for those people and even on fast bandwidth
occasionally that the video plays before your script "moves" it to the
correct place in dom (or other modification). Some way to move a
flash element in DOM without it stopping playing would also solve the
problem for me (most superior circumstance).

Its a well known flash bug (to me) that if you change the
position:relative (for flash) to position:fixed the flash reloads and
starts from the beginning again! whats up with that... its things
like this that we have html5 imho... its the same type of bug except
when you remove it from the tree and place it elsewhere, it makes
sense, whereas this does not! (another example: dragging tabs into
new windows, compare a playing flash video in chrome versus Firefox).
IMHO there is almost always something wrong with resetting the same
flash content when its not explicitly requested. (loss of video
buffer)

metzgerite

unread,
Jul 16, 2009, 4:23:21 PM7/16/09
to greasemonkey-users
I've never had to deal with moving a video, but I am knee-deep trying
to modify a page that has a billion little gaming tiles placed on load
absolutely positioned via a page script relative to the document
window... you can imagine how much that breaks if you change anything
on the page that moves these tiles. Sigh.

Something I've been toying with that holds some promise and might be
useful for large number of sites:

Almost every site has some sort of blank 1x1 white .gif image or
otherwise almost invisible image. If you change links on a page to
link to say:

http://www.somesite.com/images/blank.gif?myarg=foo1
http://www.somesite.com/images/blank.gif?myarg=foo2
... etc.

You can have the browser display essentially a blank page, while you
grab whatever real page you wanted (based on querysting) with
XMLhttprequest, modify everything you want, and then replace the
entire page with your already modified content.

I doubt this would work for everything, as you mentioned you can't get
say, a position property on an element that hasn't been displayed
yet. If it's an inline script that is setting your element positions
(it is in my case), then you can directly modify this script to
position them differently before the page is even displayed. I'm also
not sure about the header issues, and not sure yet how you'd deal with
referenced script files, but I haven't run into anything yet that
would tell me it can't be done, unlike the hard limit of having a user
edit and/or install other stuff.
Reply all
Reply to author
Forward
0 new messages