Question about HistoryImplIE6 + manual url navigation

9 views
Skip to first unread message

Matthew Mastracci

unread,
Jan 1, 2008, 6:39:40 PM1/1/08
to Google Web Toolkit Contributors
In HistoryImplIE6, this bit of code seems to break manual navigation
in the case where no history token is specified (ie: initial
navigation to somefile.html vs. somefile.html#token):

if ($wnd.__gwt_historyToken && (token !=
$wnd.__gwt_historyToken)) {
$wnd.location.reload();
}

If you visit the application without a history string,
$gwt.__gwt_historyToken is '' and is always coerced to boolean false.
If you enter a URL manually in the URL bar, this test will always fall
through and no history changes are registered.

From examining the code, I can't figure out why this test is in here.

Should it instead be the code below to avoid the coersion from '' to
false, or should the clause be eliminated altogether?

if ($wnd.__gwt_historyToken !== null && (token !=
$wnd.__gwt_historyToken)) {
$wnd.location.reload();
}

You can reproduce this on the kitchen sink example by visiting:

http://gwt.google.com/samples/KitchenSink/KitchenSink.html

Then manually entering this in the URL bar:

http://gwt.google.com/samples/KitchenSink/KitchenSink.html#Lists

Note that visiting a tab manually, then entering the URL above works
as expected.

Joel Webber

unread,
Feb 20, 2008, 2:10:51 PM2/20/08
to Google-Web-Tool...@googlegroups.com
Matthew,

It looks like your point about fallthrough on the first clause in that expression is correct. However, the reason this abomination is there in the first place is that manually entering URLs (where only the fragment changes) causes IE to get into a nasty state where it 'gets crashy' for wont of a better term. The only solution I was able to find was to forcibly reload the app.

The point of the first clause was to make sure that __gwt_historyToken was even defined in the first place (though looking at it now, I realize that it's not quite correct). It will currently fail to reload() when the user manually enters an empty history token that is different from the current state. This needs to be fixed.

Does that clear things up a bit, and am I missing anything?

Thanks,
joel.

Matthew Mastracci

unread,
Feb 20, 2008, 6:33:46 PM2/20/08
to Google-Web-Tool...@googlegroups.com, Joel Webber
Hey Joel,

Thanks for looking into this,

The problem you describe below is part of the bug. The real bug is that
once you get into a state where __gwt_historyToken is '' (ie: no hash or
hash fails to decode), you can't get to the reload() method because the
if statement always treats the history token as false and short-circuits.

The result of this is that when a new token is entered manually, the
token is picked up, but the reload block in urlChecker:

if ($wnd.__gwt_historyToken && (token != $wnd.__gwt_historyToken)) {
$wnd.location.reload();
}

evaluates to:

if ('' && (token != '')) {
$wnd.location.reload();
}

where the '' evalates to boolean false and the block is skipped.

I think that this code would fix the problem:

if ($wnd.__gwt_historyToken !== undefined && (token !=
$wnd.__gwt_historyToken)) {
$wnd.location.reload();
}

Thanks!
Matt.

Joel Webber wrote:
> Matthew,
>
> It looks like your point about fallthrough on the first clause in that
> expression is correct. However, the reason this abomination is there
> in the first place is that manually entering URLs (where only the
> fragment changes) causes IE to get into a nasty state where it 'gets
> crashy' for wont of a better term. The only solution I was able to
> find was to forcibly reload the app.
>
> The point of the first clause was to make sure that __gwt_historyToken
> was even defined in the first place (though looking at it now, I
> realize that it's not quite correct). It will currently fail to
> reload() when the user manually enters an empty history token that is
> different from the current state. This needs to be fixed.
>
> Does that clear things up a bit, and am I missing anything?
>
> Thanks,
> joel.
>

> On 1/1/08, *Matthew Mastracci* <mmas...@gmail.com

Joel Webber

unread,
Feb 21, 2008, 9:10:22 AM2/21/08
to Matthew Mastracci, Google-Web-Tool...@googlegroups.com
I think we're on the same page. That makes perfect sense to me. I'll enter an issue and a patch for this.

I just wish we could get the fundamental bug fixed, but IE is, as usual, making our lives difficult...

joel.

Yves

unread,
Mar 24, 2008, 6:42:33 AM3/24/08
to Google Web Toolkit Contributors
Hi,

As I have similar problems (see
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/23fda08d272e7c6b/6083ff49e02e8e76),
I tried your solution.

At the first look, I tried another solution that works for me:

I commented out the 'if':

//if ($wnd.__gwt_historyToken != undefined && (token !=
$wnd.__gwt_historyToken)) {
// $wnd.location.reload();
//}

Thans for your suggestions.

HTH
Yves

On Feb 21, 3:10 pm, "Joel Webber" <j...@google.com> wrote:
> I think we're on the same page. That makes perfect sense to me. I'll enter
> an issue and a patch for this.
> I just wish we could get the fundamental bug fixed, but IE is, as usual,
> making our lives difficult...
>
> joel.
>
> On Wed, Feb 20, 2008 at 6:33 PM, Matthew Mastracci <mmast...@gmail.com>
> > > On 1/1/08, *Matthew Mastracci* <mmast...@gmail.com
> > >     as expected.- Hide quoted text -
>
> - Show quoted text -

Yves

unread,
Mar 24, 2008, 7:08:55 AM3/24/08
to Google Web Toolkit Contributors
Another try that might help comes from the question: why reload ?
Couldn't we simply make a "history change" by calling
$wnd.__gwt_onHistoryLoad(token)

Thus:

if (($wnd.__gwt_historyToken != undefined) && (token !=
$wnd.__gwt_historyToken)) {
$wnd.__gwt_onHistoryLoad(token);
}

The side effect is that every call to History.newItem produces double
call to onHistoryChanged()

Yves

On Mar 24, 11:42 am, Yves <smy...@gmail.com> wrote:
> Hi,
>
> As I have similar problems (seehttp://groups.google.com/group/Google-Web-Toolkit/browse_thread/threa...),
> > - Show quoted text -- Hide quoted text -

Yves

unread,
Mar 24, 2008, 7:19:57 AM3/24/08
to Google Web Toolkit Contributors
Sorry for coming again with another suggestion...

if (($wnd.__gwt_historyToken != undefined) && (token !=
$wnd.__gwt_historyToken)) {
$wnd.__gwt_historyToken = token;
}

This seems to eliminate the problems I have encountered.

Yves

Joel Webber

unread,
Mar 25, 2008, 9:48:56 AM3/25/08
to Google-Web-Tool...@googlegroups.com
Yves,

This code

  if ($wnd.__gwt_historyToken && (token != $wnd.__gwt_historyToken)) {

    $wnd.location.reload();

  } 
is meant to deal with a nasty bug in IE that occurs when the user enters a #hash manually in the URL bar (or uses a bookmark or external link to do so). Last time I checked (granted, it has been a while, but this definitely happened on IE6), doing this caused IE to behave extremely oddly (sometimes even crashing).

Would you mind trying the following (with your patch enabled)?
- Open KitchenSink.
- Navigate through a few states.
- Add #Widgets (or the name of any sink you're *not* currently on) to the end of the url bar.
- Hit enter.
- Whether it works or not, try navigating back, forward, and clicking on other tabs.

IIRC, it should either crash or the history should start behaving very strangely (e.g. the url bar should stop updating).

Thanks,
joel.

Yves

unread,
Mar 25, 2008, 4:08:18 PM3/25/08
to Google Web Toolkit Contributors
Hi,

I tried your and mine test scenrios with "native" GWT code, and when I
play with the back/fwd buttons the history stack is corrupted after
few clicks (I'am using IE6 and GWT 1.4.6)

My suggestion to solve the problem is the following.

1) change the "KitchenSink-compile"-generated file history.html

I don't know what this file is exactly supposed to do, but it seems
that there is a bug: one should read the location.HASH value, not the
location.SEARCH

=> replace "location.search" by "location.hash"

function hst() {
var hash= location.hash;
var historyToken = '';
if (hash.length > 0)
historyToken = hash.substring(1);

document.getElementById('__gwt_historyToken').value = historyToken;
if (parent.__gwt_onHistoryLoad) {
parent.__gwt_onHistoryLoad(historyToken);
}
}

2) Change HistoryImplIE6.java
In place of :

if ($wnd.__gwt_historyToken && (token !=
$wnd.__gwt_historyToken)) {
$wnd.location.reload();
}

write:

if (($wnd.__gwt_historyToken != undefined) && (token !=
$wnd.__gwt_historyToken)) {
$wnd.__gwt_historyToken = token;
}


With these changes I didn't reproduced the problems described in the 2
tests scenarios

Does this solve the problem when you try this solution ?

HTH
Yves
Reply all
Reply to author
Forward
0 new messages