From ca51ee58ac00257eee4adaf8e92c0195c6a1003c Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Tue, 20 Dec 2011 15:34:03 +0200 Subject: [PATCH] Initial unsupported-browser-warning-page for #7985 Includes support for checking isChromeFrame and isChromeFrameCapable. Warning page can be bypassed with cookie. Works, but needs more thought, and it seems the (V)BrowserDetails and WebBrowser mess should be simplified somehow. --- .../terminal/gwt/client/VBrowserDetails.java | 29 +++++++++- .../terminal/gwt/server/AjaxPageHandler.java | 57 +++++++++++++++++++ .../terminal/gwt/server/WebBrowser.java | 28 +++++++++ .../gwt/server/WrappedHttpServletRequest.java | 18 +++++- 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java index b56a7d20a2..72ab133629 100644 --- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java +++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java @@ -22,6 +22,9 @@ public class VBrowserDetails implements Serializable { private boolean isWebKit = false; private boolean isPresto = false; + private boolean isChromeFrameCapable = false; + private boolean isChromeFrame = false; + private boolean isSafari = false; private boolean isChrome = false; private boolean isFirefox = false; @@ -59,6 +62,10 @@ public class VBrowserDetails implements Serializable { && (userAgent.indexOf("webtv") == -1); isFirefox = userAgent.indexOf(" firefox/") != -1; + // chromeframe + isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1; + isChromeFrame = isChromeFrameCapable && !isIE; + // Rendering engine version try { if (isGecko) { @@ -209,6 +216,24 @@ public class VBrowserDetails implements Serializable { return isChrome; } + /** + * Tests if the browser is capable of running ChromeFrame. + * + * @return true if it has ChromeFrame, false otherwise + */ + public boolean isChromeFrameCapable() { + return isChromeFrameCapable; + } + + /** + * Tests if the browser is running ChromeFrame. + * + * @return true if it is ChromeFrame, false otherwise + */ + public boolean isChromeFrame() { + return isChromeFrame; + } + /** * Tests if the browser is Opera. * @@ -304,7 +329,9 @@ public class VBrowserDetails implements Serializable { /** * Checks if the browser is so old that it simply won't work with a Vaadin - * application. + * application. NOTE that the browser might still be capable of running + * Crome Frame, so you might still want to check + * {@link #isChromeFrameCapable()} if this returns true. * * @return true if the browser won't work, false if not the browser is * supported or might work diff --git a/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java b/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java index d40a18308b..f006708d0c 100644 --- a/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java +++ b/src/com/vaadin/terminal/gwt/server/AjaxPageHandler.java @@ -26,6 +26,9 @@ import com.vaadin.ui.Root; public abstract class AjaxPageHandler implements RequestHandler { + /** Cookie used to ignore browser checks */ + private static final String FORCE_LOAD_COOKIE = "vaadinforceload=1"; + protected class AjaxPageContext implements Serializable { private final WrappedResponse response; private final WrappedRequest request; @@ -114,6 +117,21 @@ public abstract class AjaxPageHandler implements RequestHandler { WrappedRequest request, WrappedResponse response) throws IOException { + if (request.getBrowserDetails() != null) { + // Check if the browser is supported; we'll activate Chrome Frame + // silently if available. + WebBrowser b = request.getBrowserDetails().getWebBrowser(); + if (b.isTooOldToFunctionProperly() && !b.isChromeFrameCapable()) { + // bypass if cookie set + String c = request.getHeader("Cookie"); + if (c == null || !c.contains(FORCE_LOAD_COOKIE)) { + writeBrowserTooOldPage(request, response); + return true; + } + + } + } + // TODO Should all urls be handled here? int rootId; try { @@ -137,6 +155,45 @@ public abstract class AjaxPageHandler implements RequestHandler { return true; } + /** + * Writes a page encouraging the user to upgrade to a more current browser. + * + * @param request + * @param response + * @throws IOException + */ + protected void writeBrowserTooOldPage(WrappedRequest request, + WrappedResponse response) throws IOException { + Writer page = response.getWriter(); + WebBrowser b = request.getBrowserDetails().getWebBrowser(); + + page.write("

I'm sorry, but your browser is not supported

" + + "

The version (" + + b.getBrowserMajorVersion() + + "." + + b.getBrowserMinorVersion() + + ") of the browser you are using " + + " is outdated and not supported.

" + + "

You should consider upgrading to a more up-to-date browser.

" + + "

The most popular browsers are " + + " Chrome," + + " Firefox," + + (b.isWindows() ? " Internet Explorer," + : "") + + " Opera" + + " and Safari.
" + + "Upgrading to the latest version of one of these will make the web safer, faster and better looking.

" + + (b.isIE() ? "" + + "

If you can not upgrade your browser, please consider trying Chrome Frame.

" + : "") // + + "

Continue without updating (not recommended)

" + + "\n" + ""); + + page.close(); + } + protected final void writeAjaxPage(WrappedRequest request, WrappedResponse response, Application application, int rootId) throws IOException, JSONException { diff --git a/src/com/vaadin/terminal/gwt/server/WebBrowser.java b/src/com/vaadin/terminal/gwt/server/WebBrowser.java index 0a743fcf96..3d9540adad 100644 --- a/src/com/vaadin/terminal/gwt/server/WebBrowser.java +++ b/src/com/vaadin/terminal/gwt/server/WebBrowser.java @@ -183,6 +183,34 @@ public class WebBrowser implements Terminal { return browserDetails.isChrome(); } + /** + * Tests whether the user is using Chrome Frame. + * + * @return true if the user is using Chrome Frame, false if the user is not + * using Chrome or if no information on the browser is present + */ + public boolean isChromeFrame() { + if (browserDetails == null) { + return false; + } + + return browserDetails.isChromeFrame(); + } + + /** + * Tests whether the user's browser is Chrome Frame capable. + * + * @return true if the user can use Chrome Frame, false if the user can not + * or if no information on the browser is present + */ + public boolean isChromeFrameCapable() { + if (browserDetails == null) { + return false; + } + + return browserDetails.isChromeFrameCapable(); + } + /** * Gets the major version of the browser the user is using. * diff --git a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java b/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java index 88ba0499a1..5998f905c1 100644 --- a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java +++ b/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java @@ -11,6 +11,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import com.vaadin.Application; import com.vaadin.terminal.CombinedRequest; import com.vaadin.terminal.DeploymentConfiguration; import com.vaadin.terminal.WrappedRequest; @@ -102,8 +103,21 @@ public class WrappedHttpServletRequest implements WrappedRequest { } public BrowserDetails getBrowserDetails() { - // No browserDetails available for normal requests - return null; + return new BrowserDetails() { + public String getUriFragment() { + return null; + } + + public String getWindowName() { + return null; + } + + public WebBrowser getWebBrowser() { + WebApplicationContext context = (WebApplicationContext) Application + .getCurrentApplication().getContext(); + return context.getBrowser(); + } + }; } public Locale getLocale() { -- 2.39.5