aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-06-13 22:38:42 +0300
committerLeif Åstrand <leif@vaadin.com>2013-06-13 22:38:42 +0300
commitfaa693e33b24cb34e7811d94d5efe5605117af7f (patch)
treeb0b54d989d5ec83416b77f01c9e63398786dd8a5
parentbe274254b5e6f4dd9386d4a3dd994ec834147e8b (diff)
parent54ffbdb70746743f4754416911f726f8d556b3ed (diff)
downloadvaadin-framework-faa693e33b24cb34e7811d94d5efe5605117af7f.tar.gz
vaadin-framework-faa693e33b24cb34e7811d94d5efe5605117af7f.zip
Merge changes from origin/7.1
da0a112 Merge changes from origin/7.0 6ba8938 Restore legacyPropertyToString value parsing logic (#11970) d5c0ffa Fix NPE when converting null values (#11895) 2aa3096 Avoid string casing problems (#11970) 0f107f3 Update widgetset template (#12053) eb64fda Add support for rem units (#11279) 5f66766 Using StringTokenizer instead of String.split() in AbstractComponent (#8759) 15b217d Handle push disconnections and reconnections more reliably (#11831, #11922) 47addab Adding isIOs and isAndroid to the WebBrowser wrapper around VBrowserDetails (#11168) 0aa5907 Do not write 404 as a response to all action/event requests (#12056) 55ebe13 Detach and attach when adding or removing the caption wrapper (#11708) 7830af2 Fix GridLayout resize after removing caption (#12011) 53e3a25 DebugWindow resize/move improved, fixes #11937 (also implements shift-resize and alt-move, improves bounds-check) f2b2ce9 Updated to Smartsprites 0.2.10 (#12069) 29c9b60 SimpleTree styling changed for #12058 da8382d DebugWindow now remembers open tab/section, InfoSection fixed to support being opened at once, for #12058 4f5bcef Info tab is now tab 1, hierarchy tab 2 a089743 Consistently recover from disconnections in IE (#12073) 59103a9 Always notify parent of enable state changes (#12062) 997e9a9 Fixed test issue apparently caused by three levels of classes 54ffbdb Add missing license header Change-Id: Ifba747964fa0d8265bb468ca555b84dadec9fa0a
-rw-r--r--WebContent/VAADIN/jquery.atmosphere.js34
-rw-r--r--WebContent/VAADIN/themes/base/debug/debug.scss24
-rw-r--r--WebContent/statictestfiles/PopupViewInEmbeddedApplication.html60
-rw-r--r--client/src/com/vaadin/client/SimpleTree.java13
-rw-r--r--client/src/com/vaadin/client/communication/AtmospherePushConnection.java40
-rw-r--r--client/src/com/vaadin/client/debug/internal/InfoSection.java37
-rw-r--r--client/src/com/vaadin/client/debug/internal/ProfilerSection.java15
-rw-r--r--client/src/com/vaadin/client/debug/internal/VDebugWindow.java356
-rw-r--r--client/src/com/vaadin/client/ui/AbstractComponentConnector.java21
-rw-r--r--client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java1
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/Slot.java9
-rw-r--r--ivysettings.xml13
-rw-r--r--server/src/com/vaadin/data/util/converter/ConverterUtil.java59
-rw-r--r--server/src/com/vaadin/server/DefaultDeploymentConfiguration.java26
-rw-r--r--server/src/com/vaadin/server/Sizeable.java4
-rw-r--r--server/src/com/vaadin/server/VaadinPortletResponse.java8
-rw-r--r--server/src/com/vaadin/server/VaadinPortletService.java2
-rw-r--r--server/src/com/vaadin/server/WebBrowser.java20
-rw-r--r--server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java54
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java30
-rw-r--r--server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java31
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java24
-rw-r--r--server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java52
-rw-r--r--server/tests/src/com/vaadin/server/MockUIContainingServlet.java16
-rw-r--r--server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java25
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/ComponentSizeParseTest.java61
-rw-r--r--theme-compiler/ivy.xml2
-rw-r--r--uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.html32
-rw-r--r--uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.java52
-rw-r--r--uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.html94
-rw-r--r--uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.java61
-rw-r--r--uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.html42
-rw-r--r--uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.java76
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.html32
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.java30
-rw-r--r--uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html2
36 files changed, 1153 insertions, 305 deletions
diff --git a/WebContent/VAADIN/jquery.atmosphere.js b/WebContent/VAADIN/jquery.atmosphere.js
index 2b176668c1..b83894d2eb 100644
--- a/WebContent/VAADIN/jquery.atmosphere.js
+++ b/WebContent/VAADIN/jquery.atmosphere.js
@@ -341,12 +341,7 @@ jQuery.atmosphere = function() {
_request.ctime = jQuery.now();
if (_request.transport != 'websocket' && _request.transport != 'sse') {
- // Gives a chance to the connection to be established before calling the callback
- setTimeout(function() {
- _open('opening', _request.transport, _request);
- }, 500);
_executeRequest();
-
} else if (_request.transport == 'websocket') {
if (!_supportWebsocket()) {
_reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")");
@@ -1025,10 +1020,6 @@ jQuery.atmosphere = function() {
jQuery.atmosphere.debug("Using URL: " + location);
}
- if (webSocketOpened) {
- _open('re-opening', "websocket", _request);
- }
-
if (webSocketOpened && !_request.reconnect) {
if (_websocket != null) {
_clearState();
@@ -1068,9 +1059,7 @@ jQuery.atmosphere = function() {
jQuery.atmosphere.debug("Websocket successfully opened");
}
- if (!webSocketOpened) {
- _open('opening', "websocket", _request);
- }
+ _open('opening', 'websocket', _request);
webSocketOpened = true;
_websocket.webSocketOpened = webSocketOpened;
@@ -1445,10 +1434,14 @@ jQuery.atmosphere = function() {
if (_abordingConnection) {
return;
}
+
_response.error = null;
var skipCallbackInvocation = false;
var update = false;
+ if (rq.transport == 'streaming' && ajaxRequest.readyState == 2) {
+ _open('opening', rq.transport, rq);
+ }
// Opera doesn't call onerror if the server disconnect.
if (jQuery.browser.opera
@@ -1483,6 +1476,7 @@ jQuery.atmosphere = function() {
// Prevent onerror callback to be called
_response.errorHandled = true;
_clearState();
+ _invokeClose(true);
reconnectF();
return;
}
@@ -1579,6 +1573,11 @@ jQuery.atmosphere = function() {
}
_verifyStreamingLength(ajaxRequest, rq);
+
+ if (rq.transport == 'streaming' && rq.readyState == 4) {
+ _invokeClose(true);
+ reconnectF();
+ }
}
};
ajaxRequest.send(rq.data);
@@ -1669,16 +1668,12 @@ jQuery.atmosphere = function() {
_response.status = status == 0 ? 204 : status;
_response.reason = status == 0 ? "Server resumed the connection or down." : "OK";
- var reconnectInterval = (request.connectTimeout == -1) ? 0 : request.connectTimeout;
+ var reconnectInterval = request.reconnectInterval;
// Reconnect immedialtely
- if (!force) {
- request.id = setTimeout(function () {
- _executeRequest(request);
- }, reconnectInterval);
- } else {
+ request.id = setTimeout(function () {
_executeRequest(request);
- }
+ }, reconnectInterval);
}
}
}
@@ -2182,6 +2177,7 @@ jQuery.atmosphere = function() {
if (typeof(f.onError) != 'undefined') f.onError(response);
break;
case "opening" :
+ _request.closed = false;
if (typeof(f.onOpen) != 'undefined') f.onOpen(response);
break;
case "messagePublished" :
diff --git a/WebContent/VAADIN/themes/base/debug/debug.scss b/WebContent/VAADIN/themes/base/debug/debug.scss
index d71575c818..168c666923 100644
--- a/WebContent/VAADIN/themes/base/debug/debug.scss
+++ b/WebContent/VAADIN/themes/base/debug/debug.scss
@@ -73,6 +73,25 @@
color: $maincolor;
font-size: 13px;
+
+ .v-debugwindow-handle {
+ position: absolute;
+ bottom: 0;
+ background-color: #fff;
+ -moz-opacity: 0;
+ -webkit-opacity: 0;
+ opacity: 0;
+ z-index: 1000;
+ }
+ .v-debugwindow-handle-sw {
+ width: 7px;
+ height: 7px;
+ }
+ .v-debugwindow-handle-se {
+ right: 0;
+ width: 14px;
+ height: 14px;
+ }
}
.v-debugwindow:hover {
-moz-opacity: 1;
@@ -95,8 +114,7 @@
.v-debugwindow-head {
text-align: right;
- cursor: move;
- bakcground-color: transparent;
+ background-color: transparent;
}
.v-debugwindow-tabs {
@@ -143,6 +161,8 @@
box-shadow: 0px 0px 7px 0 rgba(55,55,55,0.6);
min-height: 1.5em;
+
+ padding-left: 5px;
}
.v-debugwindow-button {
diff --git a/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html
new file mode 100644
index 0000000000..613bb2cd41
--- /dev/null
+++ b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=9;chrome=1" />
+
+ <title>This is my Embedding Page</title>
+
+ <link rel="shortcut icon" type="image/vnd.microsoft.icon" href="/VAADIN/themes/reindeer/favicon.ico" />
+ <link rel="icon" type="image/vnd.microsoft.icon" href="/VAADIN/themes/reindeer/favicon.ico" />
+</head>
+
+<body>
+ <script type="text/javascript" src="/VAADIN/vaadinBootstrap.js"></script>
+
+
+ <p>This is a static web page that contains an embedded Vaadin
+ application. The embedded application div has been taken out of the normal element flow by applying 'float:left' causing the application
+ to float to the left.</p>
+
+ <div id="helloworld" style="border: 2px solid green; float:left; width:400px; height:400px"></div>
+
+ <div style="clear:both"></div>
+
+ <hr/>
+
+ <script type="text/javascript">//<![CDATA[
+ if (!window.vaadin) alert("Failed to load the bootstrap JavaScript: "+ "VAADIN/vaadinBootstrap.js");
+
+ /* The UI Configuration */
+ vaadin.initApplication("helloworld", {
+ "browserDetailsUrl": "/run/com.vaadin.tests.components.popupview.PopupViewInEmbeddedApplication",
+ "serviceUrl": "/run",
+ "widgetset": "com.vaadin.DefaultWidgetSet",
+ "theme": "reindeer",
+ "versionInfo": {"vaadinVersion": "7.0.0"},
+ "vaadinDir": "./../VAADIN/",
+ "heartbeatInterval": 300,
+ "debug": true,
+ "standalone": false,
+ "authErrMsg": {
+ "message": "Take note of any unsaved data, "+
+ "and <u>click here<\/u> to continue.",
+ "caption": "Authentication problem"
+ },
+ "comErrMsg": {
+ "message": "Take note of any unsaved data, "+
+ "and <u>click here<\/u> to continue.",
+ "caption": "Communication problem"
+ },
+ "sessExpMsg": {
+ "message": "Take note of any unsaved data, "+
+ "and <u>click here<\/u> to continue.",
+ "caption": "Session Expired"
+ }
+ });
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/client/src/com/vaadin/client/SimpleTree.java b/client/src/com/vaadin/client/SimpleTree.java
index 23bdc4828f..0745a49aa0 100644
--- a/client/src/com/vaadin/client/SimpleTree.java
+++ b/client/src/com/vaadin/client/SimpleTree.java
@@ -19,7 +19,6 @@ package com.vaadin.client;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style;
-import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
@@ -58,14 +57,14 @@ public class SimpleTree extends ComplexPanel implements HasDoubleClickHandlers {
style = handle.getStyle();
style.setDisplay(Display.NONE);
- style.setProperty("textAlign", "center");
- style.setWidth(10, Unit.PX);
+ style.setWidth(0.5, Unit.EM);
+ style.setHeight(0.5, Unit.EM);
style.setCursor(Cursor.POINTER);
- style.setBorderStyle(BorderStyle.SOLID);
- style.setBorderColor("#666");
- style.setBorderWidth(1, Unit.PX);
+ style.setBackgroundColor("gray");
+ style.setColor("white");
+ style.setPadding(4, Unit.PX);
style.setMarginRight(3, Unit.PX);
- style.setProperty("borderRadius", "4px");
+ style.setLineHeight(0.5, Unit.EM);
handle.setInnerHTML("+");
getElement().appendChild(handle);
getElement().appendChild(text);
diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
index 506716040d..20ccd45173 100644
--- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
+++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
@@ -292,6 +292,14 @@ public class AtmospherePushConnection implements PushConnection {
message = message.substring(9, message.length() - 1);
connection.handlePushMessage(message);
}
+
+ if (!connection.isApplicationRunning()) {
+ disconnect(new Command() {
+ @Override
+ public void execute() {
+ }
+ });
+ }
}
/**
@@ -309,9 +317,21 @@ public class AtmospherePushConnection implements PushConnection {
* the connection until successful.
*
*/
- protected void onError() {
- VConsole.error("Push connection using " + getConfig().getTransport()
- + " failed!");
+ protected void onError(AtmosphereResponse response) {
+ state = State.DISCONNECTED;
+ errorHandler.onError("Push connection using "
+ + getConfig().getTransport() + " failed!",
+ response.getStatusCode());
+ }
+
+ protected void onClose(AtmosphereResponse response) {
+ VConsole.log("Push connection closed, awaiting reconnection");
+ state = State.CONNECT_PENDING;
+ }
+
+ protected void onReconnect(JavaScriptObject request,
+ final AtmosphereResponse response) {
+ VConsole.log("Reopening push connection");
}
public static abstract class AbstractJSO extends JavaScriptObject {
@@ -370,6 +390,10 @@ public class AtmospherePushConnection implements PushConnection {
}
+ public final int getStatusCode() {
+ return getIntValue("status");
+ }
+
public final String getResponseBody() {
return getStringValue("responseBody");
}
@@ -394,7 +418,7 @@ public class AtmospherePushConnection implements PushConnection {
transport: 'websocket',
fallbackTransport: 'streaming',
contentType: 'application/json; charset=UTF-8',
- reconnectInterval: '5000',
+ reconnectInterval: 5000,
maxReconnectOnClose: 10000000,
trackMessageLength: true,
messageDelimiter: String.fromCharCode(@com.vaadin.shared.communication.PushConstants::MESSAGE_DELIMITER)
@@ -414,11 +438,17 @@ public class AtmospherePushConnection implements PushConnection {
self.@com.vaadin.client.communication.AtmospherePushConnection::onMessage(*)(response);
});
config.onError = $entry(function(response) {
- self.@com.vaadin.client.communication.AtmospherePushConnection::onError()(response);
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onError(*)(response);
});
config.onTransportFailure = $entry(function(reason,request) {
self.@com.vaadin.client.communication.AtmospherePushConnection::onTransportFailure(*)(reason);
});
+ config.onClose = $entry(function(response) {
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onClose(*)(response);
+ });
+ config.onReconnect = $entry(function(request, response) {
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onReconnect(*)(request, response);
+ });
return $wnd.jQueryVaadin.atmosphere.subscribe(config);
}-*/;
diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java
index 05908c8834..865cfac4ff 100644
--- a/client/src/com/vaadin/client/debug/internal/InfoSection.java
+++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java
@@ -16,12 +16,13 @@
package com.vaadin.client.debug.internal;
+import java.util.List;
import java.util.logging.Level;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -44,8 +45,16 @@ public class InfoSection implements Section {
+ "-info";
private static final String ERROR_STYLE = Level.SEVERE.getName();
private final HTML content = new HTML();
- private DebugButton tabButton = new DebugButton(Icon.INFO);
- private FlowPanel controls = new FlowPanel();
+ private DebugButton tabButton = new DebugButton(Icon.INFO,
+ "General information about the application(s)");
+ private HTML controls = new HTML(tabButton.getTitle());
+
+ private Timer refresher = new Timer() {
+ @Override
+ public void run() {
+ refresh();
+ }
+ };
/**
*
@@ -73,7 +82,12 @@ public class InfoSection implements Section {
row.addClassName(className);
}
Element span = DOM.createSpan();
- span.setInnerText(parameter + ": " + value);
+ span.setClassName("caption");
+ span.setInnerText(parameter);
+ row.appendChild(span);
+ span = DOM.createSpan();
+ span.setClassName("value");
+ span.setInnerText(value);
row.appendChild(span);
content.getElement().appendChild(row);
@@ -126,9 +140,15 @@ public class InfoSection implements Section {
*/
private void refresh() {
clear();
- for (ApplicationConnection application : ApplicationConfiguration
- .getRunningApplications()) {
- refresh(application);
+ List<ApplicationConnection> apps = ApplicationConfiguration
+ .getRunningApplications();
+ if (apps.size() == 0) {
+ // try again in a while
+ refresher.schedule(1000);
+ } else {
+ for (ApplicationConnection application : apps) {
+ refresh(application);
+ }
}
}
@@ -263,7 +283,7 @@ public class InfoSection implements Section {
*/
@Override
public void hide() {
-
+ refresher.cancel();
}
/*
@@ -274,6 +294,7 @@ public class InfoSection implements Section {
*/
@Override
public void meta(ApplicationConnection ac, ValueMap meta) {
+
}
/*
diff --git a/client/src/com/vaadin/client/debug/internal/ProfilerSection.java b/client/src/com/vaadin/client/debug/internal/ProfilerSection.java
index f9d401de88..aa40e8ff17 100644
--- a/client/src/com/vaadin/client/debug/internal/ProfilerSection.java
+++ b/client/src/com/vaadin/client/debug/internal/ProfilerSection.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.client.debug.internal;
import java.util.Collection;
diff --git a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
index 6c05658fe1..5e146ffda8 100644
--- a/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
+++ b/client/src/com/vaadin/client/debug/internal/VDebugWindow.java
@@ -37,6 +37,7 @@ import com.google.gwt.http.client.UrlBuilder;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.storage.client.Storage;
+import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
@@ -77,9 +78,11 @@ public final class VDebugWindow extends VOverlay {
// drag this far before actually moving window
protected static final int MOVE_TRESHOLD = 5;
- // window minimum sizes
+ // window minimum height, minimum width comes from tab+controls
protected static final int MIN_HEIGHT = 40;
- protected static final int HANDLE_SIZE = 5;
+
+ // size of area to grab for resize; bottom corners size in CSS
+ protected static final int HANDLE_SIZE = 7;
// identifiers for localStorage
private static final String STORAGE_PREFIX = "v-debug-";
@@ -129,14 +132,9 @@ public final class VDebugWindow extends VOverlay {
// sections
protected ArrayList<Section> sections = new ArrayList<Section>();
- // handles resizing (mouse)
- protected ResizeHandler resizeHandler = new ResizeHandler();
- protected HandlerRegistration resizeReg = null;
- protected HandlerRegistration resizeReg2 = null;
-
- // handles window movement (mouse)
- protected MoveHandler moveHandler = new MoveHandler();
- protected HandlerRegistration moveReg = null;
+ // handles resize/move
+ protected HandlerRegistration mouseDownHandler = null;
+ protected HandlerRegistration mouseMoveHandler = null;
// TODO this class should really be a singleton.
static VDebugWindow instance;
@@ -187,6 +185,8 @@ public final class VDebugWindow extends VOverlay {
head.add(sectionHead);
window.add(content);
+ addHandles();
+
head.setStylePrimaryName(STYLENAME_HEAD);
tabs.setStylePrimaryName(STYLENAME_TABS);
controls.setStylePrimaryName(STYLENAME_CONTROLS);
@@ -221,14 +221,31 @@ public final class VDebugWindow extends VOverlay {
Style s = content.getElement().getStyle();
s.setOverflow(Overflow.AUTO);
- // window can be moved by dragging header
- moveReg = head.addDomHandler(moveHandler, MouseDownEvent.getType());
- // resize from all sides and corners
- resizeReg = content.addDomHandler(resizeHandler,
+ // move/resize
+ final MouseHandler mouseHandler = new MouseHandler();
+ mouseDownHandler = this.addDomHandler(mouseHandler,
MouseDownEvent.getType());
- // changes mouse pointer when hovering sides / corners
- resizeReg2 = content.addDomHandler(resizeHandler,
+ mouseMoveHandler = this.addDomHandler(mouseHandler,
MouseMoveEvent.getType());
+
+ }
+
+ /**
+ * Adds dummy handle elements to the bottom corners that might have
+ * scrollbars that interfere with resizing on some platforms.
+ *
+ * @since 7.1
+ */
+ private void addHandles() {
+ Element el = DOM.createDiv();
+ el.setClassName(VDebugWindow.STYLENAME + "-handle "
+ + VDebugWindow.STYLENAME + "-handle-sw");
+ content.getElement().appendChild(el);
+
+ el = DOM.createDiv();
+ el.setClassName(VDebugWindow.STYLENAME + "-handle "
+ + VDebugWindow.STYLENAME + "-handle-se");
+ content.getElement().appendChild(el);
}
/**
@@ -248,10 +265,11 @@ public final class VDebugWindow extends VOverlay {
*/
public void close() {
// TODO disable even more
- if (resizeReg != null) {
- resizeReg.removeHandler();
- resizeReg2.removeHandler();
- moveReg.removeHandler();
+ if (mouseDownHandler != null) {
+ mouseDownHandler.removeHandler();
+ mouseMoveHandler.removeHandler();
+ mouseDownHandler = null;
+ mouseMoveHandler = null;
}
Highlight.hideAll();
hide();
@@ -306,9 +324,9 @@ public final class VDebugWindow extends VOverlay {
writeState(storage, STORAGE_MIN_Y, minY);
writeState(storage, STORAGE_FONT_SIZE, fontSize);
- if (activeSection != null) {
- writeState(storage, STORAGE_ACTIVE_SECTION,
- activeSection.getTabButton());
+ int activeIdx = getActiveSection();
+ if (activeIdx >= 0) {
+ writeState(storage, STORAGE_ACTIVE_SECTION, activeIdx);
}
writeState(storage, STORAGE_IS_MINIMIZED, minimized);
@@ -446,6 +464,16 @@ public final class VDebugWindow extends VOverlay {
content.setHeight(fullH + "px");
}
+ applyBounds(x, y);
+ }
+
+ private void applyBounds() {
+ int x = getPopupLeft();
+ int y = getPopupTop();
+ applyBounds(x, y);
+ }
+
+ private void applyBounds(int x, int y) {
// bounds check
if (x < 0) {
x = 0;
@@ -462,6 +490,7 @@ public final class VDebugWindow extends VOverlay {
}
setPopupPosition(x, y);
+
}
/**
@@ -552,6 +581,10 @@ public final class VDebugWindow extends VOverlay {
}
}
+ int getActiveSection() {
+ return sections.indexOf(activeSection);
+ }
+
/**
* Toggles the window between minimized and full states.
*/
@@ -635,8 +668,8 @@ public final class VDebugWindow extends VOverlay {
*/
static String getTimingTooltip(int sinceStart, int sinceReset) {
String title = formatDuration(sinceStart) + " since start";
- title += ", &#10;" + formatDuration(sinceReset) + " since timer reset";
- title += " &#10;@ "
+ title += ", &#10; " + formatDuration(sinceReset) + " since timer reset";
+ title += " &#10; @ "
+ DateTimeFormat.getFormat("HH:mm:ss.SSS").format(new Date());
return title;
}
@@ -861,31 +894,120 @@ public final class VDebugWindow extends VOverlay {
}
/**
- * Handler for moving window.
+ * Handler for resizing and moving window, also updates cursor on mousemove.
*
* @since 7.1
* @author Vaadin Ltd
*/
- protected class MoveHandler implements MouseDownHandler,
+ protected class MouseHandler implements MouseMoveHandler, MouseDownHandler,
NativePreviewHandler {
- HandlerRegistration handler;
+ boolean resizeLeft;
+ boolean resizeRight;
+ boolean resizeUp;
+ boolean resizeDown;
+ boolean move;
+ boolean sizing;
+
+ // dragging stopped, remove handler on next event
+ boolean stop;
+
+ HandlerRegistration dragHandler;
+
int startX;
int startY;
+ int startW;
+ int startH;
int startTop;
int startLeft;
- // moving stopped, remove handler on next event
- boolean stop;
+ @Override
+ public void onMouseMove(MouseMoveEvent event) {
+ if (null == dragHandler) {
+ updateResizeFlags(event);
+ updateCursor();
+ }
+ }
+
+ @Override
+ public void onMouseDown(MouseDownEvent event) {
+ if (event.getNativeButton() != NativeEvent.BUTTON_LEFT
+ || dragHandler != null) {
+ return;
+ }
+ updateResizeFlags(event);
+ if (sizing || move) {
+ // some os/browsers don't pass events trough scrollbars; hide
+ // while dragging (esp. important for resize from right/bottom)
+ content.getElement().getStyle().setOverflow(Overflow.HIDDEN);
+
+ startX = event.getClientX();
+ startY = event.getClientY();
+
+ startW = content.getOffsetWidth();
+ startH = content.getOffsetHeight();
+
+ startTop = getPopupTop();
+ startLeft = getPopupLeft();
+
+ dragHandler = Event.addNativePreviewHandler(this);
+
+ event.preventDefault();
+
+ stop = false;
+ }
+
+ }
@Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getTypeInt() == Event.ONMOUSEMOVE && !stop
&& hasMoved(event.getNativeEvent())) {
+
int dx = event.getNativeEvent().getClientX() - startX;
int dy = event.getNativeEvent().getClientY() - startY;
- setPopupPosition(startLeft + dx, startTop + dy);
+ if (sizing) {
+ int minWidth = tabs.getOffsetWidth()
+ + controls.getOffsetWidth();
+
+ if (resizeLeft) {
+ int w = startW - dx;
+ if (w < minWidth) {
+ w = minWidth;
+ dx = startW - minWidth;
+ }
+ content.setWidth(w + "px");
+ setPopupPosition(startLeft + dx, getPopupTop());
+
+ } else if (resizeRight) {
+ int w = startW + dx;
+ if (w < minWidth) {
+ w = minWidth;
+ }
+ content.setWidth(w + "px");
+ }
+ if (resizeUp) {
+ int h = startH - dy;
+ if (h < MIN_HEIGHT) {
+ h = MIN_HEIGHT;
+ dy = startH - MIN_HEIGHT;
+ }
+ content.setHeight(h + "px");
+ setPopupPosition(getPopupLeft(), startTop + dy);
+
+ } else if (resizeDown) {
+ int h = startH + dy;
+ if (h < MIN_HEIGHT) {
+ h = MIN_HEIGHT;
+ }
+ content.setHeight(h + "px");
+
+ }
+
+ } else if (move) {
+ setPopupPosition(startLeft + dx, startTop + dy);
+ }
event.cancel();
} else if (event.getTypeInt() == Event.ONMOUSEUP) {
@@ -902,12 +1024,23 @@ public final class VDebugWindow extends VOverlay {
} else if (stop) {
stop = false;
- handler.removeHandler();
- handler = null;
+ dragHandler.removeHandler();
+ dragHandler = null;
+ sizing = false;
+ move = false;
+
+ // restore scrollbars
+ content.getElement().getStyle().setOverflow(Overflow.AUTO);
+ updateCursor();
+
+ applyBounds();
readPositionAndSize();
writeStoredState();
+
+ event.cancel();
}
+
}
private boolean hasMoved(NativeEvent event) {
@@ -915,75 +1048,8 @@ public final class VDebugWindow extends VOverlay {
|| Math.abs(startY - event.getClientY()) > MOVE_TRESHOLD;
}
- @Override
- public void onMouseDown(MouseDownEvent event) {
- if (handler == null) {
- handler = Event.addNativePreviewHandler(MoveHandler.this);
- }
- startX = event.getClientX();
- startY = event.getClientY();
- startLeft = getPopupLeft();
- startTop = getPopupTop();
- stop = false;
- event.preventDefault();
- }
-
- }
-
- /**
- * Handler for resizing window.
- *
- * @since 7.1
- * @author Vaadin Ltd
- */
- protected class ResizeHandler implements MouseDownHandler,
- MouseMoveHandler, NativePreviewHandler {
-
- boolean resizeLeft;
- boolean resizeRight;
- boolean resizeUp;
- boolean resizeDown;
-
- boolean sizing;
-
- HandlerRegistration dragHandler;
-
- int startX;
- int startY;
- int startW;
- int startH;
- int startTop;
- int startLeft;
-
- @Override
- public void onMouseDown(MouseDownEvent event) {
- sizing = updateResizeFlags(event);
-
- if (sizing) {
- startX = event.getClientX();
- startY = event.getClientY();
-
- startW = content.getOffsetWidth();
- startH = content.getOffsetHeight();
-
- startTop = getPopupTop();
- startLeft = getPopupLeft();
-
- dragHandler = Event.addNativePreviewHandler(this);
-
- event.preventDefault();
- }
-
- }
-
- @Override
- public void onMouseMove(MouseMoveEvent event) {
- updateResizeFlags(event);
- updateCursor();
- }
-
private void updateCursor() {
- Element c = content.getElement();
+ Element c = getElement();
if (resizeLeft) {
if (resizeUp) {
c.getStyle().setCursor(Cursor.NW_RESIZE);
@@ -1004,70 +1070,54 @@ public final class VDebugWindow extends VOverlay {
c.getStyle().setCursor(Cursor.N_RESIZE);
} else if (resizeDown) {
c.getStyle().setCursor(Cursor.S_RESIZE);
+ } else if (move) {
+ c.getStyle().setCursor(Cursor.MOVE);
} else {
c.getStyle().setCursor(Cursor.AUTO);
}
}
- private boolean updateResizeFlags(MouseEvent event) {
+ protected void updateResizeFlags(MouseEvent event) {
+ if (event.isShiftKeyDown()) {
+ // resize from lower right
+ resizeUp = false;
+ resizeLeft = false;
+ resizeRight = true;
+ resizeDown = true;
+ move = false;
+ sizing = true;
+ return;
+
+ } else if (event.isAltKeyDown()) {
+ // move it
+ move = true;
+ resizeUp = false;
+ resizeLeft = false;
+ resizeRight = false;
+ resizeDown = false;
+ sizing = false;
+ return;
+ }
+
Element c = getElement();
int w = c.getOffsetWidth();
- int h = c.getOffsetHeight() - head.getOffsetHeight();
+ int h = c.getOffsetHeight();
int x = event.getRelativeX(c);
- int y = event.getRelativeY(c) - head.getOffsetHeight();
-
- resizeLeft = x < HANDLE_SIZE;
- resizeRight = x > (w - HANDLE_SIZE);
- resizeUp = y < HANDLE_SIZE;
- resizeDown = y > (h - HANDLE_SIZE);
+ int y = event.getRelativeY(c);
- return resizeLeft || resizeRight || resizeUp || resizeDown;
+ resizeLeft = x < HANDLE_SIZE && y > tabs.getOffsetHeight();
+ resizeRight = (x > (w - HANDLE_SIZE) && y > tabs.getOffsetHeight())
+ || (x > (w - 2 * HANDLE_SIZE) && y > (h - 2 * HANDLE_SIZE));
+ resizeUp = y > tabs.getOffsetHeight()
+ && y < tabs.getOffsetHeight() + HANDLE_SIZE;
+ resizeDown = y > (h - HANDLE_SIZE)
+ || (x > (w - 2 * HANDLE_SIZE) && y > (h - 2 * HANDLE_SIZE));
- }
+ move = !resizeDown && !resizeLeft && !resizeRight && !resizeUp
+ && y < head.getOffsetHeight();
- @Override
- public void onPreviewNativeEvent(NativePreviewEvent event) {
- if (event.getTypeInt() == Event.ONMOUSEMOVE) {
-
- int dx = event.getNativeEvent().getClientX() - startX;
- int dy = event.getNativeEvent().getClientY() - startY;
-
- int minw = tabs.getOffsetWidth() + controls.getOffsetWidth();
- if (resizeLeft) {
- int w = startW - dx;
- if (w >= minw) {
- content.setWidth(w + "px");
- setPopupPosition(startLeft + dx, getPopupTop());
- }
- } else if (resizeRight) {
- int w = startW + dx;
- if (w >= minw) {
- content.setWidth(w + "px");
- }
- }
- if (resizeUp) {
- int h = startH - dy;
- if (h >= MIN_HEIGHT) {
- content.setHeight(h + "px");
- setPopupPosition(getPopupLeft(), startTop + dy);
- }
- } else if (resizeDown) {
- int h = startH + dy;
- if (h >= MIN_HEIGHT) {
- content.setHeight(h + "px");
- }
- }
-
- } else if (event.getTypeInt() == Event.ONMOUSEUP) {
- dragHandler.removeHandler();
- dragHandler = null;
- content.getElement().getStyle().setCursor(Cursor.AUTO);
- sizing = false;
- readPositionAndSize();
- writeStoredState();
- }
+ sizing = resizeLeft || resizeRight || resizeUp || resizeDown;
- event.cancel();
}
}
diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
index ebc80c4728..d384549ee3 100644
--- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -185,19 +185,20 @@ public abstract class AbstractComponentConnector extends AbstractConnector
if (getWidget() instanceof HasEnabled) {
// set widget specific enabled state
((HasEnabled) getWidget()).setEnabled(widgetEnabled);
+ }
- // make sure the caption has or has not v-disabled style
- if (delegateCaptionHandling()) {
- ServerConnector parent = getParent();
- if (parent instanceof HasComponentsConnector) {
- ((HasComponentsConnector) parent).updateCaption(this);
- } else if (parent == null && !(this instanceof UIConnector)) {
- VConsole.error("Parent of connector "
- + Util.getConnectorString(this)
- + " is null. This is typically an indication of a broken component hierarchy");
- }
+ // make sure the caption has or has not v-disabled style
+ if (delegateCaptionHandling()) {
+ ServerConnector parent = getParent();
+ if (parent instanceof HasComponentsConnector) {
+ ((HasComponentsConnector) parent).updateCaption(this);
+ } else if (parent == null && !(this instanceof UIConnector)) {
+ VConsole.error("Parent of connector "
+ + Util.getConnectorString(this)
+ + " is null. This is typically an indication of a broken component hierarchy");
}
}
+
}
protected void updateComponentSize() {
diff --git a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java
index e0cb76b714..29d41e00b7 100644
--- a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java
+++ b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java
@@ -192,6 +192,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector
caption.updateCaption();
} else {
layout.setCaption(childConnector.getWidget(), null);
+ getLayoutManager().setNeedsLayout(this);
}
}
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
index 00ff5bbc5a..49b3661431 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -455,6 +455,7 @@ public final class Slot extends SimplePanel {
// since last time, and only run those changes
// Caption wrappers
+ Widget widget = getWidget();
if (captionText != null || iconUrl != null || error != null || required) {
if (caption == null) {
caption = DOM.createDiv();
@@ -462,10 +463,14 @@ public final class Slot extends SimplePanel {
captionWrap.addClassName(StyleConstants.UI_WIDGET);
captionWrap.addClassName("v-has-caption");
getElement().appendChild(captionWrap);
- captionWrap.appendChild(getWidget().getElement());
+ orphan(widget);
+ captionWrap.appendChild(widget.getElement());
+ adopt(widget);
}
} else if (caption != null) {
- getElement().appendChild(getWidget().getElement());
+ orphan(widget);
+ getElement().appendChild(widget.getElement());
+ adopt(widget);
captionWrap.removeFromParent();
caption = null;
captionWrap = null;
diff --git a/ivysettings.xml b/ivysettings.xml
index 6c230b9fd8..3db0a8a06d 100644
--- a/ivysettings.xml
+++ b/ivysettings.xml
@@ -15,16 +15,6 @@
<artifact
pattern="${user.home}/.m2/repository/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
</filesystem>
- <dual name="custom-smartsprites">
- <url name="smartsprites-ivy">
- <ivy
- pattern="http://vaadin.com/download/external/[module]-ivy-[revision].xml" />
- </url>
- <url name="smartsprites-artifact">
- <artifact
- pattern="http://vaadin.com/download/external/[artifact](-[revision]).[ext]" />
- </url>
- </dual>
<filesystem name="build-temp">
<ivy
pattern="${ivy.settings.dir}/result/artifacts/[revision]/[module]/ivy-[revision].xml" />
@@ -33,9 +23,6 @@
</filesystem>
</resolvers>
<modules>
- <!-- Custom SmartSprites until 0.2.10 is released -->
- <module organisation="com.carrotsearch" name="smartsprites"
- revision="0.2.10-vaadin" resolver="custom-smartsprites" />
<module organisation="com.vaadin" name="vaadin-buildhelpers"
resolver="build-temp" />
<module organisation="com.vaadin" name="vaadin-shared"
diff --git a/server/src/com/vaadin/data/util/converter/ConverterUtil.java b/server/src/com/vaadin/data/util/converter/ConverterUtil.java
index 3c62a71b73..3457c16755 100644
--- a/server/src/com/vaadin/data/util/converter/ConverterUtil.java
+++ b/server/src/com/vaadin/data/util/converter/ConverterUtil.java
@@ -29,17 +29,17 @@ public class ConverterUtil implements Serializable {
* {@link VaadinSession#getCurrent()}.
*
* @param <PRESENTATIONTYPE>
- * The presentation type
+ * the presentation type
* @param <MODELTYPE>
- * The model type
+ * the model type
* @param presentationType
- * The presentation type
+ * the presentation type
* @param modelType
- * The model type
+ * the model type
* @param session
- * The session to use to find a ConverterFactory or null to use
+ * the session to use to find a ConverterFactory or null to use
* the current session
- * @return A Converter capable of converting between the given types or null
+ * @return a Converter capable of converting between the given types or null
* if no converter was found
*/
public static <PRESENTATIONTYPE, MODELTYPE> Converter<PRESENTATIONTYPE, MODELTYPE> getConverter(
@@ -62,22 +62,23 @@ public class ConverterUtil implements Serializable {
* Convert the given value from the data source type to the UI type.
*
* @param modelValue
- * The model value to convert
+ * the model value to convert
* @param presentationType
- * The type of the presentation value
+ * the type of the presentation value
* @param converter
- * The converter to (try to) use
+ * the converter to use
* @param locale
- * The locale to use for conversion
+ * the locale to use for conversion
* @param <PRESENTATIONTYPE>
- * Presentation type
+ * the presentation type
+ * @param <MODELTYPE>
+ * the model type
*
- * @return The converted value, compatible with the presentation type, or
+ * @return the converted value, compatible with the presentation type, or
* the original value if its type is compatible and no converter is
* set.
* @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the model type.
+ * if there was a problem converting the value
*/
@SuppressWarnings("unchecked")
public static <PRESENTATIONTYPE, MODELTYPE> PRESENTATIONTYPE convertFromModel(
@@ -86,9 +87,14 @@ public class ConverterUtil implements Serializable {
Converter<PRESENTATIONTYPE, MODELTYPE> converter, Locale locale)
throws Converter.ConversionException {
if (converter != null) {
+ /*
+ * If there is a converter, always use it. It must convert or throw
+ * an exception.
+ */
PRESENTATIONTYPE presentation = converter.convertToPresentation(
modelValue, presentationType, locale);
- if (!presentationType.isInstance(presentation)) {
+ if (presentation != null
+ && !presentationType.isInstance(presentation)) {
throw new Converter.ConversionException(
"Converter returned an object of type "
+ presentation.getClass().getName()
@@ -99,6 +105,8 @@ public class ConverterUtil implements Serializable {
return presentation;
}
if (modelValue == null) {
+ // Null should always be passed through the converter but if there
+ // is no converter we can safely return null
return null;
}
@@ -115,14 +123,26 @@ public class ConverterUtil implements Serializable {
}
/**
- * @param <MODELTYPE>
- * @param <PRESENTATIONTYPE>
+ * Convert the given value from the presentation (UI) type to model (data
+ * source) type.
+ *
* @param presentationValue
+ * the presentation value to convert
* @param modelType
+ * the type of the model
* @param converter
+ * the converter to use
* @param locale
- * @return
+ * the locale to use for conversion
+ * @param <PRESENTATIONTYPE>
+ * the presentation type
+ * @param <MODELTYPE>
+ * the model type
+ *
+ * @return the converted value, compatible with the model type, or the
+ * original value if its type is compatible and no converter is set.
* @throws Converter.ConversionException
+ * if there was a problem converting the value
*/
public static <MODELTYPE, PRESENTATIONTYPE> MODELTYPE convertToModel(
PRESENTATIONTYPE presentationValue, Class<MODELTYPE> modelType,
@@ -135,7 +155,7 @@ public class ConverterUtil implements Serializable {
*/
MODELTYPE model = converter.convertToModel(presentationValue,
modelType, locale);
- if (!modelType.isInstance(model)) {
+ if (model != null && !modelType.isInstance(model)) {
throw new Converter.ConversionException(
"Converter returned an object of type "
+ model.getClass().getName()
@@ -143,7 +163,6 @@ public class ConverterUtil implements Serializable {
}
return model;
-
}
if (presentationValue == null) {
diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
index a55c3231f3..993d60133b 100644
--- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
+++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java
@@ -86,17 +86,25 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration {
}
private void checkLegacyPropertyToString() {
+ // Verify that the default value has not changed without also
+ // updating logic here
+ assert DEFAULT_LEGACY_PROPERTY_TO_STRING == LegacyProperyToStringMode.WARNING;
+
String param = getApplicationOrSystemProperty(
- Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING,
- DEFAULT_LEGACY_PROPERTY_TO_STRING.name().toLowerCase());
+ Constants.SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING, "warning");
- try {
- legacyPropertyToStringMode = LegacyProperyToStringMode
- .valueOf(param.toUpperCase());
- } catch (IllegalArgumentException e) {
- getLogger().log(Level.WARNING,
- Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
- param);
+ if ("true".equals(param)) {
+ legacyPropertyToStringMode = LegacyProperyToStringMode.ENABLED;
+ } else if ("false".equals(param)) {
+ legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED;
+ } else {
+ if (!"warning".equals(param)) {
+ getLogger()
+ .log(Level.WARNING,
+ Constants.WARNING_UNKNOWN_LEGACY_PROPERTY_TOSTRING_VALUE,
+ param);
+
+ }
legacyPropertyToStringMode = DEFAULT_LEGACY_PROPERTY_TO_STRING;
}
}
diff --git a/server/src/com/vaadin/server/Sizeable.java b/server/src/com/vaadin/server/Sizeable.java
index 38e998c04b..decace3d10 100644
--- a/server/src/com/vaadin/server/Sizeable.java
+++ b/server/src/com/vaadin/server/Sizeable.java
@@ -101,6 +101,10 @@ public interface Sizeable extends Serializable {
*/
EM("em"),
/**
+ * Unit code representing the font-size of the root font.
+ */
+ REM("rem"),
+ /**
* Unit code representing the x-height of the relevant font.
*/
EX("ex"),
diff --git a/server/src/com/vaadin/server/VaadinPortletResponse.java b/server/src/com/vaadin/server/VaadinPortletResponse.java
index f89cb6ea7a..334b94a5dc 100644
--- a/server/src/com/vaadin/server/VaadinPortletResponse.java
+++ b/server/src/com/vaadin/server/VaadinPortletResponse.java
@@ -65,7 +65,13 @@ public class VaadinPortletResponse implements VaadinResponse {
@Override
public OutputStream getOutputStream() throws IOException {
- return ((MimeResponse) response).getPortletOutputStream();
+ if (response instanceof MimeResponse) {
+ return ((MimeResponse) response).getPortletOutputStream();
+ } else {
+ throw new IOException(
+ "Output stream not available for response of type "
+ + response.getClass().getName());
+ }
}
/**
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java
index 2eca07dd4a..c7fc5a23bd 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/com/vaadin/server/VaadinPortletService.java
@@ -32,6 +32,7 @@ import com.vaadin.server.VaadinPortlet.RequestType;
import com.vaadin.server.communication.PortletBootstrapHandler;
import com.vaadin.server.communication.PortletDummyRequestHandler;
import com.vaadin.server.communication.PortletListenerNotifier;
+import com.vaadin.server.communication.PortletStateAwareRequestHandler;
import com.vaadin.server.communication.PortletUIInitHandler;
import com.vaadin.ui.UI;
@@ -64,6 +65,7 @@ public class VaadinPortletService extends VaadinService {
handlers.add(new PortletListenerNotifier());
handlers.add(0, new PortletDummyRequestHandler());
handlers.add(0, new PortletBootstrapHandler());
+ handlers.add(0, new PortletStateAwareRequestHandler());
return handlers;
}
diff --git a/server/src/com/vaadin/server/WebBrowser.java b/server/src/com/vaadin/server/WebBrowser.java
index 8038bbc207..4d1027f0e4 100644
--- a/server/src/com/vaadin/server/WebBrowser.java
+++ b/server/src/com/vaadin/server/WebBrowser.java
@@ -259,6 +259,26 @@ public class WebBrowser implements Serializable {
}
/**
+ * Tests if the browser is run on Android.
+ *
+ * @return true if run on Android false if the user is not using Android or
+ * if no information on the browser is present
+ */
+ public boolean isAndroid() {
+ return browserDetails.isAndroid();
+ }
+
+ /**
+ * Tests if the browser is run in iOS.
+ *
+ * @return true if run in iOS false if the user is not using iOS or if no
+ * information on the browser is present
+ */
+ public boolean isIOS() {
+ return browserDetails.isIOS();
+ }
+
+ /**
* 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
diff --git a/server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java b/server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java
new file mode 100644
index 0000000000..162c479fac
--- /dev/null
+++ b/server/src/com/vaadin/server/communication/PortletStateAwareRequestHandler.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.server.communication;
+
+import java.io.IOException;
+
+import javax.portlet.StateAwareResponse;
+
+import com.vaadin.server.RequestHandler;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinResponse;
+import com.vaadin.server.VaadinSession;
+
+/**
+ * Handler which ensures that Action and Event requests are marked as handled
+ * and do not cause a 404 to be sent.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class PortletStateAwareRequestHandler implements RequestHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.server.RequestHandler#handleRequest(com.vaadin.server.
+ * VaadinSession, com.vaadin.server.VaadinRequest,
+ * com.vaadin.server.VaadinResponse)
+ */
+ @Override
+ public boolean handleRequest(VaadinSession session, VaadinRequest request,
+ VaadinResponse response) throws IOException {
+ if (response instanceof StateAwareResponse) {
+ // StateAwareResponse is fully handled by listeners through
+ // PortletListenerNotifier
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index 6b853063a7..1c50f79349 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -28,6 +28,7 @@ import org.atmosphere.cpr.AtmosphereRequest;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResource.TRANSPORT;
import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter;
import org.json.JSONException;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
@@ -51,7 +52,8 @@ import com.vaadin.ui.UI;
* @author Vaadin Ltd
* @since 7.1
*/
-public class PushHandler implements AtmosphereHandler {
+public class PushHandler extends AtmosphereResourceEventListenerAdapter
+ implements AtmosphereHandler {
/**
* Callback interface used internally to process an event with the
@@ -67,12 +69,15 @@ public class PushHandler implements AtmosphereHandler {
* open by calling resource.suspend(). If there is a pending push, send it
* now.
*/
- private static PushEventCallback establishCallback = new PushEventCallback() {
+ private final PushEventCallback establishCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
getLogger().log(Level.FINER,
"New push connection with transport {0}",
resource.transport());
+
+ resource.addEventListener(PushHandler.this);
+
resource.getResponse().setContentType("text/plain; charset=UTF-8");
VaadinSession session = ui.getSession();
@@ -122,9 +127,12 @@ public class PushHandler implements AtmosphereHandler {
* the request and send changed UI state via the push channel (we do not
* respond to the request directly.)
*/
- private static PushEventCallback receiveCallback = new PushEventCallback() {
+ private final PushEventCallback receiveCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
+ getLogger().log(Level.FINER, "Received message from resource {0}",
+ resource.uuid());
+
AtmosphereRequest req = resource.getRequest();
AtmospherePushConnection connection = getConnectionForUI(ui);
@@ -167,7 +175,7 @@ public class PushHandler implements AtmosphereHandler {
/**
* Callback used when a connection is closed by the client.
*/
- PushEventCallback disconnectCallback = new PushEventCallback() {
+ private final PushEventCallback disconnectCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
PushMode pushMode = ui.getPushConfiguration().getPushMode();
@@ -187,7 +195,7 @@ public class PushHandler implements AtmosphereHandler {
* mode has been set to disabled, just clean up some stuff
* and be done with it
*/
- getLogger().log(Level.FINEST,
+ getLogger().log(Level.FINER,
"Connection closed for resource {0}", id);
} else {
/*
@@ -195,7 +203,7 @@ public class PushHandler implements AtmosphereHandler {
* tab.
*/
getLogger()
- .log(Level.FINE,
+ .log(Level.FINER,
"Connection unexpectedly closed for resource {0} with transport {1}",
new Object[] { id, resource.transport() });
}
@@ -316,7 +324,8 @@ public class PushHandler implements AtmosphereHandler {
String id = resource.uuid();
if (event.isCancelled()) {
- callWithUi(resource, disconnectCallback);
+ // Disconnected for whatever reason, handle in onDisconnect() as
+ // it's more reliable
} else if (event.isResuming()) {
// A connection that was suspended earlier was resumed (committed to
// the client.) Should only happen if the transport is JSONP or
@@ -352,6 +361,13 @@ public class PushHandler implements AtmosphereHandler {
}
@Override
+ public void onDisconnect(AtmosphereResourceEvent event) {
+ // Log event on trace level
+ super.onDisconnect(event);
+ callWithUi(event.getResource(), disconnectCallback);
+ }
+
+ @Override
public void destroy() {
}
diff --git a/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java b/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
index 3a0e59df71..6d0818b2cd 100644
--- a/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
+++ b/server/src/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
@@ -84,25 +84,26 @@ public class WidgetSetBuilder {
widgetsetFile.createNewFile();
PrintStream printStream = new PrintStream(new FileOutputStream(
widgetsetFile));
- printStream.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD "
- + "Google Web Toolkit 1.7.0//EN\" \"http://google"
- + "-web-toolkit.googlecode.com/svn/tags/1.7.0/dis"
- + "tro-source/core/src/gwt-module.dtd\">\n");
+ printStream
+ .print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN\" \"http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd\">\n");
printStream.print("<module>\n");
printStream
.print(" <!--\n"
- + " Uncomment the following to compile the widgetset for one browser only.\n"
- + " This can reduce the GWT compilation time significantly when debugging.\n"
- + " The line should be commented out before deployment to production\n"
- + " environments.\n\n"
- + " Multiple browsers can be specified for GWT 1.7 as a comma separated\n"
- + " list. The supported user agents at the moment of writing were:\n"
- + " ie6,ie8,gecko,gecko1_8,safari,opera\n\n"
- + " The value gecko1_8 is used for Firefox 3 and later and safari is used for\n"
- + " webkit based browsers including Google Chrome.\n"
+ + " Uncomment the following to compile the widgetset for one browser only.\n\n"
+ + " Multiple browsers can be specified as a comma separated list. The\n"
+ + " supported user agents at the moment of writing were:\n"
+ + " ie8,ie9,gecko1_8,safari,opera\n\n"
+ + " The value gecko1_8 is used for Firefox and safari is used for webkit\n"
+ + " based browsers including Google Chrome.\n"
+ + " -->\n"
+ + " <!-- <set-property name=\"user.agent\" value=\"safari\"/> -->\n\n"
+ + " <!--\n"
+ + " To enable SuperDevMode, uncomment this line.\n\n"
+ + " See https://vaadin.com/wiki/-/wiki/Main/Using%20SuperDevMode for more\n"
+ + " information and instructions.\n"
+ " -->\n"
- + " <!-- <set-property name=\"user.agent\" value=\"gecko1_8\"/> -->\n");
+ + " <!-- <set-configuration-property name=\"devModeRedirectEnabled\" value=\"true\" /> -->\n\n");
printStream.print("\n</module>\n");
printStream.close();
changed = true;
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index 0bf27435fb..262d47af18 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -81,7 +82,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
private Unit widthUnit = Unit.PIXELS;
private Unit heightUnit = Unit.PIXELS;
private static final Pattern sizePattern = Pattern
- .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|ex|in|cm|mm|pt|pc)?$");
+ .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$");
private ErrorHandler errorHandler = null;
@@ -176,11 +177,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
List<String> styles = getState().styles;
styles.clear();
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- styles.add(part);
- }
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ styles.add(tokenizer.nextToken());
}
}
@@ -201,8 +200,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
if (style.contains(" ")) {
// Split space separated style names and add them one by one.
- for (String realStyle : style.split(" ")) {
- addStyleName(realStyle);
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ addStyleName(tokenizer.nextToken());
}
return;
}
@@ -219,11 +219,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
@Override
public void removeStyleName(String style) {
if (ComponentStateUtil.hasStyles(getState())) {
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- getState().styles.remove(part);
- }
+ StringTokenizer tokenizer = new StringTokenizer(style, " ");
+ while (tokenizer.hasMoreTokens()) {
+ getState().styles.remove(tokenizer.nextToken());
}
}
}
diff --git a/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java b/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java
new file mode 100644
index 0000000000..968edd4b24
--- /dev/null
+++ b/server/tests/src/com/vaadin/benchmarks/PerformanceTester8759.java
@@ -0,0 +1,52 @@
+package com.vaadin.benchmarks;
+
+import com.vaadin.ui.Label;
+
+/*
+ * This simple test shows the performance difference between the StringTokenizer implementation and the String.split() implementation in AbstractComponent.
+ * Your results will vary.
+ * The real world use case motivating it was a 10k Row table, which generated labels for 10 columns.
+ * This is 1/10th of what this performance tester demonstrates.
+ *
+ * Please run with -server and -Xloggc:/tmp/gclog.vgc -verbose:gc -XX:+PrintCompilation
+ *
+ * My results Win 7 64, i7 2760QM 2.4Ghz, Java 7 21.
+ *
+ * Proposed Patch with StringTokenizer:
+ * 13 GC activations, 1.009GB allocated memory over time, total time 948ms
+ *
+ * Current String.split implementation:
+ * 31 GC activations, 2.277 GB allocated memory over time, total time 1557ms
+ *
+ */
+public class PerformanceTester8759 {
+
+ public static void main(String[] args) throws InterruptedException {
+ warmup();
+
+ long start = System.currentTimeMillis();
+ runBenchmark(1000000);
+ long end = System.currentTimeMillis();
+ System.out.println("took " + (end - start) + " ms");
+
+ }
+
+ private static void warmup() throws InterruptedException {
+ runBenchmark(10000);
+ System.gc();
+ System.out.println("warmup and gc complete. sleeping 5 seconds.");
+ Thread.sleep(5000l);
+ System.out.println("woke up - go.");
+ }
+
+ private static void runBenchmark(int loops) {
+ Label label = null;
+ for (int i = 0; i < loops; i++) {
+ label = new Label();
+ label.setStyleName("mainStyle");
+ label.addStyleName("foo bar baz");
+ label.addStyleName("vaadin");
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/server/MockUIContainingServlet.java b/server/tests/src/com/vaadin/server/MockUIContainingServlet.java
new file mode 100644
index 0000000000..d54242e31f
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/MockUIContainingServlet.java
@@ -0,0 +1,16 @@
+package com.vaadin.server;
+
+import com.vaadin.ui.UI;
+
+public class MockUIContainingServlet extends UI {
+
+ public static class ServletInUI extends VaadinServlet {
+ // This servlet should automatically be configured to use the
+ // enclosing UI class
+ }
+
+ @Override
+ protected void init(VaadinRequest request) {
+ // Do nothing
+ }
+}
diff --git a/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java b/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
index d347534f5c..3098970e6a 100644
--- a/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
+++ b/server/tests/src/com/vaadin/server/VaadinServletConfigurationTest.java
@@ -31,34 +31,21 @@ import org.junit.Test;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.DeploymentConfiguration.LegacyProperyToStringMode;
-import com.vaadin.server.VaadinServletConfigurationTest.MockUI;
-import com.vaadin.server.VaadinServletConfigurationTest.MockUI.ServletInUI;
+import com.vaadin.server.MockUIContainingServlet.ServletInUI;
import com.vaadin.ui.UI;
public class VaadinServletConfigurationTest {
- public static class MockUI extends UI {
-
- public static class ServletInUI extends VaadinServlet {
- // This servlet should automatically be configured to use the
- // enclosing UI class
- }
-
- @Override
- protected void init(VaadinRequest request) {
- // Do nothing
- }
- }
@Test
public void testEnclosingUIClass() throws Exception {
- ServletInUI servlet = new MockUI.ServletInUI();
+ ServletInUI servlet = new MockUIContainingServlet.ServletInUI();
servlet.init(new MockServletConfig());
Class<? extends UI> uiClass = new DefaultUIProvider()
.getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
EasyMock.createMock(HttpServletRequest.class), servlet
.getService())));
- Assert.assertEquals(MockUI.class, uiClass);
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
}
@Test
@@ -79,7 +66,7 @@ public class VaadinServletConfigurationTest {
.getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
EasyMock.createMock(HttpServletRequest.class), servlet
.getService())));
- Assert.assertEquals(MockUI.class, uiClass);
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
}
@Test
@@ -107,11 +94,11 @@ public class VaadinServletConfigurationTest {
.getUIClass(new UIClassSelectionEvent(new VaadinServletRequest(
EasyMock.createMock(HttpServletRequest.class), servlet
.getService())));
- Assert.assertEquals(MockUI.class, uiClass);
+ Assert.assertEquals(MockUIContainingServlet.class, uiClass);
}
}
-@VaadinServletConfiguration(productionMode = true, ui = MockUI.class, closeIdleSessions = true, heartbeatInterval = 1234, resourceCacheTime = 4321)
+@VaadinServletConfiguration(productionMode = true, ui = MockUIContainingServlet.class, closeIdleSessions = true, heartbeatInterval = 1234, resourceCacheTime = 4321)
class TestServlet extends VaadinServlet {
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/ComponentSizeParseTest.java b/server/tests/src/com/vaadin/tests/server/component/ComponentSizeParseTest.java
new file mode 100644
index 0000000000..11c0d10998
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/ComponentSizeParseTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.server.component;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.server.Sizeable.Unit;
+import com.vaadin.shared.ui.label.LabelState;
+import com.vaadin.ui.Label;
+
+public class ComponentSizeParseTest extends TestCase {
+
+ private final class LabelWithPublicState extends Label {
+ @Override
+ protected LabelState getState() {
+ return super.getState();
+ }
+ }
+
+ public void testAllTheUnit() {
+ testUnit("10.0px", 10, Unit.PIXELS);
+ testUnit("10.0pt", 10, Unit.POINTS);
+ testUnit("10.0pc", 10, Unit.PICAS);
+ testUnit("10.0em", 10, Unit.EM);
+ testUnit("10.0rem", 10, Unit.REM);
+ testUnit("10.0mm", 10, Unit.MM);
+ testUnit("10.0cm", 10, Unit.CM);
+ testUnit("10.0in", 10, Unit.INCH);
+ testUnit("10.0%", 10, Unit.PERCENTAGE);
+ }
+
+ private void testUnit(String string, int amout, Unit unit) {
+ LabelWithPublicState label = new LabelWithPublicState();
+ label.setHeight(string);
+
+ Assert.assertEquals(amout, label.getHeight(), 0);
+ Assert.assertEquals(unit, label.getHeightUnits());
+
+ label = new LabelWithPublicState();
+
+ label.setHeight(10, unit);
+ label.beforeClientResponse(true);
+ Assert.assertEquals(string, label.getState().height);
+ }
+}
diff --git a/theme-compiler/ivy.xml b/theme-compiler/ivy.xml
index 97ecfa4416..6a7528ceeb 100644
--- a/theme-compiler/ivy.xml
+++ b/theme-compiler/ivy.xml
@@ -45,7 +45,7 @@
<!-- Internally used, for now -->
<dependency org="com.carrotsearch" name="smartsprites"
- rev="0.2.10-vaadin" />
+ rev="0.2.10" />
<!-- Use the same commons-io as the rest of the project -->
<override org="commons-io" module="commons-io" rev="2.2" />
</dependencies>
diff --git a/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.html b/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.html
new file mode 100644
index 0000000000..0bdde03ec7
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.html
@@ -0,0 +1,32 @@
+<?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.components.abstractcomponent.RemSizeUnitTest?restartApplication&amp;debug</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertElementHeight</td>
+ <td>vaadin=runcomvaadintestscomponentsabstractcomponentRemSizeUnitTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
+ <td>80</td>
+</tr>
+<tr>
+ <td>assertElementWidth</td>
+ <td>vaadin=runcomvaadintestscomponentsabstractcomponentRemSizeUnitTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td>
+ <td>168</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.java b/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.java
new file mode 100644
index 0000000000..98c0538cd8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/abstractcomponent/RemSizeUnitTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.components.abstractcomponent;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.WebBrowser;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+
+public class RemSizeUnitTest extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ Label label = new Label("My height is 10.5 x 5 rem");
+ label.setHeight("5rem");
+ label.setWidth(10.5f, Unit.REM);
+
+ // Rem not supported in ie8, fake using pixels
+ WebBrowser webBrowser = getPage().getWebBrowser();
+ if (webBrowser.isIE() && webBrowser.getBrowserMajorVersion() == 8) {
+ label.setHeight("80px");
+ label.setWidth("168px");
+ }
+
+ addComponent(label);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Tests that REM units are properly applied to the DOM";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(11279);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.html b/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.html
new file mode 100644
index 0000000000..87bf0edb49
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.html
@@ -0,0 +1,94 @@
+<?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="http://localhost:8888/" />
+<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.components.formlayout.CaptionEnableDisable?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VCheckBox[0]</td>
+ <td>v-disabled</td>
+</tr>
+<!--Enable-->
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertNotCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VCheckBox[0]</td>
+ <td>v-disabled</td>
+</tr>
+<!--Disable-->
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+ <td>v-disabled</td>
+</tr>
+<tr>
+ <td>assertCSSClass</td>
+ <td>vaadin=runcomvaadintestscomponentsformlayoutCaptionEnableDisable::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VCheckBox[0]</td>
+ <td>v-disabled</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.java b/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.java
new file mode 100644
index 0000000000..ce9067df29
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/formlayout/CaptionEnableDisable.java
@@ -0,0 +1,61 @@
+package com.vaadin.tests.components.formlayout;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.TextField;
+
+public class CaptionEnableDisable extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ setContent(createFormLayout());
+
+ }
+
+ public FormLayout createFormLayout() {
+ FormLayout layout = new FormLayout();
+ final TextField textField = new TextField("TextField");
+ textField.setEnabled(false);
+ layout.addComponent(textField);
+
+ final ComboBox combobox = new ComboBox("Combobox");
+ combobox.setEnabled(false);
+ layout.addComponent(combobox);
+
+ final NativeSelect nativeSelect = new NativeSelect("NativeSelect");
+ nativeSelect.setEnabled(false);
+ layout.addComponent(nativeSelect);
+
+ final CheckBox checkBox = new CheckBox("Checkbox");
+ checkBox.setEnabled(false);
+ layout.addComponent(checkBox);
+
+ layout.addComponent(new Button("Toggle components enabled",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ combobox.setEnabled(!combobox.isEnabled());
+ textField.setEnabled(!textField.isEnabled());
+ checkBox.setEnabled(!checkBox.isEnabled());
+ nativeSelect.setEnabled(!nativeSelect.isEnabled());
+ }
+ }));
+ return layout;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12062;
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.html b/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.html
new file mode 100644
index 0000000000..0ad58823be
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.html
@@ -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.components.gridlayout.LayoutAfterHidingError?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsgridlayoutLayoutAfterHidingError::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VPanel[0]/VGridLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>withError</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsgridlayoutLayoutAfterHidingError::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VPanel[0]/VGridLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>withoutError</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.java b/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.java
new file mode 100644
index 0000000000..dc04e23f02
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/gridlayout/LayoutAfterHidingError.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.components.gridlayout;
+
+import com.vaadin.server.UserError;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Panel;
+
+public class LayoutAfterHidingError extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Panel panel = new Panel();
+ panel.setWidth("300px");
+ addComponent(panel);
+
+ GridLayout gl = new GridLayout();
+ gl.setWidth("100%");
+ panel.setContent(gl);
+
+ final DateField df = new DateField();
+ df.setWidth("100%");
+ gl.addComponent(df);
+
+ Button err = new Button("Set error");
+ err.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ df.setComponentError(new UserError("foo"));
+ }
+ });
+ gl.addComponent(err);
+
+ err = new Button("Clear error");
+ err.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ df.setComponentError(null);
+ }
+ });
+ gl.addComponent(err);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Setting an error icon for a component in GridLayout and then removing it should properly re-size the component";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12011;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.html b/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.html
new file mode 100644
index 0000000000..d2ca843cf5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.html
@@ -0,0 +1,32 @@
+<?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="http://localhost:8888/" />
+<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>/statictestfiles/PopupViewInEmbeddedApplication.html</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=helloworld::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPopupView[0]</td>
+ <td>28,16</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>popup-on-link</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.java
new file mode 100644
index 0000000000..d19f98124e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewInEmbeddedApplication.java
@@ -0,0 +1,30 @@
+package com.vaadin.tests.components.popupview;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+
+/*
+ * Used by PopupViewInEmbedded.html
+ */
+public class PopupViewInEmbeddedApplication extends TestBase {
+
+ @Override
+ protected void setup() {
+ PopupView pop = new PopupView("Click me!", new Label(
+ "I popped up, woohoo!"));
+ addComponent(pop);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Clicking on the popup link should pop up the popup on top of the link,"
+ + " even though the application has been embedded inside a div.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 7110;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html b/uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html
index a0ebb3bf27..f5b7e0a1df 100644
--- a/uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html
+++ b/uitest/src/com/vaadin/tests/debug/HierarchyAfterAnalyzeLayouts.html
@@ -18,7 +18,7 @@
</tr>
<tr>
<td>click</td>
- <td>vaadin=runcomvaadintestsdebugHierarchyAfterAnalyzeLayouts::Root/VDebugWindow[0]/FlowPanel[0]/FlowPanel[0]/FlowPanel[0]/domChild[1]</td>
+ <td>vaadin=runcomvaadintestsdebugHierarchyAfterAnalyzeLayouts::Root/VDebugWindow[0]/FlowPanel[0]/FlowPanel[0]/FlowPanel[0]/DebugButton[2]</td>
<td>18,9</td>
</tr>
<tr>