001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.client.impl;
017:
018: import com.google.gwt.user.client.DOM;
019: import com.google.gwt.user.client.Element;
020:
021: /**
022: * Internet Explorer 6 implementation of
023: * {@link com.google.gwt.user.client.impl.HistoryImplFrame}.
024: */
025: class HistoryImplIE6 extends HistoryImplFrame {
026:
027: /**
028: * Sanitizes an untrusted string to be used in an HTML context. NOTE: This
029: * method of escaping strings should only be used on Internet Explorer.
030: *
031: * @param maybeHtml untrusted string that may contain html
032: * @return sanitized string
033: */
034: private static String escapeHtml(String maybeHtml) {
035: final Element div = DOM.createDiv();
036: DOM.setInnerText(div, maybeHtml);
037: return DOM.getInnerHTML(div);
038: }
039:
040: private static native void initUrlCheckTimer() /*-{
041: // This is the URL check timer. It detects when an unexpected change
042: // occurs in the document's URL (e.g. when the user enters one manually
043: // or selects a 'favorite', but only the #hash part changes). When this
044: // occurs, we _must_ reload the page. This is because IE has a really
045: // nasty bug that totally mangles its history stack and causes the location
046: // bar in the UI to stop working under these circumstances.
047: var urlChecker = function() {
048: var hash = $wnd.location.hash;
049: if (hash.length > 0) {
050: var token = '';
051: try {
052: token = decodeURIComponent(hash.substring(1));
053: } catch (e) {
054: // If there's a bad hash, always reload. This could only happen if
055: // if someone entered or linked to a bad url.
056: $wnd.location.reload();
057: }
058:
059: if ($wnd.__gwt_historyToken && (token != $wnd.__gwt_historyToken)) {
060: $wnd.location.reload();
061: }
062: }
063: $wnd.setTimeout(urlChecker, 250);
064: };
065: urlChecker();
066: }-*/;
067:
068: @Override
069: public boolean init() {
070: if (!super .init()) {
071: return false;
072: }
073: initUrlCheckTimer();
074: return true;
075: }
076:
077: @Override
078: protected native String getTokenElementContent(Element tokenElement) /*-{
079: return tokenElement.innerText;
080: }-*/;
081:
082: @Override
083: protected native void initHistoryToken() /*-{
084: // Get the initial token from the url's hash component.
085: var hash = $wnd.location.hash;
086: if (hash.length > 0) {
087: try {
088: $wnd.__gwt_historyToken = decodeURIComponent(hash.substring(1));
089: } catch (e) {
090: // Clear the bad hash and __gwt_historyToken
091: // (this can't have been a valid token).
092: $wnd.location.hash = '';
093: $wnd.__gwt_historyToken = '';
094: }
095: return;
096: }
097:
098: // There was no hash. Just start off with an empty token.
099: $wnd.__gwt_historyToken = '';
100: }-*/;
101:
102: @Override
103: protected native void injectGlobalHandler() /*-{
104: $wnd.__gwt_onHistoryLoad = function(token) {
105: // Change the URL and notify the application that its history frame
106: // is changing.
107: if (token != $wnd.__gwt_historyToken) {
108: $wnd.__gwt_historyToken = token;
109: $wnd.location.hash = encodeURIComponent(token);
110: @com.google.gwt.user.client.impl.HistoryImpl::onHistoryChanged(Ljava/lang/String;)(token);
111: }
112: };
113: }-*/;
114:
115: @Override
116: protected native void newItemImpl(Element historyFrame,
117: String historyToken, boolean forceAdd) /*-{
118: historyToken = @com.google.gwt.user.client.impl.HistoryImplIE6::escapeHtml(Ljava/lang/String;)(historyToken || "");
119: if (forceAdd || ($wnd.__gwt_historyToken != historyToken)) {
120: var doc = historyFrame.contentWindow.document;
121: doc.open();
122: doc.write('<html><body onload="if(parent.__gwt_onHistoryLoad)parent.__gwt_onHistoryLoad(__gwt_historyToken.innerText)"><div id="__gwt_historyToken">' + historyToken + '</div></body></html>');
123: doc.close();
124: }
125: }-*/;
126: }
|