summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorJohannes Dahlström <johannesd@vaadin.com>2012-08-22 17:12:54 +0300
committerJohannes Dahlström <johannesd@vaadin.com>2012-08-22 17:12:54 +0300
commit7e3d95735858ba8726a7dc472a054ba279d7af21 (patch)
treebbc3556e8b0b20d03e1ccd1678d831010bdc96ef /client
parent3f36eee94aa400b85a4b322d3247b72a9eee25d0 (diff)
parent88776600733901f3f9891aa90a11a5aeb2b97ef4 (diff)
downloadvaadin-framework-7e3d95735858ba8726a7dc472a054ba279d7af21.tar.gz
vaadin-framework-7e3d95735858ba8726a7dc472a054ba279d7af21.zip
Merge branch 'master' into root-cleanup
Conflicts: client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java123
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java69
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java5
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ServerConnector.java17
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/Util.java8
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java41
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java2
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java114
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java84
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/csslayout/VCssLayout.java19
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/formlayout/VFormLayout.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/link/LinkConnector.java7
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/link/VLink.java18
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java18
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java2
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java5
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java4
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java12
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java20
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java75
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java30
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java58
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java8
30 files changed, 600 insertions, 252 deletions
diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index cd90403139..b4635c6d80 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -22,6 +22,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -54,9 +55,9 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.ComponentState;
import com.vaadin.shared.Version;
+import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.shared.communication.SharedState;
-import com.vaadin.shared.communication.UidlValue;
import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage;
import com.vaadin.terminal.gwt.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.terminal.gwt.client.ResourceLoader.ResourceLoadListener;
@@ -132,7 +133,18 @@ public class ApplicationConnection {
private final HashMap<String, String> resourcesMap = new HashMap<String, String>();
- private ArrayList<MethodInvocation> pendingInvocations = new ArrayList<MethodInvocation>();
+ /**
+ * The pending method invocations that will be send to the server by
+ * {@link #sendPendingCommand}. The key is defined differently based on
+ * whether the method invocation is enqueued with lastonly. With lastonly
+ * enabled, the method signature ( {@link MethodInvocation#getLastonlyTag()}
+ * ) is used as the key to make enable removing a previously enqueued
+ * invocation. Without lastonly, an incremental id based on
+ * {@link #lastInvocationTag} is used to get unique values.
+ */
+ private LinkedHashMap<String, MethodInvocation> pendingInvocations = new LinkedHashMap<String, MethodInvocation>();
+
+ private int lastInvocationTag = 0;
private WidgetSet widgetSet;
@@ -155,7 +167,7 @@ public class ApplicationConnection {
private ApplicationConfiguration configuration;
/** List of pending variable change bursts that must be submitted in order */
- private final ArrayList<ArrayList<MethodInvocation>> pendingBursts = new ArrayList<ArrayList<MethodInvocation>>();
+ private final ArrayList<LinkedHashMap<String, MethodInvocation>> pendingBursts = new ArrayList<LinkedHashMap<String, MethodInvocation>>();
/** Timer for automatic refirect to SessionExpiredURL */
private Timer redirectTimer;
@@ -888,12 +900,11 @@ public class ApplicationConnection {
private void checkForPendingVariableBursts() {
cleanVariableBurst(pendingInvocations);
if (pendingBursts.size() > 0) {
- for (Iterator<ArrayList<MethodInvocation>> iterator = pendingBursts
- .iterator(); iterator.hasNext();) {
- cleanVariableBurst(iterator.next());
+ for (LinkedHashMap<String, MethodInvocation> pendingBurst : pendingBursts) {
+ cleanVariableBurst(pendingBurst);
}
- ArrayList<MethodInvocation> nextBurst = pendingBursts.get(0);
- pendingBursts.remove(0);
+ LinkedHashMap<String, MethodInvocation> nextBurst = pendingBursts
+ .remove(0);
buildAndSendVariableBurst(nextBurst, false);
}
}
@@ -904,13 +915,15 @@ public class ApplicationConnection {
*
* @param variableBurst
*/
- private void cleanVariableBurst(ArrayList<MethodInvocation> variableBurst) {
- for (int i = 1; i < variableBurst.size(); i++) {
- String id = variableBurst.get(i).getConnectorId();
+ private void cleanVariableBurst(
+ LinkedHashMap<String, MethodInvocation> variableBurst) {
+ Iterator<MethodInvocation> iterator = variableBurst.values().iterator();
+ while (iterator.hasNext()) {
+ String id = iterator.next().getConnectorId();
if (!getConnectorMap().hasConnector(id)
&& !getConnectorMap().isDragAndDropPaintable(id)) {
// variable owner does not exist anymore
- variableBurst.remove(i);
+ iterator.remove();
VConsole.log("Removed variable from removed component: " + id);
}
}
@@ -1462,9 +1475,12 @@ public class ApplicationConnection {
.getName(), null), stateJson, state,
ApplicationConnection.this);
- StateChangeEvent event = GWT
- .create(StateChangeEvent.class);
- event.setConnector(connector);
+ Set<String> changedProperties = new HashSet<String>();
+ addJsonFields(stateJson, changedProperties, "");
+
+ StateChangeEvent event = new StateChangeEvent(
+ connector, changedProperties);
+
events.add(event);
}
} catch (final Throwable e) {
@@ -1476,6 +1492,30 @@ public class ApplicationConnection {
}
/**
+ * Recursively adds the names of all fields in all objects in the
+ * provided json object.
+ *
+ * @param json
+ * the json object to process
+ * @param fields
+ * a set of all currently added fields
+ * @param context
+ * the base name of the current object
+ */
+ private void addJsonFields(JSONObject json, Set<String> fields,
+ String context) {
+ for (String key : json.keySet()) {
+ String fieldName = context + key;
+ fields.add(fieldName);
+
+ JSONObject object = json.get(key).isObject();
+ if (object != null) {
+ addJsonFields(object, fields, fieldName + ".");
+ }
+ }
+ }
+
+ /**
* Updates the connector hierarchy and returns a list of events that
* should be fired after update of the hierarchy and the state is
* done.
@@ -1695,12 +1735,10 @@ public class ApplicationConnection {
private void addVariableToQueue(String connectorId, String variableName,
Object value, boolean immediate) {
+ boolean lastOnly = !immediate;
// note that type is now deduced from value
- // TODO could eliminate invocations of same shared variable setter
- addMethodInvocationToQueue(new MethodInvocation(connectorId,
- ApplicationConstants.UPDATE_VARIABLE_INTERFACE,
- ApplicationConstants.UPDATE_VARIABLE_METHOD, new Object[] {
- variableName, new UidlValue(value) }), immediate);
+ addMethodInvocationToQueue(new LegacyChangeVariablesInvocation(
+ connectorId, variableName, value), lastOnly, lastOnly);
}
/**
@@ -1710,16 +1748,31 @@ public class ApplicationConnection {
*
* @param invocation
* RPC method invocation
- * @param immediate
- * true to trigger sending within a short time window (possibly
- * combining subsequent calls to a single request), false to let
- * the framework delay sending of RPC calls and variable changes
- * until the next immediate change
+ * @param delayed
+ * <code>false</code> to trigger sending within a short time
+ * window (possibly combining subsequent calls to a single
+ * request), <code>true</code> to let the framework delay sending
+ * of RPC calls and variable changes until the next non-delayed
+ * change
+ * @param lastonly
+ * <code>true</code> to remove all previously delayed invocations
+ * of the same method that were also enqueued with lastonly set
+ * to <code>true</code>. <code>false</code> to add invocation to
+ * the end of the queue without touching previously enqueued
+ * invocations.
*/
public void addMethodInvocationToQueue(MethodInvocation invocation,
- boolean immediate) {
- pendingInvocations.add(invocation);
- if (immediate) {
+ boolean delayed, boolean lastonly) {
+ String tag;
+ if (lastonly) {
+ tag = invocation.getLastonlyTag();
+ assert !tag.matches("\\d+") : "getLastonlyTag value must have at least one non-digit character";
+ pendingInvocations.remove(tag);
+ } else {
+ tag = Integer.toString(lastInvocationTag++);
+ }
+ pendingInvocations.put(tag, invocation);
+ if (!delayed) {
sendPendingVariableChanges();
}
}
@@ -1750,14 +1803,15 @@ public class ApplicationConnection {
};
private boolean deferedSendPending = false;
- @SuppressWarnings("unchecked")
private void doSendPendingVariableChanges() {
if (applicationRunning) {
if (hasActiveRequest()) {
// skip empty queues if there are pending bursts to be sent
if (pendingInvocations.size() > 0 || pendingBursts.size() == 0) {
pendingBursts.add(pendingInvocations);
- pendingInvocations = new ArrayList<MethodInvocation>();
+ pendingInvocations = new LinkedHashMap<String, MethodInvocation>();
+ // Keep tag string short
+ lastInvocationTag = 0;
}
} else {
buildAndSendVariableBurst(pendingInvocations, false);
@@ -1778,17 +1832,18 @@ public class ApplicationConnection {
* Should we use synchronous request?
*/
private void buildAndSendVariableBurst(
- ArrayList<MethodInvocation> pendingInvocations, boolean forceSync) {
+ LinkedHashMap<String, MethodInvocation> pendingInvocations,
+ boolean forceSync) {
final StringBuffer req = new StringBuffer();
while (!pendingInvocations.isEmpty()) {
if (ApplicationConfiguration.isDebugMode()) {
- Util.logVariableBurst(this, pendingInvocations);
+ Util.logVariableBurst(this, pendingInvocations.values());
}
JSONArray reqJson = new JSONArray();
- for (MethodInvocation invocation : pendingInvocations) {
+ for (MethodInvocation invocation : pendingInvocations.values()) {
JSONArray invocationJson = new JSONArray();
invocationJson.set(0,
new JSONString(invocation.getConnectorId()));
@@ -1812,6 +1867,8 @@ public class ApplicationConnection {
req.append(escapeBurstContents(reqJson.toString()));
pendingInvocations.clear();
+ // Keep tag string short
+ lastInvocationTag = 0;
// Append all the bursts to this synchronous request
if (forceSync && !pendingBursts.isEmpty()) {
pendingInvocations = pendingBursts.get(0);
diff --git a/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java b/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
index de2d9a9cd8..680131c70c 100644
--- a/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
+++ b/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
@@ -139,7 +139,7 @@ public class BrowserInfo {
if (browserDetails.isFirefox()) {
browserIdentifier = BROWSER_FIREFOX;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_GECKO;
@@ -151,21 +151,21 @@ public class BrowserInfo {
} else if (browserDetails.isSafari()) {
browserIdentifier = BROWSER_SAFARI;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_WEBKIT;
} else if (browserDetails.isIE()) {
browserIdentifier = BROWSER_IE;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_TRIDENT;
} else if (browserDetails.isOpera()) {
browserIdentifier = BROWSER_OPERA;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_PRESTO;
@@ -222,11 +222,11 @@ public class BrowserInfo {
}
public boolean isIE8() {
- return isIE() && browserDetails.getBrowserMajorVersion() == 8;
+ return isIE() && getBrowserMajorVersion() == 8;
}
public boolean isIE9() {
- return isIE() && browserDetails.getBrowserMajorVersion() == 9;
+ return isIE() && getBrowserMajorVersion() == 9;
}
public boolean isChrome() {
@@ -274,7 +274,7 @@ public class BrowserInfo {
return -1;
}
- return browserDetails.getBrowserMajorVersion();
+ return getBrowserMajorVersion();
}
public float getOperaVersion() {
@@ -282,7 +282,7 @@ public class BrowserInfo {
return -1;
}
- return browserDetails.getBrowserMajorVersion();
+ return getBrowserMajorVersion();
}
public boolean isOpera() {
@@ -290,13 +290,11 @@ public class BrowserInfo {
}
public boolean isOpera10() {
- return browserDetails.isOpera()
- && browserDetails.getBrowserMajorVersion() == 10;
+ return browserDetails.isOpera() && getBrowserMajorVersion() == 10;
}
public boolean isOpera11() {
- return browserDetails.isOpera()
- && browserDetails.getBrowserMajorVersion() == 11;
+ return browserDetails.isOpera() && getBrowserMajorVersion() == 11;
}
public native static String getBrowserString()
@@ -387,4 +385,51 @@ public class BrowserInfo {
private int getOperatingSystemMajorVersion() {
return browserDetails.getOperatingSystemMajorVersion();
}
+
+ /**
+ * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
+ * 4, 8 for Internet Explorer 8.
+ * <p>
+ * Note that Internet Explorer 8 and newer will return the document mode so
+ * IE8 rendering as IE7 will return 7.
+ * </p>
+ *
+ * @return The major version of the browser.
+ */
+ public int getBrowserMajorVersion() {
+ return browserDetails.getBrowserMajorVersion();
+ }
+
+ /**
+ * Returns the browser minor version e.g., 5 for Firefox 3.5.
+ *
+ * @see #getBrowserMajorVersion()
+ *
+ * @return The minor version of the browser, or -1 if not known/parsed.
+ */
+ public int getBrowserMinorVersion() {
+ return browserDetails.getBrowserMinorVersion();
+ }
+
+ /**
+ * Checks if the browser version is newer or equal to the given major+minor
+ * version.
+ *
+ * @param majorVersion
+ * The major version to check for
+ * @param minorVersion
+ * The minor version to check for
+ * @return true if the browser version is newer or equal to the given
+ * version
+ */
+ public boolean isBrowserVersionNewerOrEqual(int majorVersion,
+ int minorVersion) {
+ if (getBrowserMajorVersion() == majorVersion) {
+ // Same major
+ return (getBrowserMinorVersion() >= minorVersion);
+ }
+
+ // Older or newer major
+ return (getBrowserMajorVersion() > majorVersion);
+ }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/client/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java
index 98c014b5ec..6494ae3480 100644
--- a/client/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java
+++ b/client/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java
@@ -267,7 +267,7 @@ public class JavaScriptConnectorHelper {
}
connector.getConnection().addMethodInvocationToQueue(
new MethodInvocation(connector.getConnectorId(), iface, method,
- parameters), true);
+ parameters), false, false);
}
private String findWildcardInterface(String method) {
@@ -298,7 +298,8 @@ public class JavaScriptConnectorHelper {
connector.getConnectorId(),
"com.vaadin.ui.JavaScript$JavaScriptCallbackRpc", "call",
new Object[] { name, new JSONArray(arguments) });
- connector.getConnection().addMethodInvocationToQueue(invocation, true);
+ connector.getConnection().addMethodInvocationToQueue(invocation, false,
+ false);
}
public void setNativeState(JavaScriptObject state) {
diff --git a/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java b/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
index ff37f04f04..8788de74bf 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
@@ -75,7 +75,7 @@ public interface ServerConnector extends Connector {
String rpcInterfaceId);
/**
- * Adds a handler that is called whenever some part of the state has been
+ * Adds a handler that is called whenever any part of the state has been
* updated by the server.
*
* @param handler
@@ -86,6 +86,21 @@ public interface ServerConnector extends Connector {
public HandlerRegistration addStateChangeHandler(StateChangeHandler handler);
/**
+ * Adds a handler that is called whenever the given part of the state has
+ * been updated by the server.
+ *
+ * @param propertyName
+ * the name of the property for which the handler should be
+ * called
+ * @param handler
+ * The handler that should be added.
+ * @return A handler registration reference that can be used to unregister
+ * the handler
+ */
+ public HandlerRegistration addStateChangeHandler(String propertyName,
+ StateChangeHandler handler);
+
+ /**
* Sends the given event to all registered handlers.
*
* @param event
diff --git a/client/src/com/vaadin/terminal/gwt/client/Util.java b/client/src/com/vaadin/terminal/gwt/client/Util.java
index 571258dbe3..96344f0792 100644
--- a/client/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/client/src/com/vaadin/terminal/gwt/client/Util.java
@@ -874,13 +874,13 @@ public class Util {
}
static void logVariableBurst(ApplicationConnection c,
- ArrayList<MethodInvocation> loggedBurst) {
+ Collection<MethodInvocation> loggedBurst) {
try {
VConsole.log("Variable burst to be sent to server:");
String curId = null;
ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>();
- for (int i = 0; i < loggedBurst.size(); i++) {
- String id = loggedBurst.get(i).getConnectorId();
+ for (MethodInvocation methodInvocation : loggedBurst) {
+ String id = methodInvocation.getConnectorId();
if (curId == null) {
curId = id;
@@ -889,7 +889,7 @@ public class Util {
invocations.clear();
curId = id;
}
- invocations.add(loggedBurst.get(i));
+ invocations.add(methodInvocation);
}
if (!invocations.isEmpty()) {
printConnectorInvocations(invocations, curId, c);
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java b/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
index e1847bdab7..8ed32bc94b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
+++ b/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
@@ -16,8 +16,11 @@
package com.vaadin.terminal.gwt.client.communication;
import java.io.Serializable;
+import java.util.Collections;
+import java.util.Set;
import com.google.gwt.event.shared.EventHandler;
+import com.vaadin.terminal.gwt.client.ServerConnector;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
public class StateChangeEvent extends
@@ -27,12 +30,25 @@ public class StateChangeEvent extends
*/
public static final Type<StateChangeHandler> TYPE = new Type<StateChangeHandler>();
+ private Set<String> changedProperties;
+
@Override
public Type<StateChangeHandler> getAssociatedType() {
return TYPE;
}
- public StateChangeEvent() {
+ /**
+ * Creates a new state change event.
+ *
+ * @param connector
+ * the event whose state has changed
+ * @param changedProperties
+ * a set of names of the changed properties
+ */
+ public StateChangeEvent(ServerConnector connector,
+ Set<String> changedProperties) {
+ setConnector(connector);
+ this.changedProperties = changedProperties;
}
@Override
@@ -40,7 +56,30 @@ public class StateChangeEvent extends
listener.onStateChanged(this);
}
+ /**
+ * Event handler that gets notified whenever any part of the state has been
+ * updated by the server.
+ *
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.0
+ */
public interface StateChangeHandler extends Serializable, EventHandler {
+ /**
+ * Notifies the event handler that the state has changed.
+ *
+ * @param stateChangeEvent
+ * the state change event with details about the change
+ */
public void onStateChanged(StateChangeEvent stateChangeEvent);
}
+
+ /**
+ * Gets the properties that have changed.
+ *
+ * @return a set of names of the changed properties
+ */
+ public Set<String> getChangedProperties() {
+ return Collections.unmodifiableSet(changedProperties);
+ }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java b/client/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java
index 5cc5911bb1..46578b0641 100644
--- a/client/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java
@@ -124,7 +124,7 @@ public class JavaScriptManagerConnector extends AbstractExtensionConnector {
getConnection().addMethodInvocationToQueue(
new MethodInvocation(getConnectorId(),
"com.vaadin.ui.JavaScript$JavaScriptCallbackRpc",
- "call", parameters), true);
+ "call", parameters), false, false);
}
@Override
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
index 514f63fdd8..435fff8a5b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
@@ -48,6 +48,7 @@ public abstract class AbstractConnector implements ServerConnector,
private String id;
private HandlerManager handlerManager;
+ private Map<String, HandlerManager> statePropertyHandlerManagers;
private Map<String, Collection<ClientRpc>> rpcImplementations;
private final boolean debugLogging = false;
@@ -168,6 +169,17 @@ public abstract class AbstractConnector implements ServerConnector,
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
+ if (statePropertyHandlerManagers != null
+ && event instanceof StateChangeEvent) {
+ for (String property : ((StateChangeEvent) event)
+ .getChangedProperties()) {
+ HandlerManager manager = statePropertyHandlerManagers
+ .get(property);
+ if (manager != null) {
+ manager.fireEvent(event);
+ }
+ }
+ }
}
protected HandlerManager ensureHandlerManager() {
@@ -185,6 +197,25 @@ public abstract class AbstractConnector implements ServerConnector,
}
@Override
+ public HandlerRegistration addStateChangeHandler(String propertyName,
+ StateChangeHandler handler) {
+ return ensureHandlerManager(propertyName).addHandler(
+ StateChangeEvent.TYPE, handler);
+ }
+
+ private HandlerManager ensureHandlerManager(String propertyName) {
+ if (statePropertyHandlerManagers == null) {
+ statePropertyHandlerManagers = new HashMap<String, HandlerManager>();
+ }
+ HandlerManager manager = statePropertyHandlerManagers.get(propertyName);
+ if (manager == null) {
+ manager = new HandlerManager(this);
+ statePropertyHandlerManagers.put(propertyName, manager);
+ }
+ return manager;
+ }
+
+ @Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
if (debugLogging) {
VConsole.log("State change event for "
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java b/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
index aef21ac737..97201de297 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
@@ -42,6 +42,14 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
public static class PositionAndSize {
private int left, top, width, height;
+ public PositionAndSize(int left, int top, int width, int height) {
+ super();
+ setLeft(left);
+ setTop(top);
+ setWidth(width);
+ setHeight(height);
+ }
+
public int getLeft() {
return left;
}
@@ -63,6 +71,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}
public void setWidth(int width) {
+ if (width < 0) {
+ width = 0;
+ }
+
this.width = width;
}
@@ -71,6 +83,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}
public void setHeight(int height) {
+ if (height < 0) {
+ height = 0;
+ }
+
this.height = height;
}
@@ -192,7 +208,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return shadow != null;
}
- private void removeShim() {
+ private void removeShimElement() {
if (shimElement != null) {
shimElement.removeFromParent();
}
@@ -211,7 +227,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return isShadowEnabled() && shadow.getParentElement() != null;
}
- private boolean isShimAttached() {
+ private boolean isShimElementAttached() {
return shimElement != null && shimElement.hasParentElement();
}
@@ -242,11 +258,11 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
style.setMarginLeft(-adjustByRelativeLeftBodyMargin(), Unit.PX);
style.setMarginTop(-adjustByRelativeTopBodyMargin(), Unit.PX);
super.setPopupPosition(left, top);
- sizeOrPositionUpdated(isAnimationEnabled() ? 0 : 1);
+ positionOrSizeUpdated(isAnimationEnabled() ? 0 : 1);
}
private IFrameElement getShimElement() {
- if (shimElement == null) {
+ if (shimElement == null && needsShimElement()) {
shimElement = Document.get().createIFrameElement();
// Insert shim iframe before the main overlay element. It does not
@@ -318,7 +334,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
if (isAnimationEnabled()) {
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION);
} else {
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
}
@@ -328,7 +344,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
// Always ensure shadow is removed when the overlay is removed.
removeShadowIfPresent();
- removeShim();
+ removeShimElement();
}
@Override
@@ -343,13 +359,13 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
@Override
public void setWidth(String width) {
super.setWidth(width);
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
@Override
public void setHeight(String height) {
super.setHeight(height);
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
/**
@@ -374,8 +390,16 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* 'setHeight(String)' methods (if not calling super.setWidth/Height).
*
*/
- public void sizeOrPositionUpdated() {
- sizeOrPositionUpdated(1.0);
+ public void positionOrSizeUpdated() {
+ positionOrSizeUpdated(1.0);
+ }
+
+ /**
+ * @deprecated Call {@link #positionOrSizeUpdated()} instead.
+ */
+ @Deprecated
+ protected void updateShadowSizeAndPosition() {
+ positionOrSizeUpdated();
}
/**
@@ -388,7 +412,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* A value between 0.0 and 1.0, indicating the progress of the
* animation (0=start, 1=end).
*/
- private void sizeOrPositionUpdated(final double progress) {
+ private void positionOrSizeUpdated(final double progress) {
// Don't do anything if overlay element is not attached
if (!isAttached()) {
return;
@@ -413,18 +437,8 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
getOffsetWidth();
}
- PositionAndSize positionAndSize = new PositionAndSize();
- positionAndSize.left = getActualLeft();
- positionAndSize.top = getActualTop();
- positionAndSize.width = getOffsetWidth();
- positionAndSize.height = getOffsetHeight();
-
- if (positionAndSize.width < 0) {
- positionAndSize.width = 0;
- }
- if (positionAndSize.height < 0) {
- positionAndSize.height = 0;
- }
+ PositionAndSize positionAndSize = new PositionAndSize(getActualLeft(),
+ getActualTop(), getOffsetWidth(), getOffsetHeight());
// Animate the size
positionAndSize.setAnimationFromCenterProgress(progress);
@@ -441,29 +455,31 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
// Update correct values
if (isShadowEnabled()) {
- updateSizeAndPosition(shadow, positionAndSize);
+ updatePositionAndSize(shadow, positionAndSize);
DOM.setStyleAttribute(shadow, "zIndex", zIndex);
DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none"
: "");
}
- updateSizeAndPosition((Element) Element.as(getShimElement()),
- positionAndSize);
+ if (needsShimElement()) {
+ updatePositionAndSize((Element) Element.as(getShimElement()),
+ positionAndSize);
+ }
// Opera fix, part 2 (ticket #2704)
if (BrowserInfo.get().isOpera() && isShadowEnabled()) {
// We'll fix the height of all the middle elements
DOM.getChild(shadow, 3)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 3).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 3).getOffsetHeight());
DOM.getChild(shadow, 4)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 4).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 4).getOffsetHeight());
DOM.getChild(shadow, 5)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 5).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 5).getOffsetHeight());
}
// Attach to dom if not there already
@@ -471,25 +487,37 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
RootPanel.get().getElement().insertBefore(shadow, getElement());
sinkShadowEvents();
}
- if (!isShimAttached()) {
+ if (needsShimElement() && !isShimElementAttached()) {
RootPanel.get().getElement()
- .insertBefore(shimElement, getElement());
+ .insertBefore(getShimElement(), getElement());
}
}
- private void updateSizeAndPosition(Element e,
+ /**
+ * Returns true if we should add a shim iframe below the overlay to deal
+ * with zindex issues with PDFs and applets. Can be overriden to disable
+ * shim iframes if they are not needed.
+ *
+ * @return true if a shim iframe should be added, false otherwise
+ */
+ protected boolean needsShimElement() {
+ BrowserInfo info = BrowserInfo.get();
+ return info.isIE() && info.isBrowserVersionNewerOrEqual(8, 0);
+ }
+
+ private void updatePositionAndSize(Element e,
PositionAndSize positionAndSize) {
- e.getStyle().setLeft(positionAndSize.left, Unit.PX);
- e.getStyle().setTop(positionAndSize.top, Unit.PX);
- e.getStyle().setWidth(positionAndSize.width, Unit.PX);
- e.getStyle().setHeight(positionAndSize.height, Unit.PX);
+ e.getStyle().setLeft(positionAndSize.getLeft(), Unit.PX);
+ e.getStyle().setTop(positionAndSize.getTop(), Unit.PX);
+ e.getStyle().setWidth(positionAndSize.getWidth(), Unit.PX);
+ e.getStyle().setHeight(positionAndSize.getHeight(), Unit.PX);
}
protected class ResizeAnimation extends Animation {
@Override
protected void onUpdate(double progress) {
- sizeOrPositionUpdated(progress);
+ positionOrSizeUpdated(progress);
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
index 59e187014c..59f90a9840 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
@@ -16,6 +16,8 @@
package com.vaadin.terminal.gwt.client.ui.button;
+import java.util.Set;
+
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -34,6 +36,7 @@ import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.MouseEventDetailsBuilder;
import com.vaadin.terminal.gwt.client.communication.RpcProxy;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
+import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
import com.vaadin.terminal.gwt.client.ui.Icon;
import com.vaadin.ui.Button;
@@ -59,6 +62,47 @@ public class ButtonConnector extends AbstractComponentConnector implements
super.init();
getWidget().addClickHandler(this);
getWidget().client = getConnection();
+ addStateChangeHandler("errorMessage", new StateChangeHandler() {
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ if (null != getState().getErrorMessage()) {
+ if (getWidget().errorIndicatorElement == null) {
+ getWidget().errorIndicatorElement = DOM.createSpan();
+ getWidget().errorIndicatorElement
+ .setClassName("v-errorindicator");
+ }
+ getWidget().wrapper.insertBefore(
+ getWidget().errorIndicatorElement,
+ getWidget().captionElement);
+
+ } else if (getWidget().errorIndicatorElement != null) {
+ getWidget().wrapper
+ .removeChild(getWidget().errorIndicatorElement);
+ getWidget().errorIndicatorElement = null;
+ }
+ }
+ });
+
+ addStateChangeHandler("icon", new StateChangeHandler() {
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ if (getState().getIcon() != null) {
+ if (getWidget().icon == null) {
+ getWidget().icon = new Icon(getConnection());
+ getWidget().wrapper.insertBefore(
+ getWidget().icon.getElement(),
+ getWidget().captionElement);
+ }
+ getWidget().icon.setUri(getState().getIcon().getURL());
+ } else {
+ if (getWidget().icon != null) {
+ getWidget().wrapper.removeChild(getWidget().icon
+ .getElement());
+ getWidget().icon = null;
+ }
+ }
+ }
+ });
}
@Override
@@ -68,39 +112,15 @@ public class ButtonConnector extends AbstractComponentConnector implements
focusHandlerRegistration);
blurHandlerRegistration = EventHelper.updateBlurHandler(this,
blurHandlerRegistration);
- // Set text
- if (getState().isHtmlContentAllowed()) {
- getWidget().setHtml(getState().getCaption());
- } else {
- getWidget().setText(getState().getCaption());
- }
- // handle error
- if (null != getState().getErrorMessage()) {
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createSpan();
- getWidget().errorIndicatorElement
- .setClassName("v-errorindicator");
- }
- getWidget().wrapper.insertBefore(getWidget().errorIndicatorElement,
- getWidget().captionElement);
-
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().wrapper.removeChild(getWidget().errorIndicatorElement);
- getWidget().errorIndicatorElement = null;
- }
-
- if (getState().getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- getWidget().wrapper.insertBefore(getWidget().icon.getElement(),
- getWidget().captionElement);
- }
- getWidget().icon.setUri(getState().getIcon().getURL());
- } else {
- if (getWidget().icon != null) {
- getWidget().wrapper.removeChild(getWidget().icon.getElement());
- getWidget().icon = null;
+ Set<String> changedProperties = stateChangeEvent.getChangedProperties();
+ if (changedProperties.contains("caption")
+ || changedProperties.contains("htmlContentAllowed")) {
+ // Set text
+ if (getState().isHtmlContentAllowed()) {
+ getWidget().setHtml(getState().getCaption());
+ } else {
+ getWidget().setText(getState().getCaption());
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java
index 47c2049a67..2e51d717a4 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java
@@ -23,7 +23,6 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.LayoutClickRpc;
-import com.vaadin.shared.ui.VMarginInfo;
import com.vaadin.shared.ui.csslayout.CssLayoutServerRpc;
import com.vaadin.shared.ui.csslayout.CssLayoutState;
import com.vaadin.terminal.gwt.client.BrowserInfo;
@@ -75,9 +74,6 @@ public class CssLayoutConnector extends AbstractLayoutConnector {
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
- getWidget().setMarginStyles(
- new VMarginInfo(getState().getMarginsBitmask()));
-
for (ComponentConnector child : getChildComponents()) {
if (!getState().getChildCss().containsKey(child)) {
continue;
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/VCssLayout.java b/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/VCssLayout.java
index 813e95e3ed..e66b1c4208 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/VCssLayout.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/csslayout/VCssLayout.java
@@ -21,8 +21,6 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.shared.ui.VMarginInfo;
-import com.vaadin.terminal.gwt.client.StyleConstants;
public class VCssLayout extends SimplePanel {
public static final String TAGNAME = "csslayout";
@@ -64,21 +62,4 @@ public class VCssLayout extends SimplePanel {
}
- /**
- * Sets CSS classes for margin based on the given parameters.
- *
- * @param margins
- * A {@link VMarginInfo} object that provides info on
- * top/left/bottom/right margins
- */
- protected void setMarginStyles(VMarginInfo margins) {
- setStyleName(margin, VCssLayout.CLASSNAME + "-"
- + StyleConstants.MARGIN_TOP, margins.hasTop());
- setStyleName(margin, VCssLayout.CLASSNAME + "-"
- + StyleConstants.MARGIN_RIGHT, margins.hasRight());
- setStyleName(margin, VCssLayout.CLASSNAME + "-"
- + StyleConstants.MARGIN_BOTTOM, margins.hasBottom());
- setStyleName(margin, VCssLayout.CLASSNAME + "-"
- + StyleConstants.MARGIN_LEFT, margins.hasLeft());
- }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java
index 7d5edfadf5..cbe06244af 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java
@@ -18,7 +18,7 @@ package com.vaadin.terminal.gwt.client.ui.formlayout;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState;
import com.vaadin.terminal.gwt.client.ComponentConnector;
import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangeEvent;
@@ -46,7 +46,7 @@ public class FormLayoutConnector extends AbstractLayoutConnector {
VFormLayoutTable formLayoutTable = getWidget().table;
- formLayoutTable.setMargins(new VMarginInfo(getState()
+ formLayoutTable.setMargins(new MarginInfo(getState()
.getMarginsBitmask()));
formLayoutTable.setSpacing(getState().isSpacing());
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/VFormLayout.java b/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/VFormLayout.java
index d3ce6f3d3f..7f211aaf9c 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/VFormLayout.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/formlayout/VFormLayout.java
@@ -29,7 +29,7 @@ import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ComponentState;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.ComponentConnector;
@@ -112,7 +112,7 @@ public class VFormLayout extends SimplePanel {
}
}
- public void setMargins(VMarginInfo margins) {
+ public void setMargins(MarginInfo margins) {
Element margin = getElement();
setStyleName(margin, CLASSNAME + "-" + StyleConstants.MARGIN_TOP,
margins.hasTop());
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java
index 520afb778d..9a2732e408 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java
@@ -22,7 +22,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.AlignmentInfo;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.LayoutClickRpc;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.shared.ui.gridlayout.GridLayoutServerRpc;
import com.vaadin.shared.ui.gridlayout.GridLayoutState;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
@@ -163,7 +163,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector
layout.colExpandRatioArray = uidl.getIntArrayAttribute("colExpand");
layout.rowExpandRatioArray = uidl.getIntArrayAttribute("rowExpand");
- layout.updateMarginStyleNames(new VMarginInfo(getState()
+ layout.updateMarginStyleNames(new MarginInfo(getState()
.getMarginsBitmask()));
layout.updateSpacingStyleName(getState().isSpacing());
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java b/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java
index 25d7de6ee6..ef44964da7 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java
@@ -29,7 +29,7 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.AlignmentInfo;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentConnector;
import com.vaadin.terminal.gwt.client.ConnectorMap;
@@ -677,7 +677,7 @@ public class VGridLayout extends ComplexPanel {
}
}
- void updateMarginStyleNames(VMarginInfo marginInfo) {
+ void updateMarginStyleNames(MarginInfo marginInfo) {
togglePrefixedStyleName("margin-top", marginInfo.hasTop());
togglePrefixedStyleName("margin-right", marginInfo.hasRight());
togglePrefixedStyleName("margin-bottom", marginInfo.hasBottom());
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/link/LinkConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/link/LinkConnector.java
index c4bbcd34f7..f2b8361f2b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/link/LinkConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/link/LinkConnector.java
@@ -17,6 +17,7 @@
package com.vaadin.terminal.gwt.client.ui.link;
import com.google.gwt.user.client.DOM;
+import com.vaadin.shared.ui.BorderStyle;
import com.vaadin.shared.ui.Connect;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
@@ -57,12 +58,12 @@ public class LinkConnector extends AbstractComponentConnector implements
if (uidl.hasAttribute("border")) {
if ("none".equals(uidl.getStringAttribute("border"))) {
- getWidget().borderStyle = VLink.BORDER_STYLE_NONE;
+ getWidget().borderStyle = BorderStyle.NONE;
} else {
- getWidget().borderStyle = VLink.BORDER_STYLE_MINIMAL;
+ getWidget().borderStyle = BorderStyle.MINIMAL;
}
} else {
- getWidget().borderStyle = VLink.BORDER_STYLE_DEFAULT;
+ getWidget().borderStyle = BorderStyle.DEFAULT;
}
getWidget().targetHeight = uidl.hasAttribute("targetHeight") ? uidl
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/link/VLink.java b/client/src/com/vaadin/terminal/gwt/client/ui/link/VLink.java
index e312d4d489..b0e44c9d13 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/link/VLink.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/link/VLink.java
@@ -23,6 +23,7 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTML;
+import com.vaadin.shared.ui.BorderStyle;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ui.Icon;
@@ -31,15 +32,20 @@ public class VLink extends HTML implements ClickHandler {
public static final String CLASSNAME = "v-link";
- protected static final int BORDER_STYLE_DEFAULT = 0;
- protected static final int BORDER_STYLE_MINIMAL = 1;
- protected static final int BORDER_STYLE_NONE = 2;
+ @Deprecated
+ protected static final BorderStyle BORDER_STYLE_DEFAULT = BorderStyle.DEFAULT;
+
+ @Deprecated
+ protected static final BorderStyle BORDER_STYLE_MINIMAL = BorderStyle.MINIMAL;
+
+ @Deprecated
+ protected static final BorderStyle BORDER_STYLE_NONE = BorderStyle.NONE;
protected String src;
protected String target;
- protected int borderStyle = BORDER_STYLE_DEFAULT;
+ protected BorderStyle borderStyle = BorderStyle.DEFAULT;
protected boolean enabled;
@@ -73,10 +79,10 @@ public class VLink extends HTML implements ClickHandler {
}
String features;
switch (borderStyle) {
- case BORDER_STYLE_NONE:
+ case NONE:
features = "menubar=no,location=no,status=no";
break;
- case BORDER_STYLE_MINIMAL:
+ case MINIMAL:
features = "menubar=yes,location=no,status=no";
break;
default:
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java b/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
index 9f17b81691..fe47fcca66 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
@@ -56,8 +56,8 @@ import com.vaadin.terminal.gwt.client.ui.VLazyExecutor;
import com.vaadin.terminal.gwt.client.ui.VOverlay;
public class VMenuBar extends SimpleFocusablePanel implements
- CloseHandler<PopupPanel>, KeyPressHandler, KeyDownHandler,
- FocusHandler, SubPartAware {
+CloseHandler<PopupPanel>, KeyPressHandler, KeyDownHandler,
+FocusHandler, SubPartAware {
// The hierarchy of VMenuBar is a bit weird as VMenuBar is the Paintable,
// used for the root menu but also used for the sub menus.
@@ -94,11 +94,11 @@ public class VMenuBar extends SimpleFocusablePanel implements
private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100,
new ScheduledCommand() {
- @Override
- public void execute() {
- iLayout(true);
- }
- });
+ @Override
+ public void execute() {
+ iLayout(true);
+ }
+ });
boolean openRootOnHover;
@@ -188,7 +188,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
itemHTML.append("<img src=\""
+ Util.escapeAttribute(client.translateVaadinUri(item
.getStringAttribute("icon"))) + "\" class=\""
- + Icon.CLASSNAME + "\" alt=\"\" />");
+ + Icon.CLASSNAME + "\" alt=\"\" />");
}
String itemText = item.getStringAttribute("text");
if (!htmlContentAllowed) {
@@ -606,7 +606,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
// popup
style.setWidth(contentWidth + Util.getNativeScrollbarSize(),
Unit.PX);
- popup.sizeOrPositionUpdated();
+ popup.positionOrSizeUpdated();
}
}
return top;
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java b/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
index 451e6badbe..6e253c9137 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
@@ -168,7 +168,7 @@ public class VNotification extends VOverlay {
super.show();
notifications.add(this);
setPosition(position);
- sizeOrPositionUpdated();
+ positionOrSizeUpdated();
/**
* Android 4 fails to render notifications correctly without a little
* nudge (#8551)
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
index 5da01bf127..122547ddb4 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
@@ -23,7 +23,7 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.AlignmentInfo;
import com.vaadin.shared.ui.LayoutClickRpc;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc;
import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState;
import com.vaadin.terminal.gwt.client.ComponentConnector;
@@ -133,9 +133,8 @@ public abstract class AbstractOrderedLayoutConnector extends
slot.setExpandRatio(expandRatio);
}
- layout.updateMarginStyleNames(new VMarginInfo(getState()
+ layout.updateMarginStyleNames(new MarginInfo(getState()
.getMarginsBitmask()));
-
layout.updateSpacingStyleName(getState().isSpacing());
getLayoutManager().setNeedsLayout(this);
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java b/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java
index ec2c4afa97..ee55bc07ba 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java
@@ -27,7 +27,7 @@ import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.WidgetCollection;
-import com.vaadin.shared.ui.VMarginInfo;
+import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.terminal.gwt.client.VCaption;
import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot;
@@ -75,7 +75,7 @@ public class VMeasuringOrderedLayout extends ComplexPanel {
}
}
- void updateMarginStyleNames(VMarginInfo marginInfo) {
+ void updateMarginStyleNames(MarginInfo marginInfo) {
togglePrefixedStyleName("margin-top", marginInfo.hasTop());
togglePrefixedStyleName("margin-right", marginInfo.hasRight());
togglePrefixedStyleName("margin-bottom", marginInfo.hasBottom());
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java
index 39702e6ba0..1759889a1b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java
@@ -23,6 +23,8 @@ import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
@@ -84,6 +86,16 @@ public class RootConnector extends AbstractComponentContainerConnector
com.google.gwt.user.client.Window.setTitle(title);
}
});
+ getWidget().addResizeHandler(new ResizeHandler() {
+ @Override
+ public void onResize(ResizeEvent event) {
+ rpc.resize(event.getHeight(), event.getWidth(),
+ Window.getClientWidth(), Window.getClientHeight());
+ if (getState().isImmediate()) {
+ getConnection().sendPendingVariableChanges();
+ }
+ }
+ });
}
@Override
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java b/client/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
index a473bf4846..162e7c55a8 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.logical.shared.HasResizeHandlers;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
@@ -50,7 +51,8 @@ import com.vaadin.terminal.gwt.client.ui.textfield.VTextField;
*
*/
public class VRoot extends SimplePanel implements ResizeHandler,
- Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable {
+ Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
+ HasResizeHandlers {
private static final String CLASSNAME = "v-view";
@@ -401,16 +403,7 @@ public class VRoot extends SimplePanel implements ResizeHandler,
int viewHeight = parentElement.getClientHeight();
int viewWidth = parentElement.getClientWidth();
- connection.updateVariable(id, "height", viewHeight, false);
- connection.updateVariable(id, "width", viewWidth, false);
-
- int windowWidth = Window.getClientWidth();
- int windowHeight = Window.getClientHeight();
-
- connection.updateVariable(id, RootConstants.BROWSER_WIDTH_VAR,
- windowWidth, false);
- connection.updateVariable(id, RootConstants.BROWSER_HEIGHT_VAR,
- windowHeight, immediate);
+ ResizeEvent.fire(this, viewWidth, viewHeight);
}
public native static void goTo(String url)
@@ -458,4 +451,9 @@ public class VRoot extends SimplePanel implements ResizeHandler,
touchScrollHandler.addElement(getElement());
}
+ @Override
+ public HandlerRegistration addResizeHandler(ResizeHandler resizeHandler) {
+ return addHandler(resizeHandler, ResizeEvent.getType());
+ }
+
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java b/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
index aa7da488d8..345eebc8aa 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
@@ -4122,8 +4122,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
row.addStyleName("v-selected");
}
tBodyElement.appendChild(row.getElement());
- adopt(row);
+ // Add to renderedRows before adopt so iterator() will return also
+ // this row if called in an attach handler (#9264)
renderedRows.add(row);
+ adopt(row);
}
private void insertRowAt(VScrollTableRow row, int index) {
@@ -5780,16 +5782,39 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Hey IE, are you really sure about this?
availW = scrollBody.getAvailableWidth();
int visibleCellCount = tHead.getVisibleCellCount();
- availW -= scrollBody.getCellExtraWidth() * visibleCellCount;
+ int totalExtraWidth = scrollBody.getCellExtraWidth()
+ * visibleCellCount;
if (willHaveScrollbars()) {
- availW -= Util.getNativeScrollbarSize();
+ totalExtraWidth += Util.getNativeScrollbarSize();
}
+ availW -= totalExtraWidth;
+ int forceScrollBodyWidth = -1;
int extraSpace = availW - usedMinimumWidth;
if (extraSpace < 0) {
+ if (getTotalRows() == 0) {
+ /*
+ * Too wide header combined with no rows in the table.
+ *
+ * No horizontal scrollbars would be displayed because
+ * there's no rows that grows too wide causing the
+ * scrollBody container div to overflow. Must explicitely
+ * force a width to a scrollbar. (see #9187)
+ */
+ forceScrollBodyWidth = usedMinimumWidth + totalExtraWidth;
+ }
extraSpace = 0;
}
+ if (forceScrollBodyWidth > 0) {
+ scrollBody.container.getStyle().setWidth(forceScrollBodyWidth,
+ Unit.PX);
+ } else {
+ // Clear width that might have been set to force horizontal
+ // scrolling if there are no rows
+ scrollBody.container.getStyle().clearWidth();
+ }
+
int totalUndefinedNaturalWidths = usedMinimumWidth
- totalExplicitColumnsWidths;
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java b/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
index e061cda1fa..e1df1ba0db 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
@@ -19,6 +19,10 @@ package com.vaadin.terminal.gwt.client.ui.textarea;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.TextAreaElement;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
@@ -38,10 +42,17 @@ import com.vaadin.terminal.gwt.client.ui.textfield.VTextField;
public class VTextArea extends VTextField {
public static final String CLASSNAME = "v-textarea";
private boolean wordwrap = true;
+ private MaxLengthHandler maxLengthHandler = new MaxLengthHandler();
+ private boolean browserSupportsMaxLengthAttribute = browserSupportsMaxLengthAttribute();
public VTextArea() {
super(DOM.createTextArea());
setStyleName(CLASSNAME);
+ if (!browserSupportsMaxLengthAttribute) {
+ addKeyUpHandler(maxLengthHandler);
+ addChangeHandler(maxLengthHandler);
+ sinkEvents(Event.ONPASTE);
+ }
}
public TextAreaElement getTextAreaElement() {
@@ -52,22 +63,28 @@ public class VTextArea extends VTextField {
getTextAreaElement().setRows(rows);
}
- @Override
- protected void setMaxLength(int newMaxLength) {
- super.setMaxLength(newMaxLength);
+ private class MaxLengthHandler implements KeyUpHandler, ChangeHandler {
- boolean hasMaxLength = (newMaxLength >= 0);
+ @Override
+ public void onKeyUp(KeyUpEvent event) {
+ enforceMaxLength();
+ }
- if (hasMaxLength) {
- sinkEvents(Event.ONKEYUP);
- } else {
- unsinkEvents(Event.ONKEYUP);
+ public void onPaste(Event event) {
+ enforceMaxLength();
}
+
+ @Override
+ public void onChange(ChangeEvent event) {
+ // Opera does not support paste events so this enforces max length
+ // for Opera.
+ enforceMaxLength();
+ }
+
}
- @Override
- public void onBrowserEvent(Event event) {
- if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
+ protected void enforceMaxLength() {
+ if (getMaxLength() >= 0) {
Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
@@ -77,9 +94,45 @@ public class VTextArea extends VTextField {
}
});
}
+ }
+
+ protected boolean browserSupportsMaxLengthAttribute() {
+ BrowserInfo info = BrowserInfo.get();
+ if (info.isFirefox() && info.isBrowserVersionNewerOrEqual(4, 0)) {
+ return true;
+ }
+ if (info.isSafari() && info.isBrowserVersionNewerOrEqual(5, 0)) {
+ return true;
+ }
+ if (info.isIE() && info.isBrowserVersionNewerOrEqual(10, 0)) {
+ return true;
+ }
+ if (info.isAndroid() && info.isBrowserVersionNewerOrEqual(2, 3)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void updateMaxLength(int maxLength) {
+ if (browserSupportsMaxLengthAttribute) {
+ super.updateMaxLength(maxLength);
+ } else {
+ // Events handled by MaxLengthHandler. This call enforces max length
+ // when the max length value has changed
+ enforceMaxLength();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
+ if (event.getTypeInt() == Event.ONPASTE) {
+ maxLengthHandler.onPaste(event);
+ }
}
+
@Override
public int getCursorPos() {
// This is needed so that TextBoxImplIE6 is used to return the correct
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java b/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
index b00210cdd2..8f07c67c96 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
@@ -44,7 +44,7 @@ import com.vaadin.terminal.gwt.client.ui.Field;
*
*/
public class VTextField extends TextBoxBase implements Field, ChangeHandler,
- FocusHandler, BlurHandler, KeyDownHandler {
+FocusHandler, BlurHandler, KeyDownHandler {
/**
* The input node CSS classname.
@@ -114,7 +114,7 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
if (listenTextChangeEvents
&& (event.getTypeInt() & TEXTCHANGE_EVENTS) == event
- .getTypeInt()) {
+ .getTypeInt()) {
deferTextChangeEvent();
}
@@ -261,12 +261,32 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
}
protected void setMaxLength(int newMaxLength) {
- if (newMaxLength >= 0) {
+ if (newMaxLength >= 0 && newMaxLength != maxLength) {
maxLength = newMaxLength;
- } else {
+ updateMaxLength(maxLength);
+ } else if (maxLength != -1) {
maxLength = -1;
+ updateMaxLength(maxLength);
+ }
+
+ }
+
+ /**
+ * This method is reponsible for updating the DOM or otherwise ensuring that
+ * the given max length is enforced. Called when the max length for the
+ * field has changed.
+ *
+ * @param maxLength
+ * The new max length
+ */
+ protected void updateMaxLength(int maxLength) {
+ if (maxLength >= 0) {
+ getElement().setPropertyInt("maxLength", maxLength);
+ } else {
+ getElement().removeAttribute("maxLength");
+
}
- setMaxLengthToElement(newMaxLength);
+ setMaxLengthToElement(maxLength);
}
protected void setMaxLengthToElement(int newMaxLength) {
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java b/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
index 9fbaa1d8bf..40c5e4b8af 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
@@ -79,8 +79,8 @@ import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
*
*/
public class VTree extends FocusElementPanel implements VHasDropHandler,
- FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
- SubPartAware, ActionOwner {
+FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
+SubPartAware, ActionOwner {
public static final String CLASSNAME = "v-tree";
@@ -137,12 +137,12 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
public VLazyExecutor iconLoaded = new VLazyExecutor(50,
new ScheduledCommand() {
- @Override
- public void execute() {
- Util.notifyParentOfSizeChange(VTree.this, true);
- }
+ @Override
+ public void execute() {
+ Util.notifyParentOfSizeChange(VTree.this, true);
+ }
- });
+ });
public VTree() {
super();
@@ -601,7 +601,8 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
focus();
}
- ScheduledCommand command = new ScheduledCommand() {
+ executeEventCommand(new ScheduledCommand() {
+
@Override
public void execute() {
@@ -636,17 +637,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
}
}
}
- };
-
- if (BrowserInfo.get().isWebkit() && !treeHasFocus) {
- /*
- * Safari may need to wait for focus. See FocusImplSafari.
- */
- // VConsole.log("Deferring click handling to let webkit gain focus...");
- Scheduler.get().scheduleDeferred(command);
- } else {
- command.execute();
- }
+ });
return true;
}
@@ -677,7 +668,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
&& client.hasEventListeners(VTree.this,
TreeConstants.ITEM_CLICK_EVENT_ID)
- && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
+ && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
fireClick(event);
}
if (type == Event.ONCLICK) {
@@ -709,7 +700,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
.getEventTarget().cast())) {
if (dragMode > 0
&& (type == Event.ONTOUCHSTART || event
- .getButton() == NativeEvent.BUTTON_LEFT)) {
+ .getButton() == NativeEvent.BUTTON_LEFT)) {
mouseDownEvent = event; // save event for possible
// dd operation
if (type == Event.ONMOUSEDOWN) {
@@ -790,9 +781,12 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
focus();
}
}
+
final MouseEventDetails details = MouseEventDetailsBuilder
.buildMouseEventDetails(evt);
- ScheduledCommand command = new ScheduledCommand() {
+
+ executeEventCommand(new ScheduledCommand() {
+
@Override
public void execute() {
// Determine if we should send the event immediately to the
@@ -820,14 +814,18 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
client.updateVariable(paintableId, "clickEvent",
details.toString(), sendClickEventNow);
}
- };
- if (treeHasFocus) {
- command.execute();
- } else {
- /*
- * Webkits need a deferring due to FocusImplSafari uses timeout
- */
+ });
+ }
+
+ /*
+ * Must wait for Safari to focus before sending click and value change
+ * events (see #6373, #6374)
+ */
+ private void executeEventCommand(ScheduledCommand command) {
+ if (BrowserInfo.get().isWebkit() && !treeHasFocus) {
Scheduler.get().scheduleDeferred(command);
+ } else {
+ command.execute();
}
}
@@ -1723,7 +1721,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
selectNode(
focusedNode,
(!isMultiselect || multiSelectMode == MULTISELECT_MODE_SIMPLE)
- && selectable);
+ && selectable);
} else {
deselectNode(focusedNode);
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java b/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
index a8621190ae..909acdf85f 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
@@ -188,8 +188,7 @@ public class VTreeTable extends VScrollTable {
if (isTreeCellAdded) {
return false;
}
- return curColIndex == colIndexOfHierarchy
- + (showRowHeaders ? 1 : 0);
+ return curColIndex == getHierarchyColumnIndex();
}
@Override
@@ -227,6 +226,23 @@ public class VTreeTable extends VScrollTable {
super.onAttach();
if (getIndentWidth() < 0) {
detectIndent(this);
+ // If we detect indent here then the size of the hierarchy
+ // column is still wrong as it has been set when the indent
+ // was not known.
+ int w = getCellWidthFromDom(getHierarchyColumnIndex());
+ if (w >= 0) {
+ setColWidth(getHierarchyColumnIndex(), w);
+ }
+ }
+ }
+
+ private int getCellWidthFromDom(int cellIndex) {
+ final Element cell = DOM.getChild(getElement(), cellIndex);
+ String w = cell.getStyle().getProperty("width");
+ if (w == null || "".equals(w) || !w.endsWith("px")) {
+ return -1;
+ } else {
+ return Integer.parseInt(w.substring(0, w.length() - 2));
}
}
@@ -242,14 +258,21 @@ public class VTreeTable extends VScrollTable {
@Override
protected void setCellWidth(int cellIx, int width) {
- if (cellIx == colIndexOfHierarchy + (showRowHeaders ? 1 : 0)) {
+ if (cellIx == getHierarchyColumnIndex()) {
// take indentation padding into account if this is the
// hierarchy column
- width = Math.max(width - getIndent(), 0);
+ int indent = getIndent();
+ if (indent != -1) {
+ width = Math.max(width - getIndent(), 0);
+ }
}
super.setCellWidth(cellIx, width);
}
+ private int getHierarchyColumnIndex() {
+ return colIndexOfHierarchy + (showRowHeaders ? 1 : 0);
+ }
+
private int getIndent() {
return (depth + 1) * getIndentWidth();
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
index a1bab91618..3ee266b944 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
@@ -46,8 +46,8 @@ import com.vaadin.terminal.gwt.client.ui.layout.MayScrollChildren;
@Connect(value = com.vaadin.ui.Window.class)
public class WindowConnector extends AbstractComponentContainerConnector
- implements Paintable, BeforeShortcutActionListener,
- SimpleManagedLayout, PostLayoutListener, MayScrollChildren {
+implements Paintable, BeforeShortcutActionListener,
+SimpleManagedLayout, PostLayoutListener, MayScrollChildren {
private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
@Override
@@ -102,7 +102,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
}
if (!getWidget().isAttached()) {
getWidget().setVisible(false); // hide until
- // possible centering
+ // possible centering
getWidget().show();
}
if (getState().isResizable() != getWidget().resizable) {
@@ -299,7 +299,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
if (window.centered) {
window.center();
}
- window.sizeOrPositionUpdated();
+ window.positionOrSizeUpdated();
}
@Override