GWT History Interacts Badly With Non-History iFrame

191 views
Skip to first unread message

Carl

unread,
Oct 30, 2009, 6:19:56 AM10/30/09
to Google Web Toolkit
I am developing an application that uses an iFrame to display help
page content, while keeping the main page (which contains my GWT
widgets) unchanged. This is being done to preserve the state of the
GWT widgets while various help pages are viewed by the user.

The fundamental problem is this: A browser, if left to its own
devices (i.e., no GWT history hooks) will keep track of iFrame content
in its own history list. In other words, if you have a plain HTML
page with an iFrame in it and some links in the containing page that
load stuff into that iFrame, the browser will keep track of what got
loaded and if you hit the back button the iFrame pages will be
reloaded in reverse order. But unfortunately, setting up an
onValueChange() handler using History.onValueChangeHandler() in GWT
and managing the History list in the GWT manner will not prevent the
browser from adding its own items to its own internal history, and
those items will get interleaved with whatever items your write
yourself using History.newItem().

Furthermore, when a browser re-loads this content into the iFrame in
response to pushes of the Back button, then even if you have set up an
onValueChange() handler using History.onValueChangeHandler(), that
handler will not be informed (except for IE and hosted mode) of the
back button presses that result in restoring those pages that the
browser has stuck into its history list itself. Nor will that handler
be informed when the URL loaded in the iFrame changes and the browser
detects this and adds items representing those changes to its own
history list.

The GWT History mechanism is clearly intended to keep track of state
changes that are generated within the GWT code that result in distinct
displayed states but which are not accompanied by changes to the base
URL. It pretty much does that. But when changes must occur to an
embedded iFrame in the course of using the application, the items
added to browser history by the browser get all tangled up with the
items that you add yourself via GWT's History (which of course works
by manipulating its own embedded, invisible iFrame).

For SEO and other reasons, I want my links that load help pages into
the iFrame to be regular anchors rather than Hyperlinks. But I don't
think that Hyperlinks would resolve this issue, since the main problem
is that the browser is still doing its own thing with its history each
time the content document of an embedded iFrame is changed. The
HyperLink widget is intended to signal a GWT application that it
should change its own internal state, not to signal a GWT application
that it should load something into an iFrame.

What I would really like is a feature that allows me to receive an
event when the browser adds an item of its own to the event list, and
also a way to update the hash on the URL that will not affect the
browser's internal history. I have tried the following native method:

public native static void setHashInUrl(String newHash) /*-{
$wnd.location.hash = newHash;
}-*/;

and it does set the hash in the URL without reloading the page (along
with its GWT content), but unfortunately the browser back button
behavior (i.e., its internal history list) gets all crazy with extra
items and items that do nothing (lots of them) when I use the above
method. The only browsers that do not seem to have this problem are
hosted mode and IE.

Anyway, I am at the point with this that I am going to punt and just
hook the onLoad() event for the frame to perform GWT actions (like
adjusting the scroll position or injecting content into the loaded
page) each time a new URL is loaded into the iFrame. I am going to
give up on trying to get the hash of the URL in the browser's address
bar to reflect the page that is presently loaded, because changing the
hash in response ot an iFrame load, while it can be done, wreaks havoc
with the back button's behavior for every browser except IE and the
hosted mode browser. With this (punting) approach, the browser
maintains its own history, including the loaded help pages, and all
that I lose are the hashes in the URL that would allow a user to get a
permalink to the page with the presently-loaded iFramed help content.
Which I will sorely miss, but there doesn't seem to be a good solution
for this yet in GWT...unless someone here knows otherwise.


Brian

unread,
Nov 2, 2009, 7:58:56 AM11/2/09
to Google Web Toolkit
I'm not sure that I follow completely, but perhaps a different
approach would be to serve up two versions of the help. One would be
under control of GWT and the other would be more static and would be
shown only to search engines. You could probably work out a way that
they would both show the same content so there wouldn't be versioning
issues. Again, I'm not sure I followed well enough to know if this
would help with your problem, but it's a different approach to think
about.

-Brian

Carl

unread,
Nov 17, 2009, 12:33:16 AM11/17/09
to Google Web Toolkit
Brian, I appreciate your response and apologize for not having noticed
it until now.

I've moved on from this issue for the moment and will probably revisit
it once I get my initial deployment out the door.

Your suggestion is reasonable but, as I mentioned, I have some doubts
as to whether it would work, because it seems to me that changes to
the non-GWT-History iframe can affect the browser's own
history without informing the GWT History mechanism. However, until I
actually try what you are
suggesting, I can't be sure that it would not work; it may be that
when the change to the contents of the non-GWT-History iframe are made
from a Hyperlink rather than by a direct user click on an anchor that
targets that iframe, the browser will not place its own disruptive
items on the History list in addition to those entered by GWT. So I
*will* try that more virtuous approach but,
as St. Augustine said, "not now."

Another concern, however, is that as someone fairly new to developing
for the public net, I'm a bit paranoid about the shadowy area of SEO,
and also AdSense spidering, and would like to keep things as vanilla
as possible when it comes to links to other pages. Using an iframe
alone is already a little "iffy" in that regard, because there is some
question as to whether the links to the framed page will be credited
back to the containing page. If I add on top of that dual paths for
the bots vs. the humans, the possibility that this will be perceived
as "cloaking" is added to the already cloudy mix.

So, I'll try your suggestion but may still stay with the simpler
(albeit non-ideal from the standpoint of bookmarking) approach, even
if your suggestion works.

Carl
Reply all
Reply to author
Forward
0 new messages