summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2015-01-14 10:18:39 +0200
committerArtur Signell <artur@vaadin.com>2015-01-14 10:18:39 +0200
commit032bcef30f5ada7dc1ca6eade07ee596afa25bb3 (patch)
treea036581c2b7ae7e82fdd60ba92b2fe392b85df7a /client
parent8a544b5a6e78337b24a5e56bcde1a21ff6087fae (diff)
parentb356e7e3bba9b08ad9d1ecdfb4d628b8179ef20a (diff)
downloadvaadin-framework-032bcef30f5ada7dc1ca6eade07ee596afa25bb3.tar.gz
vaadin-framework-032bcef30f5ada7dc1ca6eade07ee596afa25bb3.zip
Merge remote-tracking branch 'origin/master' into grid
Conflicts: client/src/com/vaadin/client/communication/AtmospherePushConnection.java server/tests/src/com/vaadin/data/fieldgroup/FieldGroupTests.java shared/src/com/vaadin/shared/util/SharedUtil.java Change-Id: I300b5a92bde562390a56b720adf9a37b795c9513
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ApplicationConfiguration.java11
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java128
-rw-r--r--client/src/com/vaadin/client/EventHelper.java55
-rw-r--r--client/src/com/vaadin/client/communication/AtmospherePushConnection.java4
-rw-r--r--client/src/com/vaadin/client/communication/Heartbeat.java3
-rw-r--r--client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java5
-rw-r--r--client/src/com/vaadin/client/extensions/ResponsiveConnector.java74
-rw-r--r--client/src/com/vaadin/client/ui/VNativeSelect.java17
-rw-r--r--client/src/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java21
-rw-r--r--client/tests/src/com/vaadin/client/ApplicationConnectionURLGenerationTest.java10
10 files changed, 176 insertions, 152 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java
index d3be69443e..37d689c6d3 100644
--- a/client/src/com/vaadin/client/ApplicationConfiguration.java
+++ b/client/src/com/vaadin/client/ApplicationConfiguration.java
@@ -276,8 +276,7 @@ public class ApplicationConfiguration implements EntryPoint {
* <code>false</code> if the path info goes after the service URL
*/
public boolean useServiceUrlPathParam() {
- return getJsoConfiguration(id).getConfigBoolean(
- ApplicationConstants.SERVICE_URL_PATH_AS_PARAMETER) == Boolean.TRUE;
+ return getServiceUrlParameterName() != null;
}
/**
@@ -289,12 +288,8 @@ public class ApplicationConfiguration implements EntryPoint {
* @return The parameter name, by default <code>v-resourcePath</code>
*/
public String getServiceUrlParameterName() {
- String prefix = getJsoConfiguration(id).getConfigString(
- ApplicationConstants.SERVICE_URL_PARAMETER_NAMESPACE);
- if (prefix == null) {
- prefix = "";
- }
- return prefix + ApplicationConstants.V_RESOURCE_PATH;
+ return getJsoConfiguration(id).getConfigString(
+ ApplicationConstants.SERVICE_URL_PARAMETER_NAME);
}
public String getRootPanelId() {
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 6abaf28eda..117486ffdb 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -97,12 +97,14 @@ import com.vaadin.client.ui.window.WindowConnector;
import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JsonConstants;
+import com.vaadin.shared.VaadinUriResolver;
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.ui.ui.UIConstants;
import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
+import com.vaadin.shared.util.SharedUtil;
import elemental.json.Json;
import elemental.json.JsonArray;
@@ -480,6 +482,33 @@ public class ApplicationConnection implements HasHandlers {
private boolean tooltipInitialized = false;
+ private final VaadinUriResolver uriResolver = new VaadinUriResolver() {
+ @Override
+ protected String getVaadinDirUrl() {
+ return getConfiguration().getVaadinDirUrl();
+ }
+
+ @Override
+ protected String getServiceUrlParameterName() {
+ return getConfiguration().getServiceUrlParameterName();
+ }
+
+ @Override
+ protected String getServiceUrl() {
+ return getConfiguration().getServiceUrl();
+ }
+
+ @Override
+ protected String getThemeUri() {
+ return ApplicationConnection.this.getThemeUri();
+ }
+
+ @Override
+ protected String encodeQueryStringParameterValue(String queryString) {
+ return URL.encodeQueryString(queryString);
+ }
+ };
+
public static class MultiStepDuration extends Duration {
private int previousStep = elapsedMillis();
@@ -829,10 +858,10 @@ public class ApplicationConnection implements HasHandlers {
+ ApplicationConstants.UIDL_PATH + '/');
if (extraParams != null && extraParams.length() > 0) {
- uri = addGetParameters(uri, extraParams);
+ uri = SharedUtil.addGetParameters(uri, extraParams);
}
- uri = addGetParameters(uri, UIConstants.UI_ID_PARAMETER + "="
- + configuration.getUIId());
+ uri = SharedUtil.addGetParameters(uri, UIConstants.UI_ID_PARAMETER
+ + "=" + configuration.getUIId());
doUidlRequest(uri, payload);
@@ -3240,67 +3269,7 @@ public class ApplicationConnection implements HasHandlers {
* @return translated URI ready for browser
*/
public String translateVaadinUri(String uidlUri) {
- if (uidlUri == null) {
- return null;
- }
- if (uidlUri.startsWith("theme://")) {
- final String themeUri = getThemeUri();
- if (themeUri == null) {
- VConsole.error("Theme not set: ThemeResource will not be found. ("
- + uidlUri + ")");
- }
- uidlUri = themeUri + uidlUri.substring(7);
- }
-
- if (uidlUri.startsWith(ApplicationConstants.PUBLISHED_PROTOCOL_PREFIX)) {
- // getAppUri *should* always end with /
- // substring *should* always start with / (published:///foo.bar
- // without published://)
- uidlUri = ApplicationConstants.APP_PROTOCOL_PREFIX
- + ApplicationConstants.PUBLISHED_FILE_PATH
- + uidlUri
- .substring(ApplicationConstants.PUBLISHED_PROTOCOL_PREFIX
- .length());
- // Let translation of app:// urls take care of the rest
- }
- if (uidlUri.startsWith(ApplicationConstants.APP_PROTOCOL_PREFIX)) {
- String relativeUrl = uidlUri
- .substring(ApplicationConstants.APP_PROTOCOL_PREFIX
- .length());
- ApplicationConfiguration conf = getConfiguration();
- String serviceUrl = conf.getServiceUrl();
- if (conf.useServiceUrlPathParam()) {
- // Should put path in v-resourcePath parameter and append query
- // params to base portlet url
- String[] parts = relativeUrl.split("\\?", 2);
- String path = parts[0];
-
- // If there's a "?" followed by something, append it as a query
- // string to the base URL
- if (parts.length > 1) {
- String appUrlParams = parts[1];
- serviceUrl = addGetParameters(serviceUrl, appUrlParams);
- }
- if (!path.startsWith("/")) {
- path = '/' + path;
- }
- String pathParam = conf.getServiceUrlParameterName() + "="
- + URL.encodeQueryString(path);
- serviceUrl = addGetParameters(serviceUrl, pathParam);
- uidlUri = serviceUrl;
- } else {
- uidlUri = serviceUrl + relativeUrl;
- }
- }
- if (uidlUri.startsWith(ApplicationConstants.VAADIN_PROTOCOL_PREFIX)) {
- final String vaadinUri = configuration.getVaadinDirUrl();
- String relativeUrl = uidlUri
- .substring(ApplicationConstants.VAADIN_PROTOCOL_PREFIX
- .length());
- uidlUri = vaadinUri + relativeUrl;
- }
-
- return uidlUri;
+ return uriResolver.resolveVaadinUri(uidlUri);
}
/**
@@ -3417,35 +3386,12 @@ public class ApplicationConnection implements HasHandlers {
* One or more parameters in the format "a=b" or "c=d&e=f". An
* empty string is allowed but will not modify the url.
* @return The modified URI with the get parameters in extraParams added.
+ * @deprecated Use {@link SharedUtil#addGetParameters(String,String)}
+ * instead
*/
+ @Deprecated
public static String addGetParameters(String uri, String extraParams) {
- if (extraParams == null || extraParams.length() == 0) {
- return uri;
- }
- // RFC 3986: The query component is indicated by the first question
- // mark ("?") character and terminated by a number sign ("#") character
- // or by the end of the URI.
- String fragment = null;
- int hashPosition = uri.indexOf('#');
- if (hashPosition != -1) {
- // Fragment including "#"
- fragment = uri.substring(hashPosition);
- // The full uri before the fragment
- uri = uri.substring(0, hashPosition);
- }
-
- if (uri.contains("?")) {
- uri += "&";
- } else {
- uri += "?";
- }
- uri += extraParams;
-
- if (fragment != null) {
- uri += fragment;
- }
-
- return uri;
+ return SharedUtil.addGetParameters(uri, extraParams);
}
ConnectorMap getConnectorMap() {
diff --git a/client/src/com/vaadin/client/EventHelper.java b/client/src/com/vaadin/client/EventHelper.java
index a1cb75527d..f251215d41 100644
--- a/client/src/com/vaadin/client/EventHelper.java
+++ b/client/src/com/vaadin/client/EventHelper.java
@@ -25,6 +25,7 @@ import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.Widget;
/**
* Helper class for attaching/detaching handlers for Vaadin client side
@@ -61,7 +62,7 @@ public class EventHelper {
* @param connector
* The connector to update. Must implement focusHandler.
* @param handlerRegistration
- * The old registration reference or null no handler has been
+ * The old registration reference or null if no handler has been
* registered previously
* @return a new registration handler that can be used to unregister the
* handler later
@@ -69,7 +70,27 @@ public class EventHelper {
public static <T extends ComponentConnector & FocusHandler> HandlerRegistration updateFocusHandler(
T connector, HandlerRegistration handlerRegistration) {
return updateHandler(connector, FOCUS, handlerRegistration,
- FocusEvent.getType());
+ FocusEvent.getType(), connector.getWidget());
+ }
+
+ /**
+ * Adds or removes a focus handler depending on if the connector has focus
+ * listeners on the server side or not.
+ *
+ * @param connector
+ * The connector to update. Must implement focusHandler.
+ * @param handlerRegistration
+ * The old registration reference or null if no handler has been
+ * registered previously
+ * @param widget
+ * The widget which emits focus events
+ * @return a new registration handler that can be used to unregister the
+ * handler later
+ */
+ public static <T extends ComponentConnector & FocusHandler> HandlerRegistration updateFocusHandler(
+ T connector, HandlerRegistration handlerRegistration, Widget widget) {
+ return updateHandler(connector, FOCUS, handlerRegistration,
+ FocusEvent.getType(), widget);
}
/**
@@ -79,7 +100,7 @@ public class EventHelper {
* @param connector
* The connector to update. Must implement BlurHandler.
* @param handlerRegistration
- * The old registration reference or null no handler has been
+ * The old registration reference or null if no handler has been
* registered previously
* @return a new registration handler that can be used to unregister the
* handler later
@@ -87,16 +108,36 @@ public class EventHelper {
public static <T extends ComponentConnector & BlurHandler> HandlerRegistration updateBlurHandler(
T connector, HandlerRegistration handlerRegistration) {
return updateHandler(connector, BLUR, handlerRegistration,
- BlurEvent.getType());
+ BlurEvent.getType(), connector.getWidget());
+ }
+
+ /**
+ * Adds or removes a blur handler depending on if the connector has blur
+ * listeners on the server side or not.
+ *
+ * @param connector
+ * The connector to update. Must implement BlurHandler.
+ * @param handlerRegistration
+ * The old registration reference or null if no handler has been
+ * registered previously
+ * @param widget
+ * The widget which emits blur events
+ *
+ * @return a new registration handler that can be used to unregister the
+ * handler later
+ */
+ public static <T extends ComponentConnector & BlurHandler> HandlerRegistration updateBlurHandler(
+ T connector, HandlerRegistration handlerRegistration, Widget widget) {
+ return updateHandler(connector, BLUR, handlerRegistration,
+ BlurEvent.getType(), widget);
}
private static <H extends EventHandler> HandlerRegistration updateHandler(
ComponentConnector connector, String eventIdentifier,
- HandlerRegistration handlerRegistration, Type<H> type) {
+ HandlerRegistration handlerRegistration, Type<H> type, Widget widget) {
if (connector.hasEventListener(eventIdentifier)) {
if (handlerRegistration == null) {
- handlerRegistration = connector.getWidget().addDomHandler(
- (H) connector, type);
+ handlerRegistration = widget.addDomHandler((H) connector, type);
}
} else if (handlerRegistration != null) {
handlerRegistration.removeHandler();
diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
index dc8d497a69..da08928f36 100644
--- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
+++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
@@ -34,6 +34,8 @@ import com.vaadin.shared.Version;
import com.vaadin.shared.communication.PushConstants;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
+import com.vaadin.shared.util.SharedUtil;
+
import elemental.json.JsonObject;
/**
@@ -185,7 +187,7 @@ public class AtmospherePushConnection implements PushConnection {
}
// uri is needed to identify the right connection when closing
- uri = ApplicationConnection.addGetParameters(baseUrl, extraParams);
+ uri = SharedUtil.addGetParameters(baseUrl, extraParams);
VConsole.log("Establishing push connection");
socket = doConnect(uri, getConfig());
diff --git a/client/src/com/vaadin/client/communication/Heartbeat.java b/client/src/com/vaadin/client/communication/Heartbeat.java
index b9493d4520..5d15e5585f 100644
--- a/client/src/com/vaadin/client/communication/Heartbeat.java
+++ b/client/src/com/vaadin/client/communication/Heartbeat.java
@@ -28,6 +28,7 @@ import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ApplicationConnection.ConnectionStatusEvent;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.util.SharedUtil;
/**
* Handles sending of heartbeats to the server and reacting to the response
@@ -63,7 +64,7 @@ public class Heartbeat {
setInterval(connection.getConfiguration().getHeartbeatInterval());
- uri = ApplicationConnection.addGetParameters(connection
+ uri = SharedUtil.addGetParameters(connection
.translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX
+ ApplicationConstants.HEARTBEAT_PATH + '/'),
UIConstants.UI_ID_PARAMETER + "="
diff --git a/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java b/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java
index 58457c1b7b..11e3e80a14 100644
--- a/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java
+++ b/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java
@@ -23,12 +23,12 @@ import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ServerConnector;
import com.vaadin.server.BrowserWindowOpener;
import com.vaadin.shared.ui.BrowserWindowOpenerState;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.util.SharedUtil;
/**
* Client-side code for {@link BrowserWindowOpener}
@@ -81,8 +81,7 @@ public class BrowserWindowOpenerConnector extends AbstractExtensionConnector
}
}
- url = ApplicationConnection
- .addGetParameters(url, params.toString());
+ url = SharedUtil.addGetParameters(url, params.toString());
}
if (getState().uriFragment != null) {
diff --git a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java
index 59e6600949..2e1e75f6cd 100644
--- a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java
+++ b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java
@@ -24,11 +24,13 @@ import com.google.gwt.dom.client.Element;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.ServerConnector;
+import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.layout.ElementResizeEvent;
import com.vaadin.client.ui.layout.ElementResizeListener;
import com.vaadin.server.Responsive;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.util.SharedUtil;
/**
* The client side connector for the Responsive extension.
@@ -68,6 +70,12 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
*/
protected static JavaScriptObject heightRangeCache;
+ /**
+ * The theme that was in use when the width and height range caches were
+ * created.
+ */
+ protected static String parsedTheme;
+
private static Logger getLogger() {
return Logger.getLogger(ResponsiveConnector.class.getName());
}
@@ -78,16 +86,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
@Override
protected void extend(ServerConnector target) {
- // Initialize cache if not already done
- if (widthRangeCache == null) {
- searchForBreakPoints();
- }
-
this.target = (AbstractComponentConnector) target;
-
- // Get any breakpoints from the styles defined for this widget
- getBreakPointsFor(constructSelectorsForTarget());
-
// Start listening for size changes
LayoutManager.get(getConnection()).addElementResizeListener(
this.target.getWidget().getElement(), this);
@@ -131,11 +130,37 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
target.getWidget().getElement(), this);
}
+ @Override
+ public void onStateChanged(StateChangeEvent event) {
+ super.onStateChanged(event);
+ // Changing the theme may introduce new style sheets so we may need to
+ // rebuild the cache
+ if (widthRangeCache == null
+ || !SharedUtil.equals(parsedTheme, getCurrentThemeName())) {
+ // updating break points
+ searchForBreakPoints();
+ }
+ // Get any breakpoints from the styles defined for this widget
+ getBreakPointsFor(constructSelectorsForTarget());
+ // make sure that the ranges are updated at least once regardless of
+ // resize events.
+ updateRanges();
+ }
+
+ private String getCurrentThemeName() {
+ return getConnection().getUIConnector().getActiveTheme();
+ }
+
+ private void searchForBreakPoints() {
+ searchForBreakPointsNative();
+ parsedTheme = getCurrentThemeName();
+ }
+
/**
* Build a cache of all 'width-range' and 'height-range' attribute selectors
* found in the stylesheets.
*/
- private static native void searchForBreakPoints()
+ private static native void searchForBreakPointsNative()
/*-{
// Initialize variables
@@ -307,36 +332,36 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
@Override
public void onElementResize(final ElementResizeEvent event) {
- int width = event.getLayoutManager().getOuterWidth(event.getElement());
- int height = event.getLayoutManager()
- .getOuterHeight(event.getElement());
+ updateRanges();
+ }
+ private void updateRanges() {
+ LayoutManager layoutManager = LayoutManager.get(getConnection());
com.google.gwt.user.client.Element element = target.getWidget()
.getElement();
+ int width = layoutManager.getOuterWidth(element);
+ int height = layoutManager.getOuterHeight(element);
+
boolean forceRedraw = false;
String oldWidthRanges = currentWidthRanges;
String oldHeightRanges = currentHeightRanges;
// Loop through breakpoints and see which one applies to this width
- currentWidthRanges = resolveBreakpoint("width", width,
- event.getElement());
+ currentWidthRanges = resolveBreakpoint("width", width);
if (!"".equals(currentWidthRanges)) {
- target.getWidget().getElement()
- .setAttribute("width-range", currentWidthRanges);
+ element.setAttribute("width-range", currentWidthRanges);
forceRedraw = true;
} else {
element.removeAttribute("width-range");
}
// Loop through breakpoints and see which one applies to this height
- currentHeightRanges = resolveBreakpoint("height", height,
- event.getElement());
+ currentHeightRanges = resolveBreakpoint("height", height);
if (!"".equals(currentHeightRanges)) {
- target.getWidget().getElement()
- .setAttribute("height-range", currentHeightRanges);
+ element.setAttribute("height-range", currentHeightRanges);
forceRedraw = true;
} else {
element.removeAttribute("height-range");
@@ -350,8 +375,8 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
// case some new styles are applied
if (!currentWidthRanges.equals(oldWidthRanges)
|| !currentHeightRanges.equals(oldHeightRanges)) {
- event.getLayoutManager().setNeedsMeasureRecursively(
- ResponsiveConnector.this.target);
+ layoutManager
+ .setNeedsMeasureRecursively(ResponsiveConnector.this.target);
}
}
@@ -370,8 +395,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements
}
}
- private native String resolveBreakpoint(String which, int size,
- Element element)
+ private native String resolveBreakpoint(String which, int size)
/*-{
// Default to "width" breakpoints
diff --git a/client/src/com/vaadin/client/ui/VNativeSelect.java b/client/src/com/vaadin/client/ui/VNativeSelect.java
index 879c54cae8..330442b550 100644
--- a/client/src/com/vaadin/client/ui/VNativeSelect.java
+++ b/client/src/com/vaadin/client/ui/VNativeSelect.java
@@ -19,9 +19,7 @@ package com.vaadin.client.ui;
import java.util.ArrayList;
import java.util.Iterator;
-import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.user.client.ui.ListBox;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.UIDL;
@@ -119,14 +117,6 @@ public class VNativeSelect extends VOptionGroupBase implements Field {
}
}
- public void addFocusHandler(FocusHandler handler) {
- select.addFocusHandler(handler);
- }
-
- public void addBlurHandler(BlurHandler handler) {
- select.addBlurHandler(handler);
- }
-
@Override
public void setHeight(String height) {
select.setHeight(height);
@@ -154,4 +144,11 @@ public class VNativeSelect extends VOptionGroupBase implements Field {
select.setFocus(true);
}
+ /**
+ * @return the root select widget
+ */
+ public ListBox getSelect() {
+ return getOptionsContainer();
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java b/client/src/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java
index c52b762e58..938903da9a 100644
--- a/client/src/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java
+++ b/client/src/com/vaadin/client/ui/nativeselect/NativeSelectConnector.java
@@ -20,6 +20,9 @@ import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.vaadin.client.EventHelper;
+import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.VNativeSelect;
import com.vaadin.client.ui.optiongroup.OptionGroupBaseConnector;
import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
@@ -30,10 +33,19 @@ import com.vaadin.ui.NativeSelect;
public class NativeSelectConnector extends OptionGroupBaseConnector implements
BlurHandler, FocusHandler {
+ private HandlerRegistration focusHandlerRegistration = null;
+ private HandlerRegistration blurHandlerRegistration = null;
+
public NativeSelectConnector() {
super();
- getWidget().addFocusHandler(this);
- getWidget().addBlurHandler(this);
+ }
+
+ @OnStateChange("registeredEventListeners")
+ private void onServerEventListenerChanged() {
+ focusHandlerRegistration = EventHelper.updateFocusHandler(this,
+ focusHandlerRegistration, getWidget().getSelect());
+ blurHandlerRegistration = EventHelper.updateBlurHandler(this,
+ blurHandlerRegistration, getWidget().getSelect());
}
@Override
@@ -43,11 +55,16 @@ public class NativeSelectConnector extends OptionGroupBaseConnector implements
@Override
public void onFocus(FocusEvent event) {
+ // EventHelper.updateFocusHandler ensures that this is called only when
+ // there is a listener on server side
getRpcProxy(FocusAndBlurServerRpc.class).focus();
}
@Override
public void onBlur(BlurEvent event) {
+ // EventHelper.updateFocusHandler ensures that this is called only when
+ // there is a listener on server side
getRpcProxy(FocusAndBlurServerRpc.class).blur();
}
+
}
diff --git a/client/tests/src/com/vaadin/client/ApplicationConnectionURLGenerationTest.java b/client/tests/src/com/vaadin/client/ApplicationConnectionURLGenerationTest.java
index 36baa163cb..f529ba0886 100644
--- a/client/tests/src/com/vaadin/client/ApplicationConnectionURLGenerationTest.java
+++ b/client/tests/src/com/vaadin/client/ApplicationConnectionURLGenerationTest.java
@@ -4,6 +4,8 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
+import com.vaadin.shared.util.SharedUtil;
+
public class ApplicationConnectionURLGenerationTest {
private static final String[] URIS = new String[] {
@@ -51,23 +53,23 @@ public class ApplicationConnectionURLGenerationTest {
for (int i = 0; i < URIS.length; i++) {
// Adding nothing
assertEquals(URIS[i],
- ApplicationConnection.addGetParameters(URIS[i], ""));
+ SharedUtil.addGetParameters(URIS[i], ""));
// Adding a=b&c=d
assertEquals(URIS_WITH_ABCD_PARAM[i],
- ApplicationConnection.addGetParameters(URIS[i], "a=b&c=d"));
+ SharedUtil.addGetParameters(URIS[i], "a=b&c=d"));
// Fragments
if (URIS_WITH_ABCD_PARAM_AND_FRAGMENT[i].length() > 0) {
assertEquals(
URIS_WITH_ABCD_PARAM_AND_FRAGMENT[i],
- ApplicationConnection.addGetParameters(URIS[i]
+ SharedUtil.addGetParameters(URIS[i]
+ "#fragment", "a=b&c=d"));
// Empty fragment
assertEquals(URIS_WITH_ABCD_PARAM_AND_FRAGMENT[i].replace(
"#fragment", "#"),
- ApplicationConnection.addGetParameters(URIS[i] + "#",
+ SharedUtil.addGetParameters(URIS[i] + "#",
"a=b&c=d"));
}
}