svn changeset:18000/svn branch:6.6tags/6.7.0.beta1
@@ -191,30 +191,31 @@ public class ApplicationConnection { | |||
private native void initializeTestbenchHooks( | |||
ComponentLocator componentLocator, String TTAppId) | |||
/*-{ | |||
var ap = this; | |||
var client = {}; | |||
client.isActive = function() { | |||
return ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::hasActiveRequest()() || ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::isExecutingDeferredCommands()(); | |||
} | |||
var vi = ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::getVersionInfo()(); | |||
if (vi) { | |||
client.getVersionInfo = function() { | |||
return vi; | |||
} | |||
} | |||
client.getElementByPath = function(id) { | |||
return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); | |||
} | |||
client.getPathForElement = function(element) { | |||
return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element); | |||
} | |||
if(!$wnd.vaadin.clients) { | |||
$wnd.vaadin.clients = {}; | |||
} | |||
$wnd.vaadin.clients[TTAppId] = client; | |||
var ap = this; | |||
var client = {}; | |||
client.isActive = function() { | |||
return ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::hasActiveRequest()() | |||
|| ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::isExecutingDeferredCommands()(); | |||
} | |||
var vi = ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::getVersionInfo()(); | |||
if (vi) { | |||
client.getVersionInfo = function() { | |||
return vi; | |||
} | |||
} | |||
client.getElementByPath = function(id) { | |||
return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); | |||
} | |||
client.getPathForElement = function(element) { | |||
return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element); | |||
} | |||
if (!$wnd.vaadin.clients) { | |||
$wnd.vaadin.clients = {}; | |||
} | |||
$wnd.vaadin.clients[TTAppId] = client; | |||
}-*/; | |||
/** | |||
@@ -249,27 +250,27 @@ public class ApplicationConnection { | |||
*/ | |||
private native void initializeClientHooks() | |||
/*-{ | |||
var app = this; | |||
var oldSync; | |||
if($wnd.vaadin.forceSync) { | |||
oldSync = $wnd.vaadin.forceSync; | |||
} | |||
$wnd.vaadin.forceSync = function() { | |||
if(oldSync) { | |||
oldSync(); | |||
} | |||
app.@com.vaadin.terminal.gwt.client.ApplicationConnection::sendPendingVariableChanges()(); | |||
} | |||
var oldForceLayout; | |||
if($wnd.vaadin.forceLayout) { | |||
oldForceLayout = $wnd.vaadin.forceLayout; | |||
} | |||
$wnd.vaadin.forceLayout = function() { | |||
if(oldForceLayout) { | |||
oldForceLayout(); | |||
} | |||
app.@com.vaadin.terminal.gwt.client.ApplicationConnection::forceLayout()(); | |||
} | |||
var app = this; | |||
var oldSync; | |||
if ($wnd.vaadin.forceSync) { | |||
oldSync = $wnd.vaadin.forceSync; | |||
} | |||
$wnd.vaadin.forceSync = function() { | |||
if (oldSync) { | |||
oldSync(); | |||
} | |||
app.@com.vaadin.terminal.gwt.client.ApplicationConnection::sendPendingVariableChanges()(); | |||
} | |||
var oldForceLayout; | |||
if ($wnd.vaadin.forceLayout) { | |||
oldForceLayout = $wnd.vaadin.forceLayout; | |||
} | |||
$wnd.vaadin.forceLayout = function() { | |||
if (oldForceLayout) { | |||
oldForceLayout(); | |||
} | |||
app.@com.vaadin.terminal.gwt.client.ApplicationConnection::forceLayout()(); | |||
} | |||
}-*/; | |||
/** | |||
@@ -280,15 +281,16 @@ public class ApplicationConnection { | |||
*/ | |||
private static native void runPostRequestHooks(String appId) | |||
/*-{ | |||
if($wnd.vaadin.postRequestHooks) { | |||
for(var hook in $wnd.vaadin.postRequestHooks) { | |||
if(typeof($wnd.vaadin.postRequestHooks[hook]) == "function") { | |||
try { | |||
$wnd.vaadin.postRequestHooks[hook](appId); | |||
} catch(e) {} | |||
} | |||
} | |||
} | |||
if ($wnd.vaadin.postRequestHooks) { | |||
for ( var hook in $wnd.vaadin.postRequestHooks) { | |||
if (typeof ($wnd.vaadin.postRequestHooks[hook]) == "function") { | |||
try { | |||
$wnd.vaadin.postRequestHooks[hook](appId); | |||
} catch (e) { | |||
} | |||
} | |||
} | |||
} | |||
}-*/; | |||
/** | |||
@@ -348,6 +350,8 @@ public class ApplicationConnection { | |||
int offsetWidth = pe.getOffsetWidth(); | |||
int screenWidth = BrowserInfo.get().getScreenWidth(); | |||
int screenHeight = BrowserInfo.get().getScreenHeight(); | |||
int tzOffset = BrowserInfo.get().getTimezoneOffset(); | |||
int rtzOffset = BrowserInfo.get().getRawTimezoneOffset(); | |||
String token = History.getToken(); | |||
@@ -356,7 +360,8 @@ public class ApplicationConnection { | |||
// values currently only via transaction listener. | |||
String parameters = "repaintAll=1&" + "sh=" + screenHeight + "&sw=" | |||
+ screenWidth + "&cw=" + clientWidth + "&ch=" + clientHeight | |||
+ "&vw=" + offsetWidth + "&vh=" + offsetHeight + "&fr=" + token; | |||
+ "&vw=" + offsetWidth + "&vh=" + offsetHeight + "&fr=" + token | |||
+ "&tzo=" + tzOffset + "&rtzo=" + rtzOffset; | |||
return parameters; | |||
} | |||
@@ -771,11 +776,11 @@ public class ApplicationConnection { | |||
private static native ValueMap parseJSONResponse(String jsonText) | |||
/*-{ | |||
try { | |||
return JSON.parse(jsonText); | |||
} catch(ignored) { | |||
return eval('(' + jsonText + ')'); | |||
} | |||
try { | |||
return JSON.parse(jsonText); | |||
} catch (ignored) { | |||
return eval('(' + jsonText + ')'); | |||
} | |||
}-*/; | |||
private void handleReceivedJSONMessage(Date start, String jsonText, | |||
@@ -1023,11 +1028,11 @@ public class ApplicationConnection { | |||
// Redirect browser, null reloads current page | |||
private static native void redirect(String url) | |||
/*-{ | |||
if (url) { | |||
$wnd.location = url; | |||
} else { | |||
$wnd.location.reload(false); | |||
} | |||
if (url) { | |||
$wnd.location = url; | |||
} else { | |||
$wnd.location.reload(false); | |||
} | |||
}-*/; | |||
public void registerPaintable(String pid, Paintable paintable) { | |||
@@ -1039,7 +1044,7 @@ public class ApplicationConnection { | |||
private native void setPid(Element el, String pid) | |||
/*-{ | |||
el.tkPid = pid; | |||
el.tkPid = pid; | |||
}-*/; | |||
/** | |||
@@ -1069,7 +1074,7 @@ public class ApplicationConnection { | |||
*/ | |||
public native String getPid(Element el) | |||
/*-{ | |||
return el.tkPid; | |||
return el.tkPid; | |||
}-*/; | |||
/** |
@@ -65,10 +65,10 @@ public class BrowserInfo { | |||
private native boolean isIE8InIE7CompatibilityMode() | |||
/*-{ | |||
var mode = $wnd.document.documentMode; | |||
if (!mode) | |||
return false; | |||
return (mode == 7); | |||
var mode = $wnd.document.documentMode; | |||
if (!mode) | |||
return false; | |||
return (mode == 7); | |||
}-*/; | |||
/** | |||
@@ -282,17 +282,53 @@ public class BrowserInfo { | |||
public native static String getBrowserString() | |||
/*-{ | |||
return $wnd.navigator.userAgent; | |||
return $wnd.navigator.userAgent; | |||
}-*/; | |||
public native int getScreenWidth() | |||
/*-{ | |||
return $wnd.screen.width; | |||
/*-{ | |||
return $wnd.screen.width; | |||
}-*/; | |||
public native int getScreenHeight() | |||
/*-{ | |||
return $wnd.screen.height; | |||
/*-{ | |||
return $wnd.screen.height; | |||
}-*/; | |||
/** | |||
* Get's the timezone offset from GMT in minutes, as reported by the | |||
* browser. DST affects this value. | |||
* | |||
* @return offset to GMT in minutes | |||
*/ | |||
public native int getTimezoneOffset() | |||
/*-{ | |||
return new Date().getTimezoneOffset(); | |||
}-*/; | |||
/** | |||
* Get's the timezone offset from GMT in minutes, as reported by the browser | |||
* AND adjusted to ignore daylight savings time. DST does not affect this | |||
* value. | |||
* | |||
* @return offset to GMT in minutes | |||
*/ | |||
public native int getRawTimezoneOffset() | |||
/*-{ | |||
var d = new Date(); | |||
var tzo1 = d.getTimezoneOffset(); // current offset | |||
for (var m=12;m>0;m--) { | |||
d.setUTCMonth(m); | |||
var tzo2 = d.getTimezoneOffset(); | |||
if (tzo1 != tzo2) { | |||
// NOTE js indicates this 'backwards' (e.g -180) | |||
return (tzo1 > tzo2 ? tzo1 : tzo2); // offset w/o DST | |||
} | |||
} | |||
return tzo1; // no DST | |||
}-*/; | |||
} |
@@ -545,7 +545,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet | |||
browser.updateBrowserProperties(request.getLocale(), null, | |||
request.isSecure(), userAgent, | |||
getHTTPRequestParameter(request, "sw"), | |||
getHTTPRequestParameter(request, "sh")); | |||
getHTTPRequestParameter(request, "sh"), | |||
getHTTPRequestParameter(request, "tzo"), | |||
getHTTPRequestParameter(request, "rtzo")); | |||
} | |||
@Override |
@@ -574,7 +574,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements | |||
browser.updateBrowserProperties(request.getLocale(), | |||
request.getRemoteAddr(), request.isSecure(), | |||
request.getHeader("user-agent"), request.getParameter("sw"), | |||
request.getParameter("sh")); | |||
request.getParameter("sh"), request.getParameter("tzo"),request.getParameter("rtzo")); | |||
} | |||
protected ClassLoader getClassLoader() throws ServletException { |
@@ -25,6 +25,8 @@ public class WebBrowser implements Terminal { | |||
private Locale locale; | |||
private String address; | |||
private boolean secureConnection; | |||
private int timezoneOffset = 0; | |||
private int rawTimezoneOffset = 0; | |||
private VBrowserDetails browserDetails; | |||
@@ -81,9 +83,14 @@ public class WebBrowser implements Terminal { | |||
* Screen width | |||
* @param sh | |||
* Screen height | |||
* @param tzo | |||
* TimeZone offset in minutes from GMT | |||
* @param rtzo | |||
* raw TimeZone offset in minutes from GMT (w/o DST adjustment) | |||
*/ | |||
void updateBrowserProperties(Locale locale, String address, | |||
boolean secureConnection, String agent, String sw, String sh) { | |||
boolean secureConnection, String agent, String sw, String sh, | |||
String tzo, String rtzo) { | |||
this.locale = locale; | |||
this.address = address; | |||
this.secureConnection = secureConnection; | |||
@@ -100,6 +107,22 @@ public class WebBrowser implements Terminal { | |||
screenHeight = screenWidth = 0; | |||
} | |||
} | |||
if (tzo != null) { | |||
try { | |||
// browser->java conversion: min->ms, reverse sign | |||
timezoneOffset = -Integer.parseInt(tzo) * 60 * 1000; | |||
} catch (final NumberFormatException e) { | |||
timezoneOffset = 0; // default gmt+0 | |||
} | |||
} | |||
if (rtzo != null) { | |||
try { | |||
// browser->java conversion: min->ms, reverse sign | |||
rawTimezoneOffset = -Integer.parseInt(rtzo) * 60 * 1000; | |||
} catch (final NumberFormatException e) { | |||
rawTimezoneOffset = 0; // default gmt+0 | |||
} | |||
} | |||
} | |||
/** | |||
@@ -256,4 +279,38 @@ public class WebBrowser implements Terminal { | |||
return browserDetails.isWindows(); | |||
} | |||
/** | |||
* Returns the browser-reported TimeZone offset in milliseconds from GMT. | |||
* This includes possible daylight saving adjustments, to figure out which | |||
* TimeZone the user actually might be in, see | |||
* {@link #getRawTimezoneOffset()}. | |||
* | |||
* @see WebBrowser#getRawTimezoneOffset() | |||
* @return timezone offset in milliseconds, 0 if not available | |||
*/ | |||
public Integer getTimezoneOffset() { | |||
return timezoneOffset; | |||
} | |||
/** | |||
* Returns the browser-reported TimeZone offset in milliseconds from GMT | |||
* ignoring possible daylight saving adjustments that may be in effect in | |||
* the browser. | |||
* <p> | |||
* You can use this to figure out which TimeZones the user could actually be | |||
* in by calling {@link TimeZone#getAvailableIDs(int)}. | |||
* </p> | |||
* <p> | |||
* If {@link #getRawTimezoneOffset()} and {@link #getTimezoneOffset()} | |||
* returns the same value, the browser is either in a zone that does not | |||
* currently have daylight saving time, or in a zone that never has daylight | |||
* saving time. | |||
* </p> | |||
* | |||
* @return timezone offset in milliseconds excluding DST, 0 if not available | |||
*/ | |||
public Integer getRawTimezoneOffset() { | |||
return rawTimezoneOffset; | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<link rel="selenium.base" href="" /> | |||
<title>New Test</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">New Test</td></tr> | |||
</thead><tbody> | |||
<tr> | |||
<td>open</td> | |||
<td>/run/com.vaadin.tests.application.WebBrowserTest?restartApplication</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td> | |||
<td>7200000</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VLabel[0]</td> | |||
<td>0</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> | |||
<td>Yes</td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,78 @@ | |||
package com.vaadin.tests.application; | |||
import java.util.Arrays; | |||
import java.util.Calendar; | |||
import java.util.Date; | |||
import java.util.TimeZone; | |||
import com.vaadin.tests.components.TestBase; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.Label; | |||
public class WebBrowserTest extends TestBase { | |||
@Override | |||
protected void setup() { | |||
final Label offsetLabel = new Label("n/a"); | |||
offsetLabel.setCaption("Browser offset"); | |||
final Label rawOffsetLabel = new Label("n/a"); | |||
rawOffsetLabel.setCaption("Browser raw offset"); | |||
final Label diffLabel = new Label("n/a"); | |||
diffLabel.setCaption("Browser/server offset difference"); | |||
final Label containsLabel = new Label("n/a"); | |||
containsLabel.setCaption("Browser TimeZones include server TimeZone"); | |||
final Button update = new Button("Get TimeZone from browser", | |||
new Button.ClickListener() { | |||
public void buttonClick(ClickEvent event) { | |||
TimeZone serverTZ = Calendar.getInstance() | |||
.getTimeZone(); | |||
int serverOffset = serverTZ.getOffset(new Date() | |||
.getTime()); | |||
int browserOffset = getBrowser().getTimezoneOffset(); | |||
int browserRawOffset = getBrowser() | |||
.getRawTimezoneOffset(); | |||
String[] tzs = TimeZone | |||
.getAvailableIDs(browserRawOffset); | |||
boolean contains = Arrays.asList(tzs).contains( | |||
serverTZ.getID()); | |||
offsetLabel.setValue(String.valueOf(browserOffset)); | |||
rawOffsetLabel.setValue(String | |||
.valueOf(browserRawOffset)); | |||
diffLabel.setValue(String.valueOf(browserOffset | |||
- serverOffset)); | |||
containsLabel.setValue(contains ? "Yes" : "No"); | |||
} | |||
}); | |||
addComponent(update); | |||
addComponent(offsetLabel); | |||
addComponent(rawOffsetLabel); | |||
addComponent(diffLabel); | |||
addComponent(containsLabel); | |||
} | |||
@Override | |||
protected String getDescription() { | |||
return "Verifies that browser TimeZone offset works - should be same as server in our case (NOTE assumes server+browser in same TZ)"; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 6691; | |||
} | |||
} |