diff options
62 files changed, 945 insertions, 937 deletions
diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss index 6ec85e3c6d..0a493e0356 100644 --- a/WebContent/VAADIN/themes/base/common/common.scss +++ b/WebContent/VAADIN/themes/base/common/common.scss @@ -11,6 +11,19 @@ .v-caption { cursor: default; } +/* add box-shadows to overlay elements */ +.v-window { + box-shadow: 0 5px 18px 0 rgba(0, 0, 0, .5); +} +.v-datefield-popup, +.v-filterselect-suggestpopup, +.v-menubar-popup, +.v-slider-feedback, +.v-popupview-popup, +.v-contextmenu { + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .5); +} + body &.v-app .v-app-loading { /* You can use this to provide indication for the user that the application is loading. */ /* It is applied to the same element as .v-app */ @@ -115,6 +128,7 @@ body &.v-app .v-app-loading { .v-tooltip { cursor: default; background: #fff; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .5); } .v-tooltip-text { overflow: auto; diff --git a/WebContent/VAADIN/themes/base/datefield/datefield.scss b/WebContent/VAADIN/themes/base/datefield/datefield.scss index d094235c0f..57a691211d 100644 --- a/WebContent/VAADIN/themes/base/datefield/datefield.scss +++ b/WebContent/VAADIN/themes/base/datefield/datefield.scss @@ -95,6 +95,9 @@ } .#{$primaryStyleName}-popup { background: #fff; + .v-ie9 &, .v-ie10 &, .v-ie11 & { + box-shadow: 0 2px 10px 0 rgba(0, 0, 0, .5); + } } .#{$primaryStyleName}-popupcalendar input.#{$primaryStyleName}-textfield { -webkit-box-sizing: border-box; diff --git a/WebContent/VAADIN/themes/base/shadow/shadow.scss b/WebContent/VAADIN/themes/base/shadow/shadow.scss index 47bf4acfde..3c369d3fef 100644 --- a/WebContent/VAADIN/themes/base/shadow/shadow.scss +++ b/WebContent/VAADIN/themes/base/shadow/shadow.scss @@ -2,6 +2,12 @@ .#{$primaryStyleName} { position: absolute; + display: none; + pointer-events: none; + + .v-ie8 & { + display: block; + } } .#{$primaryStyleName} .top-left { diff --git a/WebContent/VAADIN/themes/base/window/window.scss b/WebContent/VAADIN/themes/base/window/window.scss index 05f3b115ad..4e414379cf 100644 --- a/WebContent/VAADIN/themes/base/window/window.scss +++ b/WebContent/VAADIN/themes/base/window/window.scss @@ -125,6 +125,12 @@ div.#{$primaryStyleName}-header { /* Shadow for window */ .v-shadow-window { position: absolute; + display: none; + pointer-events: none; + + .v-ie8 & { + display: block; + } } .v-shadow-window .top-left { position: absolute; overflow: hidden; diff --git a/WebContent/VAADIN/themes/chameleon/common/common.scss b/WebContent/VAADIN/themes/chameleon/common/common.scss index 382dff3325..7bee2f529c 100644 --- a/WebContent/VAADIN/themes/chameleon/common/common.scss +++ b/WebContent/VAADIN/themes/chameleon/common/common.scss @@ -91,8 +91,6 @@ $chameleon-line-height: 1.4; .v-contextmenu, .v-Notification, .v-menubar-submenu { - background: #fff url(../img/grad-light-top.png) repeat-x; - background-color: rgba(255,255,255,.85); border: 1px solid #adadad; border-color: rgba(0,0,0,.4); border-radius: 4px; @@ -100,7 +98,14 @@ $chameleon-line-height: 1.4; -moz-border-radius: 4px; overflow: hidden; } - + .v-window, + .v-popupview-popup, + .v-filterselect-suggestpopup, + .v-datefield-popup, + .v-contextmenu, + .v-menubar-submenu{ + background: rgba(232,232,232,.90) url(../img/grad-light-top.png) repeat-x; + } .v-filterselect-suggestpopup, .v-contextmenu, .v-menubar-submenu { diff --git a/WebContent/VAADIN/themes/chameleon/components/menubar/menubar.scss b/WebContent/VAADIN/themes/chameleon/components/menubar/menubar.scss index 0531d0c9b5..0db478855d 100644 --- a/WebContent/VAADIN/themes/chameleon/components/menubar/menubar.scss +++ b/WebContent/VAADIN/themes/chameleon/components/menubar/menubar.scss @@ -25,5 +25,7 @@ background-image: url(../../img/grad-light-top2.png); background-position: 0 -1px; } - +.#{$primaryStyleName}-popup { + border-radius: 5px; + } }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/chameleon/components/window/window.scss b/WebContent/VAADIN/themes/chameleon/components/window/window.scss index 92ada43c90..16de81a785 100644 --- a/WebContent/VAADIN/themes/chameleon/components/window/window.scss +++ b/WebContent/VAADIN/themes/chameleon/components/window/window.scss @@ -1,5 +1,8 @@ @mixin chameleon-window($primaryStyleName : v-window) { +.#{$primaryStyleName} { + border-radius: 3px; +} .#{$primaryStyleName}-closebox, .#{$primaryStyleName}-restorebox, .#{$primaryStyleName}-maximizebox { diff --git a/WebContent/VAADIN/themes/liferay/menubar/menubar.scss b/WebContent/VAADIN/themes/liferay/menubar/menubar.scss index 448d7569c8..dd31608e79 100644 --- a/WebContent/VAADIN/themes/liferay/menubar/menubar.scss +++ b/WebContent/VAADIN/themes/liferay/menubar/menubar.scss @@ -58,7 +58,9 @@ text-shadow: 1px 1px #000; background-color: #5b677d; } - +.v-menubar-popup { + border-radius: 5px; + } .v-menubar-menuitem-disabled, .v-menubar-submenu .v-menubar-menuitem-disabled, .v-menubar span.v-menubar-menuitem-disabled:hover, diff --git a/WebContent/VAADIN/themes/liferay/window/window.scss b/WebContent/VAADIN/themes/liferay/window/window.scss index 583a81d9e4..d78c69a72f 100644 --- a/WebContent/VAADIN/themes/liferay/window/window.scss +++ b/WebContent/VAADIN/themes/liferay/window/window.scss @@ -5,7 +5,6 @@ } .v-window-wrap { - border: 1px solid #c8c9ca; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; diff --git a/WebContent/VAADIN/themes/reindeer/window/window.scss b/WebContent/VAADIN/themes/reindeer/window/window.scss index 57bd2d4c12..66c80c6a44 100644 --- a/WebContent/VAADIN/themes/reindeer/window/window.scss +++ b/WebContent/VAADIN/themes/reindeer/window/window.scss @@ -2,9 +2,9 @@ .#{$primaryStyleName} { background: transparent; + border: 1px solid #808386; } .#{$primaryStyleName}-wrap { - border: 1px solid #808386; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; @@ -48,8 +48,8 @@ height: 15px; } .#{$primaryStyleName}-closebox { - top: 12px; - right: 10px; + top: 11px; + right: 9px; width: 15px; height: 16px; background: transparent; @@ -63,8 +63,8 @@ } .#{$primaryStyleName}-maximizebox, .#{$primaryStyleName}-restorebox { - top: 12px; - right: 28px; + top: 11px; + right: 27px; width: 15px; height: 16px; background: transparent; @@ -166,7 +166,9 @@ /** Black style window ----------------------------- **/ - +.#{$primaryStyleName}-black { + border-radius: 8px; +} .#{$primaryStyleName}-black { .#{$primaryStyleName}-wrap { border-color: #2e3030; diff --git a/WebContent/VAADIN/themes/runo/common/common.scss b/WebContent/VAADIN/themes/runo/common/common.scss index 36447d9593..207660c08e 100644 --- a/WebContent/VAADIN/themes/runo/common/common.scss +++ b/WebContent/VAADIN/themes/runo/common/common.scss @@ -38,6 +38,15 @@ .v-window select { padding: 0; } +.v-window +.v-datefield-popup, +.v-filterselect-suggestpopup, +.v-menubar-popup, +.v-slider-feedback, +.v-popupview-popup, +.v-contextmenu { + box-shadow: 0 2px 5px 0 rgba(0,0,0, .28); +} /* Custom tooltip */ .v-tooltip { background-color: #fffcdd; diff --git a/WebContent/VAADIN/themes/runo/window/window.scss b/WebContent/VAADIN/themes/runo/window/window.scss index 1a7cfd3b01..bf2081674c 100644 --- a/WebContent/VAADIN/themes/runo/window/window.scss +++ b/WebContent/VAADIN/themes/runo/window/window.scss @@ -1,5 +1,10 @@ @mixin runo-window($primaryStyleName : v-window) { +/* add box-shadows to an overlay element */ +.#{$primaryStyleName} { + box-shadow: 0 10px 24px 0 rgba(42, 45, 46, .4); + border-radius: 10px; +} .#{$primaryStyleName} { color: #464f52; font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif; diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 268fe1ea66..fb2ddbd998 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -44,6 +44,11 @@ <async-supported>true</async-supported> </servlet> <servlet> + <servlet-name>GwtRpcTest</servlet-name> + <servlet-class>com.vaadin.tests.widgetset.server.gwtrpc.GwtRpcServletTest</servlet-class> + </servlet> + + <servlet> <servlet-name>UI provider app</servlet-name> <servlet-class>com.vaadin.server.VaadinServlet</servlet-class> <init-param> @@ -134,15 +139,19 @@ <param-value>false</param-value> </init-param> </servlet> + <servlet-mapping> <servlet-name>Embed App 1</servlet-name> <url-pattern>/embed1/*</url-pattern> </servlet-mapping> - <servlet-mapping> <servlet-name>Embed App 2</servlet-name> <url-pattern>/embed2/*</url-pattern> </servlet-mapping> + <servlet-mapping> + <servlet-name>GwtRpcTest</servlet-name> + <url-pattern>/VAADIN/widgetsets/com.vaadin.tests.widgetset.TestingWidgetSet/GwtRpcTest/*</url-pattern> + </servlet-mapping> <servlet-mapping> <servlet-name>UI provider app</servlet-name> diff --git a/build.properties b/build.properties index a7871ad1ef..0c0e58cb53 100644 --- a/build.properties +++ b/build.properties @@ -5,6 +5,6 @@ vaadin.vendor=Vaadin Ltd vaadin.url=http://vaadin.com vaadin.java.version=1.6 vaadin.version=0.0.0.unversioned-development-build -vaadin.sass.version=0.9.7 +vaadin.sass.version=0.9.8 gwt.version=2.6.0.vaadin3 commons-io.version=2.4 diff --git a/client-compiler/src/com/vaadin/tools/CvalAddonsChecker.java b/client-compiler/src/com/vaadin/tools/CvalAddonsChecker.java index 6780b1bc75..aab7231258 100644 --- a/client-compiler/src/com/vaadin/tools/CvalAddonsChecker.java +++ b/client-compiler/src/com/vaadin/tools/CvalAddonsChecker.java @@ -50,6 +50,8 @@ import com.vaadin.tools.CvalChecker.UnreachableCvalServerException; * </ul> * * The class also have a method to check just one product. + * + * @since 7.3 */ public final class CvalAddonsChecker { @@ -77,7 +79,7 @@ public final class CvalAddonsChecker { /** * Visit all MANIFEST.MF files in the classpath validating licenses. - * + * * Return a list of Cval licensed products in order to have enough info to * generate nag messages in the UI. */ @@ -149,7 +151,7 @@ public final class CvalAddonsChecker { /** * Set the filter regexp of .jar names which we have to consider. - * + * * default is '.*touchkit.*' */ public CvalAddonsChecker setFilter(String regexp) { diff --git a/client-compiler/src/com/vaadin/tools/CvalChecker.java b/client-compiler/src/com/vaadin/tools/CvalChecker.java index 5ad44a70f8..2de7e10faa 100644 --- a/client-compiler/src/com/vaadin/tools/CvalChecker.java +++ b/client-compiler/src/com/vaadin/tools/CvalChecker.java @@ -36,19 +36,21 @@ import org.json.JSONObject; /** * This class is able to validate the vaadin CVAL license. - * + * * It reads the developer license file and asks the server to validate the * licenseKey. If the license is invalid it throws an exception with the * information about the problem and the server response. + * + * @since 7.3 */ public final class CvalChecker { /* * Class used for binding the JSON gotten from server. - * + * * It is not in a separate f le, so as it is easier to copy into any product * which does not depend on vaadin core. - * + * * We are using org.json in order not to use additional dependency like * auto-beans, gson, etc. */ @@ -301,7 +303,7 @@ public final class CvalChecker { /** * Given a product name returns the name of the file with the license key. - * + * * Traditionally we have delivered license keys with a name like * 'vaadin.touchkit.developer.license' but our database product name is * 'vaadin-touchkit' so we have to replace '-' by '.' to maintain @@ -342,7 +344,7 @@ public final class CvalChecker { /** * Validate whether there is a valid license key for a product. - * + * * @param productName * for example vaadin-touchkit * @param productVersion diff --git a/client/src/com/vaadin/client/AnimationUtil.java b/client/src/com/vaadin/client/AnimationUtil.java index 2077cee3c0..063a0a163e 100644 --- a/client/src/com/vaadin/client/AnimationUtil.java +++ b/client/src/com/vaadin/client/AnimationUtil.java @@ -24,6 +24,7 @@ import com.google.gwt.dom.client.Style; * Utility methods for working with CSS transitions and animations. * * @author Vaadin Ltd + * @since 7.3 */ public class AnimationUtil { diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 0d17fbd94f..3ccbeba6f3 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -51,7 +51,6 @@ import com.vaadin.client.metadata.ConnectorBundleLoader; import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.TypeData; import com.vaadin.client.ui.UnknownComponentConnector; -import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; @@ -85,7 +84,7 @@ public class ApplicationConfiguration implements EntryPoint { return null; } else { return value +""; - } + } }-*/; /** @@ -106,7 +105,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Boolean::valueOf(Z)(value); - } + } }-*/; /** @@ -127,7 +126,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Integer::valueOf(I)(value); - } + } }-*/; /** @@ -286,16 +285,14 @@ public class ApplicationConfiguration implements EntryPoint { return serviceUrl; } - /** - * @return the theme name used when initializing the application - * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} to get the - * theme currently in use - */ - @Deprecated public String getThemeName() { return getJsoConfiguration(id).getConfigString("theme"); } + public String getThemeUri() { + return getVaadinDirUrl() + "themes/" + getThemeName(); + } + /** * Gets the URL of the VAADIN directory on the server. * diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index a2c1d11a7d..6bbca98042 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -3108,7 +3108,7 @@ public class ApplicationConnection implements HasHandlers { return null; } if (uidlUri.startsWith("theme://")) { - final String themeUri = getThemeUri(); + final String themeUri = configuration.getThemeUri(); if (themeUri == null) { VConsole.error("Theme not set: ThemeResource will not be found. (" + uidlUri + ")"); @@ -3174,8 +3174,7 @@ public class ApplicationConnection implements HasHandlers { * @return URI to the current theme */ public String getThemeUri() { - return configuration.getVaadinDirUrl() + "themes/" - + getUIConnector().getActiveTheme(); + return configuration.getThemeUri(); } /** diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index 2174e00de1..6c0967099f 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -37,14 +37,14 @@ import com.vaadin.client.debug.internal.ProfilerSection.ProfilerResultConsumer; * zero overhead unless enabled. To enable profiling, add * <code><set-property name="vaadin.profiler" value="true" /></code> to * your .gwt.xml file. - * + * * @author Vaadin Ltd * @since 7.0.0 */ public class Profiler { /** * Class to include using deferred binding to enable the profiling. - * + * * @author Vaadin Ltd * @since 7.0.0 */ @@ -101,7 +101,7 @@ public class Profiler { /** * Checks whether the profiling gathering is enabled. - * + * * @return <code>true</code> if the profiling is enabled, else * <code>false</code> */ @@ -115,7 +115,7 @@ public class Profiler { * Enters a named block. There should always be a matching invocation of * {@link #leave(String)} when leaving the block. Calls to this method will * be removed by the compiler unless profiling is enabled. - * + * * @param name * the name of the entered block */ @@ -129,7 +129,7 @@ public class Profiler { * Leaves a named block. There should always be a matching invocation of * {@link #enter(String)} when entering the block. Calls to this method will * be removed by the compiler unless profiling is enabled. - * + * * @param name * the name of the left block */ @@ -178,7 +178,7 @@ public class Profiler { * enabled because it will then remove a logger function that might have * been included in the HTML page and that would leak memory unless removed. * </p> - * + * * @since 7.0.2 */ public static void initialize() { @@ -281,7 +281,7 @@ public class Profiler { /** * Overridden in {@link EnabledProfiler} to make {@link #isEnabled()} return * true if GWT.create returns that class. - * + * * @return <code>true</code> if the profiling is enabled, else * <code>false</code> */ @@ -352,7 +352,7 @@ public class Profiler { if (typeof $wnd.__gwtStatsEvent != 'function') { if (typeof $wnd.vaadin.gwtStatsEvents != 'object') { $wnd.vaadin.gwtStatsEvents = []; - } + } $wnd.__gwtStatsEvent = function(event) { $wnd.vaadin.gwtStatsEvents.push(event); return true; @@ -369,9 +369,9 @@ public class Profiler { if (typeof $wnd.vaadin.gwtStatsEvents == 'object') { delete $wnd.vaadin.gwtStatsEvents; if (typeof $wnd.__gwtStatsEvent == 'function') { - $wnd.__gwtStatsEvent = function(){}; + $wnd.__gwtStatsEvent = function() { return true; }; } - } + } }-*/; private static native JsArray<GwtStatsEvent> clearEventsList() @@ -385,7 +385,7 @@ public class Profiler { * <p> * <b>Warning!</b> This is internal API and should not be used by * applications or add-ons. - * + * * @since 7.1.4 * @param profilerResultConsumer * the consumer that gets profiler data diff --git a/client/src/com/vaadin/client/ResourceLoader.java b/client/src/com/vaadin/client/ResourceLoader.java index e88def1a72..68a16e8162 100644 --- a/client/src/com/vaadin/client/ResourceLoader.java +++ b/client/src/com/vaadin/client/ResourceLoader.java @@ -221,6 +221,7 @@ public class ResourceLoader { * listener to notify when script is loaded * @param async * What mode the script.async attribute should be set to + * @since 7.2.4 */ public void loadScript(final String scriptUrl, final ResourceLoadListener resourceLoadListener, boolean async) { @@ -279,6 +280,7 @@ public class ResourceLoader { * execution order for dynamically-added scripts. * * @return Browser supports script.async='false' + * @since 7.2.4 */ public static boolean supportsInOrderScriptExecution() { return BrowserInfo.get().isIE() @@ -373,20 +375,7 @@ public class ResourceLoader { } } - /** - * Adds an onload listener to the given element, which should be a link or a - * script tag. The listener is called whenever loading is complete or an - * error occurred. - * - * @since - * @param element - * the element to attach a listener to - * @param listener - * the listener to call - * @param event - * the event passed to the listener - */ - public static native void addOnloadHandler(Element element, + private native void addOnloadHandler(Element element, ResourceLoadListener listener, ResourceLoadEvent event) /*-{ element.onload = $entry(function() { @@ -401,11 +390,11 @@ public class ResourceLoader { element.onreadystatechange = null; listener.@com.vaadin.client.ResourceLoader.ResourceLoadListener::onError(Lcom/vaadin/client/ResourceLoader$ResourceLoadEvent;)(event); }); - element.onreadystatechange = function() { + element.onreadystatechange = function() { if ("loaded" === element.readyState || "complete" === element.readyState ) { element.onload(arguments[0]); } - }; + }; }-*/; /** @@ -531,12 +520,12 @@ public class ResourceLoader { if (rules === undefined) { rules = sheet.rules; } - + if (rules === null) { // Style sheet loaded, but can't access length because of XSS -> assume there's something there return 1; } - + // Return length so we can distinguish 0 (probably 404 error) from normal case. return rules.length; } catch (err) { diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index f12a02c64f..507a5c2c2d 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -73,6 +73,7 @@ public class Util { * * @param event * @return return key code + * @since 7.2.4 */ public static int getKeyCode(KeyEvent<?> event) { int keyCode = event.getNativeEvent().getKeyCode(); diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index b1315a0d8b..d61af537a9 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -38,12 +38,12 @@ import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.ui.VWindowOverlay; +import com.vaadin.client.ui.VOverlay; /** * TODO open for extension */ -public class VTooltip extends VWindowOverlay { +public class VTooltip extends VOverlay { private static final String CLASSNAME = "v-tooltip"; private static final int MARGIN = 4; public static final int TOOLTIP_EVENTS = Event.ONKEYDOWN @@ -113,6 +113,7 @@ public class VTooltip extends VWindowOverlay { * * @param info * with the content of the tooltip + * @since 7.2.4 */ public void initializeAssistiveTooltips() { updatePosition(null, true); diff --git a/client/src/com/vaadin/client/communication/URLReference_Serializer.java b/client/src/com/vaadin/client/communication/URLReference_Serializer.java index 4ecdc606d2..586dd626f0 100644 --- a/client/src/com/vaadin/client/communication/URLReference_Serializer.java +++ b/client/src/com/vaadin/client/communication/URLReference_Serializer.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -30,16 +30,14 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> { @Override public URLReference deserialize(Type type, JSONValue jsonValue, ApplicationConnection connection) { - TranslatedURLReference reference = GWT - .create(TranslatedURLReference.class); - reference.setConnection(connection); + URLReference reference = GWT.create(URLReference.class); JSONObject json = (JSONObject) jsonValue; if (json.containsKey(URL_FIELD)) { JSONValue jsonURL = json.get(URL_FIELD); String URL = (String) JsonDecoder.decodeValue( new Type(String.class.getName(), null), jsonURL, null, connection); - reference.setURL(URL); + reference.setURL(connection.translateVaadinUri(URL)); } return reference; } diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java index a7a84f5f8f..23b77a94db 100644 --- a/client/src/com/vaadin/client/debug/internal/InfoSection.java +++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java @@ -163,7 +163,7 @@ public class InfoSection implements Section { addVersionInfo(configuration); addRow("Widget set", GWT.getModuleName()); - addRow("Theme", connection.getUIConnector().getActiveTheme()); + addRow("Theme", connection.getConfiguration().getThemeName()); String communicationMethodInfo = connection .getCommunicationMethodName(); diff --git a/client/src/com/vaadin/client/ui/AbstractConnector.java b/client/src/com/vaadin/client/ui/AbstractConnector.java index e93ea0f507..a2e0d9cd54 100644 --- a/client/src/com/vaadin/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractConnector.java @@ -28,7 +28,6 @@ import com.google.gwt.event.shared.HandlerManager; import com.google.web.bindery.event.shared.HandlerRegistration; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.FastStringMap; -import com.vaadin.client.FastStringSet; import com.vaadin.client.JsArrayObject; import com.vaadin.client.Profiler; import com.vaadin.client.ServerConnector; @@ -480,27 +479,4 @@ public abstract class AbstractConnector implements ServerConnector, Set<String> reg = getState().registeredEventListeners; return (reg != null && reg.contains(eventIdentifier)); } - - /** - * Force the connector to recheck its state variables as the variables or - * their meaning might have changed. - * - * @since 7.3 - */ - public void forceStateChange() { - StateChangeEvent event = new FullStateChangeEvent(this); - fireEvent(event); - } - - private static class FullStateChangeEvent extends StateChangeEvent { - public FullStateChangeEvent(ServerConnector connector) { - super(connector, FastStringSet.create()); - } - - @Override - public boolean hasPropertyChanged(String property) { - return true; - } - - } } diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index a4f62775e1..f9aa2ef2f8 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -51,7 +51,7 @@ import com.vaadin.client.Util; * temporary float over other components like context menus etc. This is to deal * stacking order correctly with VWindow objects. * </p> - * + * * <h3>Shadow</h3> * <p> * The separate shadow element underneath the main overlay element is <strong> @@ -62,7 +62,7 @@ import com.vaadin.client.Util; * supports, add <code>-webkit-box-shadow</code> and the standard * <code>box-shadow</code> properties. * </p> - * + * * <p> * For IE8, which doesn't support CSS box-shadow, you can use the proprietary * DropShadow filter. It doesn't provide the exact same features as box-shadow, @@ -70,7 +70,7 @@ import com.vaadin.client.Util; * border or a pseudo-element underneath the overlay which mimics a shadow, or * any combination of these. * </p> - * + * * <p> * Read more about the DropShadow filter from <a * href="http://msdn.microsoft.com/en-us/library/ms532985(v=vs.85).aspx" @@ -152,7 +152,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * Shadow element style. If an extending class wishes to use a different * style of shadow, it can use setShadowStyle(String) to give the shadow * element a new style name. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -164,14 +164,20 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { */ public static final String CLASSNAME_CONTAINER = "v-overlay-container"; + /** + * @since 7.3 + */ public static final String ADDITIONAL_CLASSNAME_ANIMATE_IN = "animate-in"; + /** + * @since 7.3 + */ public static final String ADDITIONAL_CLASSNAME_ANIMATE_OUT = "animate-out"; /** * The shadow element for this overlay. - * + * * @deprecated See main JavaDoc for VOverlay - * + * */ @Deprecated private Element shadow; @@ -200,7 +206,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * The HTML snippet that is used to render the actual shadow. In consists of * nine different DIV-elements with the following class names: - * + * * <pre> * .v-shadow[-stylename] * ---------------------------------------------- @@ -213,9 +219,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * | .bottom-left | .bottom | .bottom-right | * ---------------------------------------------- * </pre> - * + * * See default theme 'shadow.css' for implementation example. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -254,18 +260,32 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { @Deprecated public VOverlay(boolean autoHide, boolean modal, boolean showShadow) { super(autoHide, modal); - setShadowEnabled(showShadow); + setShadowEnabled(showShadow && useShadowDiv()); adjustZIndex(); } /** - * Method to controle whether DOM elements for shadow are added. With this + * Return true if a separate shadow div should be used. Since Vaadin 7.3, + * shadows are implemented with CSS box-shadow. Thus, a shadow div is only + * used for IE8 by default. + * + * @deprecated See main JavaDoc for VOverlay + * @since 7.3 + * @return true to use a shadow div + */ + @Deprecated + protected boolean useShadowDiv() { + return BrowserInfo.get().isIE8(); + } + + /** + * Method to control whether DOM elements for shadow are added. With this * method subclasses can control displaying of shadow also after the * constructor. - * + * * @param enabled * true if shadow should be displayed - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -329,7 +349,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Set the z-index (visual stack position) for this overlay. - * + * * @param zIndex * The new z-index */ @@ -424,7 +444,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * A "thread local" of sorts, set temporarily so that VOverlayImpl knows * which VOverlay is using it, so that it can be attached to the correct * overlay container. - * + * * TODO this is a strange pattern that we should get rid of when possible. */ protected static VOverlay current; @@ -542,12 +562,12 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * Sets the shadow style for this overlay. Will override any previous style * for the shadow. The default style name is defined by CLASSNAME_SHADOW. * The given style will be prefixed with CLASSNAME_SHADOW. - * + * * @param style * The new style name for the shadow element. Will be prefixed by * CLASSNAME_SHADOW, e.g. style=='foobar' -> actual style * name=='v-shadow-foobar'. - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -561,7 +581,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * Extending classes should always call this method after they change the * size of overlay without using normal 'setWidth(String)' and * 'setHeight(String)' methods (if not calling super.setWidth/Height). - * + * */ public void positionOrSizeUpdated() { positionOrSizeUpdated(1.0); @@ -580,7 +600,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * elements. Can be used to animate the related elements, using the * 'progress' parameter (used to animate the shadow in sync with GWT * PopupPanel's default animation 'PopupPanel.AnimationType.CENTER'). - * + * * @param progress * A value between 0.0 and 1.0, indicating the progress of the * animation (0=start, 1=end). @@ -683,7 +703,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * 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() { @@ -745,13 +765,13 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Enables or disables sinking the events of the shadow to the same * onBrowserEvent as events to the actual overlay goes. - * + * * Please note, that if you enable this, you can't assume that e.g. * event.getEventTarget returns an element inside the DOM structure of the * overlay - * + * * @param sinkShadowEvents - * + * * @deprecated See main JavaDoc for VOverlay */ @Deprecated @@ -775,7 +795,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Get owner (Widget that made this VOverlay, not the layout parent) of * VOverlay - * + * * @return Owner (creator) or null if not defined */ public Widget getOwner() { @@ -785,7 +805,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Set owner (Widget that made this VOverlay, not the layout parent) of * VOverlay - * + * * @param owner * Owner (creator) of VOverlay */ @@ -796,7 +816,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Get the {@link ApplicationConnection} that this overlay belongs to. If * it's not set, {@link #getOwner()} is used to figure it out. - * + * * @return */ protected ApplicationConnection getApplicationConnection() { @@ -816,7 +836,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Gets the 'overlay container' element. Tries to find the current * {@link ApplicationConnection} using {@link #getApplicationConnection()}. - * + * * @return the overlay container element for the current * {@link ApplicationConnection} or another element if the current * {@link ApplicationConnection} cannot be determined. @@ -840,7 +860,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * {@link ApplicationConnection}. Each overlay should be created in a * overlay container element, so that the correct theme and styles can be * applied. - * + * * @param ac * A reference to {@link ApplicationConnection} * @return The overlay container @@ -865,7 +885,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Set the label of the container element, where tooltip, notification and * dialgs are added to. - * + * * @param applicationConnection * the application connection for which to change the label * @param overlayContainerLabel @@ -898,10 +918,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Gets the visual viewport width, which is useful for e.g iOS where the * view can be zoomed in while keeping the layout viewport intact. - * + * * Falls back to layout viewport; for those browsers/devices the difference * is that the scrollbar with is included (if there is a scrollbar). - * + * * @since 7.0.7 * @return */ @@ -917,10 +937,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /** * Gets the visual viewport height, which is useful for e.g iOS where the * view can be zoomed in while keeping the layout viewport intact. - * + * * Falls back to layout viewport; for those browsers/devices the difference * is that the scrollbar with is included (if there is a scrollbar). - * + * * @since 7.0.7 * @return */ @@ -945,7 +965,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide() */ @Override @@ -955,7 +975,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide(boolean) */ @Override diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java index eae4f6319d..df24c3b1c7 100644 --- a/client/src/com/vaadin/client/ui/VUI.java +++ b/client/src/com/vaadin/client/ui/VUI.java @@ -48,12 +48,11 @@ import com.vaadin.client.Util; import com.vaadin.client.VConsole; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; -import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; /** - * + * */ public class VUI extends SimplePanel implements ResizeHandler, Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable, @@ -63,6 +62,9 @@ public class VUI extends SimplePanel implements ResizeHandler, private static int MONITOR_PARENT_TIMER_INTERVAL = 1000; /** For internal use only. May be removed or replaced in the future. */ + public String theme; + + /** For internal use only. May be removed or replaced in the future. */ public String id; /** For internal use only. May be removed or replaced in the future. */ @@ -317,17 +319,21 @@ public class VUI extends SimplePanel implements ResizeHandler, } } - /** - * @return the name of the theme in use by this UI. - * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} instead. - */ - @Deprecated public String getTheme() { - return ((UIConnector) ConnectorMap.get(connection).getConnector(this)) - .getActiveTheme(); + return theme; } /** + * Used to reload host page on theme changes. + * <p> + * For internal use only. May be removed or replaced in the future. + */ + public static native void reloadHostPage() + /*-{ + $wnd.location.reload(); + }-*/; + + /** * Returns true if the body is NOT generated, i.e if someone else has made * the page that we're running in. Otherwise we're in charge of the whole * page. @@ -524,5 +530,4 @@ public class VUI extends SimplePanel implements ResizeHandler, }); } } - } diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 7c1a21f654..1cee727bc9 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -76,9 +76,9 @@ import com.vaadin.shared.ui.window.WindowRole; * * @author Vaadin Ltd */ -public class VWindow extends VWindowOverlay implements - ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler, - KeyUpHandler, FocusHandler, BlurHandler, Focusable { +public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, + ScrollHandler, KeyDownHandler, KeyUpHandler, FocusHandler, BlurHandler, + Focusable { private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>(); diff --git a/client/src/com/vaadin/client/ui/VWindowOverlay.java b/client/src/com/vaadin/client/ui/VWindowOverlay.java deleted file mode 100644 index 41a8276402..0000000000 --- a/client/src/com/vaadin/client/ui/VWindowOverlay.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.client.ui; - -import com.google.gwt.dom.client.Element; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.ui.RootPanel; -import com.vaadin.client.ApplicationConnection; - -public class VWindowOverlay extends VOverlay { - public VWindowOverlay() { - } - - public VWindowOverlay(boolean autoHide, boolean modal, boolean showShadow) { - super(autoHide, modal, showShadow); - } - - /** - * Gets the 'overlay container' element. Tries to find the current - * {@link ApplicationConnection} using {@link #getApplicationConnection()}. - * - * @return the overlay container element for the current - * {@link ApplicationConnection} or another element if the current - * {@link ApplicationConnection} cannot be determined. - */ - @Override - public com.google.gwt.user.client.Element getOverlayContainer() { - ApplicationConnection ac = getApplicationConnection(); - if (ac == null) { - return super.getOverlayContainer(); - } else { - Element overlayContainer = getOverlayContainer(ac); - return DOM.asOld(overlayContainer); - } - } - - /** - * Gets the 'overlay container' element pertaining to the given - * {@link ApplicationConnection}. Each overlay should be created in a - * overlay container element, so that the correct theme and styles can be - * applied. - * - * @param ac - * A reference to {@link ApplicationConnection} - * @return The overlay container - */ - public static com.google.gwt.user.client.Element getOverlayContainer( - ApplicationConnection ac) { - String id = ac.getConfiguration().getRootPanelId(); - id = id += "-window-overlays"; - Element container = DOM.getElementById(id); - if (container == null) { - container = DOM.createDiv(); - container.setId(id); - String styles = ac.getUIConnector().getWidget().getParent() - .getStyleName(); - container.addClassName(styles); - container.addClassName(CLASSNAME_CONTAINER); - RootPanel.get().getElement().appendChild(container); - } - - return DOM.asOld(container); - } -} diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 8997509da6..1d2a49cbd1 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -18,7 +18,6 @@ package com.vaadin.client.ui.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.logging.Logger; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -27,10 +26,8 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.HeadElement; import com.google.gwt.dom.client.LinkElement; import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; -import com.google.gwt.dom.client.StyleElement; import com.google.gwt.dom.client.StyleInjector; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; @@ -54,17 +51,12 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; import com.vaadin.client.Focusable; import com.vaadin.client.Paintable; -import com.vaadin.client.ResourceLoader; -import com.vaadin.client.ResourceLoader.ResourceLoadEvent; -import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.ServerConnector; import com.vaadin.client.UIDL; import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; -import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; -import com.vaadin.client.ui.AbstractConnector; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; import com.vaadin.client.ui.ShortcutActionHandler; @@ -74,7 +66,6 @@ import com.vaadin.client.ui.VUI; import com.vaadin.client.ui.layout.MayScrollChildren; import com.vaadin.client.ui.window.WindowConnector; import com.vaadin.server.Page.Styles; -import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.communication.MethodInvocation; import com.vaadin.shared.ui.ComponentStateUtil; @@ -89,7 +80,6 @@ import com.vaadin.shared.ui.ui.UIClientRpc; import com.vaadin.shared.ui.ui.UIConstants; import com.vaadin.shared.ui.ui.UIServerRpc; import com.vaadin.shared.ui.ui.UIState; -import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.UI; @Connect(value = UI.class, loadStyle = LoadStyle.EAGER) @@ -98,8 +88,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private HandlerRegistration childStateChangeHandlerRegistration; - private String activeTheme = null; - private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { @@ -209,6 +197,14 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getWidget().immediate = getState().immediate; getWidget().resizeLazy = uidl.hasAttribute(UIConstants.RESIZE_LAZY); + String newTheme = uidl.getStringAttribute("theme"); + if (getWidget().theme != null && !newTheme.equals(getWidget().theme)) { + // Complete page refresh is needed due css can affect layout + // calculations etc + getWidget().reloadHostPage(); + } else { + getWidget().theme = newTheme; + } // this also implicitly removes old styles String styles = ""; styles += getWidget().getStylePrimaryName() + " "; @@ -403,12 +399,15 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Reads CSS strings and resources injected by {@link Styles#inject} from * the UIDL stream. - * + * * @param uidl * The uidl which contains "css-resource" and "css-string" tags */ private void injectCSS(UIDL uidl) { + final HeadElement head = HeadElement.as(Document.get() + .getElementsByTagName(HeadElement.TAG).getItem(0)); + /* * Search the UIDL stream for CSS resources and strings to be injected. */ @@ -425,7 +424,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector link.setRel("stylesheet"); link.setHref(url); link.setType("text/css"); - getHead().appendChild(link); + head.appendChild(link); + // Check if we have CSS string to inject } else if (cssInjectionsUidl.getTag().equals("css-string")) { for (Iterator<?> it2 = cssInjectionsUidl.getChildIterator(); it2 @@ -437,53 +437,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } - /** - * Internal helper to get the <head> tag of the page - * - * @since - * @return the head element - */ - private HeadElement getHead() { - return HeadElement.as(Document.get() - .getElementsByTagName(HeadElement.TAG).getItem(0)); - } - - /** - * Internal helper for removing any stylesheet with the given URL - * - * @since - * @param url - * the url to match with existing stylesheets - */ - private void removeStylesheet(String url) { - NodeList<Element> linkTags = getHead().getElementsByTagName( - LinkElement.TAG); - for (int i = 0; i < linkTags.getLength(); i++) { - LinkElement link = LinkElement.as(linkTags.getItem(i)); - if (!"stylesheet".equals(link.getRel())) { - continue; - } - if (!"text/css".equals(link.getType())) { - continue; - } - if (url.equals(link.getHref())) { - getHead().removeChild(link); - } - } - } - public void init(String rootPanelId, ApplicationConnection applicationConnection) { - // Create a style tag for style injections so they don't end up in - // the theme tag in IE8-IE10 (we don't want to wipe them out if we - // change theme) - if (BrowserInfo.get().isIE() - && BrowserInfo.get().getBrowserMajorVersion() < 11) { - StyleElement style = Document.get().createStyleElement(); - style.setType("text/css"); - getHead().appendChild(style); - } - DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN | Event.ONSCROLL); @@ -493,7 +448,9 @@ public class UIConnector extends AbstractSingleComponentContainerConnector // the user root.getElement().setInnerHTML(""); - activeTheme = applicationConnection.getConfiguration().getThemeName(); + String themeName = applicationConnection.getConfiguration() + .getThemeName(); + root.addStyleName(themeName); root.add(getWidget()); @@ -581,7 +538,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Checks if the given sub window is a child of this UI Connector - * + * * @deprecated Should be replaced by a more generic mechanism for getting * non-ComponentConnector children * @param wc @@ -595,7 +552,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Return an iterator for current subwindows. This method is meant for * testing purposes only. - * + * * @return */ public List<WindowConnector> getSubWindows() { @@ -622,7 +579,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector * public API instead of their state object directly. The page state might * not be an independent state object but can be embedded in UI state. * </p> - * + * * @since 7.1 * @return state object of the page */ @@ -686,10 +643,10 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Tries to scroll the viewport so that the given connector is in view. - * + * * @param componentConnector * The connector which should be visible - * + * */ public void scrollIntoView(final ComponentConnector componentConnector) { if (componentConnector == null) { @@ -783,7 +740,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Invokes the layout analyzer on the server - * + * * @since 7.1 */ public void analyzeLayouts() { @@ -794,7 +751,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector * Sends a request to the server to print details to console that will help * the developer to locate the corresponding server-side connector in the * source code. - * + * * @since 7.1 * @param serverConnector * the connector to locate @@ -803,195 +760,4 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getRpcProxy(DebugWindowServerRpc.class).showServerDebugInfo( serverConnector); } - - @OnStateChange("theme") - void onThemeChange() { - final String oldTheme = activeTheme; - final String newTheme = getState().theme; - if (SharedUtil.equals(oldTheme, newTheme)) { - // This should only happen on the initial load when activeTheme has - // been updated in init - return; - } - - final String oldThemeUrl = getThemeUrl(oldTheme); - final String newThemeUrl = getThemeUrl(newTheme); - getLogger().info("Changing theme from " + oldTheme + " to " + newTheme); - replaceTheme(oldTheme, newTheme, oldThemeUrl, newThemeUrl); - } - - /** - * Loads the new theme and removes references to the old theme - * - * @param oldTheme - * The name of the old theme - * @param newTheme - * The name of the new theme - * @param oldThemeUrl - * The url of the old theme - * @param newThemeUrl - * The url of the new theme - */ - private void replaceTheme(final String oldTheme, final String newTheme, - String oldThemeUrl, final String newThemeUrl) { - - LinkElement tagToReplace = null; - - if (oldTheme != null) { - NodeList<Element> linkTags = getHead().getElementsByTagName( - LinkElement.TAG); - for (int i = 0; i < linkTags.getLength(); i++) { - final LinkElement link = LinkElement.as(linkTags.getItem(i)); - if ("stylesheet".equals(link.getRel()) - && "text/css".equals(link.getType()) - && oldThemeUrl.equals(link.getHref())) { - tagToReplace = link; - break; - } - } - - if (tagToReplace == null) { - getLogger() - .warning( - "Did not find the link tag for the old theme (" - + oldThemeUrl - + "), adding a new stylesheet for the new theme (" - + newThemeUrl + ")"); - } - } - - if (newTheme != null) { - loadTheme(newTheme, newThemeUrl, tagToReplace); - } else { - if (tagToReplace != null) { - tagToReplace.getParentElement().removeChild(tagToReplace); - } - - activateTheme(null); - } - - } - - /** - * Loads the given theme and replaces the given link element with the new - * theme link element. - * - * @param newTheme - * The name of the new theme - * @param newThemeUrl - * The url of the new theme - * @param tagToReplace - * The link element to replace. If null, then the new link - * element is added at the end. - */ - private void loadTheme(final String newTheme, final String newThemeUrl, - final LinkElement tagToReplace) { - LinkElement newThemeLinkElement = Document.get().createLinkElement(); - newThemeLinkElement.setRel("stylesheet"); - newThemeLinkElement.setType("text/css"); - newThemeLinkElement.setHref(newThemeUrl); - ResourceLoader.addOnloadHandler(newThemeLinkElement, - new ResourceLoadListener() { - - @Override - public void onLoad(ResourceLoadEvent event) { - getLogger().info( - "Loading of " + newTheme + " from " - + newThemeUrl + " completed"); - - if (tagToReplace != null) { - tagToReplace.getParentElement().removeChild( - tagToReplace); - } - activateTheme(newTheme); - } - - @Override - public void onError(ResourceLoadEvent event) { - getLogger().warning( - "Could not load theme from " - + getThemeUrl(newTheme)); - } - }, null); - - if (tagToReplace != null) { - getHead().insertBefore(newThemeLinkElement, tagToReplace); - } else { - getHead().appendChild(newThemeLinkElement); - } - } - - /** - * Activates the new theme. Assumes the theme has been loaded and taken into - * use in the browser. - * - * @since 7.3 - * @param newTheme - */ - private void activateTheme(String newTheme) { - if (activeTheme != null) { - getWidget().getParent().removeStyleName(activeTheme); - } - - activeTheme = newTheme; - - if (newTheme != null) { - getWidget().getParent().addStyleName(newTheme); - } - - forceStateChangeRecursively(UIConnector.this); - getLayoutManager().forceLayout(); - } - - /** - * Force a full recursive recheck of every connector's state variables. - * - * @see #forceStateChange() - * - * @since 7.3 - */ - protected static void forceStateChangeRecursively( - AbstractConnector connector) { - connector.forceStateChange(); - - for (ServerConnector child : connector.getChildren()) { - if (child instanceof AbstractConnector) { - forceStateChangeRecursively((AbstractConnector) child); - } else { - getLogger().warning( - "Could not force state change for unknown connector type: " - + child.getClass().getName()); - } - } - - } - - /** - * Internal helper to get the theme URL for a given theme - * - * @since - * @param theme - * the name of the theme - * @return The URL the theme can be loaded from - */ - private String getThemeUrl(String theme) { - return getConnection().translateVaadinUri( - ApplicationConstants.VAADIN_PROTOCOL_PREFIX + "themes/" + theme - + "/styles" + ".css"); - } - - /** - * Returns the name of the theme currently in used by the UI - * - * @since - * @return the theme name used by this UI - */ - public String getActiveTheme() { - return activeTheme; - } - - private static Logger getLogger() { - return Logger.getLogger(UIConnector.class.getName()); - } - } diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java index bafecdabf4..03300b20e2 100644 --- a/server/src/com/vaadin/server/AbstractClientConnector.java +++ b/server/src/com/vaadin/server/AbstractClientConnector.java @@ -41,6 +41,7 @@ import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; import com.vaadin.shared.communication.SharedState; import com.vaadin.shared.ui.ComponentStateUtil; +import com.vaadin.ui.Component; import com.vaadin.ui.Component.Event; import com.vaadin.ui.HasComponents; import com.vaadin.ui.LegacyComponent; @@ -339,31 +340,6 @@ public abstract class AbstractClientConnector implements ClientConnector, } } - private static final class AllChildrenIterable implements - Iterable<ClientConnector>, Serializable { - private final ClientConnector connector; - - private AllChildrenIterable(ClientConnector connector) { - this.connector = connector; - } - - @Override - public Iterator<ClientConnector> iterator() { - CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>(); - - if (connector instanceof HasComponents) { - HasComponents hasComponents = (HasComponents) connector; - iterator.addIterator(hasComponents.iterator()); - } - - Collection<Extension> extensions = connector.getExtensions(); - if (extensions.size() > 0) { - iterator.addIterator(extensions.iterator()); - } - return iterator; - } - } - private class RpcInvocationHandler implements InvocationHandler, Serializable { @@ -493,41 +469,6 @@ public abstract class AbstractClientConnector implements ClientConnector, } } - private static final class CombinedIterator<T> implements Iterator<T>, - Serializable { - - private final Collection<Iterator<? extends T>> iterators = new ArrayList<Iterator<? extends T>>(); - - public void addIterator(Iterator<? extends T> iterator) { - iterators.add(iterator); - } - - @Override - public boolean hasNext() { - for (Iterator<? extends T> i : iterators) { - if (i.hasNext()) { - return true; - } - } - return false; - } - - @Override - public T next() { - for (Iterator<? extends T> i : iterators) { - if (i.hasNext()) { - return i.next(); - } - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - /** * Get an Iterable for iterating over all child connectors, including both * extensions and child components. @@ -536,9 +477,62 @@ public abstract class AbstractClientConnector implements ClientConnector, * the connector to get children for * @return an Iterable giving all child connectors. */ - public static Iterable<ClientConnector> getAllChildrenIterable( + public static Iterable<? extends ClientConnector> getAllChildrenIterable( final ClientConnector connector) { - return new AllChildrenIterable(connector); + + Collection<Extension> extensions = connector.getExtensions(); + boolean hasComponents = connector instanceof HasComponents; + boolean hasExtensions = extensions.size() > 0; + if (!hasComponents && !hasExtensions) { + // If has neither component nor extensions, return immutable empty + // list as iterable. + return Collections.emptyList(); + } + if (hasComponents && !hasExtensions) { + // only components + return (HasComponents) connector; + } + if (!hasComponents && hasExtensions) { + // only extensions + return extensions; + } + + // combine the iterators of extensions and components to a new iterable. + final Iterator<Component> componentsIterator = ((HasComponents) connector) + .iterator(); + final Iterator<Extension> extensionsIterator = extensions.iterator(); + Iterable<? extends ClientConnector> combinedIterable = new Iterable<ClientConnector>() { + + @Override + public Iterator<ClientConnector> iterator() { + return new Iterator<ClientConnector>() { + + @Override + public boolean hasNext() { + return componentsIterator.hasNext() + || extensionsIterator.hasNext(); + } + + @Override + public ClientConnector next() { + if (componentsIterator.hasNext()) { + return componentsIterator.next(); + } + if (extensionsIterator.hasNext()) { + return extensionsIterator.next(); + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + }; + return combinedIterable; } @Override diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java index 97790e7c0c..fd14c3cd3f 100644 --- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java @@ -53,6 +53,8 @@ public class DefaultDeploymentConfiguration implements DeploymentConfiguration { /** * Default value for {@link #isSyncIdCheckEnabled()} = {@value} . + * + * @since 7.3 */ public static final boolean DEFAULT_SYNC_ID_CHECK = true; diff --git a/server/src/com/vaadin/server/DeploymentConfiguration.java b/server/src/com/vaadin/server/DeploymentConfiguration.java index 50d84812ea..fcfeecc31f 100644 --- a/server/src/com/vaadin/server/DeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DeploymentConfiguration.java @@ -89,7 +89,7 @@ public interface DeploymentConfiguration extends Serializable { * gracefully handle situations when the client sends a message to a * connector that has recently been removed on the server. * - * @since + * @since 7.3 * @return <code>true</code> if sync id checking is enabled; * <code>false</code> otherwise */ diff --git a/server/src/com/vaadin/server/VaadinPortletRequest.java b/server/src/com/vaadin/server/VaadinPortletRequest.java index e1b521d57f..93e06d7f45 100644 --- a/server/src/com/vaadin/server/VaadinPortletRequest.java +++ b/server/src/com/vaadin/server/VaadinPortletRequest.java @@ -247,7 +247,7 @@ public class VaadinPortletRequest extends PortletRequestWrapper implements * * @return the current portlet request instance if available, otherwise * <code>null</code> - * + * @since 7.3 */ public static PortletRequest getCurrentPortletRequest() { return VaadinPortletService.getCurrentPortletRequest(); @@ -262,7 +262,7 @@ public class VaadinPortletRequest extends PortletRequestWrapper implements * * @return the current Vaadin portlet request instance if available, * otherwise <code>null</code> - * + * @since 7.3 */ public static VaadinPortletRequest getCurrent() { return VaadinPortletService.getCurrentRequest(); diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java index 1c69ebf87e..09f881cf46 100644 --- a/server/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java @@ -335,7 +335,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return position of the splitter */ public float getSplitPosition() { - return getSplitterState().position; + return getSplitterState(false).position; } /** @@ -358,7 +358,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS */ public void setMinSplitPosition(float pos, Unit unit) { - setSplitPositionLimits(pos, unit, getSplitterState().maxPosition, + setSplitPositionLimits(pos, unit, getSplitterState(false).maxPosition, posMaxUnit); } @@ -369,7 +369,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return the minimum position of the splitter */ public float getMinSplitPosition() { - return getSplitterState().minPosition; + return getSplitterState(false).minPosition; } /** @@ -392,8 +392,8 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS */ public void setMaxSplitPosition(float pos, Unit unit) { - setSplitPositionLimits(getSplitterState().minPosition, posMinUnit, pos, - unit); + setSplitPositionLimits(getSplitterState(false).minPosition, posMinUnit, + pos, unit); } /** @@ -403,7 +403,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return the maximum position of the splitter */ public float getMaxSplitPosition() { - return getSplitterState().maxPosition; + return getSplitterState(false).maxPosition; } /** @@ -467,7 +467,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return <code>true</code> if locked, <code>false</code> otherwise. */ public boolean isLocked() { - return getSplitterState().locked; + return getSplitterState(false).locked; } /** @@ -540,6 +540,10 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } private SplitterState getSplitterState() { - return getState(false).splitterState; + return ((AbstractSplitPanelState) super.getState()).splitterState; + } + + private SplitterState getSplitterState(boolean markAsDirty) { + return ((AbstractSplitPanelState) super.getState(markAsDirty)).splitterState; } } diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index c0f973106b..b5a0227d99 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -366,7 +366,7 @@ public class ConnectorTracker implements Serializable { ClientConnector connector = stack.pop(); danglingConnectors.remove(connector); - Iterable<ClientConnector> children = AbstractClientConnector + Iterable<? extends ClientConnector> children = AbstractClientConnector .getAllChildrenIterable(connector); for (ClientConnector child : children) { stack.add(child); diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 4bde8a95b3..a72cbe5c30 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -549,6 +549,8 @@ public abstract class UI extends AbstractSingleComponentContainer implements private boolean resizeLazy = false; + private String theme; + private Navigator navigator; private PushConnection pushConnection = null; @@ -631,7 +633,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements this.embedId = embedId; // Actual theme - used for finding CustomLayout templates - getState(false).theme = request.getParameter("theme"); + theme = request.getParameter("theme"); getPage().init(request); @@ -1133,31 +1135,12 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Gets the theme currently in use by this UI + * Gets the theme that was used when the UI was initialized. * * @return the theme name */ public String getTheme() { - return getState(false).theme; - } - - /** - * Sets the theme currently in use by this UI - * <p> - * Calling this method will remove the old theme (CSS file) from the - * application and add the new theme. - * <p> - * Note that this method is NOT SAFE to call in a portal environment or - * other environment where there are multiple UIs on the same page. The old - * CSS file will be removed even if there are other UIs on the page which - * are still using it. - * - * @since - * @param theme - * The new theme name - */ - public void setTheme(String theme) { - getState().theme = theme; + return theme; } /** diff --git a/server/src/com/vaadin/ui/themes/ValoTheme.java b/server/src/com/vaadin/ui/themes/ValoTheme.java index 51e2e283f2..63fa13dce4 100644 --- a/server/src/com/vaadin/ui/themes/ValoTheme.java +++ b/server/src/com/vaadin/ui/themes/ValoTheme.java @@ -38,7 +38,7 @@ import com.vaadin.ui.Table.ColumnHeaderMode; * * TODO link to Sass API documentation * - * @since 7.3.0 + * @since 7.3 * @author Vaadin Ltd */ public class ValoTheme { diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java index e938a1cd37..63f79504ff 100644 --- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java +++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java @@ -63,6 +63,8 @@ public class TestClassesSerializable extends TestCase { "com\\.vaadin\\.sass.*", // "com\\.vaadin\\.testbench.*", // "com\\.vaadin\\.util\\.CurrentInstance\\$1", // + "com\\.vaadin\\.server\\.AbstractClientConnector\\$1", // + "com\\.vaadin\\.server\\.AbstractClientConnector\\$1\\$1", // "com\\.vaadin\\.server\\.JsonCodec\\$1", // "com\\.vaadin\\.server\\.communication\\.PushConnection", // "com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection", // diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index abdc105ba7..3c3785b7d5 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -62,7 +62,6 @@ public class UIState extends TabIndexState { * Configuration for the push channel */ public PushConfigurationState pushConfiguration = new PushConfigurationState(); - public String theme; { primaryStyleName = "v-ui"; // Default is 1 for legacy reasons @@ -96,7 +95,7 @@ public class UIState extends TabIndexState { NotificationRole role) { this.prefix = prefix; this.postfix = postfix; - notificationRole = role; + this.notificationRole = role; } } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java index 9d863d2c0c..948acc5fe6 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java @@ -15,12 +15,16 @@ */ package com.vaadin.tests.components.combobox; +import java.util.Collections; +import java.util.List; + import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -60,4 +64,9 @@ public class ComboboxPageLengthZeroScrollTest extends MultiBrowserTest { cssValue); } + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); + } } diff --git a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java index cf756034a1..c80a74599d 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java @@ -34,7 +34,7 @@ public class LocaleChangeTest extends MultiBrowserTest { assertPopupOpen(true); // Close the popup and change the locale. - toggleDatePopup(); + toggleDatePopupWorkaroundClosePopupIE(); assertPopupOpen(false); driver.findElement(By.className("v-button")).click(); // Locale change. @@ -55,6 +55,26 @@ public class LocaleChangeTest extends MultiBrowserTest { driver.findElement(By.className("v-datefield-button")).click(); } + /* + * Work around bug reported in ticket #14086. Delete this method once fixed + * andd use toggleDatePopup() instead. + */ + private void toggleDatePopupWorkaroundClosePopupIE() { + if (!BrowserUtil.isIE(getDesiredCapabilities())) { + driver.findElement(By.className("v-datefield-button")).click(); + } else { + boolean popupOpen = driver.findElements( + By.className("v-datefield-popup")).size() == 1; + if (popupOpen) { + driver.findElement( + By.className("v-datefield-calendarpanel-day-selected")) + .click(); + } else { + driver.findElement(By.className("v-datefield-button")).click(); + } + } + } + private String getDateValue() { return driver.findElement(By.className("v-datefield-textfield")) .getAttribute("value"); diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutBaseTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutBaseTest.java new file mode 100644 index 0000000000..8bbb5cfe1a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutBaseTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.gridlayout; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public abstract class GridLayoutBaseTest extends MultiBrowserTest { + @Test + public void cellSizesAreCorrectlyCalculated() { + openTestURL(); + + hideMiddleRowAndColumn(); + final List<WebElement> slots4x4 = getSlots(1); + + waitUntilColumnAndRowAreHidden(slots4x4); + final List<WebElement> slots5x5 = getSlots(0); + + for (int i = 0; i < slots5x5.size(); i++) { + WebElement compared = slots5x5.get(i); + WebElement actual = slots4x4.get(i); + assertEquals("Different top coordinate for element " + i, + compared.getCssValue("top"), actual.getCssValue("top")); + assertEquals("Different left coordinate for element " + i, + compared.getCssValue("left"), actual.getCssValue("left")); + } + } + + private void waitUntilColumnAndRowAreHidden(final List<WebElement> slots4x4) { + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return getSlots(0).size() == slots4x4.size(); + } + }, 5); + } + + private List<WebElement> getSlots(int index) { + GridLayoutElement layout = $(GridLayoutElement.class).get(index); + + return layout.findElements(By.className("v-gridlayout-slot")); + } + + private void hideMiddleRowAndColumn() { + $(ButtonElement.class).first().click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java index d4d36bd10f..f543068851 100644 --- a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java @@ -15,56 +15,12 @@ */ package com.vaadin.tests.components.gridlayout; -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.testbench.elements.GridLayoutElement; -import com.vaadin.tests.tb3.MultiBrowserTest; -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.ui.ExpectedCondition; - -import java.util.List; - -import static org.junit.Assert.assertEquals; - -public class GridLayoutExpandRatioTest extends MultiBrowserTest { - @Test - public void cellSizesAreCorrectlyCalculated() { - openTestURL(); - - hideMiddleRowAndColumn(); - final List<WebElement> slots4x4 = getSlots(1); - - waitUntilColumnAndRowAreHidden(slots4x4); - final List<WebElement> slots5x5 = getSlots(0); - - for (int i = 0; i < slots5x5.size(); i++) { - WebElement compared = slots5x5.get(i); - WebElement actual = slots4x4.get(i); - assertEquals("Different top coordinate for element " + i, - compared.getCssValue("top"), actual.getCssValue("top")); - assertEquals("Different left coordinate for element " + i, - compared.getCssValue("left"), actual.getCssValue("left")); - } - } - - private void waitUntilColumnAndRowAreHidden(final List<WebElement> slots4x4) { - waitUntil(new ExpectedCondition<Boolean>() { - @Override - public Boolean apply(WebDriver input) { - return getSlots(0).size() == slots4x4.size(); - } - }, 5); - } - - private List<WebElement> getSlots(int index) { - GridLayoutElement layout = $(GridLayoutElement.class).get(index); - - return layout.findElements(By.className("v-gridlayout-slot")); - } +/** + * A test class for testing GridLayoutExpandRatio. The class is empty because + * the name convention is UIClassName+Test. GridLayoutExpandRatioTest and + * GridLayoutHideMiddleCellsTest behave the same way but on different UI + * classes. Thats why they have different names and zero code. + */ +public class GridLayoutExpandRatioTest extends GridLayoutBaseTest { - private void hideMiddleRowAndColumn() { - $(ButtonElement.class).first().click(); - } } diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java index a5eb9b6e04..f62735051b 100644 --- a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java @@ -15,5 +15,12 @@ */ package com.vaadin.tests.components.gridlayout; -public class GridLayoutHideMiddleCellsTest extends GridLayoutExpandRatioTest { +/** + * A test class for testing GridLayoutHideMiddleCellsTest. The class is empty + * because the name convention is UIClassName+Test. GridLayoutExpandRatioTest + * and GridLayoutHideMiddleCellsTest behave the same way but on different UI + * classes. Thats why they have different names and zero code. + */ +public class GridLayoutHideMiddleCellsTest extends GridLayoutBaseTest { + } diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java index 0c6f0abf3c..bca8fd4390 100644 --- a/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java +++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java @@ -20,9 +20,13 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; +import java.util.Collections; +import java.util.List; + import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Dimension; +import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.PopupViewElement; @@ -63,4 +67,8 @@ public class PopupViewResizeWhileOpenTest extends MultiBrowserTest { assertThat(shadowSize.width, is(lessThan(layoutSize.width + 10))); } + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); + } } diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java index 5502bf0495..e067ada818 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java +++ b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java @@ -1,16 +1,16 @@ package com.vaadin.tests.components.window; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - +import com.vaadin.tests.tb3.MultiBrowserTest; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Point; +import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Action; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.ui.ExpectedCondition; -import com.vaadin.tests.tb3.MultiBrowserTest; +import static org.junit.Assert.assertNotEquals; public class WindowMoveListenerTest extends MultiBrowserTest { @@ -18,21 +18,20 @@ public class WindowMoveListenerTest extends MultiBrowserTest { public void testWindowRepositioning() throws Exception { openTestURL(); - WebElement window = getDriver().findElement(By.id("testwindow")); + final WebElement window = getDriver().findElement(By.id("testwindow")); WebElement button = getDriver().findElement(By.id("testbutton")); // I'd loved to use the header, but that doesn't work. Footer works // fine, though :) - WebElement windowHeader = getDriver().findElement( + WebElement windowFooter = getDriver().findElement( By.className("v-window-footer")); - Point winPos = window.getLocation(); + final Point winPos = window.getLocation(); // move window - Action a = new Actions(driver).clickAndHold(windowHeader) + Action a = new Actions(driver).clickAndHold(windowFooter) .moveByOffset(100, 100).release().build(); a.perform(); - assertNotEquals("Window was not dragged correctly.", winPos.x, window.getLocation().x); assertNotEquals("Window was not dragged correctly.", winPos.y, @@ -41,10 +40,16 @@ public class WindowMoveListenerTest extends MultiBrowserTest { // re-set window button.click(); - assertEquals("Window was not re-positioned correctly.", winPos.x, - window.getLocation().x); - assertEquals("Window was not re-positioned correctly.", winPos.y, - window.getLocation().y); + waitUntilWindowHasReseted(window, winPos); + } + private void waitUntilWindowHasReseted(final WebElement window, final Point winPos) { + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return winPos.x == window.getLocation().x && + winPos.y == window.getLocation().y; + } + }, 5); } } diff --git a/uitest/src/com/vaadin/tests/components/window/WindowShadow.java b/uitest/src/com/vaadin/tests/components/window/WindowShadow.java new file mode 100644 index 0000000000..12e7899503 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/WindowShadow.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.window; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.UI; +import com.vaadin.ui.Window; + +//Tests that invisible divs don't overlap windows and don't block mouse events +public class WindowShadow extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Window wnd = createWindow(); + wnd.setId("topwindow"); + Window wnd2 = createWindow(); + wnd2.setId("botwindow"); + wnd.setPositionX(100); + wnd.setPositionY(100); + wnd2.setPositionX(100); + // Pick ycoord, that the top div of the Window overlaps with its footer + int yCoord = (int) (wnd.getPositionX() + wnd.getHeight() - 5); + wnd2.setPositionY(yCoord); + UI.getCurrent().addWindow(wnd); + UI.getCurrent().addWindow(wnd2); + } + + private Window createWindow() { + Window wnd = new Window(); + wnd.setHeight("200"); + wnd.setWidth("200"); + return wnd; + } + + @Override + protected String getTestDescription() { + return "Popup window has shadow div elemetns, which overlaps other elements and blocks mouse events"; + } + + @Override + protected Integer getTicketNumber() { + return 13885; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java b/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java new file mode 100644 index 0000000000..0bd6c9fa44 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.window; + +import java.awt.AWTException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.interactions.internal.Coordinates; +import org.openqa.selenium.internal.Locatable; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class WindowShadowTest extends MultiBrowserTest { + + @Test + public void dragBackgroundWindow() throws AWTException, IOException, + InterruptedException { + openTestURL(); + WebElement wnd = getDriver().findElement(By.id("topwindow")); + // There is some bug in Selenium. Can't move window using header + // need use footer instead. + WebElement wnd1Footer = wnd + .findElement(By.className("v-window-footer")); + Point startLoc = wnd.getLocation(); + Coordinates footerCoordinates = ((Locatable) wnd1Footer) + .getCoordinates(); + Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); + mouse.mouseDown(footerCoordinates); + mouse.mouseMove(footerCoordinates, 200, 200); + mouse.mouseUp(footerCoordinates); + Point endLoc = wnd.getLocation(); + // don't compare to specific coordinate, because in IE9 and IE11 + // the window position is random. + // So, checkt that the window was moved + org.junit.Assert.assertNotEquals(startLoc, endLoc); + } + + // IE8 doesn't support shadow-box css rule + // ignore this browser in testing + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( + getAllBrowsers()); + browsers.remove(Browser.IE8.getDesiredCapabilities()); + return browsers; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java index ac58deea56..f2207ccba7 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java @@ -26,33 +26,19 @@ import org.openqa.selenium.support.ui.Select; public class PushConfigurationLongPollingTest extends PushConfigurationTest { - @Override - public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - - browsers.remove(Browser.IE8.getDesiredCapabilities()); - - return browsers; - } - @Test public void testLongPolling() throws InterruptedException { - new Select(getTransportSelect()).selectByVisibleText("LONG_POLLING"); - new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + openDebugLogTab(); + new Select(getTransportSelect()).selectByVisibleText("LONG_POLLING"); assertThat(getStatusText(), containsString("fallbackTransport: long-polling")); assertThat(getStatusText(), containsString("transport: long-polling")); + clearDebugMessages(); + new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + waitForDebugMessage("Push connection established using long-polling", 10); waitForServerCounterToUpdate(); - - // Use debug console to verify we used the correct transport type - assertThat( - driver.getPageSource(), - containsString("Push connection established using long-polling")); - - new Select(getPushModeSelect()).selectByVisibleText("DISABLED"); - } } diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java index 0861e618a2..f5c015ad12 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java @@ -15,16 +15,12 @@ */ package com.vaadin.tests.push; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.util.List; - import org.junit.Test; -import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.Select; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; + public class PushConfigurationStreamingTest extends PushConfigurationTest { @Test diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index e5cceca6b8..fa704d7b0b 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -16,8 +16,6 @@ package com.vaadin.tests.tb3; -import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -26,14 +24,11 @@ import java.net.URL; import java.util.Collections; import java.util.List; +import com.vaadin.testbench.TestBenchElement; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Platform; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; +import org.openqa.selenium.*; import org.openqa.selenium.interactions.HasInputDevices; import org.openqa.selenium.interactions.Keyboard; import org.openqa.selenium.interactions.Mouse; @@ -50,12 +45,13 @@ import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; import com.vaadin.server.LegacyApplication; import com.vaadin.server.UIProvider; import com.vaadin.testbench.TestBench; -import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.TestBenchTestCase; import com.vaadin.tests.components.AbstractTestUIWithLog; import com.vaadin.tests.tb3.MultiBrowserTest.Browser; import com.vaadin.ui.UI; +import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; + /** * Base class for TestBench 3+ tests. All TB3+ tests in the project should * extend this class. @@ -157,8 +153,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } protected WebElement getTooltipElement() { - return getDriver().findElement( - com.vaadin.testbench.By.className("v-tooltip-text")); + return getDriver().findElement(com.vaadin.testbench.By.className("v-tooltip-text")); } protected Coordinates getCoordinates(TestBenchElement element) { @@ -215,22 +210,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * {@link #isPush()}. */ protected void openTestURL() { - openTestURL(""); - } - - /** - * Opens the given test (defined by {@link #getTestUrl()}, optionally with - * debug window and/or push (depending on {@link #isDebug()} and - * {@link #isPush()}. - */ - protected void openTestURL(String extraParameters) { - String url = getTestUrl(); - if (url.contains("?")) { - url = url + "&" + extraParameters; - } else { - url = url + "?" + extraParameters; - } - driver.get(url); + driver.get(getTestUrl()); } /** @@ -1030,7 +1010,19 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } protected void openDebugLogTab() { - findElement(By.xpath("//button[@title='Debug message log']")).click(); + + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + WebElement element = getDebugLogButton(); + return element != null; + } + }, 15); + getDebugLogButton().click(); + } + + private WebElement getDebugLogButton() { + return findElement(By.xpath("//button[@title='Debug message log']")); } } diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java deleted file mode 100644 index 8989d88164..0000000000 --- a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.themes; - -import com.vaadin.annotations.Theme; -import com.vaadin.server.ThemeResource; -import com.vaadin.server.VaadinRequest; -import com.vaadin.tests.components.AbstractTestUIWithLog; -import com.vaadin.tests.util.PersonContainer; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Image; -import com.vaadin.ui.Label; -import com.vaadin.ui.Table; - -@Theme("reindeer") -public class ThemeChangeOnTheFly extends AbstractTestUIWithLog { - - @Override - protected void setup(VaadinRequest request) { - Button inject = new Button("Inject blue background"); - inject.addClickListener(new ClickListener() { - - @Override - public void buttonClick(ClickEvent event) { - getPage().getStyles().add( - ".v-app { background: blue !important;}"); - - } - }); - addComponent(inject); - - GridLayout gl = new GridLayout(2, 4); - gl.setCaption("Change theme by clicking a button"); - for (final String theme : new String[] { "reindeer", "runo", - "chameleon", "base", null }) { - Button b = new Button(theme); - b.setId(theme + ""); - b.addClickListener(new ClickListener() { - - @Override - public void buttonClick(ClickEvent event) { - getUI().setTheme(theme); - } - }); - gl.addComponent(b); - } - - Table t = new Table(); - PersonContainer pc = PersonContainer.createWithTestData(); - pc.addNestedContainerBean("address"); - t.setContainerDataSource(pc); - gl.addComponent(t, 0, 3, 1, 3); - gl.setRowExpandRatio(3, 1); - - gl.setWidth("500px"); - gl.setHeight("800px"); - - HorizontalLayout images = new HorizontalLayout(); - images.setSpacing(true); - - Label l = new Label("Chameleon theme image in caption"); - l.setIcon(new ThemeResource("img/magnifier.png")); - images.addComponent(l); - Image image = new Image("Runo theme image", new ThemeResource( - "icons/64/ok.png")); - images.addComponent(image); - image = new Image("Reindeer theme image", new ThemeResource( - "button/img/left-focus.png")); - images.addComponent(image); - addComponent(images); - addComponent(gl); - - getLayout().setSpacing(true); - } - - @Override - protected String getTestDescription() { - return "Test that you can change theme on the fly"; - } - - @Override - protected Integer getTicketNumber() { - return 2874; - } - -} diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java deleted file mode 100644 index 681a7d762b..0000000000 --- a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.themes; - -import java.io.IOException; -import java.util.List; - -import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.DesiredCapabilities; -import org.openqa.selenium.support.ui.ExpectedCondition; - -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.tests.tb3.MultiBrowserTest; - -public class ThemeChangeOnTheFlyTest extends MultiBrowserTest { - - /* - * (non-Javadoc) - * - * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() - */ - @Override - public List<DesiredCapabilities> getBrowsersToTest() { - // Seems like stylesheet onload is not fired on PhantomJS - List<DesiredCapabilities> l = super.getBrowsersToTest(); - l.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return l; - } - - @Test - public void injectedStyleAndThemeChange() throws IOException { - openTestURL(); - $(ButtonElement.class).caption("Inject blue background").first() - .click(); - changeTheme("runo"); - compareScreen("runo-blue-background"); - } - - @Test - public void reindeerToOthers() throws IOException { - openTestURL(); - compareScreen("reindeer"); - - changeThemeAndCompare("runo"); - changeThemeAndCompare("chameleon"); - changeThemeAndCompare("base"); - - } - - @Test - public void runoToReindeer() throws IOException { - openTestURL("theme=runo"); - compareScreen("runo"); - changeThemeAndCompare("reindeer"); - } - - @Test - public void reindeerToNullToReindeer() throws IOException { - openTestURL(); - - changeThemeAndCompare("null"); - changeThemeAndCompare("reindeer"); - } - - private void changeThemeAndCompare(String theme) throws IOException { - changeTheme(theme); - compareScreen(theme); - } - - private void changeTheme(String theme) { - $(ButtonElement.class).id(theme).click(); - if (theme.equals("null")) { - waitForThemeToChange(""); - } else { - waitForThemeToChange(theme); - } - } - - private void waitForThemeToChange(final String theme) { - - final WebElement rootDiv = findElement(By - .xpath("//div[contains(@class,'v-app')]")); - waitUntil(new ExpectedCondition<Boolean>() { - - @Override - public Boolean apply(WebDriver input) { - String rootClass = rootDiv.getAttribute("class").trim(); - String expected = "v-app " + theme; - expected = expected.trim(); - return rootClass.equals(expected); - } - }, 30); - } -} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java new file mode 100644 index 0000000000..43d96afd2b --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcButtonConnector.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.gwtrpc; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.Label; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.gwtrpc.GwtRpcButton; + +/** + * Dummy connector to test our Vaadin/GWT RPC bug. In a Vaadin environment with + * DevMode enabled, a pure GWT RPC call would throw an exception. See #11709. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +@Connect(GwtRpcButton.class) +public class GwtRpcButtonConnector extends AbstractComponentConnector { + + static Logger logger = Logger.getLogger(GwtRpcButtonConnector.class + .getName()); + static { + logger.setLevel(Level.ALL); + } + + @Override + public Button getWidget() { + return (Button) super.getWidget(); + } + + @Override + protected Button createWidget() { + return GWT.create(Button.class); + } + + private void log(String message) { + logger.log(Level.INFO, message); + } + + @Override + public void init() { + super.init(); + + log("GwtRpcButtonTestConnector init"); + + getWidget().setText("Click me"); + getWidget().addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + doRPC(); + } + + }); + } + + /** + * The ID of the label in case the test is successful. + */ + public static final String SUCCESS_LABEL_ID = "yes"; + + /** + * The ID of the label in case the test failed. + */ + public static final String FAIL_LABEL_ID = "no"; + + /* + * Make an RPC to test our bug. + */ + private void doRPC() { + log("GwtRpcButtonTestConnector onClick"); + + GwtRpcServiceTestAsync service = GWT.create(GwtRpcServiceTest.class); + + service.giveMeThat("honey", "sugar", new AsyncCallback<String>() { + + @Override + public void onSuccess(String result) { + showResult(result, SUCCESS_LABEL_ID); + } + + @Override + public void onFailure(Throwable caught) { + showResult(caught.getMessage(), FAIL_LABEL_ID); + } + + /* + * Show the result box. + */ + private void showResult(String result, String labelID) { + DialogBox box = new DialogBox(true); + Label label = new Label(result); + label.getElement().setId(labelID); + box.add(label); + box.center(); + box.show(); + } + + }); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java new file mode 100644 index 0000000000..16df928d77 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.gwtrpc; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +/** + * Test GWT RPC in Vaadin DevMode. + * + * @author Vaadin Ltd + */ +@RemoteServiceRelativePath("GwtRpcTest") +public interface GwtRpcServiceTest extends RemoteService { + + /* + * Dummy method to verify if RPC works. + */ + String giveMeThat(String that, String haveThis); + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java new file mode 100644 index 0000000000..93eda8ca34 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/gwtrpc/GwtRpcServiceTestAsync.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.gwtrpc; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +/** + * Test GWT RPC in Vaadin DevMode. + * + * @author Vaadin Ltd + */ +public interface GwtRpcServiceTestAsync { + + /* + * Dummy async method to verify if RPC works. + */ + void giveMeThat(String that, String haveThis, AsyncCallback<String> callback); + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java new file mode 100644 index 0000000000..c9f949c465 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpc.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server.gwtrpc; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; + +/** + * Test the GWT RPC with Vaadin DevMode. See #11709. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +@Widgetset(TestingWidgetSet.NAME) +public class GwtRpc extends AbstractTestUI { + + /** + * Id of the button triggering the test case. + */ + public final static String BUTTON_ID = "gwtRpcButton"; + + @Override + protected void setup(VaadinRequest request) { + GwtRpcButton button = new GwtRpcButton(); + button.setId(BUTTON_ID); + button.setCaption("Press me"); + + addComponent(button); + } + + @Override + protected String getTestDescription() { + return "Cannot call RPC in development mode"; + } + + @Override + protected Integer getTicketNumber() { + return 11709; + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java new file mode 100644 index 0000000000..c04800713d --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcButton.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server.gwtrpc; + +import com.vaadin.ui.AbstractComponent; + +/** + * Dummy client connector to link with the client functionality where the GWT + * RPC is triggered. + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class GwtRpcButton extends AbstractComponent { + +} diff --git a/client/src/com/vaadin/client/communication/TranslatedURLReference.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java index c863b7b796..df01b4dc81 100644 --- a/client/src/com/vaadin/client/communication/TranslatedURLReference.java +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcServletTest.java @@ -13,26 +13,23 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.vaadin.client.communication; +package com.vaadin.tests.widgetset.server.gwtrpc; -import com.vaadin.client.ApplicationConnection; -import com.vaadin.shared.communication.URLReference; +import com.google.gwt.user.server.rpc.RemoteServiceServlet; +import com.vaadin.tests.widgetset.client.gwtrpc.GwtRpcServiceTest; -public class TranslatedURLReference extends URLReference { - - private ApplicationConnection connection; - - /** - * @param connection - * the connection to set - */ - public void setConnection(ApplicationConnection connection) { - this.connection = connection; - } +/** + * Test GWT RPC in Vaadin DevMode. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class GwtRpcServletTest extends RemoteServiceServlet implements + GwtRpcServiceTest { @Override - public String getURL() { - return connection.translateVaadinUri(super.getURL()); + public String giveMeThat(String that, String haveThis) { + return "Take " + that + " for " + haveThis; } } diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java new file mode 100644 index 0000000000..d27884a13a --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server.gwtrpc; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.widgetset.client.gwtrpc.GwtRpcButtonConnector; + +/** + * Test the GWT RPC with Vaadin DevMode. See #11709. + * + * @author Vaadin Ltd + */ +public class GwtRpcTest extends MultiBrowserTest { + + @Test + public void testGwtRpc() { + openTestURL(); + + getDriver().findElement(By.id(GwtRpc.BUTTON_ID)).click(); + + By label = By.id(GwtRpcButtonConnector.SUCCESS_LABEL_ID); + + waitForElementToBePresent(label); + getDriver().findElement(label); + } + +} |