summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2014-07-02 15:02:02 +0300
committerLeif Åstrand <leif@vaadin.com>2014-11-25 08:12:08 +0000
commitec1d9a12ca0e1e7e6ae13d58d9b361c19986cdd3 (patch)
tree1eb42c436d9b75ec9471abd5bc9c81a77e8506d3
parent759ec0e19569ba6b0d0e43f68cdd25e26ecf55d6 (diff)
downloadvaadin-framework-ec1d9a12ca0e1e7e6ae13d58d9b361c19986cdd3.tar.gz
vaadin-framework-ec1d9a12ca0e1e7e6ae13d58d9b361c19986cdd3.zip
Add @NoLayout annotation (#12936)
This commit adds support for @NoLayout and updates most framework components to use the annotation where it makes sense Change-Id: I99320a6aa6de717da5f2463dd8acfcd412165767
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java22
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java4
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java20
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java68
-rw-r--r--client/src/com/vaadin/client/communication/RpcManager.java17
-rw-r--r--client/src/com/vaadin/client/metadata/Method.java14
-rw-r--r--client/src/com/vaadin/client/metadata/Property.java13
-rw-r--r--client/src/com/vaadin/client/metadata/TypeDataStore.java54
-rw-r--r--shared/src/com/vaadin/shared/AbstractComponentState.java3
-rw-r--r--shared/src/com/vaadin/shared/annotations/NoLayout.java43
-rw-r--r--shared/src/com/vaadin/shared/communication/SharedState.java2
-rw-r--r--shared/src/com/vaadin/shared/data/DataProviderRpc.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/AbstractEmbeddedState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/AbstractMediaState.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/MediaControl.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/TabIndexState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/button/ButtonState.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/datefield/PopupDateFieldState.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/datefield/TextualDateFieldState.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/panel/PanelState.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/popupview/PopupViewState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/slider/SliderState.java5
-rw-r--r--shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/textarea/TextAreaState.java2
-rw-r--r--shared/src/com/vaadin/shared/ui/textfield/AbstractTextFieldState.java4
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java3
-rw-r--r--shared/src/com/vaadin/shared/ui/window/WindowState.java15
-rw-r--r--uitest/src/com/vaadin/tests/serialization/NoLayout.java101
-rw-r--r--uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java84
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java61
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java26
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java2
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java26
35 files changed, 611 insertions, 15 deletions
diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java
index 7c3bb1eb77..13bd7051f6 100644
--- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java
+++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java
@@ -68,6 +68,7 @@ import com.vaadin.server.widgetsetutils.metadata.TypeVisitor;
import com.vaadin.server.widgetsetutils.metadata.WidgetInitVisitor;
import com.vaadin.shared.annotations.Delayed;
import com.vaadin.shared.annotations.DelegateToWidget;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.ClientRpc;
import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.ui.Connect;
@@ -454,6 +455,10 @@ public class ConnectorBundleLoaderFactory extends Generator {
writer.println("var data = {");
writer.indent();
+ if (property.getAnnotation(NoLayout.class) != null) {
+ writer.println("noLayout: 1, ");
+ }
+
writer.println("setter: function(bean, value) {");
writer.indent();
property.writeSetterBody(logger, writer, "bean", "value");
@@ -497,6 +502,7 @@ public class ConnectorBundleLoaderFactory extends Generator {
writeParamTypes(w, bundle);
writeProxys(w, bundle);
writeDelayedInfo(w, bundle);
+ writeNoLayoutRpcMethods(w, bundle);
w.println("%s(store);", loadNativeJsMethodName);
@@ -509,6 +515,22 @@ public class ConnectorBundleLoaderFactory extends Generator {
writeOnStateChangeHandlers(logger, w, bundle);
}
+ private void writeNoLayoutRpcMethods(SplittingSourceWriter w,
+ ConnectorBundle bundle) {
+ Map<JClassType, Set<JMethod>> needsNoLayout = bundle
+ .getNeedsNoLayoutRpcMethods();
+ for (Entry<JClassType, Set<JMethod>> entry : needsNoLayout.entrySet()) {
+ JClassType type = entry.getKey();
+
+ for (JMethod method : entry.getValue()) {
+ w.println("store.setNoLayoutRpcMethod(%s, \"%s\");",
+ getClassLiteralString(type), method.getName());
+ }
+
+ w.splitIfNeeded();
+ }
+ }
+
private void writeOnStateChangeHandlers(TreeLogger logger,
SplittingSourceWriter w, ConnectorBundle bundle)
throws UnableToCompleteException {
diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java
index 856f67657f..1df3d78588 100644
--- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java
+++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java
@@ -24,6 +24,7 @@ import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JType;
+import com.vaadin.shared.annotations.NoLayout;
public class ClientRpcVisitor extends TypeVisitor {
@Override
@@ -39,6 +40,9 @@ public class ClientRpcVisitor extends TypeVisitor {
bundle.setNeedsInvoker(type, method);
bundle.setNeedsParamTypes(type, method);
+ if (method.getAnnotation(NoLayout.class) != null) {
+ bundle.setNeedsNoLayoutRpcMethod(type, method);
+ }
JType[] parameterTypes = method.getParameterTypes();
for (JType paramType : parameterTypes) {
diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java
index 4a079c38b0..2c2d091d5e 100644
--- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java
+++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java
@@ -73,6 +73,7 @@ public class ConnectorBundle {
private final Map<JClassType, Set<JMethod>> needsParamTypes = new HashMap<JClassType, Set<JMethod>>();
private final Map<JClassType, Set<JMethod>> needsDelayedInfo = new HashMap<JClassType, Set<JMethod>>();
private final Map<JClassType, Set<JMethod>> needsOnStateChange = new HashMap<JClassType, Set<JMethod>>();
+ private final Map<JClassType, Set<JMethod>> needsNoLayoutRpcMethods = new HashMap<JClassType, Set<JMethod>>();
private final Set<Property> needsProperty = new HashSet<Property>();
private final Map<JClassType, Set<Property>> needsDelegateToWidget = new HashMap<JClassType, Set<Property>>();
@@ -634,6 +635,25 @@ public class ConnectorBundle {
return Collections.unmodifiableMap(needsOnStateChange);
}
+ public void setNeedsNoLayoutRpcMethod(JClassType type, JMethod method) {
+ if (!isNeedsNoLayoutRpcMethod(type, method)) {
+ addMapping(needsNoLayoutRpcMethods, type, method);
+ }
+ }
+
+ private boolean isNeedsNoLayoutRpcMethod(JClassType type, JMethod method) {
+ if (hasMapping(needsNoLayoutRpcMethods, type, method)) {
+ return true;
+ } else {
+ return previousBundle != null
+ && previousBundle.isNeedsNoLayoutRpcMethod(type, method);
+ }
+ }
+
+ public Map<JClassType, Set<JMethod>> getNeedsNoLayoutRpcMethods() {
+ return Collections.unmodifiableMap(needsNoLayoutRpcMethods);
+ }
+
public static JMethod findInheritedMethod(JClassType type,
String methodName, JType... params) {
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index cba9639067..dd780406fa 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -100,6 +100,7 @@ import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JsonConstants;
import com.vaadin.shared.Version;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.shared.communication.SharedState;
@@ -1541,6 +1542,8 @@ public class ApplicationConnection implements HasHandlers {
}
Command c = new Command() {
+ private boolean onlyNoLayoutUpdates = true;
+
@Override
public void execute() {
assert syncId == -1 || syncId == lastSeenServerSyncId;
@@ -1630,15 +1633,17 @@ public class ApplicationConnection implements HasHandlers {
+ (Duration.currentTimeMillis() - processUidlStart)
+ " ms");
- Profiler.enter("Layout processing");
- try {
- LayoutManager layoutManager = getLayoutManager();
- layoutManager.setEverythingNeedsMeasure();
- layoutManager.layoutNow();
- } catch (final Throwable e) {
- VConsole.error(e);
+ if (!onlyNoLayoutUpdates) {
+ Profiler.enter("Layout processing");
+ try {
+ LayoutManager layoutManager = getLayoutManager();
+ layoutManager.setEverythingNeedsMeasure();
+ layoutManager.layoutNow();
+ } catch (final Throwable e) {
+ VConsole.error(e);
+ }
+ Profiler.leave("Layout processing");
}
- Profiler.leave("Layout processing");
if (ApplicationConfiguration.isDebugMode()) {
Profiler.enter("Dumping state changes to the console");
@@ -1942,6 +1947,11 @@ public class ApplicationConnection implements HasHandlers {
if (connector != null) {
continue;
}
+
+ // Always do layouts if there's at least one new
+ // connector
+ onlyNoLayoutUpdates = false;
+
int connectorType = Integer.parseInt(types
.getString(connectorId));
@@ -1983,6 +1993,11 @@ public class ApplicationConnection implements HasHandlers {
JsArray<ValueMap> changes = json.getJSValueMapArray("changes");
int length = changes.length();
+ // Must always do layout if there's even a single legacy update
+ if (length != 0) {
+ onlyNoLayoutUpdates = false;
+ }
+
VConsole.log(" * Passing UIDL to Vaadin 6 style connectors");
// update paintables
for (int i = 0; i < length; i++) {
@@ -2111,11 +2126,26 @@ public class ApplicationConnection implements HasHandlers {
}
SharedState state = connector.getState();
+ Type stateType = new Type(state.getClass()
+ .getName(), null);
+
+ if (onlyNoLayoutUpdates) {
+ Profiler.enter("updateConnectorState @NoLayout handling");
+ Set<String> keySet = stateJson.keySet();
+ for (String propertyName : keySet) {
+ Property property = stateType
+ .getProperty(propertyName);
+ if (!property.isNoLayout()) {
+ onlyNoLayoutUpdates = false;
+ break;
+ }
+ }
+ Profiler.leave("updateConnectorState @NoLayout handling");
+ }
Profiler.enter("updateConnectorState decodeValue");
- JsonDecoder.decodeValue(new Type(state.getClass()
- .getName(), null), stateJson, state,
- ApplicationConnection.this);
+ JsonDecoder.decodeValue(stateType, stateJson,
+ state, ApplicationConnection.this);
Profiler.leave("updateConnectorState decodeValue");
if (Profiler.isEnabled()) {
@@ -2332,6 +2362,10 @@ public class ApplicationConnection implements HasHandlers {
Profiler.leave("updateConnectorHierarchy detach removed connectors");
+ if (result.events.size() != 0) {
+ onlyNoLayoutUpdates = false;
+ }
+
Profiler.leave("updateConnectorHierarchy");
return result;
@@ -2460,8 +2494,16 @@ public class ApplicationConnection implements HasHandlers {
for (int i = 0; i < rpcLength; i++) {
try {
JSONArray rpcCall = (JSONArray) rpcCalls.get(i);
- rpcManager.parseAndApplyInvocation(rpcCall,
- ApplicationConnection.this);
+ MethodInvocation invocation = rpcManager
+ .parseAndApplyInvocation(rpcCall,
+ ApplicationConnection.this);
+
+ if (onlyNoLayoutUpdates
+ && !RpcManager.getMethod(invocation)
+ .isNoLayout()) {
+ onlyNoLayoutUpdates = false;
+ }
+
} catch (final Throwable e) {
VConsole.error(e);
}
diff --git a/client/src/com/vaadin/client/communication/RpcManager.java b/client/src/com/vaadin/client/communication/RpcManager.java
index 7b706fca2d..efedfe12a9 100644
--- a/client/src/com/vaadin/client/communication/RpcManager.java
+++ b/client/src/com/vaadin/client/communication/RpcManager.java
@@ -64,7 +64,18 @@ public class RpcManager {
}
}
- private Method getMethod(MethodInvocation invocation) {
+ /**
+ * Gets the method that an invocation targets.
+ *
+ * @param invocation
+ * the method invocation to get the method for
+ *
+ * @since
+ * @return the method targeted by this invocation
+ */
+ public static Method getMethod(MethodInvocation invocation) {
+ // Implemented here instead of in MethodInovcation since it's in shared
+ // and can't use our Method class.
Type type = new Type(invocation.getInterfaceName(), null);
Method method = type.getMethod(invocation.getMethodName());
return method;
@@ -86,7 +97,7 @@ public class RpcManager {
}
}
- public void parseAndApplyInvocation(JSONArray rpcCall,
+ public MethodInvocation parseAndApplyInvocation(JSONArray rpcCall,
ApplicationConnection connection) {
ConnectorMap connectorMap = ConnectorMap.get(connection);
@@ -114,6 +125,8 @@ public class RpcManager {
VConsole.log("Server to client RPC call: " + invocation);
applyInvocation(invocation, connector);
}
+
+ return invocation;
}
private void parseMethodParameters(MethodInvocation methodInvocation,
diff --git a/client/src/com/vaadin/client/metadata/Method.java b/client/src/com/vaadin/client/metadata/Method.java
index d6b474fabc..d88dbf876e 100644
--- a/client/src/com/vaadin/client/metadata/Method.java
+++ b/client/src/com/vaadin/client/metadata/Method.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.client.metadata;
+import com.vaadin.shared.annotations.NoLayout;
+
public class Method {
private final Type type;
@@ -100,4 +102,16 @@ public class Method {
return TypeDataStore.isLastOnly(this);
}
+ /**
+ * Checks whether this method is annotated with {@link NoLayout}.
+ *
+ * @since
+ *
+ * @return <code>true</code> if this method has a NoLayout annotation;
+ * otherwise <code>false</code>
+ */
+ public boolean isNoLayout() {
+ return TypeDataStore.isNoLayoutRpcMethod(this);
+ }
+
}
diff --git a/client/src/com/vaadin/client/metadata/Property.java b/client/src/com/vaadin/client/metadata/Property.java
index f421a5525b..5825cf12d3 100644
--- a/client/src/com/vaadin/client/metadata/Property.java
+++ b/client/src/com/vaadin/client/metadata/Property.java
@@ -16,6 +16,7 @@
package com.vaadin.client.metadata;
import com.vaadin.shared.annotations.DelegateToWidget;
+import com.vaadin.shared.annotations.NoLayout;
public class Property {
private final Type bean;
@@ -127,4 +128,16 @@ public class Property {
return b.toString();
}
+ /**
+ * Checks whether this property is annotated with {@link NoLayout}.
+ *
+ * @since
+ *
+ * @return <code>true</code> if this property has a NoLayout annotation;
+ * otherwise <code>false</code>
+ */
+ public boolean isNoLayout() {
+ return TypeDataStore.isNoLayoutProperty(this);
+ }
+
}
diff --git a/client/src/com/vaadin/client/metadata/TypeDataStore.java b/client/src/com/vaadin/client/metadata/TypeDataStore.java
index 9b1fd7d45c..a402973651 100644
--- a/client/src/com/vaadin/client/metadata/TypeDataStore.java
+++ b/client/src/com/vaadin/client/metadata/TypeDataStore.java
@@ -25,6 +25,7 @@ import com.vaadin.client.FastStringSet;
import com.vaadin.client.JsArrayObject;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.JSONSerializer;
+import com.vaadin.shared.annotations.NoLayout;
public class TypeDataStore {
private static final String CONSTRUCTOR_NAME = "!new";
@@ -48,6 +49,7 @@ public class TypeDataStore {
private final FastStringSet delayedMethods = FastStringSet.create();
private final FastStringSet lastOnlyMethods = FastStringSet.create();
+ private final FastStringSet noLayoutRpcMethods = FastStringSet.create();
private final FastStringMap<Type> returnTypes = FastStringMap.create();
private final FastStringMap<Invoker> invokers = FastStringMap.create();
@@ -345,6 +347,12 @@ public class TypeDataStore {
return typeData[beanName][propertyName].setter !== undefined;
}-*/;
+ private static native boolean hasNoLayout(JavaScriptObject typeData,
+ String beanName, String propertyName)
+ /*-{
+ return typeData[beanName][propertyName].noLayout !== undefined;
+ }-*/;
+
private static native Object getJsPropertyValue(JavaScriptObject typeData,
String beanName, String propertyName, Object beanInstance)
/*-{
@@ -429,4 +437,50 @@ public class TypeDataStore {
propertyHandlers.add(method);
}
}
+
+ /**
+ * Checks whether the provided method is annotated with {@link NoLayout}.
+ *
+ * @param method
+ * the rpc method to check
+ *
+ * @since
+ *
+ * @return <code>true</code> if the method has a NoLayout annotation;
+ * otherwise <code>false</code>
+ */
+ public static boolean isNoLayoutRpcMethod(Method method) {
+ return get().noLayoutRpcMethods.contains(method.getLookupKey());
+ }
+
+ /**
+ * Defines that a method is annotated with {@link NoLayout}.
+ *
+ * @since
+ *
+ * @param type
+ * the where the method is defined
+ * @param methodName
+ * the name of the method
+ */
+ public void setNoLayoutRpcMethod(Class<?> type, String methodName) {
+ noLayoutRpcMethods.add(new Method(getType(type), methodName)
+ .getLookupKey());
+ }
+
+ /**
+ * Checks whether the provided property is annotated with {@link NoLayout}.
+ *
+ * @param property
+ * the property to check
+ *
+ * @since
+ *
+ * @return <code>true</code> if the property has a NoLayout annotation;
+ * otherwise <code>false</code>
+ */
+ public static boolean isNoLayoutProperty(Property property) {
+ return hasNoLayout(get().jsTypeData, property.getBeanType()
+ .getSignature(), property.getName());
+ }
}
diff --git a/shared/src/com/vaadin/shared/AbstractComponentState.java b/shared/src/com/vaadin/shared/AbstractComponentState.java
index 816af978cf..f144f9e48b 100644
--- a/shared/src/com/vaadin/shared/AbstractComponentState.java
+++ b/shared/src/com/vaadin/shared/AbstractComponentState.java
@@ -18,6 +18,7 @@ package com.vaadin.shared;
import java.util.List;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.SharedState;
/**
@@ -31,7 +32,9 @@ public class AbstractComponentState extends SharedState {
public String height = "";
public String width = "";
public boolean readOnly = false;
+ @NoLayout
public boolean immediate = false;
+ @NoLayout
public String description = "";
// Note: for the caption, there is a difference between null and an empty
// string!
diff --git a/shared/src/com/vaadin/shared/annotations/NoLayout.java b/shared/src/com/vaadin/shared/annotations/NoLayout.java
new file mode 100644
index 0000000000..78ff1e2984
--- /dev/null
+++ b/shared/src/com/vaadin/shared/annotations/NoLayout.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 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.shared.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to mark client RPC methods, state fields, or state setter
+ * methods that should not trigger an layout phase after changes have been
+ * processed. Whenever there's at least one change that is not marked with this
+ * annotation, the framework will assume some sizes might have changed an will
+ * therefore start a layout phase after applying the changes.
+ * <p>
+ * This annotation can be used for any RPC method or state property that does
+ * not cause the size of the component or its children to change. Please note
+ * that almost anything related to CSS (e.g. adding or removing a stylename) has
+ * the potential of causing sizes to change with appropriate style definitions
+ * in the application theme.
+ *
+ * @since
+ *
+ * @author Vaadin Ltd
+ */
+@Documented
+@Target({ ElementType.METHOD, ElementType.FIELD })
+public @interface NoLayout {
+ // Just an empty marker annotation
+}
diff --git a/shared/src/com/vaadin/shared/communication/SharedState.java b/shared/src/com/vaadin/shared/communication/SharedState.java
index e16fc51fae..b21a675a4a 100644
--- a/shared/src/com/vaadin/shared/communication/SharedState.java
+++ b/shared/src/com/vaadin/shared/communication/SharedState.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Set;
import com.vaadin.shared.Connector;
+import com.vaadin.shared.annotations.NoLayout;
/**
* Interface to be implemented by all shared state classes used to communicate
@@ -64,6 +65,7 @@ public class SharedState implements Serializable {
/**
* A set of event identifiers with registered listeners.
*/
+ @NoLayout
public Set<String> registeredEventListeners = null;
}
diff --git a/shared/src/com/vaadin/shared/data/DataProviderRpc.java b/shared/src/com/vaadin/shared/data/DataProviderRpc.java
index 043818d573..3e5dd9a332 100644
--- a/shared/src/com/vaadin/shared/data/DataProviderRpc.java
+++ b/shared/src/com/vaadin/shared/data/DataProviderRpc.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.data;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.ClientRpc;
/**
@@ -51,6 +52,7 @@ public interface DataProviderRpc extends ClientRpc {
* @see com.vaadin.shared.ui.grid.GridState#JSONKEY_DATA
* @see com.vaadin.ui.components.grid.Renderer#encode(Object)
*/
+ @NoLayout
public void setRowData(int firstRowIndex, String rowDataJson);
/**
@@ -62,6 +64,7 @@ public interface DataProviderRpc extends ClientRpc {
* the number of rows removed from <code>firstRowIndex</code> and
* onwards
*/
+ @NoLayout
public void removeRowData(int firstRowIndex, int count);
/**
@@ -72,6 +75,7 @@ public interface DataProviderRpc extends ClientRpc {
* @param count
* the number of rows inserted at <code>firstRowIndex</code>
*/
+ @NoLayout
public void insertRowData(int firstRowIndex, int count);
/**
diff --git a/shared/src/com/vaadin/shared/ui/AbstractEmbeddedState.java b/shared/src/com/vaadin/shared/ui/AbstractEmbeddedState.java
index f5779de43d..0cb9be8702 100644
--- a/shared/src/com/vaadin/shared/ui/AbstractEmbeddedState.java
+++ b/shared/src/com/vaadin/shared/ui/AbstractEmbeddedState.java
@@ -16,10 +16,12 @@
package com.vaadin.shared.ui;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
public class AbstractEmbeddedState extends AbstractComponentState {
public static final String SOURCE_RESOURCE = "source";
+ @NoLayout
public String alternateText;
}
diff --git a/shared/src/com/vaadin/shared/ui/AbstractMediaState.java b/shared/src/com/vaadin/shared/ui/AbstractMediaState.java
index d2ef09810b..3029bedca7 100644
--- a/shared/src/com/vaadin/shared/ui/AbstractMediaState.java
+++ b/shared/src/com/vaadin/shared/ui/AbstractMediaState.java
@@ -19,17 +19,21 @@ import java.util.ArrayList;
import java.util.List;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.URLReference;
public class AbstractMediaState extends AbstractComponentState {
public boolean showControls;
+ @NoLayout
public String altText;
public boolean htmlContentAllowed;
+ @NoLayout
public boolean autoplay;
+ @NoLayout
public boolean muted;
public List<URLReference> sources = new ArrayList<URLReference>();
diff --git a/shared/src/com/vaadin/shared/ui/MediaControl.java b/shared/src/com/vaadin/shared/ui/MediaControl.java
index 2311d57b16..ab31d6f95f 100644
--- a/shared/src/com/vaadin/shared/ui/MediaControl.java
+++ b/shared/src/com/vaadin/shared/ui/MediaControl.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.ClientRpc;
/**
@@ -27,10 +28,12 @@ public interface MediaControl extends ClientRpc {
/**
* Start playing the media.
*/
+ @NoLayout
public void play();
/**
* Pause playback of the media.
*/
+ @NoLayout
public void pause();
}
diff --git a/shared/src/com/vaadin/shared/ui/TabIndexState.java b/shared/src/com/vaadin/shared/ui/TabIndexState.java
index eec61a0595..1afe982546 100644
--- a/shared/src/com/vaadin/shared/ui/TabIndexState.java
+++ b/shared/src/com/vaadin/shared/ui/TabIndexState.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
/**
* Interface implemented by state classes that support tab indexes.
@@ -29,6 +30,7 @@ public class TabIndexState extends AbstractComponentState {
/**
* The <i>tabulator index</i> of the field.
*/
+ @NoLayout
public int tabIndex = 0;
}
diff --git a/shared/src/com/vaadin/shared/ui/button/ButtonState.java b/shared/src/com/vaadin/shared/ui/button/ButtonState.java
index a12136870c..e5b94d95c4 100644
--- a/shared/src/com/vaadin/shared/ui/button/ButtonState.java
+++ b/shared/src/com/vaadin/shared/ui/button/ButtonState.java
@@ -17,6 +17,7 @@
package com.vaadin.shared.ui.button;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.ui.TabIndexState;
/**
@@ -31,11 +32,14 @@ public class ButtonState extends TabIndexState {
{
primaryStyleName = "v-button";
}
+ @NoLayout
public boolean disableOnClick = false;
+ @NoLayout
public int clickShortcutKeyCode = 0;
/**
* If caption should be rendered in HTML
*/
public boolean htmlContentAllowed = false;
+ @NoLayout
public String iconAltText = "";
}
diff --git a/shared/src/com/vaadin/shared/ui/datefield/PopupDateFieldState.java b/shared/src/com/vaadin/shared/ui/datefield/PopupDateFieldState.java
index 07726f8af0..6f10af4314 100644
--- a/shared/src/com/vaadin/shared/ui/datefield/PopupDateFieldState.java
+++ b/shared/src/com/vaadin/shared/ui/datefield/PopupDateFieldState.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.shared.ui.datefield;
+import com.vaadin.shared.annotations.NoLayout;
+
public class PopupDateFieldState extends TextualDateFieldState {
public static final String DESCRIPTION_FOR_ASSISTIVE_DEVICES = "Arrow down key opens calendar element for choosing the date";
@@ -23,5 +25,6 @@ public class PopupDateFieldState extends TextualDateFieldState {
}
public boolean textFieldEnabled = true;
+ @NoLayout
public String descriptionForAssistiveDevices = DESCRIPTION_FOR_ASSISTIVE_DEVICES;
}
diff --git a/shared/src/com/vaadin/shared/ui/datefield/TextualDateFieldState.java b/shared/src/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
index 09bfb9c1a1..bf38ee04a9 100644
--- a/shared/src/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
+++ b/shared/src/com/vaadin/shared/ui/datefield/TextualDateFieldState.java
@@ -18,6 +18,7 @@ package com.vaadin.shared.ui.datefield;
import java.util.Date;
import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.NoLayout;
public class TextualDateFieldState extends AbstractFieldState {
{
@@ -28,11 +29,13 @@ public class TextualDateFieldState extends AbstractFieldState {
* Start range that has been cleared, depending on the resolution of the
* date field
*/
+ @NoLayout
public Date rangeStart = null;
/*
* End range that has been cleared, depending on the resolution of the date
* field
*/
+ @NoLayout
public Date rangeEnd = null;
}
diff --git a/shared/src/com/vaadin/shared/ui/panel/PanelState.java b/shared/src/com/vaadin/shared/ui/panel/PanelState.java
index 6c0fcb683c..8f48fad921 100644
--- a/shared/src/com/vaadin/shared/ui/panel/PanelState.java
+++ b/shared/src/com/vaadin/shared/ui/panel/PanelState.java
@@ -16,11 +16,14 @@
package com.vaadin.shared.ui.panel;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
public class PanelState extends AbstractComponentState {
{
primaryStyleName = "v-panel";
}
+ @NoLayout
public int tabIndex;
+ @NoLayout
public int scrollLeft, scrollTop;
}
diff --git a/shared/src/com/vaadin/shared/ui/popupview/PopupViewState.java b/shared/src/com/vaadin/shared/ui/popupview/PopupViewState.java
index da49e47ae8..86fda428a1 100644
--- a/shared/src/com/vaadin/shared/ui/popupview/PopupViewState.java
+++ b/shared/src/com/vaadin/shared/ui/popupview/PopupViewState.java
@@ -16,10 +16,12 @@
package com.vaadin.shared.ui.popupview;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
public class PopupViewState extends AbstractComponentState {
public String html;
+ @NoLayout
public boolean hideOnMouseOut;
}
diff --git a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java
index 79ef766951..6f557489dd 100644
--- a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java
+++ b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressBarState.java
@@ -17,6 +17,7 @@
package com.vaadin.shared.ui.progressindicator;
import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.SharedState;
/**
@@ -32,6 +33,7 @@ public class ProgressBarState extends AbstractFieldState {
primaryStyleName = PRIMARY_STYLE_NAME;
}
public boolean indeterminate = false;
+ @NoLayout
public Float state = 0.0f;
}
diff --git a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
index 15d0a947d7..9b3cf94d4a 100644
--- a/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
+++ b/shared/src/com/vaadin/shared/ui/progressindicator/ProgressIndicatorState.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.shared.ui.progressindicator;
+import com.vaadin.shared.annotations.NoLayout;
+
@Deprecated
public class ProgressIndicatorState extends ProgressBarState {
public static final String PRIMARY_STYLE_NAME = "v-progressindicator";
@@ -23,5 +25,6 @@ public class ProgressIndicatorState extends ProgressBarState {
primaryStyleName = PRIMARY_STYLE_NAME;
}
+ @NoLayout
public int pollingInterval = 1000;
}
diff --git a/shared/src/com/vaadin/shared/ui/slider/SliderState.java b/shared/src/com/vaadin/shared/ui/slider/SliderState.java
index 0e48a0c4e2..a96d35bc13 100644
--- a/shared/src/com/vaadin/shared/ui/slider/SliderState.java
+++ b/shared/src/com/vaadin/shared/ui/slider/SliderState.java
@@ -16,21 +16,26 @@
package com.vaadin.shared.ui.slider;
import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.NoLayout;
public class SliderState extends AbstractFieldState {
{
primaryStyleName = "v-slider";
}
+ @NoLayout
public double value;
+ @NoLayout
public double maxValue = 100;
+ @NoLayout
public double minValue = 0;
/**
* The number of fractional digits that are considered significant. Must be
* non-negative.
*/
+ @NoLayout
public int resolution = 0;
public SliderOrientation orientation = SliderOrientation.HORIZONTAL;
diff --git a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
index 98a1d2b87f..69a3330f64 100644
--- a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
+++ b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.List;
import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.annotations.NoLayout;
public class TabsheetState extends AbstractComponentState {
public static final String PRIMARY_STYLE_NAME = "v-tabsheet";
@@ -31,6 +32,7 @@ public class TabsheetState extends AbstractComponentState {
* Index of the component when switching focus - not related to Tabsheet
* tabs.
*/
+ @NoLayout
public int tabIndex;
public List<TabState> tabs = new ArrayList<TabState>();
diff --git a/shared/src/com/vaadin/shared/ui/textarea/TextAreaState.java b/shared/src/com/vaadin/shared/ui/textarea/TextAreaState.java
index 380ee4c7fb..c1f9536278 100644
--- a/shared/src/com/vaadin/shared/ui/textarea/TextAreaState.java
+++ b/shared/src/com/vaadin/shared/ui/textarea/TextAreaState.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui.textarea;
import com.vaadin.shared.annotations.DelegateToWidget;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.ui.textfield.AbstractTextFieldState;
public class TextAreaState extends AbstractTextFieldState {
@@ -33,6 +34,7 @@ public class TextAreaState extends AbstractTextFieldState {
* Tells if word-wrapping should be used in the text area.
*/
@DelegateToWidget
+ @NoLayout
public boolean wordwrap = true;
}
diff --git a/shared/src/com/vaadin/shared/ui/textfield/AbstractTextFieldState.java b/shared/src/com/vaadin/shared/ui/textfield/AbstractTextFieldState.java
index 084d02cd7b..9d4272c22f 100644
--- a/shared/src/com/vaadin/shared/ui/textfield/AbstractTextFieldState.java
+++ b/shared/src/com/vaadin/shared/ui/textfield/AbstractTextFieldState.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui.textfield;
import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.annotations.NoLayout;
public class AbstractTextFieldState extends AbstractFieldState {
{
@@ -25,6 +26,7 @@ public class AbstractTextFieldState extends AbstractFieldState {
/**
* Maximum character count in text field.
*/
+ @NoLayout
public int maxLength = -1;
/**
@@ -35,10 +37,12 @@ public class AbstractTextFieldState extends AbstractFieldState {
/**
* The prompt to display in an empty field. Null when disabled.
*/
+ @NoLayout
public String inputPrompt = null;
/**
* The text in the field
*/
+ @NoLayout
public String text = null;
}
diff --git a/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java b/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java
index e32a27830d..fb052a25e9 100644
--- a/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java
+++ b/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java
@@ -16,11 +16,14 @@
package com.vaadin.shared.ui.ui;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.ClientRpc;
public interface ScrollClientRpc extends ClientRpc {
+ @NoLayout
public void setScrollTop(int scrollTop);
+ @NoLayout
public void setScrollLeft(int scrollLeft);
}
diff --git a/shared/src/com/vaadin/shared/ui/window/WindowState.java b/shared/src/com/vaadin/shared/ui/window/WindowState.java
index fa73bea391..7dafba57ff 100644
--- a/shared/src/com/vaadin/shared/ui/window/WindowState.java
+++ b/shared/src/com/vaadin/shared/ui/window/WindowState.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui.window;
import com.vaadin.shared.Connector;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.ui.panel.PanelState;
public class WindowState extends PanelState {
@@ -23,20 +24,34 @@ public class WindowState extends PanelState {
primaryStyleName = "v-window";
}
+ @NoLayout
public boolean modal = false;
+ @NoLayout
public boolean resizable = true;
+ @NoLayout
public boolean resizeLazy = false;
+ @NoLayout
public boolean draggable = true;
+ @NoLayout
public boolean centered = false;
+ @NoLayout
public int positionX = -1;
+ @NoLayout
public int positionY = -1;
public WindowMode windowMode = WindowMode.NORMAL;
+ @NoLayout
public String assistivePrefix = "";
+ @NoLayout
public String assistivePostfix = "";
+ @NoLayout
public Connector[] contentDescription = new Connector[0];
+ @NoLayout
public WindowRole role = WindowRole.DIALOG;
+ @NoLayout
public boolean assistiveTabStop = false;
+ @NoLayout
public String assistiveTabStopTopText = "Top of dialog";
+ @NoLayout
public String assistiveTabStopBottomText = "Bottom of Dialog";
}
diff --git a/uitest/src/com/vaadin/tests/serialization/NoLayout.java b/uitest/src/com/vaadin/tests/serialization/NoLayout.java
new file mode 100644
index 0000000000..8ce8c437a4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/serialization/NoLayout.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2014 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.serialization;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+import com.vaadin.tests.widgetset.server.LayoutDetector;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.JavaScript;
+
+@Widgetset(TestingWidgetSet.NAME)
+public class NoLayout extends AbstractTestUI {
+ private final LayoutDetector layoutDetector = new LayoutDetector();
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(layoutDetector);
+
+ CheckBox uiPolling = new CheckBox("UI polling enabled");
+ uiPolling.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ if (event.getProperty().getValue() == Boolean.TRUE) {
+ setPollInterval(100);
+ } else {
+ setPollInterval(-1);
+ }
+ }
+ });
+ addComponent(uiPolling);
+
+ addComponent(new Button("Change regular state",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ event.getButton().setCaption(
+ String.valueOf(System.currentTimeMillis()));
+ }
+ }));
+ addComponent(new Button("Change @NoLayout state",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ event.getButton().setDescription(
+ String.valueOf(System.currentTimeMillis()));
+ }
+ }));
+ addComponent(new Button("Do regular RPC", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ JavaScript.eval("");
+ }
+ }));
+
+ addComponent(new Button("Do @NoLayout RPC", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ layoutDetector.doNoLayoutRpc();
+ }
+ }));
+
+ addComponent(new Button("Update LegacyComponent",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ // Assumes UI is a LegacyComponent
+ markAsDirty();
+ }
+ }));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Checks which actions trigger a layout phase";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(12936);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java b/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java
new file mode 100644
index 0000000000..bb312e3f3f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 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.serialization;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class NoLayoutTest extends MultiBrowserTest {
+ @Test
+ public void testNoLayout() {
+ openTestURL();
+ assertCounts(1, 0);
+
+ $(CheckBoxElement.class).caption("UI polling enabled").first()
+ .findElement(By.tagName("input")).click();
+
+ // Toggling check box requires layout
+ assertCounts(2, 0);
+
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ // Count should not change even with polling enabled
+ assertCounts(2, 0);
+
+ // Disable polling
+ $(CheckBoxElement.class).caption("UI polling enabled").first()
+ .findElement(By.tagName("input")).click();
+ // Toggling checkbox layotus again
+ assertCounts(3, 0);
+
+ $(ButtonElement.class).caption("Change regular state").first().click();
+ // Updating normal state layouts
+ assertCounts(4, 0);
+
+ $(ButtonElement.class).caption("Change @NoLayout state").first();
+ // Updating @NoLayout state does not layout
+ assertCounts(4, 0);
+
+ $(ButtonElement.class).caption("Do regular RPC").first().click();
+ // Doing normal RPC layouts
+ assertCounts(5, 0);
+
+ $(ButtonElement.class).caption("Do @NoLayout RPC").first().click();
+ // Doing @NoLayout RPC does not layout, but updates the RPC count
+ assertCounts(5, 1);
+
+ $(ButtonElement.class).caption("Update LegacyComponent").first()
+ .click();
+ // Painting LegacyComponent layouts
+ assertCounts(6, 1);
+ }
+
+ private void assertCounts(int layoutCount, int rpcCount) {
+ Assert.assertEquals("Unexpected layout count", layoutCount,
+ getCount("layoutCount"));
+ Assert.assertEquals("Unexpected RPC count", rpcCount,
+ getCount("rpcCount"));
+ }
+
+ private int getCount(String id) {
+ return Integer.parseInt(getDriver().findElement(By.id(id)).getText());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java
new file mode 100644
index 0000000000..e999c83b75
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 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.widgetset.client;
+
+import com.google.gwt.user.client.ui.HTML;
+import com.vaadin.client.ui.AbstractComponentConnector;
+import com.vaadin.client.ui.PostLayoutListener;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.tests.widgetset.server.LayoutDetector;
+
+@Connect(LayoutDetector.class)
+public class LayoutDetectorConnector extends AbstractComponentConnector
+ implements PostLayoutListener {
+ private int layoutCount = 0;
+ private int rpcCount = 0;
+
+ @Override
+ protected void init() {
+ super.init();
+ updateText();
+
+ registerRpc(NoLayoutRpc.class, new NoLayoutRpc() {
+ @Override
+ public void doRpc() {
+ rpcCount++;
+ updateText();
+ }
+ });
+ }
+
+ @Override
+ public HTML getWidget() {
+ return (HTML) super.getWidget();
+ }
+
+ @Override
+ public void postLayout() {
+ layoutCount++;
+ updateText();
+ }
+
+ private void updateText() {
+ getWidget().setHTML(
+ "Layout count: <span id='layoutCount'>" + layoutCount
+ + "</span><br />RPC count: <span id='rpcCount'>"
+ + rpcCount + "</span>");
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java
new file mode 100644
index 0000000000..7c2693db1d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2014 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.widgetset.client;
+
+import com.vaadin.shared.annotations.NoLayout;
+import com.vaadin.shared.communication.ClientRpc;
+
+public interface NoLayoutRpc extends ClientRpc {
+
+ @NoLayout
+ public void doRpc();
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java
index 60a3fb1448..e71f9f1230 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java
@@ -15,10 +15,12 @@
*/
package com.vaadin.tests.widgetset.client;
+import com.vaadin.shared.annotations.NoLayout;
import com.vaadin.shared.communication.ClientRpc;
import com.vaadin.shared.communication.ServerRpc;
public interface RoundTripTesterRpc extends ServerRpc, ClientRpc {
+ @NoLayout
public void ping(int nr, String payload);
public void done();
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java b/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java
new file mode 100644
index 0000000000..4b1aea67ea
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2014 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.widgetset.server;
+
+import com.vaadin.tests.widgetset.client.NoLayoutRpc;
+import com.vaadin.ui.AbstractComponent;
+
+public class LayoutDetector extends AbstractComponent {
+
+ public void doNoLayoutRpc() {
+ getRpcProxy(NoLayoutRpc.class).doRpc();
+ }
+}