blob: e643ebfb50eeeaf136a0ff98c2434b9a69dafeeb [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package elemental.js;
import com.google.gwt.core.client.GWT;
import elemental.client.Browser;
import elemental.html.Navigator;
import elemental.js.dom.JsDocument;
import elemental.js.html.JsWindow;
/**
* JavaScript native implementation of {@link elemental.client.Browser}.
*/
@Deprecated
public class JsBrowser {
/**
* A {@link Browser.Info} implementation for when the browser is known to be
* Gecko at compile time.
*/
@SuppressWarnings("unused")
private static class InfoWhenKnownGecko extends InfoWhenUnknown {
@Override
public boolean isGecko() {
return true;
}
@Override
public boolean isSupported() {
return true;
}
@Override
public boolean isWebKit() {
return false;
}
}
/**
* A {@link Browser.Info} implementation for when the browser is known to be
* Unsupported at compile time.
*/
@SuppressWarnings("unused")
private static class InfoWhenKnownUnsupported extends InfoWhenUnknown {
@Override
public boolean isGecko() {
return false;
}
@Override
public boolean isSupported() {
return false;
}
@Override
public boolean isWebKit() {
return false;
}
}
/**
* A {@link Browser.Info} implementation for when the browser is known to be
* WebKit at compile time.
*/
@Deprecated
@SuppressWarnings("unused")
private static class InfoWhenKnownWebKit extends InfoWhenUnknown {
@Override
public boolean isGecko() {
return false;
}
@Override
public boolean isSupported() {
return true;
}
@Override
public boolean isWebKit() {
return true;
}
}
/**
* A {@link Browser.Info} implementation for when the browser is not known
* until runtime.
*
* <p>
* Careful Captain! All those static fields are intentional. In order to
* ensure good dead stripping of the entire InfoWhen class hierarchy, the
* instance returned by {@link JsBrowser#getInfo()} must not be aliased, so it
* instead returns a fly-weight instance referencing static fields.
* </p>
*/
private static class InfoWhenUnknown implements Browser.Info {
private native static double getGeckoVersion(String userAgent) /*-{
var r = / rv\:(\d+\.\d+)/.exec(userAgent);
return r ? parseFloat(r[1]) : 0.0;
}-*/;
private native static String getProduct(Navigator nav) /*-{
return nav.product;
}-*/;
private native static double getWebKitVersion(String userAgent) /*-{
var r = /WebKit\/(\d+\.\d+)/.exec(userAgent);
return r ? parseFloat(r[1]) : 0.0;
}-*/;
private static boolean browserDetected;
private static boolean platformDetected;
private static boolean isWebKit;
private static boolean isGecko;
private static boolean isMac;
private static boolean isWindows;
private static boolean isLinux;
private void ensurePlatformDetected() {
if (!platformDetected) {
platformDetected = true;
final String userAgent = getWindow().getNavigator().getUserAgent();
isWindows = userAgent.indexOf("Win") >= 0;
if (isWindows) {
return;
}
isMac = userAgent.indexOf("Mac") >= 0;
if (isMac) {
return;
}
isLinux = userAgent.indexOf("Linux") >= 0;
}
}
private void ensureBrowserDetected() {
if (!browserDetected) {
browserDetected = true;
final Navigator nav = getWindow().getNavigator();
final String ua = nav.getUserAgent();
boolean isWebKitBased = ua.indexOf("WebKit") >= 0;
if (isWebKitBased) {
isWebKit = getWebKitVersion(ua) >= SUPPORTED_WEBKIT_VERSION;
return;
}
assert !isWebKitBased;
isGecko = getProduct(nav).equals("Gecko") && getGeckoVersion(ua) >= SUPPORTED_GECKO_VERSION;
}
}
@Override
public boolean isGecko() {
ensureBrowserDetected();
return isGecko;
}
@Override
public boolean isSupported() {
ensureBrowserDetected();
return isGecko || isWebKit;
}
@Override
public boolean isWebKit() {
ensureBrowserDetected();
return isWebKit;
}
@Override
public boolean isLinux() {
ensurePlatformDetected();
return isLinux;
}
@Override
public boolean isMac() {
ensurePlatformDetected();
return isMac;
}
public boolean isWindows() {
ensurePlatformDetected();
return isWindows;
}
}
/**
* The minimum version of WebKit that is supported.
*
* This equates to >= Safari 5.0.2
*/
private static final double SUPPORTED_WEBKIT_VERSION = 533.18;
/**
* The minimum version of Gecko that is supported.
*
* This equates to >= Firefox 4.0
*/
private static final double SUPPORTED_GECKO_VERSION = 2.0;
/**
* Gets the document within which this script is running.
*/
public static native JsDocument getDocument() /*-{
return $doc;
}-*/;
public static Browser.Info getInfo() {
return GWT.create(InfoWhenUnknown.class);
}
/**
* Gets the window within which this script is running.
*/
public static native JsWindow getWindow() /*-{
return $wnd;
}-*/;
// Non-instantiable.
private JsBrowser() {
}
}