Closed
Bug 226416
Opened 21 years ago
Closed 21 years ago
No way to detect when document loaded with window.open finishes loading
Categories
(Core :: DOM: Core & HTML, defect, P1)
Core
DOM: Core & HTML
Tracking
()
RESOLVED
FIXED
mozilla1.6beta
People
(Reporter: hubert.kauker, Assigned: bzbarsky)
References
()
Details
Attachments
(2 files)
2.15 KB,
patch
|
danm.moz
:
review+
jst
:
superreview+
asa
:
approval1.6b+
|
Details | Diff | Splinter Review |
2.56 KB,
text/html
|
Details |
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6a) Gecko/20031030
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6a) Gecko/20031030
When a document is loaded into a new (or existing) frame or window it should be
expected, that a script doing this has a way to discover when that document has
been fully loaded and all its objects are available for use.
Apparently, neither the document property of the new window, nor document.body,
nor document.body.innerHTML all together are capable to do this.
By the way: in Internet Explorer one can use the condition
document.readyState == "complete"
to check on analogous situations.
It is very hard, however, to produce a test case.
So I use a document with a "very long" body containing a script which assigns a
long string to a variable.
I load this document at the same time into two new windows and monitor the
loading progress.
When document, document.body, and document.body.innerHTML seem to indicated that
all is finished, I try to read the 'data' variable from each window, which is
set by the new document.
In most cases I get an 'undefined' value.
Using simpler documents, however, succeeds.
But Mozilla should be a little more deterministic, shouldn't it?
Reproducible: Sometimes
Steps to Reproduce:
1. Load http://www.travelbasys.de/kauker/test/CheckReadyState.html
2.
3.
Actual Results:
Most of the time, the 'data' variable defined in one of the new windows has an
'undefined' value.
Expected Results:
The 'data' variable should be defined.
Assignee | ||
Comment 1•21 years ago
|
||
> that a script doing this has a way to discover when that document has
> been fully loaded and all its objects are available for use.
Yeah. It's called "the onload event handler". Use that, please.
> When document, document.body, and document.body.innerHTML seem to indicated
> that all is finished
None of those indicate anything. Why would you think that they do?
Status: UNCONFIRMED → RESOLVED
Closed: 21 years ago
Resolution: --- → INVALID
Reporter | ||
Comment 2•21 years ago
|
||
Sorry, you misunderstood.
I know fully well the intention and usage of the window.onload() event handler.
It is usually set INSIDE the document being loaded to handle the respective
event in its 'host' window.
But the problem is: how can a window, say 'A', find out when a document in
ANOTHER window, say 'B' has been fully loaded and all its objects are usable?
Could you please fill me in with this tiny bit of detail?
If there is no way of window 'A' getting to know this, may be the bug should
be reopened.
I naturally assumed that when 'A' finds that document.body of 'B' is valid,
then all objects which in some way 'depend' on it are valid as well.
Thanks.
Comment 3•21 years ago
|
||
if you have control over the second window:
<body onload="window.loaded=true;"> and check if loaded is set to true in the
child window.
Reporter | ||
Comment 4•21 years ago
|
||
Granted.
When I happen to have control over window two I can do all sorts of things
there including set up my own onload handler there which tells window one about
the end of the job.
But what when I can NOT persuade window two to cooperate? When I do not 'own'
it?
The idea is:
When I have script code inside a SCRIPT element, nested inside a BODY element,
nested inside a HTML element, I sort of assume that an 'inner' element becomes
valid before an 'outer' element.
By becoming 'valid' I mean that the thing can used as specified.
So when document.body becomes valid, a SCRIPT element inside it should have
become valid before, which means that all script code inside it has been
successfully parsed and executed, which means that a variable which is a
property of the window object, after all, can be used by any external method.
By the same token, a SCRIPT element inside the HEAD of a document, should be
valid as soon as document.getElementsByTagName("script") returns the SCRIPT
element in its return array.
Assignee | ||
Comment 5•21 years ago
|
||
> I sort of assume that an 'inner' element becomes valid before an 'outer'
> element.
Bad assumption...
> So when document.body becomes valid, a SCRIPT element inside it should have
> become valid before,
document.body becomes defined as soon as we parse the <body> open tag. Manu
existing pages depend on this.
Note that you can do:
w = window.open(whatever);
w.onload = function { /* do something */ }
which involves no control over the contents of the window you are opening.
Comment 6•21 years ago
|
||
bz: that would override a possibly already existing onload handler right?
Assignee | ||
Comment 7•21 years ago
|
||
The other way around. If the opened window sets its own onload handler, it
would override yours.
Reporter | ||
Comment 8•21 years ago
|
||
> document.body becomes defined as soon as we parse the <body> open tag.
Can't be true.
Maybe document.body is CREATED when the body tag is parsed.
But it certainly will not be appended to its parent node until the end body is
parsed.
At that time, however, both the script and the end script tags will have been
parsed and appended to its parent node, too.
So the question is: when are the assignment statements contained in the script
executed? Is that possibly in a parallel thread which would need more careful
synchronization?
Reporter | ||
Comment 9•21 years ago
|
||
> w = window.open(whatever);
> w.onload = function { /* do something */ }
> cb: that would override a possibly already existing onload handler right?
> bz: The other way around.
> bz: If the opened window sets its own onload handler, it would override yours.
The first case would break the new page.
The second case would make the trick useless.
So let's forget it.
Assignee | ||
Comment 10•21 years ago
|
||
> But it certainly will not be appended to its parent node until the end body is
> parsed.
Ah, but it will. That's the only way incremental rendering of web pages can
work. All nodes get appended to the parents as soon as the start tag is parsed;
that way if the interrupt timer fires partway through parsing of a node, we can
incrementally show whatever we've got up to that point.
> when are the assignment statements contained in the script executed?
For an inline script? Right after the </script> is parsed.
> Is that possibly in a parallel thread which would need more careful
> synchronization?
Not in Mozilla, but yes in some other browsers, iirc (eg Opera).
In any case, this bug, as filed, is still invalid. None of the methods you were
trying are indicative of anything regarding whether the load of the page is done.
Reporter | ||
Comment 11•21 years ago
|
||
> None of the methods you were trying are indicative of anything regarding
whether the load of the page is done.
But please: what *IS* indicative whether the load of the page is done?
I do need this for my web application?
I know that in IE, I can use an interval timer timer and periodically check
whether the condition "document.readyState == 'complete'" has become true.
What can I do in Mozilla?
Comment 12•21 years ago
|
||
Use:
w.addEventListener('load', function() { /* do something */ }, false);
Reporter | ||
Comment 13•21 years ago
|
||
Thank you, Ian. That's very kind.
I suppose you mean
var w = window.open( url, ... );
w.addEventListener('load', function() { /* do something */ }, false);
Right?
But since window.open() is not guaranteed to be a synchronous operation,
you'll be running into serious timing problems here.
You simply do not know, when addEventListener() will be executed.
Is the new document already loaded then or is it not?
In any case I made a test page:
http://www.travelbasys.de/kauker/test/readystateworkaround.html
and it does NOT work. Try yourself.
Comment 14•21 years ago
|
||
Hrm. That _should_ work, no? bz?
Assignee | ||
Comment 15•21 years ago
|
||
Yes, that should work, iirc.
Comment 16•21 years ago
|
||
bz: Well it does't...
Hubert: Could you file a bug on this?
Assignee | ||
Comment 17•21 years ago
|
||
Ian: yes, I noticed. That's why I cced danm and jst. I'd like to hear what
they say, since they're most familiar with this neck of the woods...
Comment 18•21 years ago
|
||
IIRC, the problem is that when a window is opened, we load about:blank
(synchronously, IIRC), and then when the actual document comes in off the
network, we clear event handlers (as we're supposed to) and start over. This
special case needs to be taken into account here, but it's not...
Comment 19•21 years ago
|
||
Yup. The w.addEventListener('load',...) in your example is attached to the bogus
preliminary document after it has finished loading. Then the load event listener
is cleared out just before the real contents are loaded, so it never fires.
This means, and I just tried this, that you can get what you want with an unload
listener. Yeah, that's pretty messed up.
Assignee | ||
Comment 20•21 years ago
|
||
Hmm... so what do we want to do? Do we want to clear all listeners except
onload listeners? Or do we want to leave all listeners when going from
about:blank to a page with the same principal as the opener (like we currently
do with the JS scope)?
Assignee | ||
Comment 21•21 years ago
|
||
Reopening and resummarizing to reflect the real issue.
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
Summary: The document, document.body, and document.body.innerHTML properties do not indicate reliably when a document is fully loaded and all its objects are available to scripting. → No way to detect when document loaded with window.open finishes loading
Comment 22•21 years ago
|
||
Or maybe just not clear event listeners on the window at all when leaving
about:blank, i.e. tie that code into the code that does JS_ClearScope()...
Status: UNCONFIRMED → NEW
Ever confirmed: true
Assignee | ||
Comment 23•21 years ago
|
||
Right. Should it be subject to all the same conditions (non-chrome document,
same security principal, leaving about:blank)? Or just "don't clear if leaving
about:blank"?
Comment 24•21 years ago
|
||
IMO it should be subject to all the same conditions.
Assignee | ||
Comment 25•21 years ago
|
||
Assignee | ||
Updated•21 years ago
|
Attachment #136275 -
Flags: superreview?(jst)
Attachment #136275 -
Flags: review?(danm-moz)
Comment 26•21 years ago
|
||
Comment on attachment 136275 [details] [diff] [review]
Like this?
Yeah, looks good.
Attachment #136275 -
Flags: superreview?(jst) → superreview+
Reporter | ||
Comment 27•21 years ago
|
||
I just filed a bug (226703) as suggested by Hixie in comment #16.
See http://bugzilla.mozilla.org/show_bug.cgi?id=226703.
May I draw your attentation to another thread
http://bugzilla.mozilla.org/show_bug.cgi?id=226432
Here the question "what should be reset when a new document is loaded"
is already under discussion.
Assignee | ||
Comment 28•21 years ago
|
||
*** Bug 226703 has been marked as a duplicate of this bug. ***
Comment 29•21 years ago
|
||
Comment on attachment 136275 [details] [diff] [review]
Like this?
Looks good to me. Note this is an improvement but we're still not quite there.
It would be better if event listeners on the temporary about:blank bogodocument
were deaf. We still get an anomalous unload event while loading a window's
first document (comment 19).
Note of possible historical interest: we didn't RemoveAllListeners for any
about:blank document for a very long time until rev 1.449 (Oct 2001) for bug
18553. This patch would seem to be a better version of that one.
Attachment #136275 -
Flags: review?(danm-moz) → review+
Assignee | ||
Comment 30•21 years ago
|
||
Comment on attachment 136275 [details] [diff] [review]
Like this?
Could this please be approved for 1.6b?
Attachment #136275 -
Flags: approval1.6b?
Comment 31•21 years ago
|
||
It was too much fun to write not to post. Though it doesn't add much that we
didn't already know. Note it behaves much better with the patch applied, but
the unload is of course still there.
(The festival of focus events has already been noted; that's bug 164686.)
Does this allow one site to determine how long it takes another site to load, or
are there cross-site scripting checks in the patch?
Comment 33•21 years ago
|
||
There are cross-site scripting checks in the patch.
Comment 34•21 years ago
|
||
Comment on attachment 136275 [details] [diff] [review]
Like this?
a=asa (on behalf of drivers) for checkin to 1.6beta
Attachment #136275 -
Flags: approval1.6b? → approval1.6b+
Assignee | ||
Updated•21 years ago
|
Assignee: general → bz-vacation
OS: Windows 2000 → All
Priority: -- → P1
Hardware: PC → All
Target Milestone: --- → mozilla1.6beta
Assignee | ||
Comment 35•21 years ago
|
||
*** Bug 134335 has been marked as a duplicate of this bug. ***
Assignee | ||
Comment 36•21 years ago
|
||
Fixed for 1.6b.
Status: NEW → RESOLVED
Closed: 21 years ago → 21 years ago
Resolution: --- → FIXED
Comment 37•21 years ago
|
||
Just out of interest, does this patch actually solve the problem the reporter
was asking about, or does detecting document loads still involve a race
condition?
From comment 13:
1: var w = window.open( url, ... );
/* start loading */
/* finish loading */
2: w.addEventListener('load', function() { /* do something */ }, false);
If the document completes loading after line 1, but before line 2 has had a
chance to add the event listener, will the event listener fire?
Or are we suggesting that since the document load takes /such/ a long time to
(asynchronously) complete - relative to the time that window.open takes to
return - that there's virtually no chance that the load could complete before
line 2 has finished executing?
Comment 38•21 years ago
|
||
All loads (except for the initial load of about:blank) are asynchonous and
essentially happen on the main thread (the same thread that the JS is running
on), so there is no possibility of a race there, unless the two lines of code
run off of different timers, or cause mozilla to spin a sub-event loop (by
performing synchronous IO, or opening modal dialogues).
Comment 39•21 years ago
|
||
So the JS execution actually blocks the load? If I do:
var w = window.open( url, ... );
really_slow_function();
Will the window not commence loading until really_slow_function returns?
Assignee | ||
Comment 40•21 years ago
|
||
If the function just runs and doesn't put up any modal dialogs or make any
disk/network I/O requests, yes.
Comment 41•21 years ago
|
||
Comment 42•21 years ago
|
||
I missed all the fun.
The use of a blank bogo-document seems to be the root of much evil. Why is that
necessary? It wasn't in the ancient (Nav2 and on) daze, when I made sure (a)
you could preset onload after window.open, which by definition is asynch; and
(b) no bogo-doc was loaded synchronously, to generate spurious unload or other
events.
/be
Comment 43•21 years ago
|
||
about:blank bogodocument's raison d'etre is the subject of new bug 227028.
You need to log in
before you can comment on or make changes to this bug.
Description
•