summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/terminal
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/vaadin/terminal')
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java10
-rw-r--r--src/com/vaadin/terminal/gwt/client/BrowserInfo.java64
-rw-r--r--src/com/vaadin/terminal/gwt/client/CSSRule.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ComponentDetailMap.java1
-rw-r--r--src/com/vaadin/terminal/gwt/client/ComputedStyle.java1
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java13
-rw-r--r--src/com/vaadin/terminal/gwt/client/VBrowserDetails.java127
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/button/ButtonState.java30
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/button/VButton.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/datefield/VDateFieldCalendar.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/nativebutton/NativeButtonConnector.java6
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java1
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java13
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java13
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java15
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java30
-rw-r--r--src/com/vaadin/terminal/gwt/server/RequestTimer.java55
22 files changed, 332 insertions, 92 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index be6d578112..739c232a72 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -272,7 +272,7 @@ public class ApplicationConnection {
ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::lastProcessingTime,
ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::totalProcessingTime
];
- pd = pd.concat(ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::testBenchServerStatus);
+ pd = pd.concat(ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::serverTimingInfo);
return pd;
});
@@ -698,7 +698,7 @@ public class ApplicationConnection {
* servicing the session so far. These values are always one request behind,
* since they cannot be measured before the request is finished.
*/
- private ValueMap testBenchServerStatus;
+ private ValueMap serverTimingInfo;
static final int MAX_CSS_WAITS = 100;
@@ -1037,10 +1037,10 @@ public class ApplicationConnection {
handleUIDLDuration.logDuration(
" * Handling type mappings from server completed", 10);
/*
- * Hook for TestBench to get details about server status
+ * Hook for e.g. TestBench to get details about server peformance
*/
- if (json.containsKey("tbss")) {
- testBenchServerStatus = json.getValueMap("tbss");
+ if (json.containsKey("timings")) {
+ serverTimingInfo = json.getValueMap("timings");
}
Command c = new Command() {
diff --git a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
index ef1dc481b1..064f175301 100644
--- a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
+++ b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
@@ -28,6 +28,8 @@ public class BrowserInfo {
private static final String OS_WINDOWS = "win";
private static final String OS_LINUX = "lin";
private static final String OS_MACOSX = "mac";
+ private static final String OS_ANDROID = "android";
+ private static final String OS_IOS = "ios";
private static BrowserInfo instance;
@@ -167,13 +169,18 @@ public class BrowserInfo {
if (osClass != null) {
cssClass = cssClass + " " + prefix + osClass;
}
+
}
return cssClass;
}
private String getOperatingSystemClass() {
- if (browserDetails.isWindows()) {
+ if (browserDetails.isAndroid()) {
+ return OS_ANDROID;
+ } else if (browserDetails.isIOS()) {
+ return OS_IOS;
+ } else if (browserDetails.isWindows()) {
return OS_WINDOWS;
} else if (browserDetails.isLinux()) {
return OS_LINUX;
@@ -312,4 +319,59 @@ public class BrowserInfo {
&& Util.getNativeScrollbarSize() > 0;
}
+ /**
+ * Checks if the browser is run on iOS
+ *
+ * @return true if the browser is run on iOS, false otherwise
+ */
+ public boolean isIOS() {
+ return browserDetails.isIOS();
+ }
+
+ /**
+ * Checks if the browser is run on Android
+ *
+ * @return true if the browser is run on Android, false otherwise
+ */
+ public boolean isAndroid() {
+ return browserDetails.isAndroid();
+ }
+
+ /**
+ * Checks if the browser is capable of handling scrolling natively or if a
+ * touch scroll helper is needed for scrolling.
+ *
+ * @return true if browser needs a touch scroll helper, false if the browser
+ * can handle scrolling natively
+ */
+ public boolean requiresTouchScrollDelegate() {
+ if (!isTouchDevice()) {
+ return false;
+ }
+
+ if (isAndroid() && isWebkit() && getWebkitVersion() < 534) {
+ return true;
+ }
+ // if (isIOS() && isWebkit() && getWebkitVersion() < ???) {
+ // return true;
+ // }
+
+ return false;
+ }
+
+ /**
+ * Tests if this is an Android devices with a broken scrollTop
+ * implementation
+ *
+ * @return true if scrollTop cannot be trusted on this device, false
+ * otherwise
+ */
+ public boolean isAndroidWithBrokenScrollTop() {
+ return isAndroid()
+ && (getOperatingSystemMajorVersion() == 3 || getOperatingSystemMajorVersion() == 4);
+ }
+
+ private int getOperatingSystemMajorVersion() {
+ return browserDetails.getOperatingSystemMajorVersion();
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/CSSRule.java b/src/com/vaadin/terminal/gwt/client/CSSRule.java
index 4d9196c8d6..c36b0611e8 100644
--- a/src/com/vaadin/terminal/gwt/client/CSSRule.java
+++ b/src/com/vaadin/terminal/gwt/client/CSSRule.java
@@ -33,6 +33,7 @@ public class CSSRule {
for(var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
if(sheet.href && sheet.href.indexOf("VAADIN/themes")>-1) {
+ // $entry not needed as function is not exported
this.@com.vaadin.terminal.gwt.client.CSSRule::rules = @com.vaadin.terminal.gwt.client.CSSRule::searchForRule(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Z)(sheet, selector, deep);
return;
}
@@ -58,6 +59,7 @@ public class CSSRule {
// IE handles imported sheet differently
if(deep && sheet.imports && sheet.imports.length > 0) {
for(var i=0; i < sheet.imports.length; i++) {
+ // $entry not needed as function is not exported
var imports = @com.vaadin.terminal.gwt.client.CSSRule::searchForRule(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Z)(sheet.imports[i], selector, deep);
allMatches.concat(imports);
}
@@ -83,6 +85,7 @@ public class CSSRule {
}
} else if(deep && r.type == 3) {
// Search @import stylesheet
+ // $entry not needed as function is not exported
var imports = @com.vaadin.terminal.gwt.client.CSSRule::searchForRule(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Z)(r.styleSheet, selector, deep);
allMatches = allMatches.concat(imports);
}
@@ -102,6 +105,7 @@ public class CSSRule {
/*-{
var j = this.@com.vaadin.terminal.gwt.client.CSSRule::rules.length;
for(var i=0; i<j; i++) {
+ // $entry not needed as function is not exported
var value = this.@com.vaadin.terminal.gwt.client.CSSRule::rules[i].style[propertyName];
if(value)
return value;
diff --git a/src/com/vaadin/terminal/gwt/client/ComponentDetailMap.java b/src/com/vaadin/terminal/gwt/client/ComponentDetailMap.java
index 3405d838a7..dfbcf9d38b 100644
--- a/src/com/vaadin/terminal/gwt/client/ComponentDetailMap.java
+++ b/src/com/vaadin/terminal/gwt/client/ComponentDetailMap.java
@@ -62,6 +62,7 @@ final class ComponentDetailMap extends JavaScriptObject {
private final native void fillWithValues(Collection<ComponentDetail> list)
/*-{
for(var key in this) {
+ // $entry not needed as function is not exported
list.@java.util.Collection::add(Ljava/lang/Object;)(this[key]);
}
}-*/;
diff --git a/src/com/vaadin/terminal/gwt/client/ComputedStyle.java b/src/com/vaadin/terminal/gwt/client/ComputedStyle.java
index bedb217c63..29b02b4dde 100644
--- a/src/com/vaadin/terminal/gwt/client/ComputedStyle.java
+++ b/src/com/vaadin/terminal/gwt/client/ComputedStyle.java
@@ -179,6 +179,7 @@ public class ComputedStyle {
if (isNaN(number))
return null;
else
+ // $entry not needed as function is not exported
return @java.lang.Integer::valueOf(I)(number);
}-*/;
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index bfe63caefd..c392a0ba9c 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -978,6 +978,19 @@ public class Util {
*/
final Element target = getElementFromPoint(touch.getClientX(),
touch.getClientY());
+
+ /*
+ * Fixes infocusable form fields in Safari of iOS 5.x and some Android
+ * browsers.
+ */
+ Widget targetWidget = findWidget(target, null);
+ if (targetWidget instanceof com.google.gwt.user.client.ui.Focusable) {
+ final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) targetWidget;
+ toBeFocusedWidget.setFocus(true);
+ } else if (targetWidget instanceof Focusable) {
+ ((Focusable) targetWidget).focus();
+ }
+
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
try {
diff --git a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
index 89e106f063..6e0417149c 100644
--- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
+++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java
@@ -31,14 +31,19 @@ public class VBrowserDetails implements Serializable {
private boolean isOpera = false;
private boolean isIE = false;
- private boolean isWindows = false;
- private boolean isMacOSX = false;
- private boolean isLinux = false;
+ private OperatingSystem os = OperatingSystem.UNKNOWN;
+
+ public enum OperatingSystem {
+ UNKNOWN, WINDOWS, MACOSX, LINUX, IOS, ANDROID;
+ }
private float browserEngineVersion = -1;
private int browserMajorVersion = -1;
private int browserMinorVersion = -1;
+ private int osMajorVersion = -1;
+ private int osMinorVersion = -1;
+
/**
* Create an instance based on the given user agent.
*
@@ -122,14 +127,80 @@ public class VBrowserDetails implements Serializable {
// Operating system
if (userAgent.contains("windows ")) {
- isWindows = true;
+ os = OperatingSystem.WINDOWS;
} else if (userAgent.contains("linux")) {
- isLinux = true;
+ if (userAgent.contains("android")) {
+ os = OperatingSystem.ANDROID;
+ parseAndroidVersion(userAgent);
+ } else {
+ os = OperatingSystem.LINUX;
+
+ }
} else if (userAgent.contains("macintosh")
|| userAgent.contains("mac osx")
|| userAgent.contains("mac os x")) {
- isMacOSX = true;
+ if (userAgent.contains("ipad") || userAgent.contains("ipod")
+ || userAgent.contains("iphone")) {
+ os = OperatingSystem.IOS;
+ parseIOSVersion(userAgent);
+ } else {
+ os = OperatingSystem.MACOSX;
+ }
+ }
+ }
+
+ private void parseAndroidVersion(String userAgent) {
+ // Android 5.1;
+ if (!userAgent.contains("android")) {
+ return;
+ }
+
+ String osVersionString = safeSubstring(userAgent,
+ userAgent.indexOf("android ") + "android ".length(),
+ userAgent.length());
+ osVersionString = safeSubstring(osVersionString, 0,
+ osVersionString.indexOf(";"));
+ String[] parts = osVersionString.split("\\.");
+ parseOsVersion(parts);
+ }
+
+ private void parseIOSVersion(String userAgent) {
+ // OS 5_1 like Mac OS X
+ if (!userAgent.contains("os ") || !userAgent.contains(" like mac")) {
+ return;
+ }
+
+ String osVersionString = safeSubstring(userAgent,
+ userAgent.indexOf("os ") + 3, userAgent.indexOf(" like mac"));
+ String[] parts = osVersionString.split("_");
+ parseOsVersion(parts);
+ }
+
+ private void parseOsVersion(String[] parts) {
+ osMajorVersion = -1;
+ osMinorVersion = -1;
+
+ if (parts.length >= 1) {
+ try {
+ osMajorVersion = Integer.parseInt(parts[0]);
+ } catch (Exception e) {
+ }
+ }
+ if (parts.length >= 2) {
+ try {
+ osMinorVersion = Integer.parseInt(parts[1]);
+ } catch (Exception e) {
+ }
+ // Some Androids report version numbers as "2.1-update1"
+ if (osMinorVersion == -1 && parts[1].contains("-")) {
+ try {
+ osMinorVersion = Integer.parseInt(parts[1].substring(0,
+ parts[1].indexOf('-')));
+ } catch (Exception ee) {
+ }
+ }
}
+
}
private void parseVersionString(String versionString) {
@@ -306,7 +377,7 @@ public class VBrowserDetails implements Serializable {
* @return true if run on Windows, false otherwise
*/
public boolean isWindows() {
- return isWindows;
+ return os == OperatingSystem.WINDOWS;
}
/**
@@ -315,7 +386,7 @@ public class VBrowserDetails implements Serializable {
* @return true if run on Mac OSX, false otherwise
*/
public boolean isMacOSX() {
- return isMacOSX;
+ return os == OperatingSystem.MACOSX;
}
/**
@@ -324,7 +395,45 @@ public class VBrowserDetails implements Serializable {
* @return true if run on Linux, false otherwise
*/
public boolean isLinux() {
- return isLinux;
+ return os == OperatingSystem.LINUX;
+ }
+
+ /**
+ * Tests if the browser is run on Android.
+ *
+ * @return true if run on Android, false otherwise
+ */
+ public boolean isAndroid() {
+ return os == OperatingSystem.ANDROID;
+ }
+
+ /**
+ * Tests if the browser is run in iOS.
+ *
+ * @return true if run in iOS, false otherwise
+ */
+ public boolean isIOS() {
+ return os == OperatingSystem.IOS;
+ }
+
+ /**
+ * Returns the major version of the operating system. Currently only
+ * supported for mobile devices (iOS/Android)
+ *
+ * @return The major version or -1 if unknown
+ */
+ public int getOperatingSystemMajorVersion() {
+ return osMajorVersion;
+ }
+
+ /**
+ * Returns the minor version of the operating system. Currently only
+ * supported for mobile devices (iOS/Android)
+ *
+ * @return The minor version or -1 if unknown
+ */
+ public int getOperatingSystemMinorVersion() {
+ return osMinorVersion;
}
/**
diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java
index 533d6a78ae..62697c4d98 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java
@@ -153,7 +153,7 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements
* the new vertical scroll position, in pixels
*/
public void setScrollPosition(int position) {
- if (isAndroidWithBrokenScrollTop()) {
+ if (BrowserInfo.get().isAndroidWithBrokenScrollTop()) {
ArrayList<com.google.gwt.dom.client.Element> elements = TouchScrollDelegate
.getElements(getElement());
for (com.google.gwt.dom.client.Element el : elements) {
@@ -167,11 +167,6 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements
}
}
- private boolean isAndroidWithBrokenScrollTop() {
- return BrowserInfo.getBrowserString().contains("Android 3")
- || BrowserInfo.getBrowserString().contains("Android 4");
- }
-
public void onScroll(ScrollEvent event) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java
index d4b59ed23a..8b2248aff6 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java
@@ -83,9 +83,8 @@ public class TouchScrollDelegate implements NativePreviewHandler {
private static TouchScrollDelegate activeScrollDelegate;
- private static final boolean androidWithBrokenScrollTop = BrowserInfo
- .getBrowserString().contains("Android 3")
- || BrowserInfo.getBrowserString().contains("Android 4");
+ private static final boolean androidWithBrokenScrollTop = BrowserInfo.get()
+ .isAndroidWithBrokenScrollTop();
public TouchScrollDelegate(Element... elements) {
scrollableElements = elements;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java b/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
index 62a5e8ac8b..a555ecd392 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
@@ -57,7 +57,11 @@ public class ButtonConnector extends AbstractComponentConnector implements
blurHandlerRegistration = EventHelper.updateBlurHandler(this,
blurHandlerRegistration);
// Set text
- getWidget().setText(getState().getCaption());
+ if (getState().isHtmlContentAllowed()) {
+ getWidget().setHtml(getState().getCaption());
+ } else {
+ getWidget().setText(getState().getCaption());
+ }
// handle error
if (null != getState().getErrorMessage()) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/button/ButtonState.java b/src/com/vaadin/terminal/gwt/client/ui/button/ButtonState.java
index f26cdae0c6..fdc053b3ae 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/button/ButtonState.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/button/ButtonState.java
@@ -17,6 +17,10 @@ import com.vaadin.ui.Button;
public class ButtonState extends ComponentState {
private boolean disableOnClick = false;
private int clickShortcutKeyCode = 0;
+ /**
+ * If caption should be rendered in HTML
+ */
+ private boolean htmlContentAllowed = false;
/**
* Checks whether the button should be disabled on the client side on next
@@ -62,4 +66,30 @@ public class ButtonState extends ComponentState {
this.clickShortcutKeyCode = clickShortcutKeyCode;
}
+ /**
+ * Set whether the caption text is rendered as HTML or not. You might need
+ * to retheme button to allow higher content than the original text style.
+ *
+ * If set to true, the captions are passed to the browser as html and the
+ * developer is responsible for ensuring no harmful html is used. If set to
+ * false, the content is passed to the browser as plain text.
+ *
+ * @param htmlContentAllowed
+ * <code>true</code> if caption is rendered as HTML,
+ * <code>false</code> otherwise
+ */
+ public void setHtmlContentAllowed(boolean htmlContentAllowed) {
+ this.htmlContentAllowed = htmlContentAllowed;
+ }
+
+ /**
+ * Return HTML rendering setting.
+ *
+ * @return <code>true</code> if the caption text is to be rendered as HTML,
+ * <code>false</code> otherwise
+ */
+ public boolean isHtmlContentAllowed() {
+ return htmlContentAllowed;
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
index f7d73d3b5e..e5e7dbba8b 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
@@ -98,6 +98,10 @@ public class VButton extends FocusWidget implements ClickHandler {
captionElement.setInnerText(text);
}
+ public void setHtml(String html) {
+ captionElement.setInnerHTML(html);
+ }
+
@SuppressWarnings("deprecation")
@Override
/*
diff --git a/src/com/vaadin/terminal/gwt/client/ui/datefield/VDateFieldCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/datefield/VDateFieldCalendar.java
index 21e0e0820d..84b3c678eb 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/datefield/VDateFieldCalendar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/datefield/VDateFieldCalendar.java
@@ -45,6 +45,13 @@ public class VDateFieldCalendar extends VDateField {
*/
@SuppressWarnings("deprecation")
protected void updateValueFromPanel() {
+
+ // If field is invisible at the beginning, client can still be null when
+ // this function is called.
+ if (getClient() == null) {
+ return;
+ }
+
Date date2 = calendarPanel.getDate();
Date currentDate = getCurrentDate();
if (currentDate == null || date2.getTime() != currentDate.getTime()) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/NativeButtonConnector.java b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/NativeButtonConnector.java
index 801c405826..84d3b73285 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/NativeButtonConnector.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/NativeButtonConnector.java
@@ -58,7 +58,11 @@ public class NativeButtonConnector extends AbstractComponentConnector implements
blurHandlerRegistration);
// Set text
- getWidget().setText(getState().getCaption());
+ if (getState().isHtmlContentAllowed()) {
+ getWidget().setHTML(getState().getCaption());
+ } else {
+ getWidget().setText(getState().getCaption());
+ }
// handle error
if (null != getState().getErrorMessage()) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java
index d0b8f73eb1..01ac4fab6a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java
@@ -65,6 +65,11 @@ public class VNativeButton extends Button implements ClickHandler {
}
@Override
+ public void setHTML(String html) {
+ captionElement.setInnerHTML(html);
+ }
+
+ @Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
diff --git a/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java b/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
index eb97160f52..0d222044ba 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
@@ -160,6 +160,13 @@ public class VNotification extends VOverlay {
}
super.show();
setPosition(position);
+ /**
+ * Android 4 fails to render notifications correctly without a little
+ * nudge (#8551)
+ */
+ if (BrowserInfo.get().isAndroid()) {
+ Util.setStyleTemporarily(getElement(), "display", "none");
+ }
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java b/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
index 13fc55d7ea..12a69d5556 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
@@ -306,6 +306,7 @@ public class VRoot extends SimplePanel implements ResizeHandler,
/*-{
var j;
for(j in $wnd.vaadin.vaadinConfigurations) {
+ // $entry not needed as function is not exported
list.@java.util.Collection::add(Ljava/lang/Object;)(j);
}
}-*/;
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
index 58d6a18592..77698805de 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
@@ -509,6 +509,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
protected void handleRequest(PortletRequest request,
PortletResponse response) throws PortletException, IOException {
+ RequestTimer requestTimer = new RequestTimer();
+ requestTimer.start();
+
AbstractApplicationPortletWrapper portletWrapper = new AbstractApplicationPortletWrapper(
this);
@@ -530,9 +533,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
WrappedPortletResponse wrappedResponse = new WrappedPortletResponse(
response, getDeploymentConfiguration());
- RequestTimer requestTimer = RequestTimer.get(wrappedRequest);
- requestTimer.start(wrappedRequest);
-
RequestType requestType = getRequestType(request);
if (requestType == RequestType.UNKNOWN) {
@@ -721,10 +721,11 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
} finally {
Root.setCurrentRoot(null);
Application.setCurrentApplication(null);
- }
- requestTimer.stop();
- RequestTimer.set(wrappedRequest, requestTimer);
+ requestTimer
+ .stop((AbstractWebApplicationContext) application
+ .getContext());
+ }
}
}
}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
index 799271b979..6ab2748332 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
@@ -400,12 +400,12 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
private void service(WrappedHttpServletRequest request,
WrappedHttpServletResponse response) throws ServletException,
IOException {
+ RequestTimer requestTimer = new RequestTimer();
+ requestTimer.start();
+
AbstractApplicationServletWrapper servletWrapper = new AbstractApplicationServletWrapper(
this);
- RequestTimer requestTimer = RequestTimer.get(request);
- requestTimer.start(request);
-
RequestType requestType = getRequestType(request);
if (!ensureCookiesEnabled(requestType, request, response)) {
return;
@@ -540,10 +540,11 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
} finally {
Root.setCurrentRoot(null);
Application.setCurrentApplication(null);
- }
- requestTimer.stop();
- RequestTimer.set(request, requestTimer);
+ requestTimer
+ .stop((AbstractWebApplicationContext) application
+ .getContext());
+ }
}
}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
index b780f66a23..c57e7d8bc1 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
@@ -1097,19 +1097,18 @@ public abstract class AbstractCommunicationManager implements Serializable {
dragAndDropService.printJSONResponse(outWriter);
}
- writePerformanceDataForTestBench(request, outWriter);
+ writePerformanceData(outWriter);
}
/**
- * Adds the performance timing data used by TestBench 3 to the UIDL
+ * Adds the performance timing data (used by TestBench 3) to the UIDL
* response.
*/
- private void writePerformanceDataForTestBench(final WrappedRequest request,
- final PrintWriter outWriter) {
- Long totalTime = (Long) request.getAttribute("TOTAL");
- Long lastRequestTime = (Long) request.getAttribute("LASTREQUEST");
- outWriter.write(String.format(", \"tbss\":[%d, %d]", totalTime,
- lastRequestTime));
+ private void writePerformanceData(final PrintWriter outWriter) {
+ AbstractWebApplicationContext ctx = (AbstractWebApplicationContext) application
+ .getContext();
+ outWriter.write(String.format(", \"timings\":[%d, %d]",
+ ctx.getTotalSessionTime(), ctx.getLastRequestTime()));
}
private void legacyPaint(PaintTarget paintTarget,
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java b/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java
index c8335a8607..c0ae0afc26 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java
@@ -44,6 +44,10 @@ public abstract class AbstractWebApplicationContext implements
protected HashMap<Application, AbstractCommunicationManager> applicationToAjaxAppMgrMap = new HashMap<Application, AbstractCommunicationManager>();
+ private long totalSessionTime = 0;
+
+ private long lastRequestTime = -1;
+
public void addTransactionListener(TransactionListener listener) {
if (listener != null) {
listeners.add(listener);
@@ -222,4 +226,30 @@ public abstract class AbstractWebApplicationContext implements
return relativeUri.substring(index + 1, next);
}
+ /**
+ * @return The total time spent servicing requests in this session.
+ */
+ public long getTotalSessionTime() {
+ return totalSessionTime;
+ }
+
+ /**
+ * Sets the time spent servicing the last request in the session and updates
+ * the total time spent servicing requests in this session.
+ *
+ * @param time
+ * the time spent in the last request.
+ */
+ public void setLastRequestTime(long time) {
+ lastRequestTime = time;
+ totalSessionTime += time;
+ }
+
+ /**
+ * @return the time spent servicing the last request in this session.
+ */
+ public long getLastRequestTime() {
+ return lastRequestTime;
+ }
+
} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/RequestTimer.java b/src/com/vaadin/terminal/gwt/server/RequestTimer.java
index d47f444bef..6c0edec466 100644
--- a/src/com/vaadin/terminal/gwt/server/RequestTimer.java
+++ b/src/com/vaadin/terminal/gwt/server/RequestTimer.java
@@ -4,7 +4,7 @@
package com.vaadin.terminal.gwt.server;
-import com.vaadin.terminal.WrappedRequest;
+import java.io.Serializable;
/**
* Times the handling of requests and stores the information as an attribute in
@@ -14,67 +14,30 @@ import com.vaadin.terminal.WrappedRequest;
*
* @author Jonatan Kronqvist / Vaadin Ltd
*/
-public class RequestTimer {
- public static final String SESSION_ATTR_ID = "REQUESTTIMER";
-
+public class RequestTimer implements Serializable {
private long requestStartTime = 0;
- private long totalSessionTime = 0;
- private long lastRequestTime = -1;
/**
* Starts the timing of a request. This should be called before any
* processing of the request.
- *
- * @param request
- * the request.
*/
- public void start(WrappedRequest request) {
+ public void start() {
requestStartTime = System.nanoTime();
- request.setAttribute("TOTAL", totalSessionTime);
- request.setAttribute("LASTREQUEST", lastRequestTime);
}
/**
* Stops the timing of a request. This should be called when all processing
* of a request has finished.
+ *
+ * @param context
*/
- public void stop() {
+ public void stop(AbstractWebApplicationContext context) {
// Measure and store the total handling time. This data can be
// used in TestBench 3 tests.
long time = (System.nanoTime() - requestStartTime) / 1000000;
- lastRequestTime = time;
- totalSessionTime += time;
- }
-
- /**
- * Returns a valid request timer for the specified request. Timers are
- * session bound.
- *
- * @param request
- * the request for which to get a valid timer.
- * @return a valid timer.
- */
- public static RequestTimer get(WrappedRequest request) {
- RequestTimer timer = (RequestTimer) request
- .getSessionAttribute(SESSION_ATTR_ID);
- if (timer == null) {
- timer = new RequestTimer();
- }
- return timer;
- }
- /**
- * Associates the specified request timer with the specified request. Since
- * {@link #get(RequestWrapper)} will, at one point or another, return a new
- * instance, this method should be called to keep the request <-> timer
- * association updated.
- *
- * @param request
- * the request for which to set the timer.
- * @param requestTimer
- * the timer.
- */
- public static void set(WrappedRequest request, RequestTimer requestTimer) {
- request.setSessionAttribute(RequestTimer.SESSION_ATTR_ID, requestTimer);
+ // The timings must be stored in the context, since a new
+ // RequestTimer is created for every request.
+ context.setLastRequestTime(time);
}
}