diff options
253 files changed, 8364 insertions, 2727 deletions
diff --git a/WebContent/VAADIN/themes/base/accordion/accordion.css b/WebContent/VAADIN/themes/base/accordion/accordion.css index 10c205ae24..ad762ee0ac 100644 --- a/WebContent/VAADIN/themes/base/accordion/accordion.css +++ b/WebContent/VAADIN/themes/base/accordion/accordion.css @@ -22,6 +22,5 @@ } .v-accordion-item-content { position: absolute; - overflow: auto; width: 100%; }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index 3c08a9d584..d2695a8015 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -29,7 +29,6 @@ div.v-app-loading { .v-view { height: 100%; width: 100%; - overflow: auto; /* avoid scrollbars with margins in root layout */ outline: none; position: relative; @@ -236,12 +235,17 @@ div.v-app-loading { .v-drag-element { z-index: 60000; - position: absolute; - opacity: 0.5; - filter: alpha(opacity=50); - cursor: default; + /* override any other position: properties */ + position: absolute !important; + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default; } .v-clip { overflow: hidden; -}
\ No newline at end of file +} + +.v-scrollable { + overflow: auto; +} diff --git a/WebContent/VAADIN/themes/base/panel/panel.css b/WebContent/VAADIN/themes/base/panel/panel.css index 489d6bc015..d5a9915490 100644 --- a/WebContent/VAADIN/themes/base/panel/panel.css +++ b/WebContent/VAADIN/themes/base/panel/panel.css @@ -29,7 +29,6 @@ overflow: hidden; } .v-panel-content { - overflow: auto; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 1b56b7fb9c..6f2eb8c2cc 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -76,7 +76,7 @@ purpose of receiving feedback about the changes. </p> - <p>The major changes in this second alpha phase are: + <p>The major changes in this second alpha phase are:</p> <ul> <li>Complete overhaul of the client-server communication architecture @@ -354,15 +354,25 @@ </p> <p> - Vaadin supports the following <b>browsers</b>: + Vaadin supports the following <b>desktop browsers</b>: </p> <ul> - <li>Mozilla Firefox 11</li> + <li>Mozilla Firefox 12</li> <li>Internet Explorer 8-9</li> <li>Safari 5</li> <li>Opera 11</li> - <li>Google Chrome 18</li> + <li>Google Chrome 19</li> + </ul> + + <p> + Additionally, Vaadin supports the built-in browsers in the following + <b>mobile operating systems</b>: + </p> + + <ul> + <li>iOS 4-5</li> + <li>Android 2-4</li> </ul> <h2 id="vaadinontheweb">Vaadin on the Web</h2> diff --git a/WebContent/statictestfiles/dummy.zip b/WebContent/statictestfiles/dummy.zip Binary files differnew file mode 100644 index 0000000000..e6e34282fe --- /dev/null +++ b/WebContent/statictestfiles/dummy.zip diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js index db8a065e86..d7f697dbf5 100644 --- a/WebContent/statictestfiles/jsconnector.js +++ b/WebContent/statictestfiles/jsconnector.js @@ -1,10 +1,11 @@ -window.com_vaadin_tests_components_javascriptcomponent_BasicJavascriptComponent_ExampleWidget = function() { +window.com_vaadin_tests_components_javascriptcomponent_BasicJavaScriptComponent_ExampleWidget = function() { var connector = this; var rootElement = connector.getWidgetElement(); rootElement.innerHTML = 'Hello world!'; rootElement.onclick = function() { - connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavascriptComponent$ExampleClickRpc", "onClick")("message"); + connector.getRpcProxy().onClick("message"); + connector.onclick("another message"); } connector.onStateChange = function() { console.log('state change:', this.getState()); diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index df67db8927..1a46300e45 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,13 +1,24 @@ -window.com_vaadin_tests_features_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { +window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascriptExtension = function() { + var self = this; var state = this.getState(); - var greetBack = this.getRpcProxyFunction('com.vaadin.tests.features.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); + + //var rpc = this.getRpcProxy("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionServerRpc"); + var rpc = this.getRpcProxy(); - this.registerRpc("com.vaadin.tests.features.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { +// this.registerRpc("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionClientRpc", { + this.registerRpc({ 'greet': function(greeting) { var response = window.prompt(state.prefix + greeting); if (response !== null) { - greetBack(response); + rpc.greet(response); } } }); + + this.greetToClient = function(greeting) { + var response = window.prompt(state.prefix + greeting); + if (response !== null) { + self.greetToServer(response); + } + } }
\ No newline at end of file diff --git a/build/bin/tagrelease.py b/build/bin/tagrelease.py index 0101ecdbd6..871d34515e 100644 --- a/build/bin/tagrelease.py +++ b/build/bin/tagrelease.py @@ -42,7 +42,7 @@ def readProperties(filename): def helpAndExit(): print "Usage: build/bin/tagrelease <command> [parameters...]" print "Commands:" - print "\ttag <version> <changeset> <manual-repository>" + print "\ttag <version> <changeset>" sys.exit(1) ############################################################################### @@ -77,7 +77,7 @@ def tag(product, srcUrl, trgUrl, version, changeset, dryrun = 1): ############################################################################### # Tag command ############################################################################### -def tagCommand(version, changeset, bookRepo): +def tagCommand(version, changeset): # Check parameters m = re.match(r'^[0-9]+\.[0-9]+\.[0-9]+(\.\w+)?$', version) if not m: @@ -94,19 +94,11 @@ def tagCommand(version, changeset, bookRepo): repoRoot = svnInfo["Repository Root"] tagUrl = repoRoot+"/releases/"+version - # Book tag parameters - if (not re.search(r'branches/[0-9\.]+$', bookRepo)) and (not re.search(r'doc/trunk$', bookRepo)): - print "Bad documentation branch '%s' for release." % (bookRepo) - sys.exit(1) - bookTagUrl = repoRoot+"/doc/tags/"+version - # Check that neither tag exists checkNotTagged(tagUrl) - checkNotTagged(bookTagUrl) # Do the tagging tag("Vaadin", url, tagUrl, version, changeset) - tag("Book of Vaadin", bookRepo, bookTagUrl, version, changeset) ############################################################################### # Verify command @@ -132,8 +124,8 @@ def verifyCommand(version, changeset): if len(sys.argv) < 2: helpAndExit() -if sys.argv[1] == "tag" and len(sys.argv) == 5: - tagCommand(sys.argv[2], sys.argv[3], sys.argv[4]) +if sys.argv[1] == "tag" and len(sys.argv) == 4: + tagCommand(sys.argv[2], sys.argv[3]) elif sys.argv[1] == "verify" and len(sys.argv) == 4: verifyCommand(sys.argv[2], sys.argv[3]) else: diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 4da1d52c00..dbf71408a9 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -194,6 +194,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * @see #getWindow(String) * @see Application#getRoot(WrappedRequest) */ + @Override public Root.LegacyWindow getRoot(WrappedRequest request) { String pathInfo = request.getRequestPathInfo(); @@ -246,6 +247,7 @@ public class Application implements Terminal.ErrorListener, Serializable { * <p> * {@inheritDoc} */ + @Override public String getThemeForRoot(Root root) { return theme; @@ -1066,12 +1068,14 @@ public class Application implements Terminal.ErrorListener, Serializable { * the change event. * @see com.vaadin.terminal.Terminal.ErrorListener#terminalError(com.vaadin.terminal.Terminal.ErrorEvent) */ + public void terminalError(Terminal.ErrorEvent event) { final Throwable t = event.getThrowable(); if (t instanceof SocketException) { // Most likely client browser closed socket - logger.info("SocketException in CommunicationManager." - + " Most likely client (browser) closed socket."); + getLogger().info( + "SocketException in CommunicationManager." + + " Most likely client (browser) closed socket."); return; } @@ -1090,7 +1094,7 @@ public class Application implements Terminal.ErrorListener, Serializable { } // also print the error on console - logger.log(Level.SEVERE, "Terminal error:", t); + getLogger().log(Level.SEVERE, "Terminal error:", t); } /** @@ -2416,4 +2420,8 @@ public class Application implements Terminal.ErrorListener, Serializable { } } + + private static final Logger getLogger() { + return Logger.getLogger(Application.class.getName()); + } } diff --git a/src/com/vaadin/annotations/LoadScripts.java b/src/com/vaadin/annotations/LoadScripts.java index f2b72407f7..84ac2d2fb7 100644 --- a/src/com/vaadin/annotations/LoadScripts.java +++ b/src/com/vaadin/annotations/LoadScripts.java @@ -8,8 +8,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Temporary hack used for ensuring external javascript libraries are included. + * To add a javascript, add this annotation to your Root class. + * + * @deprecated Will be removed in favor of a more robust solution before version + * 7.0.0 + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Deprecated public @interface LoadScripts { public String[] value(); diff --git a/src/com/vaadin/data/util/MethodProperty.java b/src/com/vaadin/data/util/MethodProperty.java index 4fc5531320..7df45e04ab 100644 --- a/src/com/vaadin/data/util/MethodProperty.java +++ b/src/com/vaadin/data/util/MethodProperty.java @@ -48,8 +48,6 @@ import com.vaadin.util.SerializerHelper; @SuppressWarnings("serial") public class MethodProperty<T> extends AbstractProperty<T> { - private static final Logger logger = Logger.getLogger(MethodProperty.class - .getName()); /** * The object that includes the property the MethodProperty is bound to. */ @@ -130,9 +128,9 @@ public class MethodProperty<T> extends AbstractProperty<T> { getMethod = null; } } catch (SecurityException e) { - logger.log(Level.SEVERE, "Internal deserialization error", e); + getLogger().log(Level.SEVERE, "Internal deserialization error", e); } catch (NoSuchMethodException e) { - logger.log(Level.SEVERE, "Internal deserialization error", e); + getLogger().log(Level.SEVERE, "Internal deserialization error", e); } }; @@ -777,4 +775,7 @@ public class MethodProperty<T> extends AbstractProperty<T> { super.fireValueChange(); } + private static final Logger getLogger() { + return Logger.getLogger(MethodProperty.class.getName()); + } } diff --git a/src/com/vaadin/data/util/MethodPropertyDescriptor.java b/src/com/vaadin/data/util/MethodPropertyDescriptor.java index 10faa7a0f3..5fdb982b9e 100644 --- a/src/com/vaadin/data/util/MethodPropertyDescriptor.java +++ b/src/com/vaadin/data/util/MethodPropertyDescriptor.java @@ -23,9 +23,6 @@ import com.vaadin.util.SerializerHelper; public class MethodPropertyDescriptor<BT> implements VaadinPropertyDescriptor<BT> { - private static final Logger logger = Logger - .getLogger(MethodPropertyDescriptor.class.getName()); - private final String name; private Class<?> propertyType; private transient Method readMethod; @@ -109,9 +106,9 @@ public class MethodPropertyDescriptor<BT> implements readMethod = null; } } catch (SecurityException e) { - logger.log(Level.SEVERE, "Internal deserialization error", e); + getLogger().log(Level.SEVERE, "Internal deserialization error", e); } catch (NoSuchMethodException e) { - logger.log(Level.SEVERE, "Internal deserialization error", e); + getLogger().log(Level.SEVERE, "Internal deserialization error", e); } }; @@ -128,4 +125,7 @@ public class MethodPropertyDescriptor<BT> implements writeMethod); } -} + private static final Logger getLogger() { + return Logger.getLogger(MethodPropertyDescriptor.class.getName()); + } +}
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java index 3bf33defd5..e9b5b4fea3 100644 --- a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java +++ b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java @@ -36,9 +36,6 @@ import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator; public class SQLContainer implements Container, Container.Filterable, Container.Indexed, Container.Sortable, Container.ItemSetChangeNotifier { - private static final Logger logger = Logger.getLogger(SQLContainer.class - .getName()); - /** Query delegate */ private QueryDelegate delegate; /** Auto commit mode, default = false */ @@ -132,6 +129,7 @@ public class SQLContainer implements Container, Container.Filterable, * * {@inheritDoc} */ + public Object addItem() throws UnsupportedOperationException { Object emptyKey[] = new Object[delegate.getPrimaryKeyColumns().size()]; RowId itemId = new TemporaryRowId(emptyKey); @@ -162,15 +160,15 @@ public class SQLContainer implements Container, Container.Filterable, if (notificationsEnabled) { CacheFlushNotifier.notifyOfCacheFlush(this); } - logger.log(Level.FINER, "Row added to DB..."); + getLogger().log(Level.FINER, "Row added to DB..."); return itemId; } catch (SQLException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "Failed to add row to DB. Rolling back.", e); try { delegate.rollback(); } catch (SQLException ee) { - logger.log(Level.SEVERE, + getLogger().log(Level.SEVERE, "Failed to roll back row addition", e); } return null; @@ -187,6 +185,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#containsId(java.lang.Object) */ + public boolean containsId(Object itemId) { if (itemId == null) { return false; @@ -215,7 +214,7 @@ public class SQLContainer implements Container, Container.Filterable, return delegate.containsRowWithKey(((RowId) itemId).getId()); } catch (Exception e) { /* Query failed, just return false. */ - logger.log(Level.WARNING, "containsId query failed", e); + getLogger().log(Level.WARNING, "containsId query failed", e); } } return false; @@ -227,6 +226,7 @@ public class SQLContainer implements Container, Container.Filterable, * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object, * java.lang.Object) */ + public Property<?> getContainerProperty(Object itemId, Object propertyId) { Item item = getItem(itemId); if (item == null) { @@ -240,6 +240,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#getContainerPropertyIds() */ + public Collection<?> getContainerPropertyIds() { return Collections.unmodifiableCollection(propertyIds); } @@ -249,6 +250,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#getItem(java.lang.Object) */ + public Item getItem(Object itemId) { if (!cachedItems.containsKey(itemId)) { int index = indexOfId(itemId); @@ -295,6 +297,7 @@ public class SQLContainer implements Container, Container.Filterable, * * {@inheritDoc} */ + public Collection<?> getItemIds() { updateCount(); ArrayList<RowId> ids = new ArrayList<RowId>(); @@ -325,17 +328,18 @@ public class SQLContainer implements Container, Container.Filterable, rs.close(); delegate.commit(); } catch (SQLException e) { - logger.log(Level.WARNING, "getItemIds() failed, rolling back.", e); + getLogger().log(Level.WARNING, + "getItemIds() failed, rolling back.", e); try { delegate.rollback(); } catch (SQLException e1) { - logger.log(Level.SEVERE, "Failed to roll back state", e1); + getLogger().log(Level.SEVERE, "Failed to roll back state", e1); } try { rs.getStatement().close(); rs.close(); } catch (SQLException e1) { - logger.log(Level.WARNING, "Closing session failed", e1); + getLogger().log(Level.WARNING, "Closing session failed", e1); } throw new RuntimeException("Failed to fetch item indexes.", e); } @@ -350,6 +354,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#getType(java.lang.Object) */ + public Class<?> getType(Object propertyId) { if (!propertyIds.contains(propertyId)) { return null; @@ -362,6 +367,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#size() */ + public int size() { updateCount(); return size + sizeOfAddedItems() - removedItems.size(); @@ -372,6 +378,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#removeItem(java.lang.Object) */ + public boolean removeItem(Object itemId) throws UnsupportedOperationException { if (!containsId(itemId)) { @@ -400,29 +407,29 @@ public class SQLContainer implements Container, Container.Filterable, CacheFlushNotifier.notifyOfCacheFlush(this); } if (success) { - logger.log(Level.FINER, "Row removed from DB..."); + getLogger().log(Level.FINER, "Row removed from DB..."); } return success; } catch (SQLException e) { - logger.log(Level.WARNING, "Failed to remove row, rolling back", - e); + getLogger().log(Level.WARNING, + "Failed to remove row, rolling back", e); try { delegate.rollback(); } catch (SQLException ee) { /* Nothing can be done here */ - logger.log(Level.SEVERE, "Failed to rollback row removal", - ee); + getLogger().log(Level.SEVERE, + "Failed to rollback row removal", ee); } return false; } catch (OptimisticLockException e) { - logger.log(Level.WARNING, "Failed to remove row, rolling back", - e); + getLogger().log(Level.WARNING, + "Failed to remove row, rolling back", e); try { delegate.rollback(); } catch (SQLException ee) { /* Nothing can be done here */ - logger.log(Level.SEVERE, "Failed to rollback row removal", - ee); + getLogger().log(Level.SEVERE, + "Failed to rollback row removal", ee); } throw e; } @@ -439,6 +446,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#removeAllItems() */ + public boolean removeAllItems() throws UnsupportedOperationException { if (autoCommit) { /* Remove and commit instantly. */ @@ -452,7 +460,7 @@ public class SQLContainer implements Container, Container.Filterable, } if (success) { delegate.commit(); - logger.log(Level.FINER, "All rows removed from DB..."); + getLogger().log(Level.FINER, "All rows removed from DB..."); refresh(); if (notificationsEnabled) { CacheFlushNotifier.notifyOfCacheFlush(this); @@ -462,23 +470,23 @@ public class SQLContainer implements Container, Container.Filterable, } return success; } catch (SQLException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "removeAllItems() failed, rolling back", e); try { delegate.rollback(); } catch (SQLException ee) { /* Nothing can be done here */ - logger.log(Level.SEVERE, "Failed to roll back", ee); + getLogger().log(Level.SEVERE, "Failed to roll back", ee); } return false; } catch (OptimisticLockException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "removeAllItems() failed, rolling back", e); try { delegate.rollback(); } catch (SQLException ee) { /* Nothing can be done here */ - logger.log(Level.SEVERE, "Failed to roll back", ee); + getLogger().log(Level.SEVERE, "Failed to roll back", ee); } throw e; } @@ -499,6 +507,7 @@ public class SQLContainer implements Container, Container.Filterable, /** * {@inheritDoc} */ + public void addContainerFilter(Filter filter) throws UnsupportedFilterException { // filter.setCaseSensitive(!ignoreCase); @@ -510,6 +519,7 @@ public class SQLContainer implements Container, Container.Filterable, /** * {@inheritDoc} */ + public void removeContainerFilter(Filter filter) { filters.remove(filter); } @@ -549,6 +559,7 @@ public class SQLContainer implements Container, Container.Filterable, /** * {@inheritDoc} */ + public void removeAllContainerFilters() { filters.clear(); refresh(); @@ -563,6 +574,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Indexed#indexOfId(java.lang.Object) */ + public int indexOfId(Object itemId) { // First check if the id is in the added items for (int ix = 0; ix < addedItems.size(); ix++) { @@ -609,6 +621,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Indexed#getIdByIndex(int) */ + public Object getIdByIndex(int index) { if (index < 0 || index > size() - 1) { return null; @@ -635,6 +648,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) */ + public Object nextItemId(Object itemId) { return getIdByIndex(indexOfId(itemId) + 1); } @@ -644,6 +658,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) */ + public Object prevItemId(Object itemId) { return getIdByIndex(indexOfId(itemId) - 1); } @@ -653,6 +668,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#firstItemId() */ + public Object firstItemId() { updateCount(); if (size == 0) { @@ -680,6 +696,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#lastItemId() */ + public Object lastItemId() { if (addedItems.isEmpty()) { int lastIx = size() - 1; @@ -705,6 +722,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) */ + public boolean isFirstId(Object itemId) { return firstItemId().equals(itemId); } @@ -714,6 +732,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) */ + public boolean isLastId(Object itemId) { return lastItemId().equals(itemId); } @@ -728,6 +747,7 @@ public class SQLContainer implements Container, Container.Filterable, * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], * boolean[]) */ + public void sort(Object[] propertyId, boolean[] ascending) { sorters.clear(); if (propertyId == null || propertyId.length == 0) { @@ -743,7 +763,7 @@ public class SQLContainer implements Container, Container.Filterable, try { asc = ascending[i]; } catch (Exception e) { - logger.log(Level.WARNING, "", e); + getLogger().log(Level.WARNING, "", e); } sorters.add(new OrderBy((String) propertyId[i], asc)); } @@ -756,6 +776,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() */ + public Collection<?> getSortableContainerPropertyIds() { return getContainerPropertyIds(); } @@ -872,7 +893,8 @@ public class SQLContainer implements Container, Container.Filterable, */ public void commit() throws UnsupportedOperationException, SQLException { try { - logger.log(Level.FINER, "Commiting changes through delegate..."); + getLogger().log(Level.FINER, + "Commiting changes through delegate..."); delegate.beginTransaction(); /* Perform buffered deletions */ for (RowItem item : removedItems.values()) { @@ -926,7 +948,7 @@ public class SQLContainer implements Container, Container.Filterable, * @throws SQLException */ public void rollback() throws UnsupportedOperationException, SQLException { - logger.log(Level.FINE, "Rolling back changes..."); + getLogger().log(Level.FINE, "Rolling back changes..."); removedItems.clear(); addedItems.clear(); modifiedItems.clear(); @@ -956,15 +978,15 @@ public class SQLContainer implements Container, Container.Filterable, if (notificationsEnabled) { CacheFlushNotifier.notifyOfCacheFlush(this); } - logger.log(Level.FINER, "Row updated to DB..."); + getLogger().log(Level.FINER, "Row updated to DB..."); } catch (SQLException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "itemChangeNotification failed, rolling back...", e); try { delegate.rollback(); } catch (SQLException ee) { /* Nothing can be done here */ - logger.log(Level.SEVERE, "Rollback failed", e); + getLogger().log(Level.SEVERE, "Rollback failed", e); } throw new RuntimeException(e); } @@ -1009,13 +1031,13 @@ public class SQLContainer implements Container, Container.Filterable, try { delegate.setFilters(filters); } catch (UnsupportedOperationException e) { - logger.log(Level.FINE, + getLogger().log(Level.FINE, "The query delegate doesn't support filtering", e); } try { delegate.setOrderBy(sorters); } catch (UnsupportedOperationException e) { - logger.log(Level.FINE, + getLogger().log(Level.FINE, "The query delegate doesn't support filtering", e); } int newSize = delegate.getCount(); @@ -1025,7 +1047,8 @@ public class SQLContainer implements Container, Container.Filterable, } sizeUpdated = new Date(); sizeDirty = false; - logger.log(Level.FINER, "Updated row count. New count is: " + size); + getLogger().log(Level.FINER, + "Updated row count. New count is: " + size); } catch (SQLException e) { throw new RuntimeException("Failed to update item set size.", e); } @@ -1069,7 +1092,7 @@ public class SQLContainer implements Container, Container.Filterable, try { type = Class.forName(rsmd.getColumnClassName(i)); } catch (Exception e) { - logger.log(Level.WARNING, "Class not found", e); + getLogger().log(Level.WARNING, "Class not found", e); /* On failure revert to Object and hope for the best. */ type = Object.class; } @@ -1095,14 +1118,14 @@ public class SQLContainer implements Container, Container.Filterable, rs.getStatement().close(); rs.close(); delegate.commit(); - logger.log(Level.FINER, "Property IDs fetched."); + getLogger().log(Level.FINER, "Property IDs fetched."); } catch (SQLException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "Failed to fetch property ids, rolling back", e); try { delegate.rollback(); } catch (SQLException e1) { - logger.log(Level.SEVERE, "Failed to roll back", e1); + getLogger().log(Level.SEVERE, "Failed to roll back", e1); } try { if (rs != null) { @@ -1112,7 +1135,7 @@ public class SQLContainer implements Container, Container.Filterable, rs.close(); } } catch (SQLException e1) { - logger.log(Level.WARNING, "Failed to close session", e1); + getLogger().log(Level.WARNING, "Failed to close session", e1); } throw e; } @@ -1135,7 +1158,7 @@ public class SQLContainer implements Container, Container.Filterable, } catch (UnsupportedOperationException e) { /* The query delegate doesn't support sorting. */ /* No need to do anything. */ - logger.log(Level.FINE, + getLogger().log(Level.FINE, "The query delegate doesn't support sorting", e); } delegate.beginTransaction(); @@ -1217,14 +1240,17 @@ public class SQLContainer implements Container, Container.Filterable, rs.getStatement().close(); rs.close(); delegate.commit(); - logger.log(Level.FINER, "Fetched " + pageLength * CACHE_RATIO - + " rows starting from " + currentOffset); + getLogger().log( + Level.FINER, + "Fetched " + pageLength * CACHE_RATIO + + " rows starting from " + currentOffset); } catch (SQLException e) { - logger.log(Level.WARNING, "Failed to fetch rows, rolling back", e); + getLogger().log(Level.WARNING, + "Failed to fetch rows, rolling back", e); try { delegate.rollback(); } catch (SQLException e1) { - logger.log(Level.SEVERE, "Failed to roll back", e1); + getLogger().log(Level.SEVERE, "Failed to roll back", e1); } try { if (rs != null) { @@ -1234,7 +1260,7 @@ public class SQLContainer implements Container, Container.Filterable, } } } catch (SQLException e1) { - logger.log(Level.WARNING, "Failed to close session", e1); + getLogger().log(Level.WARNING, "Failed to close session", e1); } throw new RuntimeException("Failed to fetch page.", e); } @@ -1324,6 +1350,7 @@ public class SQLContainer implements Container, Container.Filterable, * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, * java.lang.Class, java.lang.Object) */ + public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException { throw new UnsupportedOperationException(); @@ -1334,6 +1361,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object) */ + public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException { throw new UnsupportedOperationException(); @@ -1344,6 +1372,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container#addItem(java.lang.Object) */ + public Item addItem(Object itemId) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } @@ -1354,6 +1383,7 @@ public class SQLContainer implements Container, Container.Filterable, * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, * java.lang.Object) */ + public Item addItemAfter(Object previousItemId, Object newItemId) throws UnsupportedOperationException { throw new UnsupportedOperationException(); @@ -1364,6 +1394,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object) */ + public Item addItemAt(int index, Object newItemId) throws UnsupportedOperationException { throw new UnsupportedOperationException(); @@ -1374,6 +1405,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Indexed#addItemAt(int) */ + public Object addItemAt(int index) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } @@ -1383,6 +1415,7 @@ public class SQLContainer implements Container, Container.Filterable, * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) */ + public Object addItemAfter(Object previousItemId) throws UnsupportedOperationException { throw new UnsupportedOperationException(); @@ -1399,6 +1432,7 @@ public class SQLContainer implements Container, Container.Filterable, * com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin * .data.Container.ItemSetChangeListener) */ + public void addListener(Container.ItemSetChangeListener listener) { if (itemSetChangeListeners == null) { itemSetChangeListeners = new LinkedList<Container.ItemSetChangeListener>(); @@ -1413,6 +1447,7 @@ public class SQLContainer implements Container, Container.Filterable, * com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin * .data.Container.ItemSetChangeListener) */ + public void removeListener(Container.ItemSetChangeListener listener) { if (itemSetChangeListeners != null) { itemSetChangeListeners.remove(listener); @@ -1577,7 +1612,8 @@ public class SQLContainer implements Container, Container.Filterable, r.getReferencedColumn())); return true; } catch (Exception e) { - logger.log(Level.WARNING, "Setting referenced item failed.", e); + getLogger() + .log(Level.WARNING, "Setting referenced item failed.", e); return false; } } @@ -1640,4 +1676,7 @@ public class SQLContainer implements Container, Container.Filterable, } } + private static final Logger getLogger() { + return Logger.getLogger(SQLContainer.class.getName()); + } } diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java index 9e4bb772f5..40d0d0426f 100644 --- a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java +++ b/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java @@ -13,8 +13,6 @@ import javax.naming.NamingException; import javax.sql.DataSource; public class J2EEConnectionPool implements JDBCConnectionPool { - private static final Logger logger = Logger - .getLogger(J2EEConnectionPool.class.getName()); private String dataSourceJndiName; @@ -58,7 +56,8 @@ public class J2EEConnectionPool implements JDBCConnectionPool { try { conn.close(); } catch (SQLException e) { - logger.log(Level.FINE, "Could not release SQL connection", e); + Logger.getLogger(J2EEConnectionPool.class.getName()).log( + Level.FINE, "Could not release SQL connection", e); } } } diff --git a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java index 7e546309f6..22ca30cc32 100644 --- a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java +++ b/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java @@ -38,9 +38,6 @@ import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; public class TableQuery implements QueryDelegate, QueryDelegate.RowIdChangeNotifier { - private static final Logger logger = Logger.getLogger(TableQuery.class - .getName()); - /** Table name, primary key column name(s) and version column name */ private String tableName; private List<String> primaryKeyColumns; @@ -115,7 +112,7 @@ public class TableQuery implements QueryDelegate, * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getCount() */ public int getCount() throws SQLException { - logger.log(Level.FINE, "Fetching count..."); + getLogger().log(Level.FINE, "Fetching count..."); StatementHelper sh = sqlGenerator.generateSelectQuery(tableName, filters, null, 0, 0, "COUNT(*)"); boolean shouldCloseTransaction = false; @@ -228,7 +225,7 @@ public class TableQuery implements QueryDelegate, PreparedStatement pstmt = activeConnection.prepareStatement( sh.getQueryString(), primaryKeyColumns.toArray(new String[0])); sh.setParameterValuesToStatement(pstmt); - logger.log(Level.FINE, "DB -> " + sh.getQueryString()); + getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); int result = pstmt.executeUpdate(); if (result > 0) { /* @@ -293,7 +290,7 @@ public class TableQuery implements QueryDelegate, throw new IllegalStateException(); } - logger.log(Level.FINE, "DB -> begin transaction"); + getLogger().log(Level.FINE, "DB -> begin transaction"); activeConnection = connectionPool.reserveConnection(); activeConnection.setAutoCommit(false); transactionOpen = true; @@ -306,7 +303,7 @@ public class TableQuery implements QueryDelegate, */ public void commit() throws UnsupportedOperationException, SQLException { if (transactionOpen && activeConnection != null) { - logger.log(Level.FINE, "DB -> commit"); + getLogger().log(Level.FINE, "DB -> commit"); activeConnection.commit(); connectionPool.releaseConnection(activeConnection); } else { @@ -334,7 +331,7 @@ public class TableQuery implements QueryDelegate, */ public void rollback() throws UnsupportedOperationException, SQLException { if (transactionOpen && activeConnection != null) { - logger.log(Level.FINE, "DB -> rollback"); + getLogger().log(Level.FINE, "DB -> rollback"); activeConnection.rollback(); connectionPool.releaseConnection(activeConnection); } else { @@ -389,7 +386,7 @@ public class TableQuery implements QueryDelegate, } PreparedStatement pstmt = c.prepareStatement(sh.getQueryString()); sh.setParameterValuesToStatement(pstmt); - logger.log(Level.FINE, "DB -> " + sh.getQueryString()); + getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); return pstmt.executeQuery(); } @@ -415,7 +412,7 @@ public class TableQuery implements QueryDelegate, } pstmt = c.prepareStatement(sh.getQueryString()); sh.setParameterValuesToStatement(pstmt); - logger.log(Level.FINE, "DB -> " + sh.getQueryString()); + getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); int retval = pstmt.executeUpdate(); return retval; } finally { @@ -458,7 +455,7 @@ public class TableQuery implements QueryDelegate, pstmt = c.prepareStatement(sh.getQueryString(), primaryKeyColumns.toArray(new String[0])); sh.setParameterValuesToStatement(pstmt); - logger.log(Level.FINE, "DB -> " + sh.getQueryString()); + getLogger().log(Level.FINE, "DB -> " + sh.getQueryString()); int result = pstmt.executeUpdate(); genKeys = pstmt.getGeneratedKeys(); RowId newId = getNewRowId(row, genKeys); @@ -571,7 +568,7 @@ public class TableQuery implements QueryDelegate, } return new RowId(newRowId.toArray()); } catch (Exception e) { - logger.log(Level.FINE, + getLogger().log(Level.FINE, "Failed to fetch key values on insert: " + e.getMessage()); return null; } @@ -586,8 +583,8 @@ public class TableQuery implements QueryDelegate, */ public boolean removeRow(RowItem row) throws UnsupportedOperationException, SQLException { - logger.log(Level.FINE, "Removing row with id: " - + row.getId().getId()[0].toString()); + getLogger().log(Level.FINE, + "Removing row with id: " + row.getId().getId()[0].toString()); if (executeUpdate(sqlGenerator.generateDeleteQuery(getTableName(), primaryKeyColumns, versionColumn, row)) == 1) { return true; @@ -695,4 +692,8 @@ public class TableQuery implements QueryDelegate, rowIdChangeListeners.remove(listener); } } + + private static final Logger getLogger() { + return Logger.getLogger(TableQuery.class.getName()); + } } diff --git a/src/com/vaadin/event/ListenerMethod.java b/src/com/vaadin/event/ListenerMethod.java index 1f1305fa69..f7dc8a7f13 100644 --- a/src/com/vaadin/event/ListenerMethod.java +++ b/src/com/vaadin/event/ListenerMethod.java @@ -43,9 +43,6 @@ import java.util.logging.Logger; @SuppressWarnings("serial") public class ListenerMethod implements EventListener, Serializable { - private static final Logger logger = Logger.getLogger(ListenerMethod.class - .getName()); - /** * Type of the event that should trigger this listener. Also the subclasses * of this class are accepted to trigger the listener. @@ -84,9 +81,10 @@ public class ListenerMethod implements EventListener, Serializable { out.writeObject(name); out.writeObject(paramTypes); } catch (NotSerializableException e) { - logger.warning("Error in serialization of the application: Class " - + target.getClass().getName() - + " must implement serialization."); + getLogger().warning( + "Error in serialization of the application: Class " + + target.getClass().getName() + + " must implement serialization."); throw e; } @@ -103,7 +101,7 @@ public class ListenerMethod implements EventListener, Serializable { // inner classes method = findHighestMethod(target.getClass(), name, paramTypes); } catch (SecurityException e) { - logger.log(Level.SEVERE, "Internal deserialization error", e); + getLogger().log(Level.SEVERE, "Internal deserialization error", e); } }; @@ -658,4 +656,8 @@ public class ListenerMethod implements EventListener, Serializable { return target; } + private static final Logger getLogger() { + return Logger.getLogger(ListenerMethod.class.getName()); + } + } diff --git a/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java b/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java index 87193e8b3e..52ffab9263 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java +++ b/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java @@ -7,7 +7,6 @@ package com.vaadin.event.dd.acceptcriteria; import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.terminal.gwt.client.ui.dd.VAcceptAll; /** * Criterion that accepts all drops anywhere on the component. @@ -18,7 +17,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VAcceptAll; * @since 6.3 * */ -@ClientCriterion(VAcceptAll.class) public final class AcceptAll extends ClientSideCriterion { private static final long serialVersionUID = 7406683402153141461L; diff --git a/src/com/vaadin/event/dd/acceptcriteria/And.java b/src/com/vaadin/event/dd/acceptcriteria/And.java index 89c8cb377b..a0340a9cdb 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/And.java +++ b/src/com/vaadin/event/dd/acceptcriteria/And.java @@ -19,7 +19,6 @@ import com.vaadin.terminal.PaintTarget; * @since 6.3 * */ -@ClientCriterion(com.vaadin.terminal.gwt.client.ui.dd.VAnd.class) public class And extends ClientSideCriterion { private static final long serialVersionUID = -5242574480825471748L; diff --git a/src/com/vaadin/event/dd/acceptcriteria/ClientCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/ClientCriterion.java deleted file mode 100644 index 8b64106be7..0000000000 --- a/src/com/vaadin/event/dd/acceptcriteria/ClientCriterion.java +++ /dev/null @@ -1,29 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.event.dd.acceptcriteria; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterion; - -/** - * An annotation type used to point the client side counterpart for server side - * a {@link AcceptCriterion} class. - * <p> - * Annotations are used at GWT compilation phase, so remember to rebuild your - * widgetset if you do changes for {@link ClientCriterion} mappings. - * - * @since 6.3 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface ClientCriterion { - /** - * @return the client side counterpart for the annotated criterion - */ - Class<? extends VAcceptCriterion> value(); -} diff --git a/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java b/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java index 298a50a1d5..7eb04d9647 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java +++ b/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java @@ -10,7 +10,6 @@ import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VContainsDataFlavor; /** * A Criterion that checks whether {@link Transferable} contains given data @@ -19,7 +18,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VContainsDataFlavor; * * @since 6.3 */ -@ClientCriterion(VContainsDataFlavor.class) public class ContainsDataFlavor extends ClientSideCriterion { private String dataFlavorId; diff --git a/src/com/vaadin/event/dd/acceptcriteria/Not.java b/src/com/vaadin/event/dd/acceptcriteria/Not.java index 774dcc642e..85ff7e9bc9 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/Not.java +++ b/src/com/vaadin/event/dd/acceptcriteria/Not.java @@ -9,7 +9,6 @@ package com.vaadin.event.dd.acceptcriteria; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VNot; /** * Criterion that wraps another criterion and inverts its return value. @@ -17,7 +16,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VNot; * @since 6.3 * */ -@ClientCriterion(VNot.class) public class Not extends ClientSideCriterion { private static final long serialVersionUID = 1131422338558613244L; diff --git a/src/com/vaadin/event/dd/acceptcriteria/Or.java b/src/com/vaadin/event/dd/acceptcriteria/Or.java index 2e7cdf45a3..077e9114d8 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/Or.java +++ b/src/com/vaadin/event/dd/acceptcriteria/Or.java @@ -9,7 +9,6 @@ package com.vaadin.event.dd.acceptcriteria; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VOr; /** * A compound criterion that accepts the drag if any of its criterion accepts @@ -20,7 +19,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VOr; * @since 6.3 * */ -@ClientCriterion(VOr.class) public class Or extends ClientSideCriterion { private static final long serialVersionUID = 1L; private AcceptCriterion criteria[]; diff --git a/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java index b3f4702c51..77840bc94f 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java +++ b/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java @@ -8,7 +8,6 @@ import java.io.Serializable; import com.vaadin.event.Transferable; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VServerAccept; /** * Parent class for criteria which are verified on the server side during a drag @@ -27,7 +26,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VServerAccept; * * @since 6.3 */ -@ClientCriterion(VServerAccept.class) public abstract class ServerSideCriterion implements Serializable, AcceptCriterion { diff --git a/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java b/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java index 0d29e9a327..d7c47dc915 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java +++ b/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java @@ -13,7 +13,6 @@ import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VDragSourceIs; import com.vaadin.ui.Component; /** @@ -23,10 +22,7 @@ import com.vaadin.ui.Component; * @since 6.3 */ @SuppressWarnings("serial") -@ClientCriterion(VDragSourceIs.class) public class SourceIs extends ClientSideCriterion { - private static final Logger logger = Logger.getLogger(SourceIs.class - .getName()); private Component[] components; @@ -43,11 +39,11 @@ public class SourceIs extends ClientSideCriterion { if (c.getApplication() != null) { target.addAttribute("component" + paintedComponents++, c); } else { - logger.log( - Level.WARNING, - "SourceIs component {0} at index {1} is not attached to the component hierachy and will thus be ignored", - new Object[] { c.getClass().getName(), - Integer.valueOf(i) }); + Logger.getLogger(SourceIs.class.getName()) + .log(Level.WARNING, + "SourceIs component {0} at index {1} is not attached to the component hierachy and will thus be ignored", + new Object[] { c.getClass().getName(), + Integer.valueOf(i) }); } } target.addAttribute("c", paintedComponents); diff --git a/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java b/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java index 8303809140..454159b3da 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java +++ b/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java @@ -10,7 +10,6 @@ import com.vaadin.event.Transferable; import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VSourceIsTarget; import com.vaadin.ui.Component; import com.vaadin.ui.Table; import com.vaadin.ui.Tree; @@ -26,7 +25,6 @@ import com.vaadin.ui.Tree; * @since 6.3 * */ -@ClientCriterion(VSourceIsTarget.class) public class SourceIsTarget extends ClientSideCriterion { private static final long serialVersionUID = -451399314705532584L; diff --git a/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java b/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java index 25371938d2..641fddc3ea 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java +++ b/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java @@ -10,7 +10,6 @@ import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.TargetDetails; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.dd.VTargetDetailIs; /** * Criterion for checking if drop target details contains the specific property @@ -21,7 +20,6 @@ import com.vaadin.terminal.gwt.client.ui.dd.VTargetDetailIs; * TODO add support for other basic data types that we support in UIDL. * */ -@ClientCriterion(VTargetDetailIs.class) public class TargetDetailIs extends ClientSideCriterion { private static final long serialVersionUID = 763165450054331246L; diff --git a/src/com/vaadin/navigator/Navigator.java b/src/com/vaadin/navigator/Navigator.java index 9d9acf9ed3..387f1d4eae 100644 --- a/src/com/vaadin/navigator/Navigator.java +++ b/src/com/vaadin/navigator/Navigator.java @@ -10,12 +10,13 @@ import java.util.LinkedList; import java.util.List; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; +import com.vaadin.terminal.Page.FragmentChangedListener; import com.vaadin.ui.Component; import com.vaadin.ui.CssLayout; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; -import com.vaadin.ui.Root.FragmentChangedListener; /** * Navigator utility that allows switching of views in a part of an application. @@ -67,7 +68,7 @@ public class Navigator implements Serializable { */ public static class UriFragmentManager implements FragmentManager, FragmentChangedListener { - private final Root root; + private final Page page; private final Navigator navigator; /** @@ -80,20 +81,20 @@ public class Navigator implements Serializable { * {@link Navigator} to notify of fragment changes (using * {@link Navigator#navigateTo(String)} */ - public UriFragmentManager(Root root, Navigator navigator) { - this.root = root; + public UriFragmentManager(Page page, Navigator navigator) { + this.page = page; this.navigator = navigator; - root.addListener(this); + page.addListener(this); } public String getFragment() { - return root.getFragment(); + return page.getFragment(); } public void setFragment(String fragment) { // TODO ", false" ??? - root.setFragment(fragment); + page.setFragment(fragment); } public void fragmentChanged(FragmentChangedEvent event) { @@ -276,9 +277,9 @@ public class Navigator implements Serializable { * @param display * where to display the views */ - public Navigator(Root root, ViewDisplay display) { + public Navigator(Page page, ViewDisplay display) { this.display = display; - fragmentManager = new UriFragmentManager(root, this); + fragmentManager = new UriFragmentManager(page, this); } /** @@ -289,9 +290,9 @@ public class Navigator implements Serializable { * @param root * whose URI fragments are used */ - public Navigator(Root root) { + public Navigator(Page page) { display = new SimpleViewDisplay(); - fragmentManager = new UriFragmentManager(root, this); + fragmentManager = new UriFragmentManager(page, this); } /** diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java index a2bf4a0be8..6a87f58c71 100644 --- a/src/com/vaadin/terminal/AbstractClientConnector.java +++ b/src/com/vaadin/terminal/AbstractClientConnector.java @@ -31,7 +31,12 @@ import com.vaadin.ui.HasComponents; import com.vaadin.ui.Root; /** - * + * An abstract base class for ClientConnector implementations. This class + * provides all the basic functionality required for connectors. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 */ public abstract class AbstractClientConnector implements ClientConnector { /** @@ -115,6 +120,7 @@ public abstract class AbstractClientConnector implements ClientConnector { throw new RuntimeException( "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface"); } + @SuppressWarnings("unchecked") Class<T> type = (Class<T>) interfaces[0]; registerRpc(implementation, type); } @@ -210,7 +216,7 @@ public abstract class AbstractClientConnector implements ClientConnector { public Iterator<ClientConnector> iterator() { CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>(); - iterator.addIterator(connector.getExtensionIterator()); + iterator.addIterator(connector.getExtensions().iterator()); if (connector instanceof HasComponents) { HasComponents hasComponents = (HasComponents) connector; @@ -371,35 +377,42 @@ public abstract class AbstractClientConnector implements ClientConnector { } } + /** + * Get an Iterable for iterating over all child connectors, including both + * extensions and child components. + * + * @param connector + * the connector to get children for + * @return an Iterable giving all child connectors. + */ public static Iterable<ClientConnector> getAllChildrenIterable( final ClientConnector connector) { return new AllChildrenIterable(connector); } - public Iterator<Extension> getExtensionIterator() { - return Collections.unmodifiableList(extensions).iterator(); + public Collection<Extension> getExtensions() { + return Collections.unmodifiableCollection(extensions); } + /** + * Add an extension to this connector. This method is protected to allow + * extensions to select which targets they can extend. + * + * @param extension + * the extension to add + */ protected void addExtension(Extension extension) { - addExtensionAtIndex(extension, extensions.size()); - } - - protected void addExtensionAtIndex(Extension extension, int index) { ClientConnector previousParent = extension.getParent(); if (previousParent == this) { - int oldIndex = extensions.indexOf(extension); - if (oldIndex < index) { - index--; - } - extensions.remove(oldIndex); - extensions.add(index, extension); - } else { - if (previousParent != null) { - previousParent.removeExtension(extension); - } - extensions.add(index, extension); - extension.setParent(this); + // Nothing to do, already attached + return; + } else if (previousParent != null) { + throw new IllegalStateException( + "Moving an extension from one parent to another is not supported"); } + + extensions.add(extension); + extension.setParent(this); requestRepaint(); } @@ -447,6 +460,14 @@ public abstract class AbstractClientConnector implements ClientConnector { } } + /** + * {@inheritDoc} + * + * <p> + * The {@link #getApplication()} and {@link #getRoot()} methods might return + * <code>null</code> after this method is called. + * </p> + */ public void detach() { for (ClientConnector connector : getAllChildrenIterable(this)) { connector.detach(); diff --git a/src/com/vaadin/terminal/AbstractExtension.java b/src/com/vaadin/terminal/AbstractExtension.java index 353db85a18..33a60e39ef 100644 --- a/src/com/vaadin/terminal/AbstractExtension.java +++ b/src/com/vaadin/terminal/AbstractExtension.java @@ -6,26 +6,69 @@ package com.vaadin.terminal; import com.vaadin.terminal.gwt.server.ClientConnector; +/** + * An extension is an entity that is attached to a Component or another + * Extension and independently communicates between client and server. + * <p> + * Extensions can use shared state and RPC in the same way as components. + * <p> + * AbstractExtension adds a mechanism for adding the extension to any Connector + * (extend). To let the Extension determine what kind target it can be added to, + * the extend method is declared as protected. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public abstract class AbstractExtension extends AbstractClientConnector implements Extension { + private boolean previouslyAttached = false; - protected Class<? extends ClientConnector> getAcceptedParentType() { + /** + * Gets a type that the parent must be an instance of. Override this if the + * extension only support certain targets, e.g. if only TextFields can be + * extended. + * + * @return a type that the parent must be an instance of + */ + protected Class<? extends ClientConnector> getSupportedParentType() { return ClientConnector.class; } - protected void attachTo(AbstractClientConnector parent) { - parent.addExtension(this); + /** + * Add this extension to the target connector. This method is protected to + * allow subclasses to require a more specific type of target. + * + * @param target + * the connector to attach this extension to + */ + protected void extend(AbstractClientConnector target) { + target.addExtension(this); + } + + /** + * Remove this extension from its target. After an extension has been + * removed, it can not be attached again. + */ + public void removeFromTarget() { + getParent().removeExtension(this); } @Override public void setParent(ClientConnector parent) { - Class<? extends ClientConnector> acceptedParentType = getAcceptedParentType(); - if (parent == null || acceptedParentType.isInstance(parent)) { + if (previouslyAttached && parent != null) { + throw new IllegalStateException( + "An extension can not be set to extend a new target after getting detached from the previous."); + } + + Class<? extends ClientConnector> supportedParentType = getSupportedParentType(); + if (parent == null || supportedParentType.isInstance(parent)) { super.setParent(parent); + previouslyAttached = true; } else { throw new IllegalArgumentException(getClass().getName() - + " can only be attached to parents of type " - + acceptedParentType.getName() + " but attach to " + + " can only be attached to targets of type " + + supportedParentType.getName() + " but attach to " + parent.getClass().getName() + " was attempted."); } } diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java new file mode 100644 index 0000000000..bdcd948c74 --- /dev/null +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -0,0 +1,158 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import com.vaadin.terminal.gwt.client.JavaScriptExtensionState; +import com.vaadin.ui.JavaScriptCallback; + +/** + * Base class for Extensions with all client-side logic implemented using + * JavaScript. + * <p> + * When a new JavaScript extension is initialized in the browser, the framework + * will look for a globally defined JavaScript function that will initialize the + * extension. The name of the initialization function is formed by replacing . + * with _ in the name of the server-side class. If no such function is defined, + * each super class is used in turn until a match is found. The framework will + * thus first attempt with <code>com_example_MyExtension</code> for the + * server-side + * <code>com.example.MyExtension extends AbstractJavaScriptExtension</code> + * class. If MyExtension instead extends <code>com.example.SuperExtension</code> + * , then <code>com_example_SuperExtension</code> will also be attempted if + * <code>com_example_MyExtension</code> has not been defined. + * <p> + * + * The initialization function will be called with <code>this</code> pointing to + * a connector wrapper object providing integration to Vaadin with the following + * functions: + * <ul> + * <li><code>getConnectorId()</code> - returns a string with the id of the + * connector.</li> + * <li><code>getParentId([connectorId])</code> - returns a string with the id of + * the connector's parent. If <code>connectorId</code> is provided, the id of + * the parent of the corresponding connector with the passed id is returned + * instead.</li> + * <li><code>getWidgetElement([connectorId])</code> - returns the DOM Element + * that is the root of a connector's widget. <code>null</code> is returned if + * the connector can not be found or if the connector doesn't have a widget. If + * <code>connectorId</code> is not provided, the connector id of the current + * connector will be used.</li> + * <li><code>getState()</code> - returns an object corresponding to the shared + * state defined on the server. The scheme for conversion between Java and + * JavaScript types is described bellow.</li> + * <li><code>registerRpc([name, ] rpcObject)</code> - registers the + * <code>rpcObject</code> as a RPC handler. <code>rpcObject</code> should be an + * object with field containing functions for all eligible RPC functions. If + * <code>name</code> is provided, the RPC handler will only used for RPC calls + * for the RPC interface with the same fully qualified Java name. If no + * <code>name</code> is provided, the RPC handler will be used for all incoming + * RPC invocations where the RPC method name is defined as a function field in + * the handler. The scheme for conversion between Java types in the RPC + * interface definition and the JavaScript values passed as arguments to the + * handler functions is described bellow.</li> + * <li><code>getRpcProxy([name])</code> - returns an RPC proxy object. If + * <code>name</code> is provided, the proxy object will contain functions for + * all methods in the RPC interface with the same fully qualified name, provided + * a RPC handler has been registered by the server-side code. If no + * <code>name</code> is provided, the returned RPC proxy object will contain + * functions for all methods in all RPC interfaces registered for the connector + * on the server. If the same method name is present in multiple registered RPC + * interfaces, the corresponding function in the RPC proxy object will throw an + * exception when called. The scheme for conversion between Java types in the + * RPC interface and the JavaScript values that should be passed to the + * functions is described bellow.</li> + * </ul> + * The connector wrapper also supports these special functions: + * <ul> + * <li><code>onStateChange</code> - If the JavaScript code assigns a function to + * the field, that function is called whenever the contents of the shared state + * is changed.</li> + * <li>Any field name corresponding to a call to + * {@link #registerCallback(String, JavaScriptCallback)} on the server will + * automatically be present as a function that triggers the registered callback + * on the server.</li> + * <li>Any field name referred to using + * {@link #invokeCallback(String, Object...)} on the server will be called if a + * function has been assigned to the field.</li> + * </ul> + * <p> + * + * Values in the Shared State and in RPC calls are converted between Java and + * JavaScript using the following conventions: + * <ul> + * <li>Primitive Java numbers (byte, char, int, long, float, double) and their + * boxed types (Byte, Character, Integer, Long, Float, Double) are represented + * by JavaScript numbers.</li> + * <li>The primitive Java boolean and the boxed Boolean are represented by + * JavaScript booleans.</li> + * <li>Java Strings are represented by JavaScript strings.</li> + * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> + * <li>Map<String, ?> in Java is represented by JavaScript object with fields + * corresponding to the map keys.</li> + * <li>Any other Java Map is represented by a JavaScript array containing two + * arrays, the first contains the keys and the second contains the values in the + * same order.</li> + * <li>A Java Bean is represented by a JavaScript object with fields + * corresponding to the bean's properties.</li> + * <li>A Java Connector is represented by a JavaScript string containing the + * connector's id.</li> + * <li>A pluggable serialization mechanism is provided for types not described + * here. Please refer to the documentation for specific types for serialization + * information.</li> + * </ul> + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public abstract class AbstractJavaScriptExtension extends AbstractExtension { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + @Override + protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) { + super.registerRpc(implementation, rpcInterfaceType); + callbackHelper.registerRpc(rpcInterfaceType); + } + + /** + * Register a {@link JavaScriptCallback} that can be called from the + * JavaScript using the provided name. A JavaScript function with the + * provided name will be added to the connector wrapper object (initially + * available as <code>this</code>). Calling that JavaScript function will + * cause the call method in the registered {@link JavaScriptCallback} to be + * invoked with the same arguments. + * + * @param functionName + * the name that should be used for client-side callback + * @param javaScriptCallback + * the callback object that will be invoked when the JavaScript + * function is called + */ + protected void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbackHelper.registerCallback(functionName, javaScriptCallback); + } + + /** + * Invoke a named function that the connector JavaScript has added to the + * JavaScript connector wrapper object. The arguments should only contain + * data types that can be represented in JavaScript, including primitive + * boxing types, arrays, String, List, Set, Map, Connector and JavaBeans. + * + * @param name + * the name of the function + * @param arguments + * function arguments + */ + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } + + @Override + public JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } +} diff --git a/src/com/vaadin/terminal/AbstractJavascriptExtension.java b/src/com/vaadin/terminal/AbstractJavascriptExtension.java deleted file mode 100644 index e741e2af1e..0000000000 --- a/src/com/vaadin/terminal/AbstractJavascriptExtension.java +++ /dev/null @@ -1,20 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import com.vaadin.ui.JavascriptCallback; - -public class AbstractJavascriptExtension extends AbstractExtension { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/terminal/ClassResource.java b/src/com/vaadin/terminal/ClassResource.java index fa196e90d9..e7419576f1 100644 --- a/src/com/vaadin/terminal/ClassResource.java +++ b/src/com/vaadin/terminal/ClassResource.java @@ -60,13 +60,7 @@ public class ClassResource implements ApplicationResource, Serializable { * the application this resource will be added to. */ public ClassResource(String resourceName, Application application) { - associatedClass = application.getClass(); - this.resourceName = resourceName; - this.application = application; - if (resourceName == null) { - throw new NullPointerException(); - } - application.addResource(this); + this(application.getClass(), resourceName, application); } /** diff --git a/src/com/vaadin/terminal/Extension.java b/src/com/vaadin/terminal/Extension.java index 7769423f0d..ef5bb4cf8d 100644 --- a/src/com/vaadin/terminal/Extension.java +++ b/src/com/vaadin/terminal/Extension.java @@ -6,6 +6,22 @@ package com.vaadin.terminal; import com.vaadin.terminal.gwt.server.ClientConnector; +/** + * An extension is an entity that is attached to a Component or another + * Extension and independently communicates between client and server. + * <p> + * An extension can only be attached once. It is not supported to move an + * extension from one target to another. + * <p> + * Extensions can use shared state and RPC in the same way as components. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ public interface Extension extends ClientConnector { - + /* + * Currently just an empty marker interface to distinguish between + * extensions and other connectors, e.g. components + */ } diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java new file mode 100644 index 0000000000..01db0267d9 --- /dev/null +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -0,0 +1,115 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; +import com.vaadin.ui.JavaScriptCallback; + +/** + * Internal helper class used to implement functionality common to + * {@link AbstractJavaScriptComponent} and {@link AbstractJavaScriptExtension}. + * Corresponding support in client-side code is in + * {@link JavaScriptConnectorHelper}. + * <p> + * You should most likely no use this class directly. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class JavaScriptCallbackHelper implements Serializable { + + private static final Method CALL_METHOD = ReflectTools.findMethod( + JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class); + private AbstractClientConnector connector; + + private Map<String, JavaScriptCallback> callbacks = new HashMap<String, JavaScriptCallback>(); + private JavaScriptCallbackRpc javascriptCallbackRpc; + + public JavaScriptCallbackHelper(AbstractClientConnector connector) { + this.connector = connector; + } + + public void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbacks.put(functionName, javaScriptCallback); + JavaScriptConnectorState state = getConnectorState(); + if (state.getCallbackNames().add(functionName)) { + connector.requestRepaint(); + } + ensureRpc(); + } + + private JavaScriptConnectorState getConnectorState() { + JavaScriptConnectorState state = (JavaScriptConnectorState) connector + .getState(); + return state; + } + + private void ensureRpc() { + if (javascriptCallbackRpc == null) { + javascriptCallbackRpc = new JavaScriptCallbackRpc() { + public void call(String name, JSONArray arguments) { + JavaScriptCallback callback = callbacks.get(name); + try { + callback.call(arguments); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + }; + connector.registerRpc(javascriptCallbackRpc); + } + } + + public void invokeCallback(String name, Object... arguments) { + if (callbacks.containsKey(name)) { + throw new IllegalStateException( + "Can't call callback " + + name + + " on the client because a callback with the same name is registered on the server."); + } + JSONArray args = new JSONArray(Arrays.asList(arguments)); + connector.addMethodInvocationToQueue( + JavaScriptCallbackRpc.class.getName(), CALL_METHOD, + new Object[] { name, args }); + connector.requestRepaint(); + } + + public void registerRpc(Class<?> rpcInterfaceType) { + if (rpcInterfaceType == JavaScriptCallbackRpc.class) { + // Ignore + return; + } + Map<String, Set<String>> rpcInterfaces = getConnectorState() + .getRpcInterfaces(); + String interfaceName = rpcInterfaceType.getName(); + if (!rpcInterfaces.containsKey(interfaceName)) { + Set<String> methodNames = new HashSet<String>(); + + for (Method method : rpcInterfaceType.getMethods()) { + methodNames.add(method.getName()); + } + + rpcInterfaces.put(interfaceName, methodNames); + connector.requestRepaint(); + } + } + +} diff --git a/src/com/vaadin/terminal/JavascriptRpcHelper.java b/src/com/vaadin/terminal/JavascriptRpcHelper.java deleted file mode 100644 index b566462833..0000000000 --- a/src/com/vaadin/terminal/JavascriptRpcHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; -import com.vaadin.tools.ReflectTools; -import com.vaadin.ui.JavascriptCallback; -import com.vaadin.ui.JavascriptManager.JavascriptCallbackRpc; - -public class JavascriptRpcHelper { - - private static final Method CALL_METHOD = ReflectTools.findMethod( - JavascriptCallbackRpc.class, "call", String.class, JSONArray.class); - private AbstractClientConnector connector; - - private Map<String, JavascriptCallback> callbacks = new HashMap<String, JavascriptCallback>(); - private JavascriptCallbackRpc javascriptCallbackRpc; - - public JavascriptRpcHelper(AbstractClientConnector connector) { - this.connector = connector; - } - - public void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - callbacks.put(functionName, javascriptCallback); - ensureRpc(); - } - - private void ensureRpc() { - if (javascriptCallbackRpc == null) { - javascriptCallbackRpc = new JavascriptCallbackRpc() { - public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); - try { - callback.call(arguments); - } catch (JSONException e) { - throw new IllegalArgumentException(e); - } - } - }; - connector.registerRpc(javascriptCallbackRpc); - } - } - - public void invokeCallback(String name, Object... arguments) { - JSONArray args = new JSONArray(Arrays.asList(arguments)); - connector.addMethodInvocationToQueue( - JavascriptCallbackRpc.class.getName(), CALL_METHOD, - new Object[] { name, args }); - connector.requestRepaint(); - } - -} diff --git a/src/com/vaadin/terminal/Page.java b/src/com/vaadin/terminal/Page.java new file mode 100644 index 0000000000..65fa500d27 --- /dev/null +++ b/src/com/vaadin/terminal/Page.java @@ -0,0 +1,630 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.EventObject; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.vaadin.event.EventRouter; +import com.vaadin.terminal.WrappedRequest.BrowserDetails; +import com.vaadin.terminal.gwt.client.ui.notification.VNotification; +import com.vaadin.terminal.gwt.client.ui.root.PageClientRpc; +import com.vaadin.terminal.gwt.client.ui.root.VRoot; +import com.vaadin.terminal.gwt.server.WebApplicationContext; +import com.vaadin.terminal.gwt.server.WebBrowser; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.JavaScript; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Root; + +public class Page implements Serializable { + + /** + * Listener that gets notified when the size of the browser window + * containing the root has changed. + * + * @see Root#addListener(BrowserWindowResizeListener) + */ + public interface BrowserWindowResizeListener extends Serializable { + /** + * Invoked when the browser window containing a Root has been resized. + * + * @param event + * a browser window resize event + */ + public void browserWindowResized(BrowserWindowResizeEvent event); + } + + /** + * Event that is fired when a browser window containing a root is resized. + */ + public class BrowserWindowResizeEvent extends EventObject { + + private final int width; + private final int height; + + /** + * Creates a new event + * + * @param source + * the root for which the browser window has been resized + * @param width + * the new width of the browser window + * @param height + * the new height of the browser window + */ + public BrowserWindowResizeEvent(Page source, int width, int height) { + super(source); + this.width = width; + this.height = height; + } + + @Override + public Page getSource() { + return (Page) super.getSource(); + } + + /** + * Gets the new browser window height + * + * @return an integer with the new pixel height of the browser window + */ + public int getHeight() { + return height; + } + + /** + * Gets the new browser window width + * + * @return an integer with the new pixel width of the browser window + */ + public int getWidth() { + return width; + } + } + + /** + * Private class for storing properties related to opening resources. + */ + private class OpenResource implements Serializable { + + /** + * The resource to open + */ + private final Resource resource; + + /** + * The name of the target window + */ + private final String name; + + /** + * The width of the target window + */ + private final int width; + + /** + * The height of the target window + */ + private final int height; + + /** + * The border style of the target window + */ + private final int border; + + /** + * Creates a new open resource. + * + * @param resource + * The resource to open + * @param name + * The name of the target window + * @param width + * The width of the target window + * @param height + * The height of the target window + * @param border + * The border style of the target window + */ + private OpenResource(Resource resource, String name, int width, + int height, int border) { + this.resource = resource; + this.name = name; + this.width = width; + this.height = height; + this.border = border; + } + + /** + * Paints the open request. Should be painted inside the window. + * + * @param target + * the paint target + * @throws PaintException + * if the paint operation fails + */ + private void paintContent(PaintTarget target) throws PaintException { + target.startTag("open"); + target.addAttribute("src", resource); + if (name != null && name.length() > 0) { + target.addAttribute("name", name); + } + if (width >= 0) { + target.addAttribute("width", width); + } + if (height >= 0) { + target.addAttribute("height", height); + } + switch (border) { + case BORDER_MINIMAL: + target.addAttribute("border", "minimal"); + break; + case BORDER_NONE: + target.addAttribute("border", "none"); + break; + } + + target.endTag("open"); + } + } + + private static final Method BROWSWER_RESIZE_METHOD = ReflectTools + .findMethod(BrowserWindowResizeListener.class, + "browserWindowResized", BrowserWindowResizeEvent.class); + + /** + * A border style used for opening resources in a window without a border. + */ + public static final int BORDER_NONE = 0; + + /** + * A border style used for opening resources in a window with a minimal + * border. + */ + public static final int BORDER_MINIMAL = 1; + + /** + * A border style that indicates that the default border style should be + * used when opening resources. + */ + public static final int BORDER_DEFAULT = 2; + + /** + * Listener that listens changes in URI fragment. + */ + public interface FragmentChangedListener extends Serializable { + public void fragmentChanged(FragmentChangedEvent event); + } + + private static final Method FRAGMENT_CHANGED_METHOD = ReflectTools + .findMethod(Page.FragmentChangedListener.class, "fragmentChanged", + FragmentChangedEvent.class); + + /** + * Resources to be opened automatically on next repaint. The list is + * automatically cleared when it has been sent to the client. + */ + private final LinkedList<OpenResource> openList = new LinkedList<OpenResource>(); + + /** + * A list of notifications that are waiting to be sent to the client. + * Cleared (set to null) when the notifications have been sent. + */ + private List<Notification> notifications; + + /** + * Event fired when uri fragment changes. + */ + public class FragmentChangedEvent extends EventObject { + + /** + * The new uri fragment + */ + private final String fragment; + + /** + * Creates a new instance of UriFragmentReader change event. + * + * @param source + * the Source of the event. + */ + public FragmentChangedEvent(Page source, String fragment) { + super(source); + this.fragment = fragment; + } + + /** + * Gets the root in which the fragment has changed. + * + * @return the root in which the fragment has changed + */ + public Page getPage() { + return (Page) getSource(); + } + + /** + * Get the new fragment + * + * @return the new fragment + */ + public String getFragment() { + return fragment; + } + } + + private EventRouter eventRouter; + + /** + * The current URI fragment. + */ + private String fragment; + + private final Root root; + + private int browserWindowWidth = -1; + private int browserWindowHeight = -1; + + private JavaScript javaScript; + + public Page(Root root) { + this.root = root; + } + + private void addListener(Class<?> eventType, Object target, Method method) { + if (eventRouter == null) { + eventRouter = new EventRouter(); + } + eventRouter.addListener(eventType, target, method); + } + + private void removeListener(Class<?> eventType, Object target, Method method) { + if (eventRouter != null) { + eventRouter.removeListener(eventType, target, method); + } + } + + public void addListener(Page.FragmentChangedListener listener) { + addListener(FragmentChangedEvent.class, listener, + FRAGMENT_CHANGED_METHOD); + } + + public void removeListener(Page.FragmentChangedListener listener) { + removeListener(FragmentChangedEvent.class, listener, + FRAGMENT_CHANGED_METHOD); + } + + /** + * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent} + * + * @param newFragment + * id of the new fragment + * @param fireEvent + * true to fire event + * @see FragmentChangedEvent + * @see Page.FragmentChangedListener + */ + public void setFragment(String newFragment, boolean fireEvents) { + if (newFragment == null) { + throw new NullPointerException("The fragment may not be null"); + } + if (!newFragment.equals(fragment)) { + fragment = newFragment; + if (fireEvents) { + fireEvent(new FragmentChangedEvent(this, newFragment)); + } + root.requestRepaint(); + } + } + + private void fireEvent(EventObject event) { + if (eventRouter != null) { + eventRouter.fireEvent(event); + } + } + + /** + * Sets URI fragment. This method fires a {@link FragmentChangedEvent} + * + * @param newFragment + * id of the new fragment + * @see FragmentChangedEvent + * @see Page.FragmentChangedListener + */ + public void setFragment(String newFragment) { + setFragment(newFragment, true); + } + + /** + * Gets currently set URI fragment. + * <p> + * To listen changes in fragment, hook a + * {@link Page.FragmentChangedListener}. + * + * @return the current fragment in browser uri or null if not known + */ + public String getFragment() { + return fragment; + } + + public void init(WrappedRequest request) { + BrowserDetails browserDetails = request.getBrowserDetails(); + if (browserDetails != null) { + fragment = browserDetails.getUriFragment(); + } + } + + public WebBrowser getWebBrowser() { + return ((WebApplicationContext) root.getApplication().getContext()) + .getBrowser(); + } + + public void setBrowserWindowSize(Integer width, Integer height) { + boolean fireEvent = false; + + if (width != null) { + int newWidth = width.intValue(); + if (newWidth != browserWindowWidth) { + browserWindowWidth = newWidth; + fireEvent = true; + } + } + + if (height != null) { + int newHeight = height.intValue(); + if (newHeight != browserWindowHeight) { + browserWindowHeight = newHeight; + fireEvent = true; + } + } + + if (fireEvent) { + fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth, + browserWindowHeight)); + } + + } + + /** + * Adds a new {@link BrowserWindowResizeListener} to this root. The listener + * will be notified whenever the browser window within which this root + * resides is resized. + * + * @param resizeListener + * the listener to add + * + * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) + * @see #setResizeLazy(boolean) + */ + public void addListener(BrowserWindowResizeListener resizeListener) { + addListener(BrowserWindowResizeEvent.class, resizeListener, + BROWSWER_RESIZE_METHOD); + } + + /** + * Removes a {@link BrowserWindowResizeListener} from this root. The + * listener will no longer be notified when the browser window is resized. + * + * @param resizeListener + * the listener to remove + */ + public void removeListener(BrowserWindowResizeListener resizeListener) { + removeListener(BrowserWindowResizeEvent.class, resizeListener, + BROWSWER_RESIZE_METHOD); + } + + /** + * Gets the last known height of the browser window in which this root + * resides. + * + * @return the browser window height in pixels + */ + public int getBrowserWindowHeight() { + return browserWindowHeight; + } + + /** + * Gets the last known width of the browser window in which this root + * resides. + * + * @return the browser window width in pixels + */ + public int getBrowserWindowWidth() { + return browserWindowWidth; + } + + public JavaScript getJavaScript() { + if (javaScript == null) { + // Create and attach on first use + javaScript = new JavaScript(); + javaScript.extend(root); + } + + return javaScript; + } + + public void paintContent(PaintTarget target) throws PaintException { + if (!openList.isEmpty()) { + for (final Iterator<OpenResource> i = openList.iterator(); i + .hasNext();) { + (i.next()).paintContent(target); + } + openList.clear(); + } + + // Paint notifications + if (notifications != null) { + target.startTag("notifications"); + for (final Iterator<Notification> it = notifications.iterator(); it + .hasNext();) { + final Notification n = it.next(); + target.startTag("notification"); + if (n.getCaption() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_CAPTION, + n.getCaption()); + } + if (n.getDescription() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_MESSAGE, + n.getDescription()); + } + if (n.getIcon() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_ICON, + n.getIcon()); + } + if (!n.isHtmlContentAllowed()) { + target.addAttribute( + VRoot.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); + } + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_POSITION, + n.getPosition()); + target.addAttribute(VNotification.ATTRIBUTE_NOTIFICATION_DELAY, + n.getDelayMsec()); + if (n.getStyleName() != null) { + target.addAttribute( + VNotification.ATTRIBUTE_NOTIFICATION_STYLE, + n.getStyleName()); + } + target.endTag("notification"); + } + target.endTag("notifications"); + notifications = null; + } + + if (fragment != null) { + target.addAttribute(VRoot.FRAGMENT_VARIABLE, fragment); + } + + } + + /** + * Opens the given resource in this root. The contents of this Root is + * replaced by the {@code Resource}. + * + * @param resource + * the resource to show in this root + */ + public void open(Resource resource) { + openList.add(new OpenResource(resource, null, -1, -1, BORDER_DEFAULT)); + root.requestRepaint(); + } + + /** + * Opens the given resource in a window with the given name. + * <p> + * The supplied {@code windowName} is used as the target name in a + * window.open call in the client. This means that special values such as + * "_blank", "_self", "_top", "_parent" have special meaning. An empty or + * <code>null</code> window name is also a special case. + * </p> + * <p> + * "", null and "_self" as {@code windowName} all causes the resource to be + * opened in the current window, replacing any old contents. For + * downloadable content you should avoid "_self" as "_self" causes the + * client to skip rendering of any other changes as it considers them + * irrelevant (the page will be replaced by the resource). This can speed up + * the opening of a resource, but it might also put the client side into an + * inconsistent state if the window content is not completely replaced e.g., + * if the resource is downloaded instead of displayed in the browser. + * </p> + * <p> + * "_blank" as {@code windowName} causes the resource to always be opened in + * a new window or tab (depends on the browser and browser settings). + * </p> + * <p> + * "_top" and "_parent" as {@code windowName} works as specified by the HTML + * standard. + * </p> + * <p> + * Any other {@code windowName} will open the resource in a window with that + * name, either by opening a new window/tab in the browser or by replacing + * the contents of an existing window with that name. + * </p> + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + */ + public void open(Resource resource, String windowName) { + openList.add(new OpenResource(resource, windowName, -1, -1, + BORDER_DEFAULT)); + root.requestRepaint(); + } + + /** + * Opens the given resource in a window with the given size, border and + * name. For more information on the meaning of {@code windowName}, see + * {@link #open(Resource, String)}. + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @param width + * the width of the window in pixels + * @param height + * the height of the window in pixels + * @param border + * the border style of the window. See {@link #BORDER_NONE + * Window.BORDER_* constants} + */ + public void open(Resource resource, String windowName, int width, + int height, int border) { + openList.add(new OpenResource(resource, windowName, width, height, + border)); + root.requestRepaint(); + } + + /** + * Internal helper method to actually add a notification. + * + * @param notification + * the notification to add + */ + private void addNotification(Notification notification) { + if (notifications == null) { + notifications = new LinkedList<Notification>(); + } + notifications.add(notification); + root.requestRepaint(); + } + + /** + * Shows a notification message. + * + * @see Notification + * @see #showNotification(String) + * @see #showNotification(String, int) + * @see #showNotification(String, String) + * @see #showNotification(String, String, int) + * + * @param notification + * The notification message to show + */ + public void showNotification(Notification notification) { + addNotification(notification); + } + + public static Page getCurrent() { + Root currentRoot = Root.getCurrentRoot(); + if (currentRoot == null) { + return null; + } + return currentRoot.getPage(); + } + + public void setTitle(String title) { + root.getRpcProxy(PageClientRpc.class).setTitle(title); + } + +} diff --git a/src/com/vaadin/terminal/UserError.java b/src/com/vaadin/terminal/UserError.java index baaf331fa0..a7a4fd89e2 100644 --- a/src/com/vaadin/terminal/UserError.java +++ b/src/com/vaadin/terminal/UserError.java @@ -44,6 +44,16 @@ public class UserError extends AbstractErrorMessage { super(textErrorMessage); } + /** + * Creates an error message with level and content mode. + * + * @param message + * the error message. + * @param contentMode + * the content Mode. + * @param errorLevel + * the level of error. + */ public UserError(String message, ContentMode contentMode, ErrorLevel errorLevel) { super(message); diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 244f310c1a..960b0a8b0e 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -18,6 +18,7 @@ import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; public class ApplicationConfiguration implements EntryPoint { @@ -346,6 +347,7 @@ public class ApplicationConfiguration implements EntryPoint { */ public static void startApplication(final String applicationId) { Scheduler.get().scheduleDeferred(new ScheduledCommand() { + public void execute() { ApplicationConfiguration appConf = getConfigFromDOM(applicationId); ApplicationConnection a = GWT @@ -568,6 +570,7 @@ public class ApplicationConfiguration implements EntryPoint { * GWT hosted mode. */ GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + public void onUncaughtException(Throwable e) { /* * Note in case of null console (without ?debug) we eat @@ -602,12 +605,15 @@ public class ApplicationConfiguration implements EntryPoint { * * @return true if client side is currently been debugged */ - public native static boolean isDebugMode() + public static boolean isDebugMode() { + return isDebugAvailable() + && Window.Location.getParameter("debug") != null; + } + + private native static boolean isDebugAvailable() /*-{ if($wnd.vaadin.debug) { - var parameters = $wnd.location.search; - var re = /debug[^\/]*$/; - return re.test(parameters); + return true; } else { return false; } @@ -618,12 +624,11 @@ public class ApplicationConfiguration implements EntryPoint { * * @return <code>true</code> if debug logging should be quiet */ - public native static boolean isQuietDebugMode() - /*-{ - var uri = $wnd.location; - var re = /debug=q[^\/]*$/; - return re.test(uri); - }-*/; + public static boolean isQuietDebugMode() { + String debugParameter = Window.Location.getParameter("debug"); + return isDebugAvailable() && debugParameter != null + && debugParameter.startsWith("q"); + } /** * Checks whether information from the web browser (e.g. uri fragment and diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 93a51e6e96..f0470c8ee8 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -40,7 +40,7 @@ import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.communication.JsonDecoder; import com.vaadin.terminal.gwt.client.communication.JsonEncoder; import com.vaadin.terminal.gwt.client.communication.MethodInvocation; @@ -50,6 +50,7 @@ import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; import com.vaadin.terminal.gwt.client.communication.Type; import com.vaadin.terminal.gwt.client.communication.UidlValue; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; import com.vaadin.terminal.gwt.client.ui.VContextMenu; import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; @@ -370,6 +371,25 @@ public class ApplicationConnection { }-*/; /** + * If on Liferay and logged in, ask the client side session management + * JavaScript to extend the session duration. + * + * Otherwise, Liferay client side JavaScript will explicitly expire the + * session even though the server side considers the session to be active. + * See ticket #8305 for more information. + */ + protected native void extendLiferaySession() + /*-{ + if ($wnd.Liferay && $wnd.Liferay.Session) { + $wnd.Liferay.Session.extend(); + // if the extend banner is visible, hide it + if ($wnd.Liferay.Session.banner) { + $wnd.Liferay.Session.banner.remove(); + } + } + }-*/; + + /** * Get the active Console for writing debug messages. May return an actual * logging console, or the NullConsole if debugging is not turned on. * @@ -851,6 +871,14 @@ public class ApplicationConnection { public void execute() { if (!hasActiveRequest()) { hideLoadingIndicator(); + + // If on Liferay and session expiration management is in + // use, extend session duration on each request. + // Doing it here rather than before the request to improve + // responsiveness. + // Postponed until the end of the next request if other + // requests still pending. + extendLiferaySession(); } } }); @@ -1415,8 +1443,8 @@ public class ApplicationConnection { JSONObject stateJson = new JSONObject( states.getJavaScriptObject(connectorId)); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper() .setNativeState( stateJson.getJavaScriptObject()); @@ -1491,6 +1519,10 @@ public class ApplicationConnection { if (childConnector instanceof ComponentConnector) { newComponents .add((ComponentConnector) childConnector); + } else if (!(childConnector instanceof AbstractExtensionConnector)) { + throw new IllegalStateException( + Util.getConnectorString(childConnector) + + " is not a ComponentConnector nor an AbstractExtensionConnector"); } if (childConnector.getParent() != parentConnector) { // Avoid extra calls to setParent diff --git a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java index e12c002930..82cf925ec1 100644 --- a/src/com/vaadin/terminal/gwt/client/BrowserInfo.java +++ b/src/com/vaadin/terminal/gwt/client/BrowserInfo.java @@ -31,6 +31,9 @@ public class BrowserInfo { private static final String OS_ANDROID = "android"; private static final String OS_IOS = "ios"; + // Common CSS class for all touch devices + private static final String UI_TOUCH = "touch"; + private static BrowserInfo instance; private static String cssClass = null; @@ -169,7 +172,9 @@ public class BrowserInfo { if (osClass != null) { cssClass = cssClass + " " + prefix + osClass; } - + if (isTouchDevice()) { + cssClass = cssClass + " " + prefix + UI_TOUCH; + } } return cssClass; @@ -344,15 +349,14 @@ public class BrowserInfo { if (!isTouchDevice()) { return false; } - - if (isAndroid() && isWebkit() && getWebkitVersion() < 534) { - return true; + if (isAndroid() && isWebkit() && getWebkitVersion() >= 534) { + return false; } - // if (isIOS() && isWebkit() && getWebkitVersion() < ???) { - // return true; + // Cannot enable native touch scrolling on iOS 5 until #8792 is resolved + // if (isIOS() && isWebkit() && getWebkitVersion() >= 534) { + // return false; // } - - return false; + return true; } /** diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java new file mode 100644 index 0000000000..bd62a759cb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java @@ -0,0 +1,372 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.user.client.Element; +import com.vaadin.terminal.gwt.client.communication.MethodInvocation; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler; + +public class JavaScriptConnectorHelper { + + public interface JavaScriptConnectorState { + public Set<String> getCallbackNames(); + + public Map<String, Set<String>> getRpcInterfaces(); + } + + private final ServerConnector connector; + private final JavaScriptObject nativeState = JavaScriptObject + .createObject(); + private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); + + private final Map<String, JavaScriptObject> rpcObjects = new HashMap<String, JavaScriptObject>(); + private final Map<String, Set<String>> rpcMethods = new HashMap<String, Set<String>>(); + + private JavaScriptObject connectorWrapper; + private int tag; + + private boolean inited = false; + + public JavaScriptConnectorHelper(ServerConnector connector) { + this.connector = connector; + + // Wildcard rpc object + rpcObjects.put("", JavaScriptObject.createObject()); + } + + public void init() { + connector.addStateChangeHandler(new StateChangeHandler() { + public void onStateChanged(StateChangeEvent stateChangeEvent) { + JavaScriptObject wrapper = getConnectorWrapper(); + JavaScriptConnectorState state = getConnectorState(); + + for (String callback : state.getCallbackNames()) { + ensureCallback(JavaScriptConnectorHelper.this, wrapper, + callback); + } + + for (Entry<String, Set<String>> entry : state + .getRpcInterfaces().entrySet()) { + String rpcName = entry.getKey(); + String jsName = getJsInterfaceName(rpcName); + if (!rpcObjects.containsKey(jsName)) { + Set<String> methods = entry.getValue(); + rpcObjects.put(jsName, + createRpcObject(rpcName, methods)); + + // Init all methods for wildcard rpc + for (String method : methods) { + JavaScriptObject wildcardRpcObject = rpcObjects + .get(""); + Set<String> interfaces = rpcMethods.get(method); + if (interfaces == null) { + interfaces = new HashSet<String>(); + rpcMethods.put(method, interfaces); + attachRpcMethod(wildcardRpcObject, null, method); + } + interfaces.add(rpcName); + } + } + } + + // Init after setting up callbacks & rpc + if (!inited) { + initJavaScript(); + inited = true; + } + + fireNativeStateChange(wrapper); + } + }); + } + + private static String getJsInterfaceName(String rpcName) { + return rpcName.replace('$', '.'); + } + + protected JavaScriptObject createRpcObject(String iface, Set<String> methods) { + JavaScriptObject object = JavaScriptObject.createObject(); + + for (String method : methods) { + attachRpcMethod(object, iface, method); + } + + return object; + } + + private boolean initJavaScript() { + ApplicationConfiguration conf = connector.getConnection() + .getConfiguration(); + ArrayList<String> attemptedNames = new ArrayList<String>(); + Integer tag = Integer.valueOf(this.tag); + while (tag != null) { + String serverSideClassName = conf.getServerSideClassNameForTag(tag); + String initFunctionName = serverSideClassName + .replaceAll("\\.", "_"); + if (tryInitJs(initFunctionName, getConnectorWrapper())) { + VConsole.log("JavaScript connector initialized using " + + initFunctionName); + return true; + } else { + VConsole.log("No JavaScript function " + initFunctionName + + " found"); + attemptedNames.add(initFunctionName); + tag = conf.getParentTag(tag.intValue()); + } + } + VConsole.log("No JavaScript init for connector not found"); + showInitProblem(attemptedNames); + return false; + } + + protected void showInitProblem(ArrayList<String> attemptedNames) { + // Default does nothing + } + + private static native boolean tryInitJs(String initFunctionName, + JavaScriptObject connectorWrapper) + /*-{ + if (typeof $wnd[initFunctionName] == 'function') { + $wnd[initFunctionName].apply(connectorWrapper); + return true; + } else { + return false; + } + }-*/; + + private JavaScriptObject getConnectorWrapper() { + if (connectorWrapper == null) { + connectorWrapper = createConnectorWrapper(this, nativeState, + rpcMap, connector.getConnectorId(), rpcObjects); + } + + return connectorWrapper; + } + + private static native void fireNativeStateChange( + JavaScriptObject connectorWrapper) + /*-{ + if (typeof connectorWrapper.onStateChange == 'function') { + connectorWrapper.onStateChange(); + } + }-*/; + + private static native JavaScriptObject createConnectorWrapper( + JavaScriptConnectorHelper h, JavaScriptObject nativeState, + JavaScriptObject registeredRpc, String connectorId, + Map<String, JavaScriptObject> rpcObjects) + /*-{ + return { + 'getConnectorId': function() { + return connectorId; + }, + 'getParentId': $entry(function(connectorId) { + return h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::getParentId(Ljava/lang/String;)(connectorId); + }), + 'getState': function() { + return nativeState; + }, + 'getRpcProxy': $entry(function(iface) { + if (!iface) { + iface = ''; + } + return rpcObjects.@java.util.Map::get(Ljava/lang/Object;)(iface); + }), + 'getWidgetElement': $entry(function(connectorId) { + return h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::getWidgetElement(Ljava/lang/String;)(connectorId); + }), + 'registerRpc': function(iface, rpcHandler) { + //registerRpc(handler) -> registerRpc('', handler); + if (!rpcHandler) { + rpcHandler = iface; + iface = ''; + } + if (!registeredRpc[iface]) { + registeredRpc[iface] = []; + } + registeredRpc[iface].push(rpcHandler); + }, + }; + }-*/; + + private native void attachRpcMethod(JavaScriptObject rpc, String iface, + String method) + /*-{ + var self = this; + rpc[method] = $entry(function() { + self.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); + }); + }-*/; + + private String getParentId(String connectorId) { + ServerConnector target = getConnector(connectorId); + if (target == null) { + return null; + } + ServerConnector parent = target.getParent(); + if (parent == null) { + return null; + } else { + return parent.getConnectorId(); + } + } + + private Element getWidgetElement(String connectorId) { + ServerConnector target = getConnector(connectorId); + if (target instanceof ComponentConnector) { + return ((ComponentConnector) target).getWidget().getElement(); + } else { + return null; + } + } + + private ServerConnector getConnector(String connectorId) { + if (connectorId == null || connectorId.length() == 0) { + return connector; + } + + return ConnectorMap.get(connector.getConnection()) + .getConnector(connectorId); + } + + private void fireRpc(String iface, String method, + JsArray<JavaScriptObject> arguments) { + if (iface == null) { + iface = findWildcardInterface(method); + } + + JSONArray argumentsArray = new JSONArray(arguments); + Object[] parameters = new Object[arguments.length()]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = argumentsArray.get(i); + } + connector.getConnection().addMethodInvocationToQueue( + new MethodInvocation(connector.getConnectorId(), iface, method, + parameters), true); + } + + private String findWildcardInterface(String method) { + Set<String> interfaces = rpcMethods.get(method); + if (interfaces.size() == 1) { + return interfaces.iterator().next(); + } else { + // TODO Resolve conflicts using argument count and types + String interfaceList = ""; + for (String iface : interfaces) { + if (interfaceList.length() != 0) { + interfaceList += ", "; + } + interfaceList += getJsInterfaceName(iface); + } + + throw new IllegalStateException( + "Can not call method " + + method + + " for wildcard rpc proxy because the function is defined for multiple rpc interfaces: " + + interfaceList + + ". Retrieve a rpc proxy for a specific interface using getRpcProxy(interfaceName) to use the function."); + } + } + + private void fireCallback(String name, JsArray<JavaScriptObject> arguments) { + MethodInvocation invocation = new MethodInvocation( + connector.getConnectorId(), + "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc", "call", + new Object[] { name, new JSONArray(arguments) }); + connector.getConnection().addMethodInvocationToQueue(invocation, true); + } + + public void setNativeState(JavaScriptObject state) { + updateNativeState(nativeState, state); + } + + private static native void updateNativeState(JavaScriptObject state, + JavaScriptObject input) + /*-{ + // Copy all fields to existing state object + for(var key in state) { + if (state.hasOwnProperty(key)) { + delete state[key]; + } + } + + for(var key in input) { + if (input.hasOwnProperty(key)) { + state[key] = input[key]; + } + } + }-*/; + + public Object[] decodeRpcParameters(JSONArray parametersJson) { + return new Object[] { parametersJson.getJavaScriptObject() }; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public void invokeJsRpc(MethodInvocation invocation, + JSONArray parametersJson) { + String iface = invocation.getInterfaceName(); + String method = invocation.getMethodName(); + if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(iface) + && "call".equals(method)) { + String callbackName = parametersJson.get(0).isString() + .stringValue(); + JavaScriptObject arguments = parametersJson.get(1).isArray() + .getJavaScriptObject(); + invokeCallback(getConnectorWrapper(), callbackName, arguments); + } else { + JavaScriptObject arguments = parametersJson.getJavaScriptObject(); + invokeJsRpc(rpcMap, iface, method, arguments); + // Also invoke wildcard interface + invokeJsRpc(rpcMap, "", method, arguments); + } + } + + private static native void invokeCallback(JavaScriptObject connector, + String name, JavaScriptObject arguments) + /*-{ + connector[name].apply(connector, arguments); + }-*/; + + private static native void invokeJsRpc(JavaScriptObject rpcMap, + String interfaceName, String methodName, JavaScriptObject parameters) + /*-{ + var targets = rpcMap[interfaceName]; + if (!targets) { + return; + } + for(var i = 0; i < targets.length; i++) { + var target = targets[i]; + target[methodName].apply(target, parameters); + } + }-*/; + + private static native void ensureCallback(JavaScriptConnectorHelper h, + JavaScriptObject connector, String name) + /*-{ + connector[name] = $entry(function() { + var args = Array.prototype.slice.call(arguments, 0); + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireCallback(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); + }); + }-*/; + + private JavaScriptConnectorState getConnectorState() { + return (JavaScriptConnectorState) connector.getState(); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java new file mode 100644 index 0000000000..2a97e4a770 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -0,0 +1,32 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; + +@Connect(AbstractJavaScriptExtension.class) +public final class JavaScriptExtension extends AbstractExtensionConnector + implements HasJavaScriptConnectorHelper { + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this); + + @Override + protected void init() { + super.init(); + helper.init(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } + + @Override + public JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java new file mode 100644 index 0000000000..e7bfbc4bb2 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java @@ -0,0 +1,36 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; +import com.vaadin.terminal.gwt.client.communication.SharedState; + +public class JavaScriptExtensionState extends SharedState implements + JavaScriptConnectorState { + + private Set<String> callbackNames = new HashSet<String>(); + private Map<String, Set<String>> rpcInterfaces = new HashMap<String, Set<String>>(); + + public Set<String> getCallbackNames() { + return callbackNames; + } + + public void setCallbackNames(Set<String> callbackNames) { + this.callbackNames = callbackNames; + } + + public Map<String, Set<String>> getRpcInterfaces() { + return rpcInterfaces; + } + + public void setRpcInterfaces(Map<String, Set<String>> rpcInterfaces) { + this.rpcInterfaces = rpcInterfaces; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java deleted file mode 100644 index ab0e62222c..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java +++ /dev/null @@ -1,205 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import java.util.ArrayList; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.json.client.JSONArray; -import com.vaadin.terminal.gwt.client.communication.MethodInvocation; - -public class JavascriptConnectorHelper { - - private final ServerConnector connector; - private final JavaScriptObject nativeState = JavaScriptObject - .createObject(); - private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); - - private JavaScriptObject connectorWrapper; - private int tag; - - public JavascriptConnectorHelper(ServerConnector connector) { - this.connector = connector; - } - - public boolean init() { - ApplicationConfiguration conf = connector.getConnection() - .getConfiguration(); - ArrayList<String> attemptedNames = new ArrayList<String>(); - Integer tag = Integer.valueOf(this.tag); - while (tag != null) { - String serverSideClassName = conf.getServerSideClassNameForTag(tag); - String initFunctionName = serverSideClassName - .replaceAll("\\.", "_"); - if (tryInitJs(initFunctionName, getConnectorWrapper())) { - VConsole.log("Javascript connector initialized using " - + initFunctionName); - return true; - } else { - VConsole.log("No javascript function " + initFunctionName - + " found"); - attemptedNames.add(initFunctionName); - tag = conf.getParentTag(tag.intValue()); - } - } - VConsole.log("No javascript init for connector not found"); - showInitProblem(attemptedNames); - return false; - } - - protected void showInitProblem(ArrayList<String> attemptedNames) { - // Default does nothing - } - - private static native boolean tryInitJs(String initFunctionName, - JavaScriptObject connectorWrapper) - /*-{ - if (typeof $wnd[initFunctionName] == 'function') { - $wnd[initFunctionName].apply(connectorWrapper); - return true; - } else { - return false; - } - }-*/; - - private JavaScriptObject getConnectorWrapper() { - if (connectorWrapper == null) { - connectorWrapper = createConnectorWrapper(); - } - - return connectorWrapper; - } - - protected JavaScriptObject createConnectorWrapper() { - return createConnectorWrapper(this, nativeState, rpcMap, - connector.getConnectorId()); - } - - public void fireNativeStateChange() { - fireNativeStateChange(getConnectorWrapper()); - } - - private static native void fireNativeStateChange( - JavaScriptObject connectorWrapper) - /*-{ - if (typeof connectorWrapper.onStateChange == 'function') { - connectorWrapper.onStateChange(); - } - }-*/; - - private static native JavaScriptObject createConnectorWrapper( - JavascriptConnectorHelper h, JavaScriptObject nativeState, - JavaScriptObject registeredRpc, String connectorId) - /*-{ - return { - 'getConnectorId': function() { - return connectorId; - }, - 'getState': function() { - return nativeState; - }, - 'getRpcProxyFunction': function(iface, method) { - return $entry(function() { - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); - }); - }, - 'getCallback': function(name) { - return $entry(function() { - var args = [name, Array.prototype.slice.call(arguments, 0)]; - var iface = "com.vaadin.ui.JavascriptManager$JavascriptCallbackRpc"; - var method = "call"; - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); - }); - }, - 'registerCallback': function(name, callback) { - //TODO maintain separate map - if (!registeredRpc[name]) { - registeredRpc[name] = []; - } - registeredRpc[name].push(callback); - }, - 'registerRpc': function(iface, rpcHandler) { - if (!registeredRpc[iface]) { - registeredRpc[iface] = []; - } - registeredRpc[iface].push(rpcHandler); - }, - }; - }-*/; - - private void fireRpc(String iface, String method, - JsArray<JavaScriptObject> arguments) { - JSONArray argumentsArray = new JSONArray(arguments); - Object[] parameters = new Object[arguments.length()]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = argumentsArray.get(i); - } - connector.getConnection().addMethodInvocationToQueue( - new MethodInvocation(connector.getConnectorId(), iface, method, - parameters), true); - } - - public void setNativeState(JavaScriptObject state) { - updateNativeState(nativeState, state); - } - - private static native void updateNativeState(JavaScriptObject state, - JavaScriptObject input) - /*-{ - // Copy all fields to existing state object - for(var key in state) { - if (state.hasOwnProperty(key)) { - delete state[key]; - } - } - - for(var key in input) { - if (input.hasOwnProperty(key)) { - state[key] = input[key]; - } - } - }-*/; - - public Object[] decodeRpcParameters(JSONArray parametersJson) { - return new Object[] { parametersJson.getJavaScriptObject() }; - } - - public void setTag(int tag) { - this.tag = tag; - } - - public void invokeJsRpc(MethodInvocation invocation, - JSONArray parametersJson) { - if ("com.vaadin.ui.JavascriptManager$JavascriptCallbackRpc" - .equals(invocation.getInterfaceName()) - && "call".equals(invocation.getMethodName())) { - invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), - null, parametersJson.get(1).isArray().getJavaScriptObject()); - } else { - invokeJsRpc(rpcMap, invocation.getInterfaceName(), - invocation.getMethodName(), - parametersJson.getJavaScriptObject()); - } - } - - private static native void invokeJsRpc(JavaScriptObject rpcMap, - String interfaceName, String methodName, JavaScriptObject parameters) - /*-{ - var targets = rpcMap[interfaceName]; - if (!targets) { - return; - } - for(var i = 0; i < targets.length; i++) { - var target = targets[i]; - if (methodName === null && typeof target === 'function') { - target.apply($wnd, parameters); - } else { - target[methodName].apply(target, parameters); - } - } - }-*/; - -} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java deleted file mode 100644 index 6c098a52f6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.terminal.gwt.client.ui.AbstractConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; - -@Connect(AbstractJavascriptExtension.class) -public class JavascriptExtension extends AbstractConnector implements - HasJavascriptConnectorHelper { - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this); - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 87bf27fc27..d3cb54160d 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -911,6 +911,22 @@ public class Util { } /** + * Find the element corresponding to the coordinates in the passed mouse + * event. Please note that this is not always the same as the target of the + * event e.g. if event capture is used. + * + * @param event + * the mouse event to get coordinates from + * @return the element at the coordinates of the event + */ + public static Element getElementUnderMouse(NativeEvent event) { + int pageX = getTouchOrMouseClientX(event); + int pageY = getTouchOrMouseClientY(event); + + return getElementFromPoint(pageX, pageY); + } + + /** * A helper method to return the client position from an event. Returns * position from either first changed touch (if touch event) or from the * event itself. diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index ecbfb0ecc9..3d7e838c62 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -5,7 +5,7 @@ package com.vaadin.terminal.gwt.client; import com.google.gwt.core.client.GWT; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; public class WidgetSet { @@ -54,8 +54,8 @@ public class WidgetSet { * let the auto generated code instantiate this type */ ServerConnector connector = widgetMap.instantiate(classType); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().setTag(tag); } return connector; diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java new file mode 100644 index 0000000000..a5191a5fed --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java @@ -0,0 +1,11 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.communication; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; + +public interface HasJavaScriptConnectorHelper { + public JavaScriptConnectorHelper getJavascriptConnectorHelper(); +} diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java deleted file mode 100644 index 74bc75da66..0000000000 --- a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java +++ /dev/null @@ -1,11 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.communication; - -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; - -public interface HasJavascriptConnectorHelper { - public JavascriptConnectorHelper getJavascriptConnectorHelper(); -} diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java index e0ffb40125..07d6292ce2 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java +++ b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java @@ -89,8 +89,8 @@ public class RpcManager { MethodInvocation invocation = new MethodInvocation(connectorId, interfaceName, methodName); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().invokeJsRpc(invocation, parametersJson); } else { diff --git a/src/com/vaadin/terminal/gwt/client/extensions/AbstractExtensionConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/AbstractExtensionConnector.java new file mode 100644 index 0000000000..bcefcf05cb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/AbstractExtensionConnector.java @@ -0,0 +1,27 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.extensions; + +import com.vaadin.terminal.gwt.client.ServerConnector; +import com.vaadin.terminal.gwt.client.ui.AbstractConnector; + +public abstract class AbstractExtensionConnector extends AbstractConnector { + @Override + public void setParent(ServerConnector parent) { + ServerConnector oldParent = getParent(); + if (oldParent != null && oldParent != parent) { + throw new IllegalStateException( + "An extension can not be moved from one parent to another."); + } + + super.setParent(parent); + + extend(parent); + } + + protected void extend(ServerConnector target) { + // Default does nothing + } +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/ExecuteJavaScriptRpc.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/ExecuteJavaScriptRpc.java new file mode 100644 index 0000000000..f1185586d5 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/ExecuteJavaScriptRpc.java @@ -0,0 +1,11 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; + +import com.vaadin.terminal.gwt.client.communication.ClientRpc; + +public interface ExecuteJavaScriptRpc extends ClientRpc { + public void executeJavaScript(String script); +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java new file mode 100644 index 0000000000..8656783a86 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java @@ -0,0 +1,119 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.json.client.JSONArray; +import com.vaadin.terminal.gwt.client.communication.MethodInvocation; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; +import com.vaadin.ui.JavaScript; + +@Connect(JavaScript.class) +public class JavaScriptManagerConnector extends AbstractExtensionConnector { + private Set<String> currentNames = new HashSet<String>(); + + @Override + protected void init() { + registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() { + public void executeJavaScript(String Script) { + eval(Script); + } + }); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + + Set<String> newNames = getState().getNames(); + + // Current names now only contains orphan callbacks + currentNames.removeAll(newNames); + + for (String name : currentNames) { + removeCallback(name); + } + + currentNames = new HashSet<String>(newNames); + for (String name : newNames) { + addCallback(name); + } + } + + // TODO Ensure we don't overwrite anything (important) in $wnd + private native void addCallback(String name) + /*-{ + var m = this; + var target = $wnd; + var parts = name.split('.'); + + for(var i = 0; i < parts.length - 1; i++) { + var part = parts[i]; + if (target[part] === undefined) { + target[part] = {}; + } + target = target[part]; + } + + target[parts[parts.length - 1]] = $entry(function() { + //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding + var args = Array.prototype.slice.call(arguments, 0); + m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); + }); + }-*/; + + // TODO only remove what we actually added + // TODO We might leave empty objects behind, but there's no good way of + // knowing whether they are unused + private native void removeCallback(String name) + /*-{ + var target = $wnd; + var parts = name.split('.'); + + for(var i = 0; i < parts.length - 1; i++) { + var part = parts[i]; + if (target[part] === undefined) { + $wnd.console.log(part,'not defined in',target); + // No longer attached -> nothing more to do + return; + } + target = target[part]; + } + + $wnd.console.log('removing',parts[parts.length - 1],'from',target); + delete target[parts[parts.length - 1]]; + }-*/; + + private static native void eval(String script) + /*-{ + if(script) { + (new $wnd.Function(script)).apply($wnd); + } + }-*/; + + public void sendRpc(String name, JsArray<JavaScriptObject> arguments) { + Object[] parameters = new Object[] { name, new JSONArray(arguments) }; + + /* + * Must invoke manually as the RPC interface can't be used in GWT + * because of the JSONArray parameter + */ + getConnection().addMethodInvocationToQueue( + new MethodInvocation(getConnectorId(), + "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc", + "call", parameters), true); + } + + @Override + public JavaScriptManagerState getState() { + return (JavaScriptManagerState) super.getState(); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java index 77794ffdca..fc246aff04 100644 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java @@ -9,7 +9,7 @@ import java.util.Set; import com.vaadin.terminal.gwt.client.communication.SharedState; -public class JavascriptManagerState extends SharedState { +public class JavaScriptManagerState extends SharedState { private Set<String> names = new HashSet<String>(); public Set<String> getNames() { diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java deleted file mode 100644 index 979a6d22c4..0000000000 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java +++ /dev/null @@ -1,78 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; - -import java.util.HashSet; -import java.util.Set; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.json.client.JSONArray; -import com.vaadin.terminal.gwt.client.communication.MethodInvocation; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.terminal.gwt.client.ui.AbstractConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; -import com.vaadin.ui.JavascriptManager; - -@Connect(JavascriptManager.class) -public class JavascriptManagerConnector extends AbstractConnector { - private Set<String> currentNames = new HashSet<String>(); - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - - Set<String> newNames = getState().getNames(); - - // Current names now only contains orphan callbacks - currentNames.removeAll(newNames); - - for (String name : currentNames) { - removeCallback(name); - } - - currentNames = new HashSet<String>(newNames); - for (String name : newNames) { - addCallback(name); - } - } - - // TODO Ensure we don't overwrite anything (important) in $wnd - private native void addCallback(String name) - /*-{ - var m = this; - $wnd[name] = $entry(function() { - //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding - var args = Array.prototype.slice.call(arguments, 0); - m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); - }); - }-*/; - - // TODO only remove what we actually added - private native void removeCallback(String name) - /*-{ - delete $wnd[name]; - }-*/; - - public void sendRpc(String name, JsArray<JavaScriptObject> arguments) { - Object[] parameters = new Object[] { name, new JSONArray(arguments) }; - - /* - * Must invoke manually as the RPC interface can't be used in GWT - * because of the JSONArray parameter - */ - getConnection() - .addMethodInvocationToQueue( - new MethodInvocation( - getConnectorId(), - "com.vaadin.ui.JavascriptManager$JavascriptCallbackRpc", - "call", parameters), true); - } - - @Override - public JavascriptManagerState getState() { - return (JavascriptManagerState) super.getState(); - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractClickEventHandler.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractClickEventHandler.java index 31204aa0c6..e0ca798682 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/AbstractClickEventHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractClickEventHandler.java @@ -3,29 +3,76 @@ */ package com.vaadin.terminal.gwt.client.ui; +import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.ContextMenuEvent; import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DoubleClickHandler; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Event.NativePreviewEvent; +import com.google.gwt.user.client.Event.NativePreviewHandler; import com.vaadin.terminal.gwt.client.ComponentConnector; +import com.vaadin.terminal.gwt.client.Util; -public abstract class AbstractClickEventHandler implements DoubleClickHandler, - ContextMenuHandler, MouseUpHandler { +public abstract class AbstractClickEventHandler implements MouseDownHandler, + MouseUpHandler, DoubleClickHandler, ContextMenuHandler { - private HandlerRegistration doubleClickHandlerRegistration; + private HandlerRegistration mouseDownHandlerRegistration; private HandlerRegistration mouseUpHandlerRegistration; + private HandlerRegistration doubleClickHandlerRegistration; private HandlerRegistration contextMenuHandlerRegistration; protected ComponentConnector connector; private String clickEventIdentifier; + /** + * The element where the last mouse down event was registered. + */ + private JavaScriptObject lastMouseDownTarget; + + /** + * Set to true by {@link #mouseUpPreviewHandler} if it gets a mouseup at the + * same element as {@link #lastMouseDownTarget}. + */ + private boolean mouseUpPreviewMatched = false; + + private HandlerRegistration mouseUpEventPreviewRegistration; + + /** + * Previews events after a mousedown to detect where the following mouseup + * hits. + */ + private final NativePreviewHandler mouseUpPreviewHandler = new NativePreviewHandler() { + + public void onPreviewNativeEvent(NativePreviewEvent event) { + if (event.getTypeInt() == Event.ONMOUSEUP) { + mouseUpEventPreviewRegistration.removeHandler(); + + // Event's reported target not always correct if event + // capture is in use + Element elementUnderMouse = Util.getElementUnderMouse(event + .getNativeEvent()); + if (lastMouseDownTarget != null + && elementUnderMouse.cast() == lastMouseDownTarget) { + mouseUpPreviewMatched = true; + } else { + System.out.println("Ignoring mouseup from " + + elementUnderMouse + " when mousedown was on " + + lastMouseDownTarget); + } + } + } + }; + public AbstractClickEventHandler(ComponentConnector connector, String clickEventIdentifier) { this.connector = connector; @@ -36,25 +83,28 @@ public abstract class AbstractClickEventHandler implements DoubleClickHandler, // Handle registering/unregistering of click handler depending on if // server side listeners have been added or removed. if (hasEventListener()) { - if (mouseUpHandlerRegistration == null) { + if (mouseDownHandlerRegistration == null) { + mouseDownHandlerRegistration = registerHandler(this, + MouseDownEvent.getType()); mouseUpHandlerRegistration = registerHandler(this, MouseUpEvent.getType()); - contextMenuHandlerRegistration = registerHandler(this, - ContextMenuEvent.getType()); doubleClickHandlerRegistration = registerHandler(this, DoubleClickEvent.getType()); + contextMenuHandlerRegistration = registerHandler(this, + ContextMenuEvent.getType()); } } else { - if (mouseUpHandlerRegistration != null) { + if (mouseDownHandlerRegistration != null) { // Remove existing handlers - doubleClickHandlerRegistration.removeHandler(); + mouseDownHandlerRegistration.removeHandler(); mouseUpHandlerRegistration.removeHandler(); + doubleClickHandlerRegistration.removeHandler(); contextMenuHandlerRegistration.removeHandler(); - contextMenuHandlerRegistration = null; + mouseDownHandlerRegistration = null; mouseUpHandlerRegistration = null; doubleClickHandlerRegistration = null; - + contextMenuHandlerRegistration = null; } } @@ -93,6 +143,7 @@ public abstract class AbstractClickEventHandler implements DoubleClickHandler, * Event handler for context menu. Prevents the browser context menu from * popping up if there is a listener for right clicks. */ + public void onContextMenu(ContextMenuEvent event) { if (hasEventListener() && shouldFireEvent(event)) { // Prevent showing the browser's context menu when there is a right @@ -101,18 +152,34 @@ public abstract class AbstractClickEventHandler implements DoubleClickHandler, } } - /** - * Event handler for mouse up. This is used to detect all single click - * events. - */ + public void onMouseDown(MouseDownEvent event) { + /* + * When getting a mousedown event, we must detect where the + * corresponding mouseup event if it's on a different part of the page. + */ + lastMouseDownTarget = event.getNativeEvent().getEventTarget(); + mouseUpPreviewMatched = false; + mouseUpEventPreviewRegistration = Event + .addNativePreviewHandler(mouseUpPreviewHandler); + } + public void onMouseUp(MouseUpEvent event) { - // TODO For perfect accuracy we should check that a mousedown has - // occured on this element before this mouseup and that no mouseup - // has occured anywhere after that. - if (hasEventListener() && shouldFireEvent(event)) { + /* + * Only fire a click if the mouseup hits the same element as the + * corresponding mousedown. This is first checked in the event preview + * but we can't fire the even there as the event might get canceled + * before it gets here. + */ + if (hasEventListener() + && mouseUpPreviewMatched + && lastMouseDownTarget != null + && Util.getElementUnderMouse(event.getNativeEvent()) == lastMouseDownTarget + && shouldFireEvent(event)) { // "Click" with left, right or middle button fireClick(event.getNativeEvent()); } + mouseUpPreviewMatched = false; + lastMouseDownTarget = null; } /** @@ -140,6 +207,7 @@ public abstract class AbstractClickEventHandler implements DoubleClickHandler, * that browsers typically fail to prevent the second click event so a * double click will result in two click events and one double click event. */ + public void onDoubleClick(DoubleClickEvent event) { if (hasEventListener() && shouldFireEvent(event)) { fireClick(event.getNativeEvent()); diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java index 67dbd2d9d9..f0b9d518ca 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java @@ -131,7 +131,22 @@ public abstract class AbstractComponentConnector extends AbstractConnector public void setWidgetEnabled(boolean widgetEnabled) { if (getWidget() instanceof HasEnabled) { + // set widget specific enabled state ((HasEnabled) getWidget()).setEnabled(widgetEnabled); + // add or remove v-disabled style name from the widget + getWidget().setStyleName(ApplicationConnection.DISABLED_CLASSNAME, + !widgetEnabled); + // make sure the caption has or has not v-disabled style + if (delegateCaptionHandling()) { + ServerConnector parent = getParent(); + if (parent instanceof ComponentContainerConnector) { + ((ComponentContainerConnector) parent).updateCaption(this); + } else if (parent == null && !(this instanceof RootConnector)) { + VConsole.error("Parent of connector " + + Util.getConnectorString(this) + + " is null. This is typically an indication of a broken component hierarchy"); + } + } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java index cffdb1e68a..758f798ef2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java +++ b/src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java @@ -28,6 +28,7 @@ public abstract class ClickEventHandler extends AbstractClickEventHandler { * @param event * The native event that caused this click event */ + @Override protected void fireClick(NativeEvent event) { MouseEventDetails mouseDetails = MouseEventDetailsBuilder .buildMouseEventDetails(event, getRelativeToElement()); diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java index 62697c4d98..ef1ea8521b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java @@ -34,8 +34,8 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements public FocusableScrollPanel() { // Prevent IE standard mode bug when a AbsolutePanel is contained. + TouchScrollDelegate.enableTouchScrolling(this, getElement()); Style style = getElement().getStyle(); - style.setOverflow(Overflow.AUTO); style.setProperty("zoom", "1"); style.setPosition(Position.RELATIVE); } @@ -153,7 +153,8 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * the new vertical scroll position, in pixels */ public void setScrollPosition(int position) { - if (BrowserInfo.get().isAndroidWithBrokenScrollTop()) { + if (BrowserInfo.get().isAndroidWithBrokenScrollTop() + && BrowserInfo.get().requiresTouchScrollDelegate()) { ArrayList<com.google.gwt.dom.client.Element> elements = TouchScrollDelegate .getElements(getElement()); for (com.google.gwt.dom.client.Element el : elements) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java new file mode 100644 index 0000000000..bb062a6677 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -0,0 +1,42 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.ui.AbstractJavaScriptComponent; + +@Connect(AbstractJavaScriptComponent.class) +public final class JavaScriptComponentConnector extends + AbstractComponentConnector implements HasJavaScriptConnectorHelper { + + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this) { + @Override + protected void showInitProblem( + java.util.ArrayList<String> attemptedNames) { + getWidget().showNoInitFound(attemptedNames); + } + }; + + @Override + public JavaScriptWidget getWidget() { + return (JavaScriptWidget) super.getWidget(); + } + + @Override + protected void init() { + super.init(); + helper.init(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } + + @Override + public JavaScriptComponentState getState() { + return (JavaScriptComponentState) super.getState(); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java new file mode 100644 index 0000000000..6728f85ec9 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java @@ -0,0 +1,37 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; + +public class JavaScriptComponentState extends ComponentState implements + JavaScriptConnectorState { + + private Set<String> callbackNames = new HashSet<String>(); + private Map<String, Set<String>> rpcInterfaces = new HashMap<String, Set<String>>(); + + public Set<String> getCallbackNames() { + return callbackNames; + } + + public void setCallbackNames(Set<String> callbackNames) { + this.callbackNames = callbackNames; + } + + public Map<String, Set<String>> getRpcInterfaces() { + return rpcInterfaces; + } + + public void setRpcInterfaces(Map<String, Set<String>> rpcInterfaces) { + this.rpcInterfaces = rpcInterfaces; + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java index 93a4417b1c..e6c3323893 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java @@ -8,13 +8,13 @@ import java.util.ArrayList; import com.google.gwt.dom.client.Document; import com.google.gwt.user.client.ui.Widget; -public class JavascriptWidget extends Widget { - public JavascriptWidget() { +public class JavaScriptWidget extends Widget { + public JavaScriptWidget() { setElement(Document.get().createDivElement()); } public void showNoInitFound(ArrayList<String> attemptedNames) { - String message = "Could not initialize JavascriptConnector because no javascript init function was found. Make sure one of these functions are defined: <ul>"; + String message = "Could not initialize JavaScriptConnector because no JavaScript init function was found. Make sure one of these functions are defined: <ul>"; for (String name : attemptedNames) { message += "<li>" + name + "</li>"; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java deleted file mode 100644 index 57e65e91c6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.user.client.Element; -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.ui.AbstractJavascriptComponent; - -@Connect(AbstractJavascriptComponent.class) -public class JavascriptComponentConnector extends AbstractComponentConnector - implements HasJavascriptConnectorHelper { - - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this) { - @Override - protected void showInitProblem( - java.util.ArrayList<String> attemptedNames) { - getWidget().showNoInitFound(attemptedNames); - } - - @Override - protected JavaScriptObject createConnectorWrapper() { - JavaScriptObject connectorWrapper = super.createConnectorWrapper(); - addGetWidgetElement(connectorWrapper, getWidget().getElement()); - return connectorWrapper; - } - }; - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - private static native void addGetWidgetElement( - JavaScriptObject connectorWrapper, Element element) - /*-{ - connectorWrapper.getWidgetElement = function() { - return element; - }; - }-*/; - - @Override - public JavascriptWidget getWidget() { - return (JavascriptWidget) super.getWidget(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java index 8b2248aff6..7302f9f2ac 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java @@ -4,6 +4,8 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.Duration; @@ -15,10 +17,12 @@ import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.dom.client.TouchStartEvent; +import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.VConsole; @@ -68,7 +72,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { private static final double DECELERATION = 0.002; private static final int MAX_DURATION = 1500; private int origY; - private Element[] scrollableElements; + private HashSet<Element> scrollableElements; private Element scrolledElement; private int origScrollTop; private HandlerRegistration handlerRegistration; @@ -86,8 +90,107 @@ public class TouchScrollDelegate implements NativePreviewHandler { private static final boolean androidWithBrokenScrollTop = BrowserInfo.get() .isAndroidWithBrokenScrollTop(); + /** + * A helper class for making a widget scrollable. Uses native scrolling if + * supported by the browser, otherwise registers a touch start handler + * delegating to a TouchScrollDelegate instance. + */ + public static class TouchScrollHandler implements TouchStartHandler { + + private static final String SCROLLABLE_CLASSNAME = "v-scrollable"; + + private final TouchScrollDelegate delegate; + private final boolean requiresDelegate = BrowserInfo.get() + .requiresTouchScrollDelegate(); + + /** + * Constructs a scroll handler for the given widget. + * + * @param widget + * The widget that contains scrollable elements + * @param scrollables + * The elements of the widget that should be scrollable. + */ + public TouchScrollHandler(Widget widget, Element... scrollables) { + if (requiresDelegate) { + delegate = new TouchScrollDelegate(); + widget.addDomHandler(this, TouchStartEvent.getType()); + } else { + delegate = null; + } + setElements(scrollables); + } + + public void onTouchStart(TouchStartEvent event) { + assert delegate != null; + delegate.onTouchStart(event); + } + + public void debug(Element e) { + VConsole.log("Classes: " + e.getClassName() + " overflow: " + + e.getStyle().getProperty("overflow") + " w-o-s: " + + e.getStyle().getProperty("WebkitOverflowScrolling")); + } + + /** + * Registers the given element as scrollable. + */ + public void addElement(Element scrollable) { + scrollable.addClassName(SCROLLABLE_CLASSNAME); + if (requiresDelegate) { + delegate.scrollableElements.add(scrollable); + } + } + + /** + * Unregisters the given element as scrollable. Should be called when a + * previously-registered element is removed from the DOM to prevent + * memory leaks. + */ + public void removeElement(Element scrollable) { + scrollable.removeClassName(SCROLLABLE_CLASSNAME); + if (requiresDelegate) { + delegate.scrollableElements.remove(scrollable); + } + } + + /** + * Registers the given elements as scrollable, removing previously + * registered scrollables from this handler. + * + * @param scrollables + * The elements that should be scrollable + */ + public void setElements(Element... scrollables) { + if (requiresDelegate) { + for (Element e : delegate.scrollableElements) { + e.removeClassName(SCROLLABLE_CLASSNAME); + } + delegate.scrollableElements.clear(); + } + for (Element e : scrollables) { + addElement(e); + } + } + } + + /** + * Makes the given elements scrollable, either natively or by using a + * TouchScrollDelegate, depending on platform capabilities. + * + * @param widget + * The widget that contains scrollable elements + * @param scrollables + * The elements inside the widget that should be scrollable + * @return A scroll handler for the given widget. + */ + public static TouchScrollHandler enableTouchScrolling(Widget widget, + Element... scrollables) { + return new TouchScrollHandler(widget, scrollables); + } + public TouchScrollDelegate(Element... elements) { - scrollableElements = elements; + setElements(elements); } public void setScrollHandler(ScrollHandler scrollHandler) { @@ -535,8 +638,8 @@ public class TouchScrollDelegate implements NativePreviewHandler { } } - public void setElements(com.google.gwt.user.client.Element[] elements) { - scrollableElements = elements; + public void setElements(Element[] elements) { + scrollableElements = new HashSet<Element>(Arrays.asList(elements)); } /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java index dcd520bbb3..b83d5afb00 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java +++ b/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java @@ -20,6 +20,8 @@ import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VCaption; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler; import com.vaadin.terminal.gwt.client.ui.tabsheet.TabsheetBaseConnector; import com.vaadin.terminal.gwt.client.ui.tabsheet.VTabsheetBase; @@ -35,8 +37,11 @@ public class VAccordion extends VTabsheetBase { int selectedUIDLItemIndex = -1; + private final TouchScrollHandler touchScrollHandler; + public VAccordion() { super(CLASSNAME); + touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); } @Override @@ -145,7 +150,6 @@ public class VAccordion extends VTabsheetBase { } } } - if (!alreadyOpen) { item.open(); activeTabIndex = itemIndex; @@ -342,11 +346,13 @@ public class VAccordion extends VTabsheetBase { DOM.appendChild(captionNode, caption.getElement()); DOM.appendChild(getElement(), captionNode); DOM.appendChild(getElement(), content); - setStyleName(CLASSNAME + "-item"); - DOM.setElementProperty(content, "className", CLASSNAME - + "-item-content"); - DOM.setElementProperty(captionNode, "className", CLASSNAME - + "-item-caption"); + + getElement().addClassName(CLASSNAME + "-item"); + captionNode.addClassName(CLASSNAME + "-item-caption"); + content.addClassName(CLASSNAME + "-item-content"); + + touchScrollHandler.addElement(getContainerElement()); + close(); } @@ -488,6 +494,7 @@ public class VAccordion extends VTabsheetBase { protected void removeTab(int index) { StackItem item = getStackItem(index); remove(item); + touchScrollHandler.removeElement(item.getContainerElement()); } @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java index e5e7dbba8b..0cd8bc54f4 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java @@ -10,6 +10,7 @@ import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Accessibility; @@ -61,7 +62,9 @@ public class VButton extends FocusWidget implements ClickHandler { private boolean isCapturing; /** - * If <code>true</code>, this widget has focus with the space bar down. + * If <code>true</code>, this widget has focus with the space bar down. This + * means that we will get events when the button is released, but we should + * trigger the button only if the button is still focused at that point. */ private boolean isFocusing; @@ -74,6 +77,14 @@ public class VButton extends FocusWidget implements ClickHandler { protected int clickShortcut = 0; + private HandlerRegistration focusHandlerRegistration; + private HandlerRegistration blurHandlerRegistration; + + /** + * If caption should be rendered in HTML + */ + protected boolean htmlCaption = false; + public VButton() { super(DOM.createDiv()); setTabIndex(0); @@ -229,37 +240,28 @@ public class VButton extends FocusWidget implements ClickHandler { if ((event.getTypeInt() & Event.KEYEVENTS) != 0) { switch (type) { case Event.ONKEYDOWN: + // Stop propagation when the user starts pressing a button that + // we are handling to prevent actions from getting triggered if (event.getKeyCode() == 32 /* space */) { isFocusing = true; event.preventDefault(); + event.stopPropagation(); + } else if (event.getKeyCode() == KeyCodes.KEY_ENTER) { + event.stopPropagation(); } break; case Event.ONKEYUP: if (isFocusing && event.getKeyCode() == 32 /* space */) { isFocusing = false; - - /* - * If click shortcut is space then the shortcut handler will - * take care of the click. - */ - if (clickShortcut != 32 /* space */) { - onClick(); - } - + onClick(); + event.stopPropagation(); event.preventDefault(); } break; case Event.ONKEYPRESS: if (event.getKeyCode() == KeyCodes.KEY_ENTER) { - - /* - * If click shortcut is enter then the shortcut handler will - * take care of the click. - */ - if (clickShortcut != KeyCodes.KEY_ENTER) { - onClick(); - } - + onClick(); + event.stopPropagation(); event.preventDefault(); } break; @@ -336,12 +338,10 @@ public class VButton extends FocusWidget implements ClickHandler { Accessibility.removeState(getElement(), Accessibility.STATE_PRESSED); super.setTabIndex(-1); - addStyleName(ApplicationConnection.DISABLED_CLASSNAME); } else { Accessibility.setState(getElement(), Accessibility.STATE_PRESSED, "false"); super.setTabIndex(tabIndex); - removeStyleName(ApplicationConnection.DISABLED_CLASSNAME); } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/combobox/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/combobox/VFilterSelect.java index d29eda0d6a..8c5d521445 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/combobox/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/combobox/VFilterSelect.java @@ -69,7 +69,8 @@ import com.vaadin.terminal.gwt.client.ui.menubar.MenuItem; */ @SuppressWarnings("deprecation") public class VFilterSelect extends Composite implements Field, KeyDownHandler, - KeyUpHandler, ClickHandler, FocusHandler, BlurHandler, Focusable { + KeyUpHandler, ClickHandler, FocusHandler, BlurHandler, Focusable, + SubPartAware { /** * Represents a suggestion in the suggestion popup box @@ -100,6 +101,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * contains an image tag with the rows icon (if an icon has been * specified) and the caption of the item */ + public String getDisplayString() { final StringBuffer sb = new StringBuffer(); if (iconUri != null) { @@ -122,6 +124,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Get a string that represents this item. This is used in the text box. */ + public String getReplacementString() { return caption; } @@ -147,6 +150,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Executes a selection of this item. */ + public void execute() { onSuggestionSelected(this); } @@ -392,6 +396,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt * .user.client.Event) */ + @Override public void onBrowserEvent(Event event) { if (event.getTypeInt() == Event.ONCLICK) { @@ -449,6 +454,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.user.client.ui.PopupPanel$PositionCallback#setPosition * (int, int) */ + public void setPosition(int offsetWidth, int offsetHeight) { int top = -1; @@ -541,6 +547,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google * .gwt.event.logical.shared.CloseEvent) */ + @Override public void onClose(CloseEvent<PopupPanel> event) { if (event.isAutoClosed()) { @@ -824,6 +831,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.user.client.ui.TextBoxBase#onBrowserEvent(com.google * .gwt.user.client.Event) */ + @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -832,8 +840,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } } - @Override // Overridden to avoid selecting text when text input is disabled + @Override public void setSelectionRange(int pos, int length) { if (textInputEnabled) { super.setSelectionRange(pos, length); @@ -857,6 +865,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt * .user.client.Event) */ + @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -951,6 +960,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, public VFilterSelect() { selectedItemIcon.setStyleName("v-icon"); selectedItemIcon.addLoadHandler(new LoadHandler() { + public void onLoad(LoadEvent event) { if (BrowserInfo.get().isIE8()) { // IE8 needs some help to discover it should reposition the @@ -1203,6 +1213,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt * .event.dom.client.KeyDownEvent) */ + public void onKeyDown(KeyDownEvent event) { if (enabled && !readonly) { int keyCode = event.getNativeKeyCode(); @@ -1364,6 +1375,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * @param event * The KeyUpEvent of the key depressed */ + public void onKeyUp(KeyUpEvent event) { if (enabled && !readonly) { switch (event.getNativeKeyCode()) { @@ -1411,6 +1423,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Listener for popupopener */ + public void onClick(ClickEvent event) { if (textInputEnabled && event.getNativeEvent().getEventTarget().cast() == tb @@ -1474,6 +1487,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event * .dom.client.FocusEvent) */ + public void onFocus(FocusEvent event) { /* @@ -1567,6 +1581,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * * @see com.vaadin.terminal.gwt.client.Focusable#focus() */ + public void focus() { focused = true; if (prompting && !readonly) { @@ -1674,4 +1689,22 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, super.onDetach(); suggestionPopup.hide(); } + + public Element getSubPartElement(String subPart) { + if ("textbox".equals(subPart)) { + return this.tb.getElement(); + } else if ("button".equals(subPart)) { + return this.popupOpener.getElement(); + } + return null; + } + + public String getSubPartName(Element subElement) { + if (tb.getElement().isOrHasChild(subElement)) { + return "textbox"; + } else if (popupOpener.getElement().isOrHasChild(subElement)) { + return "button"; + } + return null; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java new file mode 100644 index 0000000000..32dac10170 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptCriterion.java @@ -0,0 +1,33 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui.dd; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation type used to point the server side counterpart for client side + * a {@link VAcceptCriterion} class. + * <p> + * Annotations are used at GWT compilation phase, so remember to rebuild your + * widgetset if you do changes for {@link AcceptCriterion} mappings. + * + * Prior to Vaadin 7, the mapping was done with an annotation on server side + * classes. + * + * @since 7.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface AcceptCriterion { + /** + * @return the fully qualified class name of the server side counterpart for + * the annotated criterion + */ + String value(); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java b/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java index 02c1fe5061..97f5eb86fd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/DDUtil.java @@ -5,6 +5,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Window; import com.vaadin.terminal.gwt.client.Util; public class DDUtil { @@ -43,8 +44,11 @@ public class DDUtil { public static VerticalDropLocation getVerticalDropLocation(Element element, int offsetHeight, int clientY, double topBottomRatio) { - int absoluteTop = element.getAbsoluteTop(); - int fromTop = clientY - absoluteTop; + // Event coordinates are relative to the viewport, element absolute + // position is relative to the document. Make element position relative + // to viewport by adjusting for viewport scrolling. See #6021 + int elementTop = element.getAbsoluteTop() - Window.getScrollTop(); + int fromTop = clientY - elementTop; float percentageFromTop = (fromTop / (float) offsetHeight); if (percentageFromTop < topBottomRatio) { @@ -74,14 +78,17 @@ public class DDUtil { public static HorizontalDropLocation getHorizontalDropLocation( Element element, int clientX, double leftRightRatio) { - int absoluteLeft = element.getAbsoluteLeft(); + // Event coordinates are relative to the viewport, element absolute + // position is relative to the document. Make element position relative + // to viewport by adjusting for viewport scrolling. See #6021 + int elementLeft = element.getAbsoluteLeft() - Window.getScrollLeft(); int offsetWidth = element.getOffsetWidth(); - int fromTop = clientX - absoluteLeft; + int fromLeft = clientX - elementLeft; - float percentageFromTop = (fromTop / (float) offsetWidth); - if (percentageFromTop < leftRightRatio) { + float percentageFromLeft = (fromLeft / (float) offsetWidth); + if (percentageFromLeft < leftRightRatio) { return HorizontalDropLocation.LEFT; - } else if (percentageFromTop > 1 - leftRightRatio) { + } else if (percentageFromLeft > 1 - leftRightRatio) { return HorizontalDropLocation.RIGHT; } else { return HorizontalDropLocation.CENTER; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptAll.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptAll.java index 51782c002d..07e931fb02 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptAll.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptAll.java @@ -8,6 +8,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.AcceptAll") final public class VAcceptAll extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAnd.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAnd.java index 65c67e6b8a..727c30075c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAnd.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAnd.java @@ -8,6 +8,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.And") final public class VAnd extends VAcceptCriterion implements VAcceptCallback { private boolean b1; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VContainsDataFlavor.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VContainsDataFlavor.java index 4a95034d4a..5786068174 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VContainsDataFlavor.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VContainsDataFlavor.java @@ -8,6 +8,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor") final public class VContainsDataFlavor extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java index aabbf58b24..58550af918 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragSourceIs.java @@ -12,6 +12,7 @@ import com.vaadin.terminal.gwt.client.UIDL; * * @since 6.3 */ +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.SourceIs") final public class VDragSourceIs extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java index 90e2b033c9..3fc54e6fd3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VIsOverId.java @@ -10,6 +10,7 @@ import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.ui.AbstractSelect.TargetItemIs") final public class VIsOverId extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java index eb55c1a91c..5f1fe978b5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VItemIdIs.java @@ -9,6 +9,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.ui.AbstractSelect.AcceptItem") final public class VItemIdIs extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VLazyInitItemIdentifiers.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VLazyInitItemIdentifiers.java index b824c1cb65..e972371b9f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VLazyInitItemIdentifiers.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VLazyInitItemIdentifiers.java @@ -13,11 +13,23 @@ import com.vaadin.terminal.gwt.client.UIDL; /** * */ -final public class VLazyInitItemIdentifiers extends VAcceptCriterion { +public class VLazyInitItemIdentifiers extends VAcceptCriterion { private boolean loaded = false; private HashSet<String> hashSet; private VDragEvent lastDragEvent; + @AcceptCriterion("com.vaadin.ui.Table.TableDropCriterion") + final public static class VTableLazyInitItemIdentifiers extends + VLazyInitItemIdentifiers { + // all logic in superclass + } + + @AcceptCriterion("com.vaadin.ui.Tree.TreeDropCriterion") + final public static class VTreeLazyInitItemIdentifiers extends + VLazyInitItemIdentifiers { + // all logic in superclass + } + @Override public void accept(final VDragEvent drag, UIDL configuration, final VAcceptCallback callback) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VNot.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VNot.java index f4ba868497..e91ad6149a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VNot.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VNot.java @@ -13,6 +13,7 @@ import com.vaadin.terminal.gwt.client.VConsole; * TODO implementation could now be simplified/optimized * */ +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.Not") final public class VNot extends VAcceptCriterion { private boolean b1; private VAcceptCriterion crit1; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VOr.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VOr.java index e47447b7fc..3664326568 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VOr.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VOr.java @@ -11,6 +11,7 @@ import com.vaadin.terminal.gwt.client.UIDL; /** * */ +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.Or") final public class VOr extends VAcceptCriterion implements VAcceptCallback { private boolean accepted; diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VServerAccept.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VServerAccept.java index bccb6656aa..e679b64369 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VServerAccept.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VServerAccept.java @@ -8,6 +8,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.ServerSideCriterion") final public class VServerAccept extends VAcceptCriterion { @Override public void accept(final VDragEvent drag, UIDL configuration, diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java index 430b422b34..9bbabe9d29 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VSourceIsTarget.java @@ -9,6 +9,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.SourceIsTarget") final public class VSourceIsTarget extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetDetailIs.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetDetailIs.java index 713a0d6646..7d92359f7d 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetDetailIs.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetDetailIs.java @@ -8,6 +8,7 @@ package com.vaadin.terminal.gwt.client.ui.dd; import com.vaadin.terminal.gwt.client.UIDL; +@AcceptCriterion("com.vaadin.event.dd.acceptcriteria.TargetDetailIs") final public class VTargetDetailIs extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetInSubtree.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetInSubtree.java index f69fa85290..3db44f3162 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetInSubtree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VTargetInSubtree.java @@ -11,6 +11,7 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.ui.tree.VTree; import com.vaadin.terminal.gwt.client.ui.tree.VTree.TreeNode; +@AcceptCriterion("com.vaadin.ui.Tree.TargetInSubtree") final public class VTargetInSubtree extends VAcceptCriterion { @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/DragAndDropWrapperConnector.java b/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/DragAndDropWrapperConnector.java index 57f6835bcc..2a78cc4433 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/DragAndDropWrapperConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/DragAndDropWrapperConnector.java @@ -57,6 +57,9 @@ public class DragAndDropWrapperConnector extends CustomComponentConnector getWidget().initDragStartMode(); getWidget().html5DataFlavors = uidl .getMapAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS); + + // Used to prevent wrapper from stealing tooltips when not defined + getWidget().hasTooltip = getState().hasDescription(); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/VDragAndDropWrapper.java index d09b81e1e1..4c36e92bbb 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/draganddropwrapper/VDragAndDropWrapper.java @@ -60,6 +60,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements private static final String CLASSNAME = "v-ddwrapper"; protected static final String DRAGGABLE = "draggable"; + boolean hasTooltip = false; + public VDragAndDropWrapper() { super(); sinkEvents(VTooltip.TOOLTIP_EVENTS); @@ -67,6 +69,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements hookHtml5Events(getElement()); setStyleName(CLASSNAME); addDomHandler(new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { if (startDrag(event.getNativeEvent())) { event.preventDefault(); // prevent text selection @@ -75,6 +78,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements }, MouseDownEvent.getType()); addDomHandler(new TouchStartHandler() { + public void onTouchStart(TouchStartEvent event) { if (startDrag(event.getNativeEvent())) { /* @@ -92,7 +96,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements public void onBrowserEvent(Event event) { super.onBrowserEvent(event); - if (client != null) { + if (hasTooltip && client != null) { + // Override child tooltips if the wrapper has a tooltip defined client.handleTooltipEvent(event, this); } } @@ -172,6 +177,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements private boolean uploading; private ReadyStateChangeHandler readyStateChangeHandler = new ReadyStateChangeHandler() { + public void onReadyStateChange(XMLHttpRequest xhr) { if (xhr.getReadyState() == XMLHttpRequest.DONE) { // visit server for possible @@ -269,6 +275,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements try { dragleavetimer = new Timer() { + @Override public void run() { // Yes, dragleave happens before drop. Makes no sense to me. @@ -455,6 +462,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements if (detailsChanged) { currentlyValid = false; validate(new VAcceptCallback() { + public void accepted(VDragEvent event) { dragAccepted(drag); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/form/VForm.java b/src/com/vaadin/terminal/gwt/client/ui/form/VForm.java index e3a0c9b321..81f24a8e7e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/form/VForm.java +++ b/src/com/vaadin/terminal/gwt/client/ui/form/VForm.java @@ -4,7 +4,6 @@ package com.vaadin.terminal.gwt.client.ui.form; -import com.google.gwt.dom.client.Style.Display; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.shared.HandlerRegistration; @@ -27,7 +26,6 @@ public class VForm extends ComplexPanel implements KeyDownHandler { Widget lo; Element legend = DOM.createLegend(); Element caption = DOM.createSpan(); - private Element errorIndicatorElement = DOM.createDiv(); Element desc = DOM.createDiv(); Icon icon; VErrorMessage errorMessage = new VErrorMessage(); @@ -52,9 +50,6 @@ public class VForm extends ComplexPanel implements KeyDownHandler { setStyleName(CLASSNAME); fieldSet.appendChild(legend); legend.appendChild(caption); - errorIndicatorElement.setClassName("v-errorindicator"); - errorIndicatorElement.getStyle().setDisplay(Display.NONE); - errorIndicatorElement.setInnerText(" "); // needed for IE desc.setClassName("v-form-description"); fieldSet.appendChild(desc); // Adding description for initial padding // measurements, removed later if no diff --git a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java index 01ac4fab6a..dd6e741126 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/nativebutton/VNativeButton.java @@ -127,11 +127,4 @@ public class VNativeButton extends Button implements ClickHandler { clickPending = false; } - @Override - public void setEnabled(boolean enabled) { - if (isEnabled() != enabled) { - super.setEnabled(enabled); - setStyleName(ApplicationConnection.DISABLED_CLASSNAME, !enabled); - } - } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java b/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java index 0d222044ba..fb853b8a55 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java +++ b/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java @@ -43,6 +43,8 @@ public class VNotification extends VOverlay { public static final String STYLE_SYSTEM = "system"; private static final int FADE_ANIMATION_INTERVAL = 50; // == 20 fps + private static final ArrayList<VNotification> notifications = new ArrayList<VNotification>(); + private int startOpacity = 90; private int fadeMsec = 400; private int delayMsec = 1000; @@ -159,6 +161,7 @@ public class VNotification extends VOverlay { addStyleDependentName(style); } super.show(); + notifications.add(this); setPosition(position); /** * Android 4 fails to render notifications correctly without a little @@ -180,6 +183,7 @@ public class VNotification extends VOverlay { temporaryStyle = null; } super.hide(); + notifications.remove(this); fireEvent(new HideEvent(this)); } @@ -435,4 +439,19 @@ public class VNotification extends VOverlay { public interface EventListener extends java.util.EventListener { public void notificationHidden(HideEvent event); } + + /** + * Moves currently visible notifications to the top of the event preview + * stack. Can be called when opening other overlays such as subwindows to + * ensure the notifications receive the events they need and don't linger + * indefinitely. See #7136. + * + * TODO Should this be a generic Overlay feature instead? + */ + public static void bringNotificationsToFront() { + for (VNotification notification : notifications) { + DOM.removeEventPreview(notification); + DOM.addEventPreview(notification); + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java b/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java index 5b97fc110f..d9096526f3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java @@ -111,6 +111,8 @@ public class PanelConnector extends AbstractComponentContainerConnector getWidget().captionNode.setClassName(captionClass); getWidget().contentNode.setClassName(contentClass); getWidget().bottomDecoration.setClassName(decoClass); + + getWidget().makeScrollable(); } if (!isRealUpdate(uidl)) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java index e2d3d443a0..6a06367acd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/panel/VPanel.java @@ -6,8 +6,6 @@ package com.vaadin.terminal.gwt.client.ui.panel; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; -import com.google.gwt.event.dom.client.TouchStartEvent; -import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; @@ -18,6 +16,7 @@ import com.vaadin.terminal.gwt.client.ui.Icon; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler; public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, Focusable { @@ -46,7 +45,7 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, int scrollLeft; - private TouchScrollDelegate touchScrollDelegate; + private TouchScrollHandler touchScrollHandler; public VPanel() { super(); @@ -74,11 +73,11 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, setStyleName(CLASSNAME); DOM.sinkEvents(getElement(), Event.ONKEYDOWN); DOM.sinkEvents(contentNode, Event.ONSCROLL | Event.TOUCHEVENTS); - addHandler(new TouchStartHandler() { - public void onTouchStart(TouchStartEvent event) { - getTouchScrollDelegate().onTouchStart(event); - } - }, TouchStartEvent.getType()); + + contentNode.getStyle().setProperty("position", "relative"); + getElement().getStyle().setProperty("overflow", "hidden"); + + makeScrollable(); } /** @@ -100,6 +99,7 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, * * @see com.vaadin.terminal.gwt.client.Focusable#focus() */ + public void focus() { setFocus(true); @@ -174,16 +174,17 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, } } - protected TouchScrollDelegate getTouchScrollDelegate() { - if (touchScrollDelegate == null) { - touchScrollDelegate = new TouchScrollDelegate(contentNode); - } - return touchScrollDelegate; - - } - public ShortcutActionHandler getShortcutActionHandler() { return shortcutHandler; } + /** + * Ensures the panel is scrollable eg. after style name changes + */ + void makeScrollable() { + if (touchScrollHandler == null) { + touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); + } + touchScrollHandler.addElement(contentNode); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java b/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java new file mode 100644 index 0000000000..a02ecc8ded --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/root/PageClientRpc.java @@ -0,0 +1,13 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui.root; + +import com.vaadin.terminal.gwt.client.communication.ClientRpc; + +public interface PageClientRpc extends ClientRpc { + + public void setTitle(String title); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java index 9be41a9623..1a62e566ad 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java @@ -61,6 +61,11 @@ public class RootConnector extends AbstractComponentContainerConnector @Override protected void init() { super.init(); + registerRpc(PageClientRpc.class, new PageClientRpc() { + public void setTitle(String title) { + com.google.gwt.user.client.Window.setTitle(title); + } + }); } public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { @@ -93,12 +98,9 @@ public class RootConnector extends AbstractComponentContainerConnector } getWidget().setStyleName(styles.trim()); - clickEventHandler.handleEventHandlerRegistration(); + getWidget().makeScrollable(); - if (!getWidget().isEmbedded() && getState().getCaption() != null) { - // only change window title if we're in charge of the whole page - com.google.gwt.user.client.Window.setTitle(getState().getCaption()); - } + clickEventHandler.handleEventHandlerRegistration(); // Process children int childIndex = 0; @@ -168,9 +170,6 @@ public class RootConnector extends AbstractComponentContainerConnector getWidget().id, client); } getWidget().actionHandler.updateActionMap(childUidl); - } else if (tag == "execJS") { - String script = childUidl.getStringAttribute("script"); - VRoot.eval(script); } else if (tag == "notifications") { for (final Iterator<?> it = childUidl.getChildIterator(); it .hasNext();) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java b/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java index 12a69d5556..0af8919280 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java +++ b/src/com/vaadin/terminal/gwt/client/ui/root/VRoot.java @@ -7,6 +7,7 @@ package com.vaadin.terminal.gwt.client.ui.root; import java.util.ArrayList; import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Element; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; @@ -26,6 +27,8 @@ import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler; import com.vaadin.terminal.gwt.client.ui.VLazyExecutor; import com.vaadin.terminal.gwt.client.ui.textfield.VTextField; @@ -37,21 +40,36 @@ public class VRoot extends SimplePanel implements ResizeHandler, public static final String FRAGMENT_VARIABLE = "fragment"; + public static final String BROWSER_HEIGHT_VAR = "browserHeight"; + + public static final String BROWSER_WIDTH_VAR = "browserWidth"; + private static final String CLASSNAME = "v-view"; public static final String NOTIFICATION_HTML_CONTENT_NOT_ALLOWED = "useplain"; + private static int MONITOR_PARENT_TIMER_INTERVAL = 1000; + String theme; String id; ShortcutActionHandler actionHandler; - /** stored width for IE resize optimization */ - private int width; + /* + * Last known window size used to detect whether VView should be layouted + * again. Detection must check window size, because the VView size might be + * fixed and thus not automatically adapt to changed window sizes. + */ + private int windowWidth; + private int windowHeight; - /** stored height for IE resize optimization */ - private int height; + /* + * Last know view size used to detect whether new dimensions should be sent + * to the server. + */ + private int viewWidth; + private int viewHeight; ApplicationConnection connection; @@ -59,13 +77,19 @@ public class VRoot extends SimplePanel implements ResizeHandler, public static final String CLICK_EVENT_ID = "click"; /** - * We are postponing resize process with IE. IE bugs with scrollbars in some - * situations, that causes false onWindowResized calls. With Timer we will - * give IE some time to decide if it really wants to keep current size - * (scrollbars). + * Keep track of possible parent size changes when an embedded application. + * + * Uses {@link #parentWidth} and {@link #parentHeight} as an optimization to + * keep track of when there is a real change. */ private Timer resizeTimer; + /** stored width of parent for embedded application auto-resize */ + private int parentWidth; + + /** stored height of parent for embedded application auto-resize */ + private int parentHeight; + int scrollTop; int scrollLeft; @@ -85,6 +109,8 @@ public class VRoot extends SimplePanel implements ResizeHandler, private HandlerRegistration historyHandlerRegistration; + private TouchScrollHandler touchScrollHandler; + /** * The current URI fragment, used to avoid sending updates if nothing has * changed. @@ -96,6 +122,7 @@ public class VRoot extends SimplePanel implements ResizeHandler, * whenever the value changes. */ private final ValueChangeHandler<String> historyChangeHandler = new ValueChangeHandler<String>() { + public void onValueChange(ValueChangeEvent<String> event) { String newFragment = event.getValue(); @@ -110,9 +137,9 @@ public class VRoot extends SimplePanel implements ResizeHandler, private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200, new ScheduledCommand() { + public void execute() { - windowSizeMaybeChanged(Window.getClientWidth(), - Window.getClientHeight()); + performSizeCheck(); } }); @@ -124,6 +151,29 @@ public class VRoot extends SimplePanel implements ResizeHandler, // Allow focusing the view by using the focus() method, the view // should not be in the document focus flow getElement().setTabIndex(-1); + makeScrollable(); + } + + /** + * Start to periodically monitor for parent element resizes if embedded + * application (e.g. portlet). + */ + @Override + protected void onLoad() { + super.onLoad(); + if (isMonitoringParentSize()) { + resizeTimer = new Timer() { + + @Override + public void run() { + // trigger check to see if parent size has changed, + // recalculate layouts + performSizeCheck(); + resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL); + } + }; + resizeTimer.schedule(MONITOR_PARENT_TIMER_INTERVAL); + } } @Override @@ -142,32 +192,95 @@ public class VRoot extends SimplePanel implements ResizeHandler, } /** - * Called when the window might have been resized. + * Stop monitoring for parent element resizes. + */ + + @Override + protected void onUnload() { + if (resizeTimer != null) { + resizeTimer.cancel(); + resizeTimer = null; + } + super.onUnload(); + } + + /** + * Called when the window or parent div might have been resized. * - * @param newWidth + * This immediately checks the sizes of the window and the parent div (if + * monitoring it) and triggers layout recalculation if they have changed. + */ + protected void performSizeCheck() { + windowSizeMaybeChanged(Window.getClientWidth(), + Window.getClientHeight()); + } + + /** + * Called when the window or parent div might have been resized. + * + * This immediately checks the sizes of the window and the parent div (if + * monitoring it) and triggers layout recalculation if they have changed. + * + * @param newWindowWidth * The new width of the window - * @param newHeight + * @param newWindowHeight * The new height of the window + * + * @deprecated use {@link #performSizeCheck()} */ - protected void windowSizeMaybeChanged(int newWidth, int newHeight) { + @Deprecated + protected void windowSizeMaybeChanged(int newWindowWidth, + int newWindowHeight) { boolean changed = false; ComponentConnector connector = ConnectorMap.get(connection) .getConnector(this); - if (width != newWidth) { - width = newWidth; + if (windowWidth != newWindowWidth) { + windowWidth = newWindowWidth; changed = true; - connector.getLayoutManager().reportOuterWidth(connector, newWidth); - VConsole.log("New window width: " + width); + connector.getLayoutManager().reportOuterWidth(connector, + newWindowWidth); + VConsole.log("New window width: " + windowWidth); } - if (height != newHeight) { - height = newHeight; + if (windowHeight != newWindowHeight) { + windowHeight = newWindowHeight; changed = true; - connector.getLayoutManager() - .reportOuterHeight(connector, newHeight); - VConsole.log("New window height: " + height); + connector.getLayoutManager().reportOuterHeight(connector, + newWindowHeight); + VConsole.log("New window height: " + windowHeight); + } + Element parentElement = getElement().getParentElement(); + if (isMonitoringParentSize() && parentElement != null) { + // check also for parent size changes + int newParentWidth = parentElement.getClientWidth(); + int newParentHeight = parentElement.getClientHeight(); + if (parentWidth != newParentWidth) { + parentWidth = newParentWidth; + changed = true; + VConsole.log("New parent width: " + parentWidth); + } + if (parentHeight != newParentHeight) { + parentHeight = newParentHeight; + changed = true; + VConsole.log("New parent height: " + parentHeight); + } } if (changed) { - VConsole.log("Running layout functions due to window resize"); + /* + * If the window size has changed, layout the VView again and send + * new size to the server if the size changed. (Just checking VView + * size would cause us to ignore cases when a relatively sized VView + * should shrink as the content's size is fixed and would thus not + * automatically shrink.) + */ + VConsole.log("Running layout functions due to window or parent resize"); + + // update size to avoid (most) redundant re-layout passes + // there can still be an extra layout recalculation if webkit + // overflow fix updates the size in a deferred block + if (isMonitoringParentSize() && parentElement != null) { + parentWidth = parentElement.getClientWidth(); + parentHeight = parentElement.getClientHeight(); + } sendClientResized(); @@ -188,21 +301,6 @@ public class VRoot extends SimplePanel implements ResizeHandler, }-*/; /** - * Evaluate the given script in the browser document. - * - * @param script - * Script to be executed. - */ - static native void eval(String script) - /*-{ - try { - if (script == null) return; - $wnd.eval(script); - } catch (e) { - } - }-*/; - - /** * 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. @@ -214,6 +312,17 @@ public class VRoot extends SimplePanel implements ResizeHandler, .contains(ApplicationConnection.GENERATED_BODY_CLASSNAME); } + /** + * Returns true if the size of the parent should be checked periodically and + * the application should react to its changes. + * + * @return true if size of parent should be tracked + */ + protected boolean isMonitoringParentSize() { + // could also perform a more specific check (Liferay portlet) + return isEmbedded(); + } + @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); @@ -251,14 +360,19 @@ public class VRoot extends SimplePanel implements ResizeHandler, * com.google.gwt.event.logical.shared.ResizeHandler#onResize(com.google * .gwt.event.logical.shared.ResizeEvent) */ + public void onResize(ResizeEvent event) { - onResize(); + triggerSizeChangeCheck(); } /** * Called when a resize event is received. + * + * This may trigger a lazy refresh or perform the size check immediately + * depending on the browser used and whether the server side requests + * resizes to be lazy. */ - void onResize() { + private void triggerSizeChangeCheck() { /* * IE (pre IE9 at least) will give us some false resize events due to * problems with scrollbars. Firefox 3 might also produce some extra @@ -274,8 +388,7 @@ public class VRoot extends SimplePanel implements ResizeHandler, if (lazy) { delayedResizeExecutor.trigger(); } else { - windowSizeMaybeChanged(Window.getClientWidth(), - Window.getClientHeight()); + performSizeCheck(); } } @@ -283,8 +396,19 @@ public class VRoot extends SimplePanel implements ResizeHandler, * Send new dimensions to the server. */ private void sendClientResized() { - connection.updateVariable(id, "height", height, false); - connection.updateVariable(id, "width", width, immediate); + Element parentElement = getElement().getParentElement(); + int viewHeight = parentElement.getClientHeight(); + int viewWidth = parentElement.getClientWidth(); + + connection.updateVariable(id, "height", viewHeight, false); + connection.updateVariable(id, "width", viewWidth, false); + + int windowWidth = Window.getClientWidth(); + int windowHeight = Window.getClientHeight(); + + connection.updateVariable(id, BROWSER_WIDTH_VAR, windowWidth, false); + connection.updateVariable(id, BROWSER_HEIGHT_VAR, windowHeight, + immediate); } public native static void goTo(String url) @@ -319,4 +443,13 @@ public class VRoot extends SimplePanel implements ResizeHandler, getElement().focus(); } + /** + * Ensures the root is scrollable eg. after style name changes. + */ + void makeScrollable() { + if (touchScrollHandler == null) { + touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); + } + touchScrollHandler.addElement(getElement()); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/slider/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/slider/VSlider.java index 9ff614252d..5c7ee7a784 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/slider/VSlider.java +++ b/src/com/vaadin/terminal/gwt/client/ui/slider/VSlider.java @@ -18,6 +18,7 @@ import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.ContainerResizedListener; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; +import com.vaadin.terminal.gwt.client.VTooltip; import com.vaadin.terminal.gwt.client.ui.Field; import com.vaadin.terminal.gwt.client.ui.SimpleFocusablePanel; import com.vaadin.terminal.gwt.client.ui.VLazyExecutor; @@ -51,6 +52,7 @@ public class VSlider extends SimpleFocusablePanel implements Field, private final HTML feedback = new HTML("", false); private final VOverlay feedbackPopup = new VOverlay(true, false, true) { + @Override public void show() { super.show(); @@ -112,6 +114,8 @@ public class VSlider extends SimpleFocusablePanel implements Field, feedbackPopup.addStyleName(CLASSNAME + "-feedback"); feedbackPopup.setWidget(feedback); + + sinkEvents(VTooltip.TOOLTIP_EVENTS); } void setFeedbackValue(double value) { @@ -139,8 +143,12 @@ public class VSlider extends SimpleFocusablePanel implements Field, void buildBase() { final String styleAttribute = vertical ? "height" : "width"; + final String oppositeStyleAttribute = vertical ? "width" : "height"; final String domProperty = vertical ? "offsetHeight" : "offsetWidth"; + // clear unnecessary opposite style attribute + DOM.setStyleAttribute(base, oppositeStyleAttribute, ""); + final Element p = DOM.getParent(getElement()); if (DOM.getElementPropertyInt(p, domProperty) > 50) { if (vertical) { @@ -153,6 +161,7 @@ public class VSlider extends SimpleFocusablePanel implements Field, // (supposedly) been drawn completely. DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px"); Scheduler.get().scheduleDeferred(new Command() { + public void execute() { final Element p = DOM.getParent(getElement()); if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) { @@ -173,9 +182,14 @@ public class VSlider extends SimpleFocusablePanel implements Field, void buildHandle() { final String handleAttribute = vertical ? "marginTop" : "marginLeft"; + final String oppositeHandleAttribute = vertical ? "marginLeft" + : "marginTop"; DOM.setStyleAttribute(handle, handleAttribute, "0"); + // clear unnecessary opposite handle attribute + DOM.setStyleAttribute(handle, oppositeHandleAttribute, ""); + // Restore visibility DOM.setStyleAttribute(handle, "visibility", "visible"); @@ -277,6 +291,9 @@ public class VSlider extends SimpleFocusablePanel implements Field, event.preventDefault(); // avoid simulated events event.stopPropagation(); } + if (client != null) { + client.handleTooltipEvent(event, this); + } } private void processMouseWheelEvent(final Event event) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java index 10e5dbe37a..e33755bc9b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java @@ -127,6 +127,12 @@ public abstract class AbstractSplitPanelConnector extends getWidget().setStylenames(); + getWidget().minimumPosition = splitterState.getMinPosition() + + splitterState.getMinPositionUnit(); + + getWidget().maximumPosition = splitterState.getMaxPosition() + + splitterState.getMaxPositionUnit(); + getWidget().position = splitterState.getPosition() + splitterState.getPositionUnit(); @@ -136,6 +142,7 @@ public abstract class AbstractSplitPanelConnector extends getLayoutManager().setNeedsLayout(this); + getWidget().makeScrollable(); } public void layout() { diff --git a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelState.java b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelState.java index 8b80eed840..db3a39d3a5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelState.java +++ b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelState.java @@ -49,6 +49,10 @@ public class AbstractSplitPanelState extends ComponentState { public static class SplitterState implements Serializable { private float position; private String positionUnit; + private float minPosition; + private String minPositionUnit; + private float maxPosition; + private String maxPositionUnit; private boolean positionReversed = false; private boolean locked = false; @@ -68,6 +72,38 @@ public class AbstractSplitPanelState extends ComponentState { this.positionUnit = positionUnit; } + public float getMinPosition() { + return minPosition; + } + + public void setMinPosition(float minPosition) { + this.minPosition = minPosition; + } + + public String getMinPositionUnit() { + return minPositionUnit; + } + + public void setMinPositionUnit(String minPositionUnit) { + this.minPositionUnit = minPositionUnit; + } + + public float getMaxPosition() { + return maxPosition; + } + + public void setMaxPosition(float maxPosition) { + this.maxPosition = maxPosition; + } + + public String getMaxPositionUnit() { + return maxPositionUnit; + } + + public void setMaxPositionUnit(String maxPositionUnit) { + this.maxPositionUnit = maxPositionUnit; + } + public boolean isPositionReversed() { return positionReversed; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java index 166e79e92e..e2f30c6676 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java @@ -4,6 +4,7 @@ package com.vaadin.terminal.gwt.client.ui.splitpanel; +import java.util.Collections; import java.util.List; import com.google.gwt.dom.client.Node; @@ -31,6 +32,7 @@ import com.vaadin.terminal.gwt.client.LayoutManager; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler; import com.vaadin.terminal.gwt.client.ui.VOverlay; import com.vaadin.terminal.gwt.client.ui.splitpanel.VAbstractSplitPanel.SplitterMoveHandler.SplitterMoveEvent; @@ -76,7 +78,7 @@ public class VAbstractSplitPanel extends ComplexPanel { private boolean positionReversed = false; - List<String> componentStyleNames; + List<String> componentStyleNames = Collections.emptyList(); private Element draggingCurtain; @@ -87,12 +89,16 @@ public class VAbstractSplitPanel extends ComplexPanel { /* The current position of the split handle in either percentages or pixels */ String position; + String maximumPosition; + + String minimumPosition; + + private TouchScrollHandler touchScrollHandler; + protected Element scrolledContainer; protected int origScrollTop; - private TouchScrollDelegate touchScrollDelegate; - public VAbstractSplitPanel() { this(ORIENTATION_HORIZONTAL); } @@ -116,6 +122,8 @@ public class VAbstractSplitPanel extends ComplexPanel { setOrientation(orientation); sinkEvents(Event.MOUSEEVENTS); + makeScrollable(); + addDomHandler(new TouchCancelHandler() { public void onTouchCancel(TouchCancelEvent event) { // TODO When does this actually happen?? @@ -127,11 +135,8 @@ public class VAbstractSplitPanel extends ComplexPanel { Node target = event.getTouches().get(0).getTarget().cast(); if (splitter.isOrHasChild(target)) { onMouseDown(Event.as(event.getNativeEvent())); - } else { - getTouchScrollDelegate().onTouchStart(event); } } - }, TouchStartEvent.getType()); addDomHandler(new TouchMoveHandler() { public void onTouchMove(TouchMoveEvent event) { @@ -150,14 +155,6 @@ public class VAbstractSplitPanel extends ComplexPanel { } - private TouchScrollDelegate getTouchScrollDelegate() { - if (touchScrollDelegate == null) { - touchScrollDelegate = new TouchScrollDelegate(firstContainer, - secondContainer); - } - return touchScrollDelegate; - } - protected void constructDom() { DOM.appendChild(splitter, DOM.createDiv()); // for styling DOM.appendChild(getElement(), wrapper); @@ -172,9 +169,7 @@ public class VAbstractSplitPanel extends ComplexPanel { DOM.setStyleAttribute(splitter, "position", "absolute"); DOM.setStyleAttribute(secondContainer, "position", "absolute"); - DOM.setStyleAttribute(firstContainer, "overflow", "auto"); - DOM.setStyleAttribute(secondContainer, "overflow", "auto"); - + setStylenames(); } private void setOrientation(int orientation) { @@ -190,11 +185,6 @@ public class VAbstractSplitPanel extends ComplexPanel { DOM.setStyleAttribute(firstContainer, "width", "100%"); DOM.setStyleAttribute(secondContainer, "width", "100%"); } - - DOM.setElementProperty(firstContainer, "className", CLASSNAME - + "-first-container"); - DOM.setElementProperty(secondContainer, "className", CLASSNAME - + "-second-container"); } @Override @@ -232,11 +222,109 @@ public class VAbstractSplitPanel extends ComplexPanel { } } + /** + * Converts given split position string (in pixels or percentage) to a + * floating point pixel value. + * + * @param pos + * @return + */ + private float convertToPixels(String pos) { + float posAsFloat; + if (pos.indexOf("%") > 0) { + posAsFloat = Math.round(Float.parseFloat(pos.substring(0, + pos.length() - 1)) + / 100 + * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() + : getOffsetHeight())); + } else { + posAsFloat = Float.parseFloat(pos.substring(0, pos.length() - 2)); + } + return posAsFloat; + } + + /** + * Converts given split position string (in pixels or percentage) to a float + * percentage value. + * + * @param pos + * @return + */ + private float convertToPercentage(String pos) { + float posAsFloat = 0; + + if (pos.indexOf("px") > 0) { + int posAsInt = Integer.parseInt(pos.substring(0, pos.length() - 2)); + int offsetLength = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() + : getOffsetHeight(); + + // 100% needs special handling + if (posAsInt + getSplitterSize() >= offsetLength) { + posAsInt = offsetLength; + } + posAsFloat = ((float) posAsInt / (float) offsetLength * 100); + + } else { + posAsFloat = Float.parseFloat(pos.substring(0, pos.length() - 1)); + } + return posAsFloat; + } + + /** + * Returns the given position clamped to the range between current minimum + * and maximum positions. + * + * TODO Should this be in the connector? + * + * @param pos + * Position of the splitter as a CSS string, either pixels or a + * percentage. + * @return minimumPosition if pos is less than minimumPosition; + * maximumPosition if pos is greater than maximumPosition; pos + * otherwise. + */ + private String checkSplitPositionLimits(String pos) { + float positionAsFloat = convertToPixels(pos); + + if (maximumPosition != null + && convertToPixels(maximumPosition) < positionAsFloat) { + pos = maximumPosition; + } else if (minimumPosition != null + && convertToPixels(minimumPosition) > positionAsFloat) { + pos = minimumPosition; + } + return pos; + } + + /** + * Converts given string to the same units as the split position is. + * + * @param pos + * position to be converted + * @return converted position string + */ + private String convertToPositionUnits(String pos) { + if (position.indexOf("%") != -1 && pos.indexOf("%") == -1) { + // position is in percentage, pos in pixels + pos = convertToPercentage(pos) + "%"; + } else if (position.indexOf("px") > 0 && pos.indexOf("px") == -1) { + // position is in pixels and pos in percentage + pos = convertToPixels(pos) + "px"; + } + + return pos; + } + void setSplitPosition(String pos) { if (pos == null) { return; } + pos = checkSplitPositionLimits(pos); + if (!pos.equals(position)) { + position = convertToPositionUnits(pos); + } + // Convert percentage values to pixels if (pos.indexOf("%") > 0) { int size = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() @@ -375,7 +463,6 @@ public class VAbstractSplitPanel extends ComplexPanel { } break; } - } void setFirstWidget(Widget w) { @@ -481,16 +568,7 @@ public class VAbstractSplitPanel extends ComplexPanel { } if (position.indexOf("%") > 0) { - float pos = newX; - // 100% needs special handling - if (newX + getSplitterSize() >= getOffsetWidth()) { - pos = getOffsetWidth(); - } - // Reversed position - if (positionReversed) { - pos = getOffsetWidth() - pos - getSplitterSize(); - } - position = (pos / getOffsetWidth() * 100) + "%"; + position = convertToPositionUnits(newX + "px"); } else { // Reversed position if (positionReversed) { @@ -523,16 +601,7 @@ public class VAbstractSplitPanel extends ComplexPanel { } if (position.indexOf("%") > 0) { - float pos = newY; - // 100% needs special handling - if (newY + getSplitterSize() >= getOffsetHeight()) { - pos = getOffsetHeight(); - } - // Reversed position - if (positionReversed) { - pos = getOffsetHeight() - pos - getSplitterSize(); - } - position = pos / getOffsetHeight() * 100 + "%"; + position = convertToPositionUnits(newY + "px"); } else { // Reversed position if (positionReversed) { @@ -659,30 +728,24 @@ public class VAbstractSplitPanel extends ComplexPanel { } void setStylenames() { - final String splitterSuffix = (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter" - : "-vsplitter"); - final String firstContainerSuffix = "-first-container"; - final String secondContainerSuffix = "-second-container"; - String lockedSuffix = ""; - - String splitterStyle = CLASSNAME + splitterSuffix; - String firstStyle = CLASSNAME + firstContainerSuffix; - String secondStyle = CLASSNAME + secondContainerSuffix; - - if (locked) { - splitterStyle = CLASSNAME + splitterSuffix + "-locked"; - lockedSuffix = "-locked"; - } - for (String style : componentStyleNames) { - splitterStyle += " " + CLASSNAME + splitterSuffix + "-" + style - + lockedSuffix; - firstStyle += " " + CLASSNAME + firstContainerSuffix + "-" + style; - secondStyle += " " + CLASSNAME + secondContainerSuffix + "-" - + style; - } - DOM.setElementProperty(splitter, "className", splitterStyle); - DOM.setElementProperty(firstContainer, "className", firstStyle); - DOM.setElementProperty(secondContainer, "className", secondStyle); + final String splitterClass = CLASSNAME + + (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter" + : "-vsplitter"); + final String firstContainerClass = CLASSNAME + "-first-container"; + final String secondContainerClass = CLASSNAME + "-second-container"; + final String lockedSuffix = locked ? "-locked" : ""; + + splitter.setClassName(splitterClass + lockedSuffix); + firstContainer.setClassName(firstContainerClass); + secondContainer.setClassName(secondContainerClass); + + for (String styleName : componentStyleNames) { + splitter.addClassName(splitterClass + "-" + styleName + + lockedSuffix); + firstContainer.addClassName(firstContainerClass + "-" + styleName); + secondContainer + .addClassName(secondContainerClass + "-" + styleName); + } } public void setEnabled(boolean enabled) { @@ -693,4 +756,14 @@ public class VAbstractSplitPanel extends ComplexPanel { return enabled; } + /** + * Ensures the panels are scrollable eg. after style name changes + */ + void makeScrollable() { + if (touchScrollHandler == null) { + touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); + } + touchScrollHandler.addElement(firstContainer); + touchScrollHandler.addElement(secondContainer); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java index c45c26c4ac..c4a57f5c8b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java @@ -44,8 +44,6 @@ import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; -import com.google.gwt.event.dom.client.TouchStartEvent; -import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.user.client.Command; @@ -236,6 +234,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private boolean enableDebug = false; + private static final boolean hasNativeTouchScrolling = BrowserInfo.get() + .isTouchDevice() + && !BrowserInfo.get().requiresTouchScrollDelegate(); + + private Set<String> noncollapsibleColumns; + /** * Represents a select range of rows */ @@ -268,6 +272,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * * @see java.lang.Object#toString() */ + @Override public String toString() { return startRow.getKey() + "-" + length; @@ -321,6 +326,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(true); private KeyPressHandler navKeyPressHandler = new KeyPressHandler() { + public void onKeyPress(KeyPressEvent keyPressEvent) { // This is used for Firefox only, since Firefox auto-repeat // works correctly only if we use a key press handler, other @@ -489,12 +495,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, public VScrollTable() { setMultiSelectMode(MULTISELECT_MODE_DEFAULT); - scrollBodyPanel.setStyleName(CLASSNAME + "-body-wrapper"); + scrollBodyPanel.addStyleName(CLASSNAME + "-body-wrapper"); scrollBodyPanel.addFocusHandler(this); scrollBodyPanel.addBlurHandler(this); scrollBodyPanel.addScrollHandler(this); - scrollBodyPanel.setStyleName(CLASSNAME + "-body"); + scrollBodyPanel.addStyleName(CLASSNAME + "-body"); /* * Firefox auto-repeat works correctly only if we use a key press @@ -509,14 +515,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, scrollBodyPanel.addKeyUpHandler(navKeyUpHandler); scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS); - scrollBodyPanel.addDomHandler(new TouchStartHandler() { - public void onTouchStart(TouchStartEvent event) { - getTouchScrollDelegate().onTouchStart(event); - } - }, TouchStartEvent.getType()); scrollBodyPanel.sinkEvents(Event.ONCONTEXTMENU); scrollBodyPanel.addDomHandler(new ContextMenuHandler() { + public void onContextMenu(ContextMenuEvent event) { handleBodyContextMenu(event); } @@ -536,22 +538,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // Add a handler to clear saved context menu details when the menu // closes. See #8526. client.getContextMenu().addCloseHandler(new CloseHandler<PopupPanel>() { + public void onClose(CloseEvent<PopupPanel> event) { contextMenu = null; } }); } - protected TouchScrollDelegate getTouchScrollDelegate() { - if (touchScrollDelegate == null) { - touchScrollDelegate = new TouchScrollDelegate( - scrollBodyPanel.getElement()); - touchScrollDelegate.setScrollHandler(this); - } - return touchScrollDelegate; - - } - private void handleBodyContextMenu(ContextMenuEvent event) { if (enabled && bodyActionKeys != null) { int left = Util.getTouchOrMouseClientX(event.getNativeEvent()); @@ -896,6 +889,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, updateHeader(uidl.getStringArrayAttribute("vcolorder")); updateFooter(uidl.getStringArrayAttribute("vcolorder")); + if (uidl.hasVariable("noncollapsiblecolumns")) { + noncollapsibleColumns = uidl + .getStringArrayVariableAsSet("noncollapsiblecolumns"); + } } private void updateCollapsedColumns(UIDL uidl) { @@ -1848,12 +1845,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, isNewBody = false; if (firstvisible > 0) { - // FIXME #7607 - // Originally deferred due to Firefox oddities which should not - // occur any more. Currently deferring breaks Webkit scrolling with - // relative-height tables, but not deferring instead breaks tables - // with explicit page length. + // Deferred due to some Firefox oddities Scheduler.get().scheduleDeferred(new Command() { + public void execute() { scrollBodyPanel .setScrollPosition(measureRowHeightOffset(firstvisible)); @@ -1888,6 +1882,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, */ scrollBody.reLayoutComponents(); Scheduler.get().scheduleDeferred(new Command() { + public void execute() { Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); } @@ -2218,6 +2213,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, setWidth(tdWidth + "px"); } else { Scheduler.get().scheduleDeferred(new Command() { + public void execute() { int tdWidth = width + scrollBody.getCellExtraWidth(); @@ -2271,6 +2267,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** * Handle column reordering. */ + @Override public void onBrowserEvent(Event event) { if (enabled && event != null) { @@ -2814,6 +2811,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, final int newWidth = width; Scheduler.get().scheduleDeferred( new ScheduledCommand() { + public void execute() { setColWidth(colIx, newWidth, true); } @@ -2841,6 +2839,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (refreshContentWidths) { // Recalculate the column sizings if any column has changed Scheduler.get().scheduleDeferred(new ScheduledCommand() { + public void execute() { triggerLazyColumnAdjustment(true); } @@ -3029,6 +3028,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, String colKey; private boolean collapsed; + private boolean noncollapsible = false; private VScrollTableRow currentlyFocusedRow; public VisibleColumnAction(String colKey) { @@ -3040,6 +3040,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, @Override public void execute() { + if (noncollapsible) { + return; + } client.getContextMenu().hide(); // toggle selected column if (collapsedColumns.contains(colKey)) { @@ -3063,17 +3066,28 @@ public class VScrollTable extends FlowPanel implements HasWidgets, collapsed = b; } + public void setNoncollapsible(boolean b) { + noncollapsible = b; + } + /** * Override default method to distinguish on/off columns */ + @Override public String getHTML() { final StringBuffer buf = new StringBuffer(); + buf.append("<span class=\""); if (collapsed) { - buf.append("<span class=\"v-off\">"); + buf.append("v-off"); } else { - buf.append("<span class=\"v-on\">"); + buf.append("v-on"); + } + if (noncollapsible) { + buf.append(" v-disabled"); } + buf.append("\">"); + buf.append(super.getHTML()); buf.append("</span>"); @@ -3085,6 +3099,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /* * Returns columns as Action array for column select popup */ + public Action[] getActions() { Object[] cols; if (columnReordering && columnOrder != null) { @@ -3115,6 +3130,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (!c.isEnabled()) { a.setCollapsed(true); } + if (noncollapsibleColumns.contains(cid)) { + a.setNoncollapsible(true); + } actions[i] = a; } return actions; @@ -3200,6 +3218,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * The text in the footer */ public void setText(String footerText) { + if (footerText == null || footerText.equals("")) { + footerText = " "; + } + DOM.setInnerHTML(captionContainer, footerText); } @@ -3295,6 +3317,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, setWidth(tdWidth + "px"); } else { Scheduler.get().scheduleDeferred(new Command() { + public void execute() { int borderWidths = 1; int tdWidth = width @@ -3541,6 +3564,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * com.google.gwt.user.client.ui.Panel#remove(com.google.gwt.user.client * .ui.Widget) */ + @Override public boolean remove(Widget w) { if (visibleCells.contains(w)) { @@ -3557,6 +3581,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * * @see com.google.gwt.user.client.ui.HasWidgets#iterator() */ + public Iterator<Widget> iterator() { return visibleCells.iterator(); } @@ -3835,7 +3860,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, DOM.appendChild(container, preSpacer); DOM.appendChild(container, table); DOM.appendChild(container, postSpacer); - if (BrowserInfo.get().isTouchDevice()) { + if (BrowserInfo.get().requiresTouchScrollDelegate()) { NodeList<Node> childNodes = container.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Element item = (Element) childNodes.getItem(i); @@ -4388,7 +4413,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private String[] actionKeys = null; private final TableRowElement rowElement; - private boolean mDown; private int index; private Event touchStart; private static final String ROW_CLASSNAME_EVEN = CLASSNAME + "-row"; @@ -4396,8 +4420,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, + "-row-odd"; private static final int TOUCH_CONTEXT_MENU_TIMEOUT = 500; private Timer contextTouchTimeout; + private Timer dragTouchTimeout; private int touchStartY; private int touchStartX; + private boolean isDragging = false; private VScrollTableRow(int rowKey) { this.rowKey = rowKey; @@ -4785,12 +4811,128 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + /** + * Special handler for touch devices that support native scrolling + * + * @return Whether the event was handled by this method. + */ + private boolean handleTouchEvent(final Event event) { + + boolean touchEventHandled = false; + + if (enabled && hasNativeTouchScrolling) { + final Element targetTdOrTr = getEventTargetTdOrTr(event); + final int type = event.getTypeInt(); + + switch (type) { + case Event.ONTOUCHSTART: + touchEventHandled = true; + touchStart = event; + isDragging = false; + Touch touch = event.getChangedTouches().get(0); + // save position to fields, touches in events are same + // instance during the operation. + touchStartX = touch.getClientX(); + touchStartY = touch.getClientY(); + + if (dragmode != 0) { + if (dragTouchTimeout == null) { + dragTouchTimeout = new Timer() { + + @Override + public void run() { + if (touchStart != null) { + // Start a drag if a finger is held + // in place long enough, then moved + isDragging = true; + } + } + }; + } + dragTouchTimeout.schedule(TOUCHSCROLL_TIMEOUT); + } + + if (actionKeys != null) { + if (contextTouchTimeout == null) { + contextTouchTimeout = new Timer() { + + @Override + public void run() { + if (touchStart != null) { + // Open the context menu if finger + // is held in place long enough. + showContextMenu(touchStart); + event.preventDefault(); + touchStart = null; + } + } + }; + } + contextTouchTimeout + .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + } + break; + case Event.ONTOUCHMOVE: + touchEventHandled = true; + if (isSignificantMove(event)) { + if (contextTouchTimeout != null) { + // Moved finger before the context menu timer + // expired, so let the browser handle this as a + // scroll. + contextTouchTimeout.cancel(); + contextTouchTimeout = null; + } + if (!isDragging && dragTouchTimeout != null) { + // Moved finger before the drag timer expired, + // so let the browser handle this as a scroll. + dragTouchTimeout.cancel(); + dragTouchTimeout = null; + } + + if (dragmode != 0 && touchStart != null + && isDragging) { + event.preventDefault(); + event.stopPropagation(); + startRowDrag(touchStart, type, targetTdOrTr); + } + touchStart = null; + } + break; + case Event.ONTOUCHEND: + case Event.ONTOUCHCANCEL: + touchEventHandled = true; + if (contextTouchTimeout != null) { + contextTouchTimeout.cancel(); + } + if (dragTouchTimeout != null) { + dragTouchTimeout.cancel(); + } + if (touchStart != null) { + event.preventDefault(); + event.stopPropagation(); + if (!BrowserInfo.get().isAndroid()) { + Util.simulateClickFromTouchEvent(touchStart, + this); + } + touchStart = null; + } + isDragging = false; + break; + } + } + return touchEventHandled; + } + /* * React on click that occur on content cells only */ + @Override public void onBrowserEvent(final Event event) { - if (enabled) { + + final boolean touchEventHandled = handleTouchEvent(event); + + if (enabled && !touchEventHandled) { final int type = event.getTypeInt(); final Element targetTdOrTr = getEventTargetTdOrTr(event); if (type == Event.ONCONTEXTMENU) { @@ -4823,7 +4965,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, break; case Event.ONMOUSEUP: if (targetCellOrRowFound) { - mDown = false; /* * Queue here, send at the same time as the * corresponding value change event - see #7127 @@ -4983,6 +5124,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, touchStart.preventDefault(); if (dragmode != 0 || actionKeys != null) { new Timer() { + @Override public void run() { TouchScrollDelegate activeScrollDelegate = TouchScrollDelegate @@ -5021,6 +5163,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (contextTouchTimeout == null && actionKeys != null) { contextTouchTimeout = new Timer() { + @Override public void run() { if (touchStart != null) { @@ -5066,9 +5209,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } break; case Event.ONMOUSEOUT: - if (targetCellOrRowFound) { - mDown = false; - } break; default: break; @@ -5098,7 +5238,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, protected void startRowDrag(Event event, final int type, Element targetTdOrTr) { - mDown = true; VTransferable transferable = new VTransferable(); transferable.setDragSource(ConnectorMap.get(client) .getConnector(VScrollTable.this)); @@ -5290,6 +5429,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * * @see com.vaadin.terminal.gwt.client.ui.IActionOwner#getActions () */ + public Action[] getActions() { if (actionKeys == null) { return new Action[] {}; @@ -5299,6 +5439,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, final String actionKey = actionKeys[i]; final TreeAction a = new TreeAction(this, String.valueOf(rowKey), actionKey) { + @Override public void execute() { super.execute(); @@ -5586,6 +5727,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * column widths "optimally". Doing this lazily to avoid expensive * calculation when resizing is not yet finished. */ + @Override public void run() { if (scrollBody == null) { @@ -5682,7 +5824,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (isDynamicHeight() && totalRows == pageLength) { // fix body height (may vary if lazy loading is offhorizontal // scrollbar appears/disappears) - int bodyHeight = scrollBody.getRequiredHeight(); + int bodyHeight = Util.getRequiredHeight(scrollBody); boolean needsSpaceForHorizontalScrollbar = (availW < usedMinimumWidth); if (needsSpaceForHorizontalScrollbar) { bodyHeight += Util.getNativeScrollbarSize(); @@ -5695,6 +5837,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } scrollBody.reLayoutComponents(); Scheduler.get().scheduleDeferred(new Command() { + public void execute() { Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); } @@ -5804,15 +5947,26 @@ public class VScrollTable extends FlowPanel implements HasWidgets, void updateHeight() { setContainerHeight(); - updatePageLength(); - + if (initializedAndAttached) { + updatePageLength(); + } if (!rendering) { // Webkit may sometimes get an odd rendering bug (white space // between header and body), see bug #3875. Running // overflow hack here to shake body element a bit. - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); + // We must run the fix as a deferred command to prevent it from + // overwriting the scroll position with an outdated value, see + // #7607. + Scheduler.get().scheduleDeferred(new Command() { + + public void execute() { + Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); + } + }); } + triggerLazyColumnAdjustment(false); + /* * setting height may affect wheter the component has scrollbars -> * needs scrolling or not @@ -5826,6 +5980,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * lost). Example ITabPanel just set contained components invisible and back * when changing tabs. */ + @Override public void setVisible(boolean visible) { if (isVisible() != visible) { @@ -5833,6 +5988,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (initializedAndAttached) { if (visible) { Scheduler.get().scheduleDeferred(new Command() { + public void execute() { scrollBodyPanel .setScrollPosition(measureRowHeightOffset(firstRowInViewPort)); @@ -5866,6 +6022,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * This method has logic which rows needs to be requested from server when * user scrolls */ + public void onScroll(ScrollEvent event) { scrollLeft = scrollBodyPanel.getElement().getScrollLeft(); scrollTop = scrollBodyPanel.getScrollPosition(); @@ -5894,6 +6051,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // correct // value available soon. Scheduler.get().scheduleDeferred(new Command() { + public void execute() { onScroll(null); } @@ -5994,7 +6152,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return false; } - // @Override + // // public int hashCode() { // return overkey; // } @@ -6053,6 +6211,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, deEmphasis(); final TableDDDetails newDetails = dropDetails; VAcceptCallback cb = new VAcceptCallback() { + public void accepted(VDragEvent event) { if (newDetails.equals(dropDetails)) { dragAccepted(event); @@ -6459,6 +6618,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * com.google.gwt.event.dom.client.FocusHandler#onFocus(com.google.gwt.event * .dom.client.FocusEvent) */ + public void onFocus(FocusEvent event) { if (isFocusable()) { hasFocus = true; @@ -6479,6 +6639,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * com.google.gwt.event.dom.client.BlurHandler#onBlur(com.google.gwt.event * .dom.client.BlurEvent) */ + public void onBlur(BlurEvent event) { hasFocus = false; navKeyDown = false; @@ -6551,6 +6712,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * * @see com.vaadin.terminal.gwt.client.Focusable#focus() */ + public void focus() { if (isFocusable()) { scrollBodyPanel.focus(); @@ -6594,6 +6756,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, public void startScrollingVelocityTimer() { if (scrollingVelocityTimer == null) { scrollingVelocityTimer = new Timer() { + @Override public void run() { scrollingVelocity++; @@ -6630,6 +6793,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, public void lazyRevertFocusToRow(final VScrollTableRow currentlyFocusedRow) { Scheduler.get().scheduleFinally(new ScheduledCommand() { + public void execute() { if (currentlyFocusedRow != null) { setRowFocus(currentlyFocusedRow); diff --git a/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheet.java index c97ede1252..aba5a41f9a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheet.java @@ -331,6 +331,11 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } return width; } + + public Element getCloseButton() { + return closeButton; + } + } static class TabBar extends ComplexPanel implements ClickHandler, @@ -393,7 +398,14 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } public void onClick(ClickEvent event) { - Widget caption = (Widget) event.getSource(); + TabCaption caption = (TabCaption) event.getSource(); + Element targetElement = event.getNativeEvent().getEventTarget() + .cast(); + // the tab should not be focused if the close button was clicked + if (targetElement == caption.getCloseButton()) { + return; + } + int index = getWidgetIndex(caption.getParent()); // IE needs explicit focus() if (BrowserInfo.get().isIE()) { @@ -1021,6 +1033,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, final Style style = scroller.getStyle(); style.setProperty("whiteSpace", "normal"); Scheduler.get().scheduleDeferred(new Command() { + public void execute() { style.setProperty("whiteSpace", ""); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheetPanel.java b/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheetPanel.java index f2b37c3a1c..bd6cddb682 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheetPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/tabsheet/VTabsheetPanel.java @@ -4,16 +4,12 @@ package com.vaadin.terminal.gwt.client.ui.tabsheet; -import com.google.gwt.dom.client.Node; -import com.google.gwt.dom.client.NodeList; -import com.google.gwt.event.dom.client.TouchStartEvent; -import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler; /** * A panel that displays all of its child widgets in a 'deck', where only one @@ -27,38 +23,15 @@ import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate; public class VTabsheetPanel extends ComplexPanel { private Widget visibleWidget; - private TouchScrollDelegate touchScrollDelegate; + + private final TouchScrollHandler touchScrollHandler; /** * Creates an empty tabsheet panel. */ public VTabsheetPanel() { setElement(DOM.createDiv()); - sinkEvents(Event.TOUCHEVENTS); - addDomHandler(new TouchStartHandler() { - public void onTouchStart(TouchStartEvent event) { - /* - * All container elements needs to be scrollable by one finger. - * Update the scrollable element list of touch delegate on each - * touch start. - */ - NodeList<Node> childNodes = getElement().getChildNodes(); - Element[] elements = new Element[childNodes.getLength()]; - for (int i = 0; i < elements.length; i++) { - elements[i] = (Element) childNodes.getItem(i); - } - getTouchScrollDelegate().setElements(elements); - getTouchScrollDelegate().onTouchStart(event); - } - }, TouchStartEvent.getType()); - } - - protected TouchScrollDelegate getTouchScrollDelegate() { - if (touchScrollDelegate == null) { - touchScrollDelegate = new TouchScrollDelegate(); - } - return touchScrollDelegate; - + touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); } /** @@ -77,8 +50,8 @@ public class VTabsheetPanel extends ComplexPanel { private Element createContainerElement() { Element el = DOM.createDiv(); DOM.setStyleAttribute(el, "position", "absolute"); - DOM.setStyleAttribute(el, "overflow", "auto"); hide(el); + touchScrollHandler.addElement(el); return el; } @@ -122,6 +95,7 @@ public class VTabsheetPanel extends ComplexPanel { if (parent != null) { DOM.removeChild(getElement(), parent); } + touchScrollHandler.removeElement(parent); } return removed; } @@ -141,6 +115,8 @@ public class VTabsheetPanel extends ComplexPanel { hide(DOM.getParent(visibleWidget.getElement())); } visibleWidget = newVisible; + touchScrollHandler.setElements(visibleWidget.getElement() + .getParentElement()); } // Always ensure the selected tab is visible. If server prevents a tab // change we might end up here with visibleWidget == newVisible but its diff --git a/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java b/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java index f7cd9d133e..9a8e0e9ce1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java @@ -379,26 +379,34 @@ public class VTreeTable extends VScrollTable { rowsToDelete.add(row); } } - RowCollapseAnimation anim = new RowCollapseAnimation(rowsToDelete) { - @Override - protected void onComplete() { - super.onComplete(); - // Actually unlink the rows and update the cache after the - // animation is done. - unlinkAndReindexRows(firstIndex, rows); - discardRowsOutsideCacheWindow(); - ensureCacheFilled(); - } - }; - anim.run(150); + if (!rowsToDelete.isEmpty()) { + // #8810 Only animate if there's something to animate + RowCollapseAnimation anim = new RowCollapseAnimation( + rowsToDelete) { + @Override + protected void onComplete() { + super.onComplete(); + // Actually unlink the rows and update the cache after + // the + // animation is done. + unlinkAndReindexRows(firstIndex, rows); + discardRowsOutsideCacheWindow(); + ensureCacheFilled(); + } + }; + anim.run(150); + } } protected List<VScrollTableRow> insertRowsAnimated(UIDL rowData, int firstIndex, int rows) { List<VScrollTableRow> insertedRows = insertAndReindexRows(rowData, firstIndex, rows); - RowExpandAnimation anim = new RowExpandAnimation(insertedRows); - anim.run(150); + if (!insertedRows.isEmpty()) { + // Only animate if there's something to animate (#8810) + RowExpandAnimation anim = new RowExpandAnimation(insertedRows); + anim.run(150); + } return insertedRows; } @@ -521,6 +529,10 @@ public class VTreeTable extends VScrollTable { private Element cloneTable; private AnimationPreparator preparator; + /** + * @param rows + * List of rows to animate. Must not be empty. + */ public RowExpandAnimation(List<VScrollTableRow> rows) { this.rows = rows; buildAndInsertAnimatingDiv(); @@ -641,6 +653,10 @@ public class VTreeTable extends VScrollTable { private final List<VScrollTableRow> rows; + /** + * @param rows + * List of rows to animate. Must not be empty. + */ public RowCollapseAnimation(List<VScrollTableRow> rows) { super(rows); this.rows = rows; diff --git a/src/com/vaadin/terminal/gwt/client/ui/window/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/window/VWindow.java index d08387fc6d..8fd84a9ea6 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/window/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/window/VWindow.java @@ -40,6 +40,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.terminal.gwt.client.ui.VLazyExecutor; import com.vaadin.terminal.gwt.client.ui.VOverlay; +import com.vaadin.terminal.gwt.client.ui.notification.VNotification; /** * "Sub window" component. @@ -264,8 +265,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, if (!orderingDefered) { orderingDefered = true; Scheduler.get().scheduleFinally(new Command() { + public void execute() { doServerSideOrdering(); + VNotification.bringNotificationsToFront(); } }); } @@ -275,6 +278,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, orderingDefered = false; VWindow[] array = windowOrder.toArray(new VWindow[windowOrder.size()]); Arrays.sort(array, new Comparator<VWindow>() { + public int compare(VWindow o1, VWindow o2) { /* * Order by modality, then by bringtofront sequence. diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 5b2be308a3..bf29144cc1 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -64,9 +64,6 @@ import com.vaadin.ui.Root; public abstract class AbstractApplicationPortlet extends GenericPortlet implements Constants { - private static final Logger logger = Logger - .getLogger(AbstractApplicationPortlet.class.getName()); - public static class WrappedHttpAndPortletRequest extends WrappedPortletRequest { @@ -203,6 +200,8 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet */ public static final String PORTAL_PARAMETER_VAADIN_THEME = "vaadin.theme"; + public static final String WRITE_AJAX_PAGE_SCRIPT_WIDGETSET_SHOULD_WRITE = "writeAjaxPageScriptWidgetsetShouldWrite"; + // TODO some parts could be shared with AbstractApplicationServlet // TODO Can we close the application when the portlet is removed? Do we know @@ -213,6 +212,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet private boolean productionMode = false; private DeploymentConfiguration deploymentConfiguration = new DeploymentConfiguration() { + public String getConfiguredWidgetset(WrappedRequest request) { String widgetset = getApplicationOrSystemProperty( @@ -271,6 +271,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet * @return The location of static resources (inside which there should * be a VAADIN directory). Does not end with a slash (/). */ + public String getStaticFileLocation(WrappedRequest request) { String staticFileLocation = WrappedPortletRequest.cast(request) .getPortalProperty( @@ -329,7 +330,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet * Print an information/warning message about running with xsrf * protection disabled */ - logger.warning(WARNING_XSRF_PROTECTION_DISABLED); + getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED); } } @@ -345,7 +346,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet if (!productionMode) { /* Print an information/warning message about running in debug mode */ // TODO Maybe we need a different message for portlets? - logger.warning(NOT_PRODUCTION_MODE_INFO); + getLogger().warning(NOT_PRODUCTION_MODE_INFO); } } @@ -665,11 +666,12 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } catch (final SessionExpiredException e) { // TODO Figure out a better way to deal with // SessionExpiredExceptions - logger.finest("A user session has expired"); + getLogger().finest("A user session has expired"); } catch (final GeneralSecurityException e) { // TODO Figure out a better way to deal with // GeneralSecurityExceptions - logger.fine("General security exception, the security key was probably incorrect."); + getLogger() + .fine("General security exception, the security key was probably incorrect."); } catch (final Throwable e) { handleServiceException(request, response, application, e); } finally { @@ -690,9 +692,11 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet Root.setCurrentRoot(null); Application.setCurrentApplication(null); - requestTimer - .stop((AbstractWebApplicationContext) application - .getContext()); + PortletSession session = request + .getPortletSession(false); + if (session != null) { + requestTimer.stop(getApplicationContext(session)); + } } } } @@ -729,7 +733,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet private void handleUnknownRequest(PortletRequest request, PortletResponse response) { - logger.warning("Unknown request type"); + getLogger().warning("Unknown request type"); } /** @@ -795,8 +799,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet os.write(buffer, 0, bytes); } } else { - logger.info("Requested resource [" + resourceID - + "] could not be found"); + getLogger().info( + "Requested resource [" + resourceID + + "] could not be found"); response.setProperty(ResourceResponse.HTTP_STATUS_CODE, Integer.toString(HttpServletResponse.SC_NOT_FOUND)); } @@ -1141,4 +1146,8 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet return PortletApplicationContext2.getApplicationContext(portletSession); } + private static final Logger getLogger() { + return Logger.getLogger(AbstractApplicationPortlet.class.getName()); + } + } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 905cfe7e3c..2179761d31 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -87,9 +87,6 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // TODO Move some (all?) of the constants to a separate interface (shared // with portlet) - private static final Logger logger = Logger - .getLogger(AbstractApplicationServlet.class.getName()); - private Properties applicationProperties; private boolean productionMode = false; @@ -99,6 +96,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements private int resourceCacheTime = 3600; private DeploymentConfiguration deploymentConfiguration = new DeploymentConfiguration() { + public String getStaticFileLocation(WrappedRequest request) { HttpServletRequest servletRequest = WrappedHttpServletRequest .cast(request); @@ -149,8 +147,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * if an exception has occurred that interferes with the * servlet's normal operation. */ - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public void init(javax.servlet.ServletConfig servletConfig) throws javax.servlet.ServletException { super.init(servletConfig); @@ -186,7 +184,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Print an information/warning message about running with xsrf * protection disabled */ - logger.warning(WARNING_XSRF_PROTECTION_DISABLED); + getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED); } } @@ -200,7 +198,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements if (!productionMode) { /* Print an information/warning message about running in debug mode */ - logger.warning(NOT_PRODUCTION_MODE_INFO); + getLogger().warning(NOT_PRODUCTION_MODE_INFO); } } @@ -214,7 +212,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } catch (NumberFormatException nfe) { // Default is 1h resourceCacheTime = 3600; - logger.warning(WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC); + getLogger().warning(WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC); } } @@ -333,6 +331,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * @throws IOException * if the request for the TRACE cannot be handled. */ + @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -478,9 +477,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements Root.setCurrentRoot(null); Application.setCurrentApplication(null); - requestTimer - .stop((AbstractWebApplicationContext) application - .getContext()); + HttpSession session = request.getSession(false); + if (session != null) { + requestTimer.stop(getApplicationContext(session)); + } } } @@ -796,8 +796,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements resultPath = url.getFile(); } catch (final Exception e) { // FIXME: Handle exception - logger.log(Level.INFO, "Could not find resource path " + path, - e); + getLogger().log(Level.INFO, + "Could not find resource path " + path, e); } } return resultPath; @@ -1054,10 +1054,11 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements if (resourceUrl == null) { // cannot serve requested file - logger.info("Requested resource [" - + filename - + "] not found from filesystem or through class loader." - + " Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder."); + getLogger() + .info("Requested resource [" + + filename + + "] not found from filesystem or through class loader." + + " Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder."); response.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } @@ -1065,9 +1066,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // security check: do not permit navigation out of the VAADIN // directory if (!isAllowedVAADINResourceUrl(request, resourceUrl)) { - logger.info("Requested resource [" - + filename - + "] not accessible in the VAADIN directory or access to it is forbidden."); + getLogger() + .info("Requested resource [" + + filename + + "] not accessible in the VAADIN directory or access to it is forbidden."); response.setStatus(HttpServletResponse.SC_FORBIDDEN); return; } @@ -1090,10 +1092,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } } catch (Exception e) { // Failed to find out last modified timestamp. Continue without it. - logger.log( - Level.FINEST, - "Failed to find out last modified timestamp. Continuing without it.", - e); + getLogger() + .log(Level.FINEST, + "Failed to find out last modified timestamp. Continuing without it.", + e); } finally { if (connection instanceof URLConnection) { try { @@ -1105,7 +1107,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements is.close(); } } catch (IOException e) { - logger.log(Level.INFO, + getLogger().log(Level.INFO, "Error closing URLConnection input stream", e); } } @@ -1130,7 +1132,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * parameter in web.xml */ response.setHeader("Cache-Control", - "max-age: " + String.valueOf(resourceCacheTime)); + "max-age= " + String.valueOf(resourceCacheTime)); } // Write the resource to the client. @@ -1173,12 +1175,14 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // loader sees it. if (!resourceUrl.getPath().contains("!/VAADIN/")) { - logger.info("Blocked attempt to access a JAR entry not starting with /VAADIN/: " - + resourceUrl); + getLogger().info( + "Blocked attempt to access a JAR entry not starting with /VAADIN/: " + + resourceUrl); return false; } - logger.fine("Accepted access to a JAR entry using a class loader: " - + resourceUrl); + getLogger().fine( + "Accepted access to a JAR entry using a class loader: " + + resourceUrl); return true; } else { // Some servers such as GlassFish extract files from JARs (file:) @@ -1188,11 +1192,13 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // "/../" if (!resourceUrl.getPath().contains("/VAADIN/") || resourceUrl.getPath().contains("/../")) { - logger.info("Blocked attempt to access file: " + resourceUrl); + getLogger().info( + "Blocked attempt to access file: " + resourceUrl); return false; } - logger.fine("Accepted access to a file using a class loader: " - + resourceUrl); + getLogger().fine( + "Accepted access to a file using a class loader: " + + resourceUrl); return true; } } @@ -1733,4 +1739,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements c > 96 && c < 123 // a-z ; } + + private static final Logger getLogger() { + return Logger.getLogger(AbstractApplicationServlet.class.getName()); + } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index 494ca7e28e..e04857f800 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -92,9 +92,6 @@ public abstract class AbstractCommunicationManager implements Serializable { private static final String DASHDASH = "--"; - private static final Logger logger = Logger - .getLogger(AbstractCommunicationManager.class.getName()); - private static final RequestHandler APP_RESOURCE_HANDLER = new ApplicationResourceHandler(); private static final RequestHandler UNSUPPORTED_BROWSER_HANDLER = new UnsupportedBrowserHandler(); @@ -539,7 +536,7 @@ public abstract class AbstractCommunicationManager implements Serializable { if (root == null) { // This should not happen, no windows exists but // application is still open. - logger.warning("Could not get root for application"); + getLogger().warning("Could not get root for application"); return; } } else { @@ -562,7 +559,7 @@ public abstract class AbstractCommunicationManager implements Serializable { // FIXME: Handle exception // Not critical, but something is still wrong; print // stacktrace - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "getSystemMessages() failed - continuing", e2); } if (ci != null) { @@ -604,8 +601,9 @@ public abstract class AbstractCommunicationManager implements Serializable { } if (!Version.getFullVersion().equals(widgetsetVersion)) { - logger.warning(String.format(Constants.WIDGETSET_MISMATCH_INFO, - Version.getFullVersion(), widgetsetVersion)); + getLogger().warning( + String.format(Constants.WIDGETSET_MISMATCH_INFO, + Version.getFullVersion(), widgetsetVersion)); } } @@ -638,7 +636,7 @@ public abstract class AbstractCommunicationManager implements Serializable { printHighlightedComponentHierarchy(sb, component); } - logger.info(sb.toString()); + getLogger().info(sb.toString()); } protected void printHighlightedComponentHierarchy(StringBuilder sb, @@ -767,7 +765,7 @@ public abstract class AbstractCommunicationManager implements Serializable { // Paints components DirtyConnectorTracker rootConnectorTracker = root .getDirtyConnectorTracker(); - logger.log(Level.FINE, "* Creating response to client"); + getLogger().log(Level.FINE, "* Creating response to client"); if (repaintAll) { getClientCache(root).clear(); rootConnectorTracker.markAllConnectorsDirty(); @@ -780,8 +778,10 @@ public abstract class AbstractCommunicationManager implements Serializable { dirtyVisibleConnectors .addAll(getDirtyVisibleConnectors(rootConnectorTracker)); - logger.log(Level.FINE, "Found " + dirtyVisibleConnectors.size() - + " dirty connectors to paint"); + getLogger().log( + Level.FINE, + "Found " + dirtyVisibleConnectors.size() + + " dirty connectors to paint"); for (ClientConnector connector : dirtyVisibleConnectors) { if (connector instanceof Component) { ((Component) connector).updateState(); @@ -841,7 +841,8 @@ public abstract class AbstractCommunicationManager implements Serializable { try { referenceState = stateType.newInstance(); } catch (Exception e) { - logger.log(Level.WARNING, + getLogger().log( + Level.WARNING, "Error creating reference object for state of type " + stateType.getName()); } @@ -1006,16 +1007,16 @@ public abstract class AbstractCommunicationManager implements Serializable { (Class[]) null); ci = (Application.SystemMessages) m.invoke(null, (Object[]) null); } catch (NoSuchMethodException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "getSystemMessages() failed - continuing", e); } catch (IllegalArgumentException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "getSystemMessages() failed - continuing", e); } catch (IllegalAccessException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "getSystemMessages() failed - continuing", e); } catch (InvocationTargetException e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "getSystemMessages() failed - continuing", e); } @@ -1054,8 +1055,8 @@ public abstract class AbstractCommunicationManager implements Serializable { is = getThemeResourceAsStream(root, getTheme(root), resource); } catch (final Exception e) { // FIXME: Handle exception - logger.log(Level.FINER, "Failed to get theme resource stream.", - e); + getLogger().log(Level.FINER, + "Failed to get theme resource stream.", e); } if (is != null) { @@ -1074,13 +1075,13 @@ public abstract class AbstractCommunicationManager implements Serializable { r.close(); } catch (final java.io.IOException e) { // FIXME: Handle exception - logger.log(Level.INFO, "Resource transfer failed", e); + getLogger().log(Level.INFO, "Resource transfer failed", e); } outWriter.print("\"" + JsonPaintTarget.escapeJSON(layout.toString()) + "\""); } else { // FIXME: Handle exception - logger.severe("CustomLayout not found: " + resource); + getLogger().severe("CustomLayout not found: " + resource); } } outWriter.print("}"); @@ -1171,8 +1172,9 @@ public abstract class AbstractCommunicationManager implements Serializable { } sortByHierarchy((List) legacyComponents); for (Vaadin6Component c : legacyComponents) { - logger.fine("Painting Vaadin6Component " + c.getClass().getName() - + "@" + Integer.toHexString(c.hashCode())); + getLogger().fine( + "Painting Vaadin6Component " + c.getClass().getName() + "@" + + Integer.toHexString(c.hashCode())); paintTarget.startTag("change"); final String pid = c.getConnectorId(); paintTarget.addAttribute("pid", pid); @@ -1187,6 +1189,7 @@ public abstract class AbstractCommunicationManager implements Serializable { // containers rely on that their updateFromUIDL method has been called // before children start calling e.g. updateCaption Collections.sort(paintables, new Comparator<Component>() { + public int compare(Component c1, Component c2) { int depth1 = 0; while (c1.getParent() != null) { @@ -1472,6 +1475,7 @@ public abstract class AbstractCommunicationManager implements Serializable { enabledConnectors.add(connector); } } + for (int i = 0; i < invocations.size(); i++) { MethodInvocation invocation = invocations.get(i); @@ -1479,7 +1483,7 @@ public abstract class AbstractCommunicationManager implements Serializable { invocation.getConnectorId()); if (connector == null) { - logger.log( + getLogger().log( Level.WARNING, "RPC call to " + invocation.getInterfaceName() + "." + invocation.getMethodName() @@ -1517,7 +1521,7 @@ public abstract class AbstractCommunicationManager implements Serializable { msg += ", caption=" + caption; } } - logger.warning(msg); + getLogger().warning(msg); continue; } @@ -1545,14 +1549,13 @@ public abstract class AbstractCommunicationManager implements Serializable { } handleChangeVariablesError(app, errorComponent, e, changes); - } } } - } catch (JSONException e) { - logger.warning("Unable to parse RPC call from the client: " - + e.getMessage()); + getLogger().warning( + "Unable to parse RPC call from the client: " + + e.getMessage()); // TODO or return success = false? throw new RuntimeException(e); } @@ -1895,8 +1898,9 @@ public abstract class AbstractCommunicationManager implements Serializable { DateFormat dateFormat = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, l); if (!(dateFormat instanceof SimpleDateFormat)) { - logger.warning("Unable to get default date pattern for locale " - + l.toString()); + getLogger().warning( + "Unable to get default date pattern for locale " + + l.toString()); dateFormat = new SimpleDateFormat(); } final String df = ((SimpleDateFormat) dateFormat).toPattern(); @@ -2095,7 +2099,8 @@ public abstract class AbstractCommunicationManager implements Serializable { if (id == null) { id = nextTypeKey++; typeToKey.put(class1, id); - logger.log(Level.FINE, "Mapping " + class1.getName() + " to " + id); + getLogger().log(Level.FINE, + "Mapping " + class1.getName() + " to " + id); } return id.toString(); } @@ -2232,7 +2237,7 @@ public abstract class AbstractCommunicationManager implements Serializable { writeUidlResponse(request, true, pWriter, root, false); pWriter.print("}"); String initialUIDL = sWriter.toString(); - logger.log(Level.FINE, "Initial UIDL:" + initialUIDL); + getLogger().log(Level.FINE, "Initial UIDL:" + initialUIDL); return initialUIDL; } @@ -2386,4 +2391,7 @@ public abstract class AbstractCommunicationManager implements Serializable { } } + private static final Logger getLogger() { + return Logger.getLogger(AbstractCommunicationManager.class.getName()); + } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java b/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java index c0ae0afc26..bf4ea860a8 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java @@ -32,9 +32,6 @@ import com.vaadin.terminal.ApplicationResource; public abstract class AbstractWebApplicationContext implements ApplicationContext, HttpSessionBindingListener, Serializable { - private static final Logger logger = Logger - .getLogger(AbstractWebApplicationContext.class.getName()); - protected Collection<TransactionListener> listeners = Collections .synchronizedList(new LinkedList<TransactionListener>()); @@ -145,7 +142,7 @@ public abstract class AbstractWebApplicationContext implements // remove same application here. Possible if you got e.g. session // lifetime 1 min but socket write may take longer than 1 min. // FIXME: Handle exception - logger.log(Level.SEVERE, + getLogger().log(Level.SEVERE, "Could not remove application, leaking memory.", e); } } @@ -252,4 +249,8 @@ public abstract class AbstractWebApplicationContext implements return lastRequestTime; } + private Logger getLogger() { + return Logger.getLogger(AbstractWebApplicationContext.class.getName()); + } + }
\ No newline at end of file diff --git a/src/com/vaadin/terminal/gwt/server/ClientConnector.java b/src/com/vaadin/terminal/gwt/server/ClientConnector.java index 359e112738..dfdd58879d 100644 --- a/src/com/vaadin/terminal/gwt/server/ClientConnector.java +++ b/src/com/vaadin/terminal/gwt/server/ClientConnector.java @@ -3,7 +3,7 @@ */ package com.vaadin.terminal.gwt.server; -import java.util.Iterator; +import java.util.Collection; import java.util.List; import com.vaadin.terminal.AbstractClientConnector; @@ -12,7 +12,6 @@ import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; -import com.vaadin.ui.Root; /** * Interface implemented by all connectors that are capable of communicating @@ -30,8 +29,6 @@ public interface ClientConnector extends Connector, RpcTarget { * * @return an unmodifiable ordered list of pending server to client method * calls (not null) - * - * @since 7.0 */ public List<ClientMethodInvocation> retrievePendingRpcCalls(); @@ -61,7 +58,7 @@ public interface ClientConnector extends Connector, RpcTarget { * Causes a repaint of this connector, and all connectors below it. * * This should only be used in special cases, e.g when the state of a - * descendant depends on the state of a ancestor. + * descendant depends on the state of an ancestor. */ public void requestRepaintAll(); @@ -69,18 +66,18 @@ public interface ClientConnector extends Connector, RpcTarget { * Sets the parent connector of the connector. * * <p> - * This method automatically calls {@link #attach()} if the parent becomes - * attached to the application, regardless of whether it was attached - * previously. Conversely, if the parent is {@code null} and the connector - * is attached to the application, {@link #detach()} is called for the - * connector. + * This method automatically calls {@link #attach()} if the connector + * becomes attached to the application, regardless of whether it was + * attached previously. Conversely, if the parent is {@code null} and the + * connector is attached to the application, {@link #detach()} is called for + * the connector. * </p> * <p> * This method is rarely called directly. One of the * {@link ComponentContainer#addComponent(Component)} or - * {@link AbstractClientConnector#addFeature(Feature)} methods is normally - * used for adding connectors to a container and it will call this method - * implicitly. + * {@link AbstractClientConnector#addExtension(Extension)} methods are + * normally used for adding connectors to a parent and they will call this + * method implicitly. * </p> * * <p> @@ -103,15 +100,13 @@ public interface ClientConnector extends Connector, RpcTarget { * The caller of this method is {@link #setParent(ClientConnector)} if the * parent is itself already attached to the application. If not, the parent * will call the {@link #attach()} for all its children when it is attached - * to the application. This method is always called before the connector is - * painted for the first time. + * to the application. This method is always called before the connector's + * data is sent to the client-side for the first time. * </p> * * <p> * The attachment logic is implemented in {@link AbstractClientConnector}. * </p> - * - * @see #getApplication() */ public void attach(); @@ -119,25 +114,26 @@ public interface ClientConnector extends Connector, RpcTarget { * Notifies the component that it is detached from the application. * * <p> - * The {@link #getApplication()} and {@link #getRoot()} methods might return - * <code>null</code> after this method is called. - * </p> - * - * <p> - * This method must call {@link Root#componentDetached(Component)} to let - * the Root know that a new Component has been attached. - * </p> - * * - * <p> - * The caller of this method is {@link #setParent(Component)} if the parent - * is in the application. When the parent is detached from the application - * it is its response to call {@link #detach()} for all the children and to - * detach itself from the terminal. + * The caller of this method is {@link #setParent(ClientConnector)} if the + * parent is in the application. When the parent is detached from the + * application it is its response to call {@link #detach()} for all the + * children and to detach itself from the terminal. * </p> */ public void detach(); - public Iterator<Extension> getExtensionIterator(); + /** + * Get a read-only collection of all extensions attached to this connector. + * + * @return a collection of extensions + */ + public Collection<Extension> getExtensions(); + /** + * Remove an extension from this connector. + * + * @param extension + * the extension to remove. + */ public void removeExtension(Extension extension); } diff --git a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java b/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java index 335067ca7a..171d440796 100644 --- a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java +++ b/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java @@ -34,9 +34,6 @@ import com.vaadin.ui.Window; @SuppressWarnings({ "serial", "deprecation" }) public class ComponentSizeValidator implements Serializable { - private final static Logger logger = Logger - .getLogger(ComponentSizeValidator.class.getName()); - private final static int LAYERS_SHOWN = 4; /** @@ -134,7 +131,7 @@ public class ComponentSizeValidator implements Serializable { return parentCanDefineHeight(component); } catch (Exception e) { - logger.log(Level.FINER, + getLogger().log(Level.FINER, "An exception occurred while validating sizes.", e); return true; } @@ -154,7 +151,7 @@ public class ComponentSizeValidator implements Serializable { return parentCanDefineWidth(component); } catch (Exception e) { - logger.log(Level.FINER, + getLogger().log(Level.FINER, "An exception occurred while validating sizes.", e); return true; } @@ -653,11 +650,15 @@ public class ComponentSizeValidator implements Serializable { return; } catch (Exception e) { // TODO Auto-generated catch block - logger.log(Level.FINER, + getLogger().log(Level.FINER, "An exception occurred while validating sizes.", e); } } } + private static Logger getLogger() { + return Logger.getLogger(ComponentSizeValidator.class.getName()); + } + } diff --git a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java index 68fb87a986..0e8d1c0152 100644 --- a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java +++ b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java @@ -4,7 +4,8 @@ package com.vaadin.terminal.gwt.server; import java.io.PrintWriter; -import java.util.Iterator; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -28,9 +29,6 @@ import com.vaadin.ui.Component; public class DragAndDropService implements VariableOwner, ClientConnector { - private static final Logger logger = Logger - .getLogger(DragAndDropService.class.getName()); - private int lastVisitId; private boolean lastVisitAccepted = false; @@ -50,8 +48,9 @@ public class DragAndDropService implements VariableOwner, ClientConnector { // Validate drop handler owner if (!(owner instanceof DropTarget)) { - logger.severe("DropHandler owner " + owner - + " must implement DropTarget"); + getLogger() + .severe("DropHandler owner " + owner + + " must implement DropTarget"); return; } // owner cannot be null here @@ -81,8 +80,9 @@ public class DragAndDropService implements VariableOwner, ClientConnector { DropHandler dropHandler = (dropTarget).getDropHandler(); if (dropHandler == null) { // No dropHandler returned so no drop can be performed. - logger.fine("DropTarget.getDropHandler() returned null for owner: " - + dropTarget); + getLogger().fine( + "DropTarget.getDropHandler() returned null for owner: " + + dropTarget); return; } @@ -275,13 +275,16 @@ public class DragAndDropService implements VariableOwner, ClientConnector { } - public Iterator<Extension> getExtensionIterator() { + public Collection<Extension> getExtensions() { // TODO Auto-generated method stub - return null; + return Collections.emptySet(); } public void removeExtension(Extension extension) { // TODO Auto-generated method stub + } + private Logger getLogger() { + return Logger.getLogger(DragAndDropService.class.getName()); } } diff --git a/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java index 485c98f036..a6032fa98d 100644 --- a/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java @@ -94,9 +94,6 @@ import com.vaadin.service.ApplicationContext; */ public class GAEApplicationServlet extends ApplicationServlet { - private static final Logger logger = Logger - .getLogger(GAEApplicationServlet.class.getName()); - // memcache mutex is MUTEX_BASE + sessio id private static final String MUTEX_BASE = "_vmutex"; @@ -209,8 +206,9 @@ public class GAEApplicationServlet extends ApplicationServlet { try { Thread.sleep(RETRY_AFTER_MILLISECONDS); } catch (InterruptedException e) { - logger.finer("Thread.sleep() interrupted while waiting for lock. Trying again. " - + e); + getLogger().finer( + "Thread.sleep() interrupted while waiting for lock. Trying again. " + + e); } } @@ -252,16 +250,16 @@ public class GAEApplicationServlet extends ApplicationServlet { ds.put(entity); } catch (DeadlineExceededException e) { - logger.warning("DeadlineExceeded for " + session.getId()); + getLogger().warning("DeadlineExceeded for " + session.getId()); sendDeadlineExceededNotification(request, response); } catch (NotSerializableException e) { - logger.log(Level.SEVERE, "Not serializable!", e); + getLogger().log(Level.SEVERE, "Not serializable!", e); // TODO this notification is usually not shown - should we redirect // in some other way - can we? sendNotSerializableNotification(request, response); } catch (Exception e) { - logger.log(Level.WARNING, + getLogger().log(Level.WARNING, "An exception occurred while servicing request.", e); sendCriticalErrorNotification(request, response); @@ -308,12 +306,14 @@ public class GAEApplicationServlet extends ApplicationServlet { session.setAttribute(WebApplicationContext.class.getName(), applicationContext); } catch (IOException e) { - logger.log(Level.WARNING, + getLogger().log( + Level.WARNING, "Could not de-serialize ApplicationContext for " + session.getId() + " A new one will be created. ", e); } catch (ClassNotFoundException e) { - logger.log(Level.WARNING, + getLogger().log( + Level.WARNING, "Could not de-serialize ApplicationContext for " + session.getId() + " A new one will be created. ", e); @@ -368,8 +368,9 @@ public class GAEApplicationServlet extends ApplicationServlet { List<Entity> entities = pq.asList(Builder .withLimit(CLEANUP_LIMIT)); if (entities != null) { - logger.info("Vaadin cleanup deleting " + entities.size() - + " expired Vaadin sessions."); + getLogger().info( + "Vaadin cleanup deleting " + entities.size() + + " expired Vaadin sessions."); List<Key> keys = new ArrayList<Key>(); for (Entity e : entities) { keys.add(e.getKey()); @@ -387,8 +388,9 @@ public class GAEApplicationServlet extends ApplicationServlet { List<Entity> entities = pq.asList(Builder .withLimit(CLEANUP_LIMIT)); if (entities != null) { - logger.info("Vaadin cleanup deleting " + entities.size() - + " expired appengine sessions."); + getLogger().info( + "Vaadin cleanup deleting " + entities.size() + + " expired appengine sessions."); List<Key> keys = new ArrayList<Key>(); for (Entity e : entities) { keys.add(e.getKey()); @@ -397,7 +399,11 @@ public class GAEApplicationServlet extends ApplicationServlet { } } } catch (Exception e) { - logger.log(Level.WARNING, "Exception while cleaning.", e); + getLogger().log(Level.WARNING, "Exception while cleaning.", e); } } + + private static final Logger getLogger() { + return Logger.getLogger(GAEApplicationServlet.class.getName()); + } } diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java index 1cde164618..70ab452e4e 100644 --- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java @@ -43,9 +43,6 @@ import com.vaadin.ui.CustomLayout; @SuppressWarnings("serial") public class JsonPaintTarget implements PaintTarget { - private static final Logger logger = Logger.getLogger(JsonPaintTarget.class - .getName()); - /* Document type declarations */ private final static String UIDL_ARG_NAME = "name"; @@ -162,6 +159,7 @@ public class JsonPaintTarget implements PaintTarget { * @throws Paintexception * if the paint operation failed. */ + public void endTag(String tagName) throws PaintException { // In case of null data output nothing: if (tagName == null) { @@ -328,6 +326,7 @@ public class JsonPaintTarget implements PaintTarget { * if the paint operation failed. * */ + public void addText(String str) throws PaintException { tag.addData("\"" + escapeJSON(str) + "\""); } @@ -468,8 +467,8 @@ public class JsonPaintTarget implements PaintTarget { tag.addVariable(new StringVariable(owner, name, escapeJSON(value))); } - public void addVariable(VariableOwner owner, String name, - Component value) throws PaintException { + public void addVariable(VariableOwner owner, String name, Component value) + throws PaintException { tag.addVariable(new StringVariable(owner, name, value.getConnectorId())); } @@ -516,6 +515,7 @@ public class JsonPaintTarget implements PaintTarget { * @throws PaintException * if the paint operation failed. */ + public void addUploadStreamVariable(VariableOwner owner, String name) throws PaintException { startTag("uploadstream"); @@ -535,6 +535,7 @@ public class JsonPaintTarget implements PaintTarget { * @throws PaintException * if the paint operation failed. */ + public void addSection(String sectionTagName, String sectionData) throws PaintException { tag.addData("{\"" + sectionTagName + "\":\"" + escapeJSON(sectionData) @@ -549,6 +550,7 @@ public class JsonPaintTarget implements PaintTarget { * @throws PaintException * if the paint operation failed. */ + public void addUIDL(String xml) throws PaintException { // Ensure that the target is open @@ -582,6 +584,7 @@ public class JsonPaintTarget implements PaintTarget { * @see com.vaadin.terminal.PaintTarget#addXMLSection(String, String, * String) */ + public void addXMLSection(String sectionTagName, String sectionData, String namespace) throws PaintException { @@ -646,12 +649,14 @@ public class JsonPaintTarget implements PaintTarget { * @see com.vaadin.terminal.PaintTarget#startPaintable(com.vaadin.terminal * .Paintable, java.lang.String) */ + public PaintStatus startPaintable(Component connector, String tagName) throws PaintException { boolean topLevelPaintable = openPaintables.isEmpty(); - logger.fine("startPaintable for " + connector.getClass().getName() - + "@" + Integer.toHexString(connector.hashCode())); + getLogger().fine( + "startPaintable for " + connector.getClass().getName() + "@" + + Integer.toHexString(connector.hashCode())); startTag(tagName, true); openPaintables.push(connector); @@ -672,8 +677,9 @@ public class JsonPaintTarget implements PaintTarget { } public void endPaintable(Component paintable) throws PaintException { - logger.fine("endPaintable for " + paintable.getClass().getName() + "@" - + Integer.toHexString(paintable.hashCode())); + getLogger().fine( + "endPaintable for " + paintable.getClass().getName() + "@" + + Integer.toHexString(paintable.hashCode())); ClientConnector openPaintable = openPaintables.peek(); if (paintable != openPaintable) { @@ -692,6 +698,7 @@ public class JsonPaintTarget implements PaintTarget { * * @see com.vaadin.terminal.PaintTarget#addCharacterData(java.lang.String ) */ + public void addCharacterData(String text) throws PaintException { if (text != null) { tag.addData(text); @@ -998,8 +1005,13 @@ public class JsonPaintTarget implements PaintTarget { * * @see com.vaadin.terminal.PaintTarget#isFullRepaint() */ + public boolean isFullRepaint() { return !cacheEnabled; } + private static final Logger getLogger() { + return Logger.getLogger(JsonPaintTarget.class.getName()); + } + } diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index 661da57af6..de4f918b75 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -48,9 +48,6 @@ import com.vaadin.ui.Root; @SuppressWarnings("serial") public class PortletApplicationContext2 extends AbstractWebApplicationContext { - private static final Logger logger = Logger - .getLogger(PortletApplicationContext2.class.getName()); - protected Map<Application, Set<PortletListener>> portletListeners = new HashMap<Application, Set<PortletListener>>(); protected transient PortletSession session; @@ -76,11 +73,11 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { return new File(url.getFile()); } catch (final Exception e) { // FIXME: Handle exception - logger.log( - Level.INFO, - "Cannot access base directory, possible security issue " - + "with Application Server or Servlet Container", - e); + getLogger() + .log(Level.INFO, + "Cannot access base directory, possible security issue " + + "with Application Server or Servlet Container", + e); } } return null; @@ -419,4 +416,8 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { "Portlet mode can only be changed from a portlet request"); } } + + private Logger getLogger() { + return Logger.getLogger(PortletApplicationContext2.class.getName()); + } } diff --git a/src/com/vaadin/terminal/gwt/server/WebBrowser.java b/src/com/vaadin/terminal/gwt/server/WebBrowser.java index 358f6f38fb..38b5409594 100644 --- a/src/com/vaadin/terminal/gwt/server/WebBrowser.java +++ b/src/com/vaadin/terminal/gwt/server/WebBrowser.java @@ -23,8 +23,6 @@ public class WebBrowser implements Terminal { private int screenHeight = 0; private int screenWidth = 0; - private int clientHeight = 0; - private int clientWidth = 0; private String browserApplication = null; private Locale locale; private String address; @@ -43,6 +41,7 @@ public class WebBrowser implements Terminal { * * @return Always returns null. */ + public String getDefaultTheme() { return null; } @@ -52,6 +51,7 @@ public class WebBrowser implements Terminal { * * @see com.vaadin.terminal.Terminal#getScreenHeight() */ + public int getScreenHeight() { return screenHeight; } @@ -61,35 +61,12 @@ public class WebBrowser implements Terminal { * * @see com.vaadin.terminal.Terminal#getScreenWidth() */ + public int getScreenWidth() { return screenWidth; } /** - * Gets the height of the client (browser window). - * <p> - * Note that the client size is only updated on a full repaint, not when the - * browser window size changes - * - * @return The height of the client or 0 if unknown. - */ - public int getClientHeight() { - return clientHeight; - } - - /** - * Gets the width of the client (browser window) - * <p> - * Note that the client size is only updated on a full repaint, not when the - * browser window size changes - * - * @return The width of the client or 0 if unknown. - */ - public int getClientWidth() { - return clientWidth; - } - - /** * Get the browser user-agent string. * * @return The raw browser userAgent string @@ -367,10 +344,6 @@ public class WebBrowser implements Terminal { * Screen width * @param sh * Screen height - * @param cw - * Client width - * @param ch - * Client height * @param tzo * TimeZone offset in minutes from GMT * @param rtzo @@ -383,9 +356,9 @@ public class WebBrowser implements Terminal { * the current date in milliseconds since the epoch * @param touchDevice */ - void updateClientSideDetails(String sw, String sh, String cw, String ch, - String tzo, String rtzo, String dstSavings, String dstInEffect, - String curDate, boolean touchDevice) { + void updateClientSideDetails(String sw, String sh, String tzo, String rtzo, + String dstSavings, String dstInEffect, String curDate, + boolean touchDevice) { if (sw != null) { try { screenHeight = Integer.parseInt(sh); @@ -394,14 +367,6 @@ public class WebBrowser implements Terminal { screenHeight = screenWidth = 0; } } - if (cw != null) { - try { - clientHeight = Integer.parseInt(ch); - clientWidth = Integer.parseInt(cw); - } catch (final NumberFormatException e) { - clientHeight = clientWidth = 0; - } - } if (tzo != null) { try { // browser->java conversion: min->ms, reverse sign @@ -462,8 +427,7 @@ public class WebBrowser implements Terminal { if (request.getParameter("sw") != null) { updateClientSideDetails(request.getParameter("sw"), - request.getParameter("sh"), request.getParameter("cw"), - request.getParameter("ch"), request.getParameter("tzo"), + request.getParameter("sh"), request.getParameter("tzo"), request.getParameter("rtzo"), request.getParameter("dstd"), request.getParameter("dston"), request.getParameter("curdate"), diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriteriaFactoryGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriteriaFactoryGenerator.java index d8d3c23e0c..459b6ddd30 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriteriaFactoryGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriteriaFactoryGenerator.java @@ -4,7 +4,6 @@ package com.vaadin.terminal.gwt.widgetsetutils; import java.io.PrintWriter; -import java.util.Collection; import java.util.Date; import com.google.gwt.core.ext.Generator; @@ -16,14 +15,13 @@ import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.event.dd.acceptcriteria.ClientCriterion; +import com.vaadin.terminal.gwt.client.ui.dd.AcceptCriterion; import com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterion; import com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterionFactory; /** * GWT generator to build {@link VAcceptCriterionFactory} implementation - * dynamically based on {@link ClientCriterion} annotations available in + * dynamically based on {@link AcceptCriterion} annotations available in * classpath. * */ @@ -102,21 +100,23 @@ public class AcceptCriteriaFactoryGenerator extends Generator { sourceWriter.println("name = name.intern();"); - Collection<Class<? extends AcceptCriterion>> clientSideVerifiableCriterion = ClassPathExplorer - .getCriterion(); - - for (Class<? extends AcceptCriterion> class1 : clientSideVerifiableCriterion) { - logger.log(Type.INFO, - "creating mapping for " + class1.getCanonicalName()); - String canonicalName = class1.getCanonicalName(); - Class<? extends VAcceptCriterion> clientClass = class1 - .getAnnotation(ClientCriterion.class).value(); - sourceWriter.print("if (\""); - sourceWriter.print(canonicalName); - sourceWriter.print("\" == name) return GWT.create("); - sourceWriter.print(clientClass.getCanonicalName()); - sourceWriter.println(".class );"); - sourceWriter.print("else "); + JClassType criteriaType = context.getTypeOracle().findType( + VAcceptCriterion.class.getName()); + for (JClassType clientClass : criteriaType.getSubtypes()) { + AcceptCriterion annotation = clientClass + .getAnnotation(AcceptCriterion.class); + if (annotation != null) { + String clientClassName = clientClass.getQualifiedSourceName(); + String serverClassName = clientClass.getAnnotation( + AcceptCriterion.class).value(); + logger.log(Type.INFO, "creating mapping for " + serverClassName); + sourceWriter.print("if (\""); + sourceWriter.print(serverClassName); + sourceWriter.print("\" == name) return GWT.create("); + sourceWriter.print(clientClassName); + sourceWriter.println(".class );"); + sourceWriter.print("else "); + } } sourceWriter.println("return null;"); diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java index 6a0aa0f4c2..1c5b736492 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java @@ -6,33 +6,23 @@ package com.vaadin.terminal.gwt.widgetsetutils; import java.io.File; import java.io.FileFilter; import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.Attributes; -import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.event.dd.acceptcriteria.ClientCriterion; -import com.vaadin.terminal.gwt.server.ClientConnector; - /** * Utility class to collect widgetset related information from classpath. * Utility will seek all directories from classpaths, and jar files having @@ -53,9 +43,6 @@ import com.vaadin.terminal.gwt.server.ClientConnector; */ public class ClassPathExplorer { - private static Logger logger = Logger.getLogger(ClassPathExplorer.class - .getName()); - private static final String VAADIN_ADDON_VERSION_ATTRIBUTE = "Vaadin-Package-Version"; /** @@ -92,46 +79,6 @@ public class ClassPathExplorer { } /** - * Finds server side widgets with ClientWidget annotation on the class path - * (entries that can contain widgets/widgetsets - see - * getRawClasspathEntries()). - * - * As a side effect, also accept criteria are searched under the same class - * path entries and added into the acceptCriterion collection. - * - * @return a collection of {@link ClientConnector} classes - */ - public static void findAcceptCriteria() { - logger.info("Searching for accept criteria.."); - long start = System.currentTimeMillis(); - Set<String> keySet = classpathLocations.keySet(); - for (String url : keySet) { - logger.fine("Searching for accept criteria in " - + classpathLocations.get(url)); - searchForPaintables(classpathLocations.get(url), url); - } - long end = System.currentTimeMillis(); - - logger.info("Search took " + (end - start) + "ms"); - - } - - /** - * Finds all accept criteria having client side counterparts (classes with - * the {@link ClientCriterion} annotation). - * - * @return Collection of AcceptCriterion classes - */ - public static Collection<Class<? extends AcceptCriterion>> getCriterion() { - if (acceptCriterion.isEmpty()) { - // accept criterion are searched as a side effect, normally after - // paintable detection - findAcceptCriteria(); - } - return acceptCriterion; - } - - /** * Finds the names and locations of widgetsets available on the class path. * * @return map from widgetset classname to widgetset location URL @@ -154,6 +101,7 @@ public class ClassPathExplorer { sb.append(widgetsets.get(ws)); sb.append("\n"); } + final Logger logger = getLogger(); logger.info(sb.toString()); logger.info("Search took " + (end - start) + "ms"); return widgetsets; @@ -214,7 +162,7 @@ public class ClassPathExplorer { } catch (MalformedURLException e) { // should never happen as based on an existing URL, // only changing end of file name/path part - logger.log(Level.SEVERE, + getLogger().log(Level.SEVERE, "Error locating the widgetset " + classname, e); } } @@ -250,7 +198,7 @@ public class ClassPathExplorer { } } } catch (IOException e) { - logger.log(Level.WARNING, "Error parsing jar file", e); + getLogger().log(Level.WARNING, "Error parsing jar file", e); } } @@ -278,7 +226,7 @@ public class ClassPathExplorer { classpath = classpath.substring(0, classpath.length() - 1); } - logger.fine("Classpath: " + classpath); + getLogger().fine("Classpath: " + classpath); String[] split = classpath.split(pathSep); for (int i = 0; i < split.length; i++) { @@ -312,6 +260,7 @@ public class ClassPathExplorer { include(null, file, locations); } long end = System.currentTimeMillis(); + Logger logger = getLogger(); if (logger.isLoggable(Level.FINE)) { logger.fine("getClassPathLocations took " + (end - start) + "ms"); } @@ -352,7 +301,7 @@ public class ClassPathExplorer { url = new URL("jar:" + url.toExternalForm() + "!/"); JarURLConnection conn = (JarURLConnection) url .openConnection(); - logger.fine(url.toString()); + getLogger().fine(url.toString()); JarFile jarFile = conn.getJarFile(); Manifest manifest = jarFile.getManifest(); if (manifest != null) { @@ -363,9 +312,11 @@ public class ClassPathExplorer { } } } catch (MalformedURLException e) { - logger.log(Level.FINEST, "Failed to inspect JAR file", e); + getLogger().log(Level.FINEST, "Failed to inspect JAR file", + e); } catch (IOException e) { - logger.log(Level.FINEST, "Failed to inspect JAR file", e); + getLogger().log(Level.FINEST, "Failed to inspect JAR file", + e); } return false; @@ -445,151 +396,6 @@ public class ClassPathExplorer { } /** - * Searches for all paintable classes and accept criteria under a location - * based on {@link ClientCriterion} annotations. - * - * Note that client criteria are updated directly to the - * {@link #acceptCriterion} field, whereas paintables are added to the - * paintables map given as a parameter. - * - * @param location - * @param locationString - */ - private final static void searchForPaintables(URL location, - String locationString) { - - // Get a File object for the package - File directory = new File(location.getFile()); - - if (directory.exists() && !directory.isHidden()) { - // Get the list of the files contained in the directory - String[] files = directory.list(); - for (int i = 0; i < files.length; i++) { - // we are only interested in .class files - if (files[i].endsWith(".class")) { - // remove the .class extension - String classname = files[i].substring(0, - files[i].length() - 6); - String packageName = locationString - .substring(locationString.lastIndexOf("/") + 1); - classname = packageName + "." + classname; - tryToAdd(classname); - } - } - } else { - try { - // check files in jar file, entries will list all directories - // and files in jar - - URLConnection openConnection = location.openConnection(); - - if (openConnection instanceof JarURLConnection) { - JarURLConnection conn = (JarURLConnection) openConnection; - - JarFile jarFile = conn.getJarFile(); - - // Only scan for paintables in Vaadin add-ons - if (!isVaadinAddon(jarFile)) { - return; - } - - Enumeration<JarEntry> e = jarFile.entries(); - while (e.hasMoreElements()) { - JarEntry entry = e.nextElement(); - String entryname = entry.getName(); - if (!entry.isDirectory() - && entryname.endsWith(".class")) { - String classname = entryname.substring(0, - entryname.length() - 6); - if (classname.startsWith("/")) { - classname = classname.substring(1); - } - classname = classname.replace('/', '.'); - tryToAdd(classname); - } - } - } - } catch (IOException e) { - logger.warning(e.toString()); - } - } - - } - - /** - * A print stream that ignores all output. - * - * This is used to hide error messages from static initializers of classes - * being inspected. - */ - private static PrintStream devnull = new PrintStream(new OutputStream() { - @Override - public void write(int b) throws IOException { - // NOP - } - }); - - /** - * Collection of all {@link AcceptCriterion} classes, updated as a side - * effect of {@link #searchForPaintables(URL, String, Collection)} based on - * {@link ClientCriterion} annotations. - */ - private static Set<Class<? extends AcceptCriterion>> acceptCriterion = new HashSet<Class<? extends AcceptCriterion>>(); - - /** - * Checks a class for the {@link ClientCriterion} annotations, and adds it - * to the appropriate collection. - * - * @param fullclassName - */ - @SuppressWarnings("unchecked") - private static void tryToAdd(final String fullclassName) { - PrintStream out = System.out; - PrintStream err = System.err; - Throwable errorToShow = null; - Level logLevel = null; - try { - System.setErr(devnull); - System.setOut(devnull); - - Class<?> c = Class.forName(fullclassName); - - if (c.getAnnotation(ClientCriterion.class) != null) { - acceptCriterion.add((Class<? extends AcceptCriterion>) c); - } - } catch (UnsupportedClassVersionError e) { - // Inform the user about this as the class might contain a Paintable - // Typically happens when using an add-on that is compiled using a - // newer Java version. - logLevel = Level.INFO; - errorToShow = e; - } catch (ClassNotFoundException e) { - // Don't show to avoid flooding the user with irrelevant messages - logLevel = Level.FINE; - errorToShow = e; - } catch (LinkageError e) { - // Don't show to avoid flooding the user with irrelevant messages - logLevel = Level.FINE; - errorToShow = e; - } catch (Exception e) { - // Don't show to avoid flooding the user with irrelevant messages - logLevel = Level.FINE; - errorToShow = e; - } finally { - System.setErr(err); - System.setOut(out); - } - - // Must be done here after stderr and stdout have been reset. - if (errorToShow != null && logLevel != null) { - logger.log(logLevel, - "Failed to load class " + fullclassName + ". " - + errorToShow.getClass().getName() + ": " - + errorToShow.getMessage()); - } - } - - /** * Find and return the default source directory where to create new * widgetsets. * @@ -601,6 +407,9 @@ public class ClassPathExplorer { * @return URL */ public static URL getDefaultSourceDirectory() { + + final Logger logger = getLogger(); + if (logger.isLoggable(Level.FINE)) { logger.fine("classpathLocations values:"); ArrayList<String> locations = new ArrayList<String>( @@ -632,44 +441,21 @@ public class ClassPathExplorer { } /** - * Checks if the given jarFile is a Vaadin add-on. - * - * @param jarFile - * @return true if the file is an add-on, false otherwise - * @throws IOException - */ - private static boolean isVaadinAddon(JarFile jarFile) throws IOException { - Manifest manifest = jarFile.getManifest(); - if (manifest == null) { - return false; - } - Attributes mainAttributes = manifest.getMainAttributes(); - if (mainAttributes == null) { - return false; - } - - return (mainAttributes.getValue(VAADIN_ADDON_VERSION_ATTRIBUTE) != null); - } - - /** * Test method for helper tool */ public static void main(String[] args) { - ClassPathExplorer.findAcceptCriteria(); - logger.info("Found client criteria:"); - for (Class<? extends AcceptCriterion> cls : acceptCriterion) { - logger.info(cls.getCanonicalName()); - } - - logger.info(""); - logger.info("Searching available widgetsets..."); + getLogger().info("Searching available widgetsets..."); Map<String, URL> availableWidgetSets = ClassPathExplorer .getAvailableWidgetSets(); for (String string : availableWidgetSets.keySet()) { - logger.info(string + " in " + availableWidgetSets.get(string)); + getLogger().info(string + " in " + availableWidgetSets.get(string)); } } + private static final Logger getLogger() { + return Logger.getLogger(ClassPathExplorer.class.getName()); + } + } diff --git a/src/com/vaadin/tools/WidgetsetCompiler.java b/src/com/vaadin/tools/WidgetsetCompiler.java index 618313a8d8..407f0e2387 100644 --- a/src/com/vaadin/tools/WidgetsetCompiler.java +++ b/src/com/vaadin/tools/WidgetsetCompiler.java @@ -36,9 +36,6 @@ import com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder; @Deprecated public class WidgetsetCompiler { - private static final Logger logger = Logger - .getLogger(WidgetsetCompiler.class.getName()); - /** * @param args * same arguments as for com.google.gwt.dev.Compiler @@ -75,7 +72,7 @@ public class WidgetsetCompiler { String[].class); method.invoke(null, new Object[] { args }); } catch (Throwable thr) { - logger.log(Level.SEVERE, + getLogger().log(Level.SEVERE, "Widgetset compilation failed", thr); } } @@ -85,7 +82,11 @@ public class WidgetsetCompiler { runThread.join(); System.out.println("Widgetset compilation finished"); } catch (Throwable thr) { - logger.log(Level.SEVERE, "Widgetset compilation failed", thr); + getLogger().log(Level.SEVERE, "Widgetset compilation failed", thr); } } + + private static final Logger getLogger() { + return Logger.getLogger(WidgetsetCompiler.class.getName()); + } } diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java new file mode 100644 index 0000000000..95c45f55f9 --- /dev/null +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -0,0 +1,161 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +import com.vaadin.terminal.JavaScriptCallbackHelper; +import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; +import com.vaadin.terminal.gwt.client.ui.JavaScriptWidget; + +/** + * Base class for Components with all client-side logic implemented using + * JavaScript. + * <p> + * When a new JavaScript component is initialized in the browser, the framework + * will look for a globally defined JavaScript function that will initialize the + * component. The name of the initialization function is formed by replacing . + * with _ in the name of the server-side class. If no such function is defined, + * each super class is used in turn until a match is found. The framework will + * thus first attempt with <code>com_example_MyComponent</code> for the + * server-side + * <code>com.example.MyComponent extends AbstractJavaScriptComponent</code> + * class. If MyComponent instead extends <code>com.example.SuperComponent</code> + * , then <code>com_example_SuperComponent</code> will also be attempted if + * <code>com_example_MyComponent</code> has not been defined. + * <p> + * JavaScript components have a very simple GWT widget ({@link JavaScriptWidget} + * ) just consisting of a <code>div</code> element to which the JavaScript code + * should initialize its own user interface. + * <p> + * The initialization function will be called with <code>this</code> pointing to + * a connector wrapper object providing integration to Vaadin with the following + * functions: + * <ul> + * <li><code>getConnectorId()</code> - returns a string with the id of the + * connector.</li> + * <li><code>getParentId([connectorId])</code> - returns a string with the id of + * the connector's parent. If <code>connectorId</code> is provided, the id of + * the parent of the corresponding connector with the passed id is returned + * instead.</li> + * <li><code>getWidgetElement([connectorId])</code> - returns the DOM Element + * that is the root of a connector's widget. <code>null</code> is returned if + * the connector can not be found or if the connector doesn't have a widget. If + * <code>connectorId</code> is not provided, the connector id of the current + * connector will be used.</li> + * <li><code>getState()</code> - returns an object corresponding to the shared + * state defined on the server. The scheme for conversion between Java and + * JavaScript types is described bellow.</li> + * <li><code>registerRpc([name, ] rpcObject)</code> - registers the + * <code>rpcObject</code> as a RPC handler. <code>rpcObject</code> should be an + * object with field containing functions for all eligible RPC functions. If + * <code>name</code> is provided, the RPC handler will only used for RPC calls + * for the RPC interface with the same fully qualified Java name. If no + * <code>name</code> is provided, the RPC handler will be used for all incoming + * RPC invocations where the RPC method name is defined as a function field in + * the handler. The scheme for conversion between Java types in the RPC + * interface definition and the JavaScript values passed as arguments to the + * handler functions is described bellow.</li> + * <li><code>getRpcProxy([name])</code> - returns an RPC proxy object. If + * <code>name</code> is provided, the proxy object will contain functions for + * all methods in the RPC interface with the same fully qualified name, provided + * a RPC handler has been registered by the server-side code. If no + * <code>name</code> is provided, the returned RPC proxy object will contain + * functions for all methods in all RPC interfaces registered for the connector + * on the server. If the same method name is present in multiple registered RPC + * interfaces, the corresponding function in the RPC proxy object will throw an + * exception when called. The scheme for conversion between Java types in the + * RPC interface and the JavaScript values that should be passed to the + * functions is described bellow.</li> + * </ul> + * The connector wrapper also supports these special functions: + * <ul> + * <li><code>onStateChange</code> - If the JavaScript code assigns a function to + * the field, that function is called whenever the contents of the shared state + * is changed.</li> + * <li>Any field name corresponding to a call to + * {@link #registerCallback(String, JavaScriptCallback)} on the server will + * automatically be present as a function that triggers the registered callback + * on the server.</li> + * <li>Any field name referred to using + * {@link #invokeCallback(String, Object...)} on the server will be called if a + * function has been assigned to the field.</li> + * </ul> + * <p> + * + * Values in the Shared State and in RPC calls are converted between Java and + * JavaScript using the following conventions: + * <ul> + * <li>Primitive Java numbers (byte, char, int, long, float, double) and their + * boxed types (Byte, Character, Integer, Long, Float, Double) are represented + * by JavaScript numbers.</li> + * <li>The primitive Java boolean and the boxed Boolean are represented by + * JavaScript booleans.</li> + * <li>Java Strings are represented by JavaScript strings.</li> + * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> + * <li>Map<String, ?> in Java is represented by JavaScript object with fields + * corresponding to the map keys.</li> + * <li>Any other Java Map is represented by a JavaScript array containing two + * arrays, the first contains the keys and the second contains the values in the + * same order.</li> + * <li>A Java Bean is represented by a JavaScript object with fields + * corresponding to the bean's properties.</li> + * <li>A Java Connector is represented by a JavaScript string containing the + * connector's id.</li> + * <li>A pluggable serialization mechanism is provided for types not described + * here. Please refer to the documentation for specific types for serialization + * information.</li> + * </ul> + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class AbstractJavaScriptComponent extends AbstractComponent { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + @Override + protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) { + super.registerRpc(implementation, rpcInterfaceType); + callbackHelper.registerRpc(rpcInterfaceType); + } + + /** + * Register a {@link JavaScriptCallback} that can be called from the + * JavaScript using the provided name. A JavaScript function with the + * provided name will be added to the connector wrapper object (initially + * available as <code>this</code>). Calling that JavaScript function will + * cause the call method in the registered {@link JavaScriptCallback} to be + * invoked with the same arguments. + * + * @param functionName + * the name that should be used for client-side callback + * @param javaScriptCallback + * the callback object that will be invoked when the JavaScript + * function is called + */ + protected void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbackHelper.registerCallback(functionName, javaScriptCallback); + } + + /** + * Invoke a named function that the connector JavaScript has added to the + * JavaScript connector wrapper object. The arguments should only contain + * data types that can be represented in JavaScript, including primitive + * boxing types, arrays, String, List, Set, Map, Connector and JavaBeans. + * + * @param name + * the name of the function + * @param arguments + * function arguments + */ + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } + + @Override + public JavaScriptComponentState getState() { + return (JavaScriptComponentState) super.getState(); + } +} diff --git a/src/com/vaadin/ui/AbstractJavascriptComponent.java b/src/com/vaadin/ui/AbstractJavascriptComponent.java deleted file mode 100644 index 0a26c10239..0000000000 --- a/src/com/vaadin/ui/AbstractJavascriptComponent.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import com.vaadin.terminal.JavascriptRpcHelper; - -public class AbstractJavascriptComponent extends AbstractComponent { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java index e586810b2d..6a927251af 100644 --- a/src/com/vaadin/ui/AbstractSelect.java +++ b/src/com/vaadin/ui/AbstractSelect.java @@ -24,7 +24,6 @@ import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropTarget; import com.vaadin.event.dd.TargetDetailsImpl; -import com.vaadin.event.dd.acceptcriteria.ClientCriterion; import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion; import com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor; import com.vaadin.event.dd.acceptcriteria.TargetDetailIs; @@ -33,8 +32,6 @@ import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; import com.vaadin.terminal.Vaadin6Component; -import com.vaadin.terminal.gwt.client.ui.dd.VIsOverId; -import com.vaadin.terminal.gwt.client.ui.dd.VItemIdIs; import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; import com.vaadin.ui.AbstractSelect.ItemCaptionMode; @@ -1800,7 +1797,6 @@ public abstract class AbstractSelect extends AbstractField<Object> implements * * @since 6.3 */ - @ClientCriterion(VIsOverId.class) public static class TargetItemIs extends AbstractItemSetCriterion { /** @@ -1867,7 +1863,6 @@ public abstract class AbstractSelect extends AbstractField<Object> implements * * @since 6.3 */ - @ClientCriterion(VItemIdIs.class) public static class AcceptItem extends AbstractItemSetCriterion { /** diff --git a/src/com/vaadin/ui/AbstractSplitPanel.java b/src/com/vaadin/ui/AbstractSplitPanel.java index 5205952621..876d39f2ae 100644 --- a/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/src/com/vaadin/ui/AbstractSplitPanel.java @@ -22,7 +22,7 @@ import com.vaadin.tools.ReflectTools; * AbstractSplitPanel. * * <code>AbstractSplitPanel</code> is base class for a component container that - * can contain two components. The comopnents are split by a divider element. + * can contain two components. The components are split by a divider element. * * @author Vaadin Ltd. * @version @@ -31,7 +31,10 @@ import com.vaadin.tools.ReflectTools; */ public abstract class AbstractSplitPanel extends AbstractComponentContainer { + // TODO use Unit in AbstractSplitPanelState and remove these private Unit posUnit; + private Unit posMinUnit; + private Unit posMaxUnit; private AbstractSplitPanelRpc rpc = new AbstractSplitPanelRpc() { @@ -41,13 +44,14 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } public void setSplitterPosition(float position) { - getState().getSplitterState().setPosition(position); + getSplitterState().setPosition(position); } }; public AbstractSplitPanel() { registerRpc(rpc); setSplitPosition(50, Unit.PERCENTAGE, false); + setSplitPositionLimits(0, Unit.PERCENTAGE, 100, Unit.PERCENTAGE); } /** @@ -101,6 +105,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @param c * the component to be added. */ + @Override public void addComponent(Component c) { if (getFirstComponent() == null) { @@ -188,6 +193,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @param c * the component to be removed. */ + @Override public void removeComponent(Component c) { super.removeComponent(c); @@ -204,6 +210,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * * @see com.vaadin.ui.ComponentContainer#getComponentIterator() */ + public Iterator<Component> getComponentIterator() { return new ComponentIterator(); } @@ -214,6 +221,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * * @return the number of contained components (zero, one or two) */ + public int getComponentCount() { int count = 0; if (getFirstComponent() != null) { @@ -226,6 +234,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } /* Documented in superclass */ + public void replaceComponent(Component oldComponent, Component newComponent) { if (oldComponent == getFirstComponent()) { setFirstComponent(newComponent); @@ -297,7 +306,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { if (unit != Unit.PERCENTAGE) { pos = Math.round(pos); } - SplitterState splitterState = getState().getSplitterState(); + SplitterState splitterState = getSplitterState(); splitterState.setPosition(pos); splitterState.setPositionUnit(unit.getSymbol()); splitterState.setPositionReversed(reverse); @@ -313,7 +322,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return position of the splitter */ public float getSplitPosition() { - return getState().getSplitterState().getPosition(); + return getSplitterState().getPosition(); } /** @@ -326,6 +335,110 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } /** + * Sets the minimum split position to the given position and unit. If the + * split position is reversed, maximum and minimum are also reversed. + * + * @param pos + * the minimum position of the split + * @param unit + * the unit (from {@link Sizeable}) in which the size is given. + * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS + */ + public void setMinSplitPosition(int pos, Unit unit) { + setSplitPositionLimits(pos, unit, getSplitterState().getMaxPosition(), + posMaxUnit); + } + + /** + * Returns the current minimum position of the splitter, in + * {@link #getMinSplitPositionUnit()} units. + * + * @return the minimum position of the splitter + */ + public float getMinSplitPosition() { + return getSplitterState().getMinPosition(); + } + + /** + * Returns the unit of the minimum position of the splitter. + * + * @return the unit of the minimum position of the splitter + */ + public Unit getMinSplitPositionUnit() { + return posMinUnit; + } + + /** + * Sets the maximum split position to the given position and unit. If the + * split position is reversed, maximum and minimum are also reversed. + * + * @param pos + * the maximum position of the split + * @param unit + * the unit (from {@link Sizeable}) in which the size is given. + * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS + */ + public void setMaxSplitPosition(float pos, Unit unit) { + setSplitPositionLimits(getSplitterState().getMinPosition(), posMinUnit, + pos, unit); + } + + /** + * Returns the current maximum position of the splitter, in + * {@link #getMaxSplitPositionUnit()} units. + * + * @return the maximum position of the splitter + */ + public float getMaxSplitPosition() { + return getSplitterState().getMaxPosition(); + } + + /** + * Returns the unit of the maximum position of the splitter + * + * @return the unit of the maximum position of the splitter + */ + public Unit getMaxSplitPositionUnit() { + return posMaxUnit; + } + + /** + * Sets the maximum and minimum position of the splitter. If the split + * position is reversed, maximum and minimum are also reversed. + * + * @param minPos + * the new minimum position + * @param minPosUnit + * the unit (from {@link Sizeable}) in which the minimum position + * is given. + * @param maxPos + * the new maximum position + * @param maxPosUnit + * the unit (from {@link Sizeable}) in which the maximum position + * is given. + */ + private void setSplitPositionLimits(float minPos, Unit minPosUnit, + float maxPos, Unit maxPosUnit) { + if ((minPosUnit != Unit.PERCENTAGE && minPosUnit != Unit.PIXELS) + || (maxPosUnit != Unit.PERCENTAGE && maxPosUnit != Unit.PIXELS)) { + throw new IllegalArgumentException( + "Only percentage and pixel units are allowed"); + } + + SplitterState state = getSplitterState(); + + state.setMinPosition(minPos); + state.setMinPositionUnit(minPosUnit.getSymbol()); + posMinUnit = minPosUnit; + + state.setMaxPosition(maxPos); + state.setMaxPositionUnit(maxPosUnit.getSymbol()); + posMaxUnit = maxPosUnit; + + requestRepaint(); + } + + /** * Lock the SplitPanels position, disabling the user from dragging the split * handle. * @@ -333,7 +446,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * Set <code>true</code> if locked, <code>false</code> otherwise. */ public void setLocked(boolean locked) { - getState().getSplitterState().setLocked(locked); + getSplitterState().setLocked(locked); requestRepaint(); } @@ -344,7 +457,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { * @return <code>true</code> if locked, <code>false</code> otherwise. */ public boolean isLocked() { - return getState().getSplitterState().isLocked(); + return getSplitterState().isLocked(); } /** @@ -394,4 +507,7 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { return (AbstractSplitPanelState) super.getState(); } + private SplitterState getSplitterState() { + return getState().getSplitterState(); + } } diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java index 876fe593e2..8e504d828b 100644 --- a/src/com/vaadin/ui/Button.java +++ b/src/com/vaadin/ui/Button.java @@ -38,6 +38,7 @@ public class Button extends AbstractComponent implements Action.ShortcutNotifier { private ButtonServerRpc rpc = new ButtonServerRpc() { + public void click(MouseEventDetails mouseEventDetails) { fireClick(mouseEventDetails); } @@ -50,6 +51,7 @@ public class Button extends AbstractComponent implements }; FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(this) { + @Override protected void fireEvent(Event event) { Button.this.fireEvent(event); diff --git a/src/com/vaadin/ui/HelloWorldExtension.java b/src/com/vaadin/ui/HelloWorldExtension.java index 6d9ce9bcf1..e705954f2e 100644 --- a/src/com/vaadin/ui/HelloWorldExtension.java +++ b/src/com/vaadin/ui/HelloWorldExtension.java @@ -13,7 +13,7 @@ public class HelloWorldExtension extends AbstractExtension { public HelloWorldExtension() { registerRpc(new HelloWorldRpc() { public void onMessageSent(String message) { - getRoot().showNotification(message); + Notification.show(message); } }); } diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java new file mode 100644 index 0000000000..d256717711 --- /dev/null +++ b/src/com/vaadin/ui/JavaScript.java @@ -0,0 +1,146 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.util.HashMap; +import java.util.Map; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.AbstractExtension; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; + +/** + * Provides access to JavaScript functionality in the web browser. To get an + * instance of JavaScript, either use Page.getJavaScript() or + * JavaScript.getCurrent() as a shorthand for getting the JavaScript object + * corresponding to the current Page. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class JavaScript extends AbstractExtension { + private Map<String, JavaScriptCallback> callbacks = new HashMap<String, JavaScriptCallback>(); + + // Can not be defined in client package as this JSONArray is not available + // in GWT + public interface JavaScriptCallbackRpc extends ServerRpc { + public void call(String name, JSONArray arguments); + } + + /** + * Creates a new JavaScript object. You should typically not this, but + * instead use the JavaScript object already associated with your Page + * object. + */ + public JavaScript() { + registerRpc(new JavaScriptCallbackRpc() { + public void call(String name, JSONArray arguments) { + JavaScriptCallback callback = callbacks.get(name); + // TODO handle situation if name is not registered + try { + callback.call(arguments); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + }); + } + + @Override + public JavaScriptManagerState getState() { + return (JavaScriptManagerState) super.getState(); + } + + /** + * Add a new function to the global JavaScript namespace (i.e. the window + * object). The <code>call</code> method in the passed + * {@link JavaScriptCallback} object will be invoked with the same + * parameters whenever the JavaScript function is called in the browser. + * + * A callback added with the name <code>"myCallback"</code> can thus be + * invoked with the following JavaScript code: + * <code>window.myCallback(argument1, argument2)</code>. + * + * If the name parameter contains dots, simple objects are created on demand + * to allow calling the function using the same name (e.g. + * <code>window.myObject.myFunction</code>). + * + * @param name + * the name that the callback function should get in the global + * JavaScript namespace. + * @param callback + * the JavaScriptCallback that will be invoked if the JavaScript + * function is called. + */ + public void addCallback(String name, JavaScriptCallback callback) { + callbacks.put(name, callback); + if (getState().getNames().add(name)) { + requestRepaint(); + } + } + + /** + * Removes a JavaScripCallback from the browser's global JavaScript + * namespace. + * + * If the name contains dots and intermediate were created by + * {@link #addCallback(String, JavaScriptCallback)}addCallback, these + * objects will not be removed when the callback is removed. + * + * @param name + * the name of the callback to remove + */ + public void removeCallback(String name) { + callbacks.remove(name); + if (getState().getNames().remove(name)) { + requestRepaint(); + } + } + + /** + * Executes the given JavaScript code in the browser. + * + * @param script + * The JavaScript code to run. + */ + public void execute(String script) { + getRpcProxy(ExecuteJavaScriptRpc.class).executeJavaScript(script); + } + + /** + * Get the JavaScript object for the current Page, or null if there is no + * current page. + * + * @see Page#getCurrent() + * + * @return the JavaScript object corresponding to the current Page, or + * <code>null</code> if there is no current page. + */ + public static JavaScript getCurrent() { + Page page = Page.getCurrent(); + if (page == null) { + return null; + } + return page.getJavaScript(); + } + + /** + * JavaScript is not designed to be removed. + * + * @throws UnsupportedOperationException + * when invoked + */ + @Override + public void removeFromTarget() { + throw new UnsupportedOperationException( + "JavaScript is not designed to be removed."); + } + +} diff --git a/src/com/vaadin/ui/JavaScriptCallback.java b/src/com/vaadin/ui/JavaScriptCallback.java new file mode 100644 index 0000000000..49f7695e89 --- /dev/null +++ b/src/com/vaadin/ui/JavaScriptCallback.java @@ -0,0 +1,41 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.io.Serializable; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.AbstractJavaScriptExtension; + +/** + * Defines a method that is called by a client-side JavaScript function. When + * the corresponding JavaScript function is called, the {@link #call(JSONArray)} + * method is invoked. + * + * @see JavaScript#addCallback(String, JavaScriptCallback) + * @see AbstractJavaScriptComponent#registerCallback(String, JavaScriptCallback) + * @see AbstractJavaScriptExtension#registerCallback(String, JavaScriptCallback) + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public interface JavaScriptCallback extends Serializable { + /** + * Invoked whenever the corresponding JavaScript function is called in the + * browser. + * <p> + * Because of the asynchronous nature of the communication between client + * and server, no return value can be sent back to the browser. + * + * @param arguments + * an array with JSON representations of the arguments with which + * the JavaScript function was called. + * @throws JSONException + * if the arguments can not be interpreted + */ + public void call(JSONArray arguments) throws JSONException; +} diff --git a/src/com/vaadin/ui/JavascriptCallback.java b/src/com/vaadin/ui/JavascriptCallback.java deleted file mode 100644 index 89700b3faf..0000000000 --- a/src/com/vaadin/ui/JavascriptCallback.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; - -public interface JavascriptCallback extends Serializable { - public void call(JSONArray arguments) throws JSONException; -} diff --git a/src/com/vaadin/ui/JavascriptManager.java b/src/com/vaadin/ui/JavascriptManager.java deleted file mode 100644 index 72295dce2b..0000000000 --- a/src/com/vaadin/ui/JavascriptManager.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; -import com.vaadin.terminal.AbstractExtension; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerState; - -public class JavascriptManager extends AbstractExtension { - private Map<String, JavascriptCallback> callbacks = new HashMap<String, JavascriptCallback>(); - - // Can not be defined in client package as this JSONArray is not available - // in GWT - public interface JavascriptCallbackRpc extends ServerRpc { - public void call(String name, JSONArray arguments); - } - - public JavascriptManager() { - registerRpc(new JavascriptCallbackRpc() { - public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); - // TODO handle situation if name is not registered - try { - callback.call(arguments); - } catch (JSONException e) { - throw new IllegalArgumentException(e); - } - } - }); - } - - @Override - public JavascriptManagerState getState() { - return (JavascriptManagerState) super.getState(); - } - - public void addCallback(String name, JavascriptCallback javascriptCallback) { - callbacks.put(name, javascriptCallback); - if (getState().getNames().add(name)) { - requestRepaint(); - } - } - - public void removeCallback(String name) { - callbacks.remove(name); - if (getState().getNames().remove(name)) { - requestRepaint(); - } - } - -} diff --git a/src/com/vaadin/ui/Link.java b/src/com/vaadin/ui/Link.java index ed5ffbba3a..db0dc58e6b 100644 --- a/src/com/vaadin/ui/Link.java +++ b/src/com/vaadin/ui/Link.java @@ -6,6 +6,7 @@ package com.vaadin.ui; import java.util.Map; +import com.vaadin.terminal.Page; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; @@ -23,13 +24,13 @@ import com.vaadin.terminal.Vaadin6Component; public class Link extends AbstractComponent implements Vaadin6Component { /* Target window border type constant: No window border */ - public static final int TARGET_BORDER_NONE = Root.BORDER_NONE; + public static final int TARGET_BORDER_NONE = Page.BORDER_NONE; /* Target window border type constant: Minimal window border */ - public static final int TARGET_BORDER_MINIMAL = Root.BORDER_MINIMAL; + public static final int TARGET_BORDER_MINIMAL = Page.BORDER_MINIMAL; /* Target window border type constant: Default window border */ - public static final int TARGET_BORDER_DEFAULT = Root.BORDER_DEFAULT; + public static final int TARGET_BORDER_DEFAULT = Page.BORDER_DEFAULT; private Resource resource = null; diff --git a/src/com/vaadin/ui/Notification.java b/src/com/vaadin/ui/Notification.java index bb1f874635..075ab50196 100644 --- a/src/com/vaadin/ui/Notification.java +++ b/src/com/vaadin/ui/Notification.java @@ -6,6 +6,7 @@ package com.vaadin.ui; import java.io.Serializable; +import com.vaadin.terminal.Page; import com.vaadin.terminal.Resource; /** @@ -318,4 +319,118 @@ public class Notification implements Serializable { public boolean isHtmlContentAllowed() { return htmlContentAllowed; } + + public void show() { + Page.getCurrent().showNotification(this); + } + + /** + * Shows a notification message on the middle of the current page. The + * message automatically disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + */ + public static void show(String caption) { + new Notification(caption).show(); + } + + /** + * Shows a notification message the current page. The position and behavior + * of the message depends on the type, which is one of the basic types + * defined in {@link Notification}, for instance + * Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption is + * rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * @param type + * The message type + */ + public static void show(String caption, int type) { + new Notification(caption, type).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description on the middle of the current page. The message automatically + * disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * + */ + public static void show(String caption, String description) { + new Notification(caption, description).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption and + * description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * @param type + * The message type + */ + public static void show(String caption, String description, int type) { + + new Notification(caption, description, type).show(); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification}, + * for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to avoid XSS vulnerabilities if html content is + * allowed. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message caption + * @param description + * The message description + * @param type + * The type of message + * @param htmlContentAllowed + * Whether html in the caption and description should be + * displayed as html or as plain text + */ + public static void show(String caption, String description, int type, + boolean htmlContentAllowed) { + new Notification(caption, description, type, htmlContentAllowed).show(); + } }
\ No newline at end of file diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java index 9814084cbc..50ad99571e 100644 --- a/src/com/vaadin/ui/Root.java +++ b/src/com/vaadin/ui/Root.java @@ -4,8 +4,6 @@ package com.vaadin.ui; -import java.io.Serializable; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -13,8 +11,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import com.vaadin.Application; @@ -24,6 +20,9 @@ import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; import com.vaadin.event.MouseEvents.ClickEvent; import com.vaadin.event.MouseEvents.ClickListener; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; +import com.vaadin.terminal.Page.BrowserWindowResizeListener; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; @@ -31,11 +30,9 @@ import com.vaadin.terminal.Vaadin6Component; import com.vaadin.terminal.WrappedRequest; import com.vaadin.terminal.WrappedRequest.BrowserDetails; import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.ui.notification.VNotification; import com.vaadin.terminal.gwt.client.ui.root.RootServerRpc; import com.vaadin.terminal.gwt.client.ui.root.RootState; import com.vaadin.terminal.gwt.client.ui.root.VRoot; -import com.vaadin.tools.ReflectTools; import com.vaadin.ui.Window.CloseListener; /** @@ -79,121 +76,6 @@ public abstract class Root extends AbstractComponentContainer implements Action.Container, Action.Notifier, Vaadin6Component { /** - * Listener that gets notified when the size of the browser window - * containing the root has changed. - * - * @see Root#addListener(BrowserWindowResizeListener) - */ - public interface BrowserWindowResizeListener extends Serializable { - /** - * Invoked when the browser window containing a Root has been resized. - * - * @param event - * a browser window resize event - */ - public void browserWindowResized(BrowserWindowResizeEvent event); - } - - /** - * Event that is fired when a browser window containing a root is resized. - */ - public class BrowserWindowResizeEvent extends Component.Event { - - private final int width; - private final int height; - - /** - * Creates a new event - * - * @param source - * the root for which the browser window has been resized - * @param width - * the new width of the browser window - * @param height - * the new height of the browser window - */ - public BrowserWindowResizeEvent(Root source, int width, int height) { - super(source); - this.width = width; - this.height = height; - } - - @Override - public Root getSource() { - return (Root) super.getSource(); - } - - /** - * Gets the new browser window height - * - * @return an integer with the new pixel height of the browser window - */ - public int getHeight() { - return height; - } - - /** - * Gets the new browser window width - * - * @return an integer with the new pixel width of the browser window - */ - public int getWidth() { - return width; - } - } - - private static final Method BROWSWER_RESIZE_METHOD = ReflectTools - .findMethod(BrowserWindowResizeListener.class, - "browserWindowResized", BrowserWindowResizeEvent.class); - - /** - * Listener that listens changes in URI fragment. - */ - public interface FragmentChangedListener extends Serializable { - public void fragmentChanged(FragmentChangedEvent event); - } - - /** - * Event fired when uri fragment changes. - */ - public class FragmentChangedEvent extends Component.Event { - - /** - * The new uri fragment - */ - private final String fragment; - - /** - * Creates a new instance of UriFragmentReader change event. - * - * @param source - * the Source of the event. - */ - public FragmentChangedEvent(Root source, String fragment) { - super(source); - this.fragment = fragment; - } - - /** - * Gets the root in which the fragment has changed. - * - * @return the root in which the fragment has changed - */ - public Root getRoot() { - return (Root) getComponent(); - } - - /** - * Get the new fragment - * - * @return the new fragment - */ - public String getFragment() { - return fragment; - } - } - - /** * Helper class to emulate the main window from Vaadin 6 using roots. This * class should be used in the same way as Window used as a browser level * window in Vaadin 6 with {@link com.vaadin.Application.LegacyApplication} @@ -312,55 +194,337 @@ public abstract class Root extends AbstractComponentContainer implements "Internal problem getting window URL, please report"); } } - } - private static final Method FRAGMENT_CHANGED_METHOD; - - static { - try { - FRAGMENT_CHANGED_METHOD = FragmentChangedListener.class - .getDeclaredMethod("fragmentChanged", - new Class[] { FragmentChangedEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in FragmentChangedListener"); + /** + * Opens the given resource in this root. The contents of this Root is + * replaced by the {@code Resource}. + * + * @param resource + * the resource to show in this root + * + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource) { + getPage().open(resource); } - } - /** - * A border style used for opening resources in a window without a border. - */ - public static final int BORDER_NONE = 0; + /* ********************************************************************* */ - /** - * A border style used for opening resources in a window with a minimal - * border. - */ - public static final int BORDER_MINIMAL = 1; + /** + * Opens the given resource in a window with the given name. + * <p> + * The supplied {@code windowName} is used as the target name in a + * window.open call in the client. This means that special values such + * as "_blank", "_self", "_top", "_parent" have special meaning. An + * empty or <code>null</code> window name is also a special case. + * </p> + * <p> + * "", null and "_self" as {@code windowName} all causes the resource to + * be opened in the current window, replacing any old contents. For + * downloadable content you should avoid "_self" as "_self" causes the + * client to skip rendering of any other changes as it considers them + * irrelevant (the page will be replaced by the resource). This can + * speed up the opening of a resource, but it might also put the client + * side into an inconsistent state if the window content is not + * completely replaced e.g., if the resource is downloaded instead of + * displayed in the browser. + * </p> + * <p> + * "_blank" as {@code windowName} causes the resource to always be + * opened in a new window or tab (depends on the browser and browser + * settings). + * </p> + * <p> + * "_top" and "_parent" as {@code windowName} works as specified by the + * HTML standard. + * </p> + * <p> + * Any other {@code windowName} will open the resource in a window with + * that name, either by opening a new window/tab in the browser or by + * replacing the contents of an existing window with that name. + * </p> + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource, String windowName) { + getPage().open(resource, windowName); + } - /** - * A border style that indicates that the default border style should be - * used when opening resources. - */ - public static final int BORDER_DEFAULT = 2; + /** + * Opens the given resource in a window with the given size, border and + * name. For more information on the meaning of {@code windowName}, see + * {@link #open(Resource, String)}. + * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @param width + * the width of the window in pixels + * @param height + * the height of the window in pixels + * @param border + * the border style of the window. See {@link #BORDER_NONE + * Window.BORDER_* constants} + * @deprecated As of 7.0, use getPage().open instead + */ + @Deprecated + public void open(Resource resource, String windowName, int width, + int height, int border) { + getPage().open(resource, windowName, width, height, border); + } - /** - * The application to which this root belongs - */ - private Application application; + /** + * Adds a new {@link BrowserWindowResizeListener} to this root. The + * listener will be notified whenever the browser window within which + * this root resides is resized. + * + * @param resizeListener + * the listener to add + * + * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) + * @see #setResizeLazy(boolean) + * + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public void addListener(BrowserWindowResizeListener resizeListener) { + getPage().addListener(resizeListener); + } - /** - * A list of notifications that are waiting to be sent to the client. - * Cleared (set to null) when the notifications have been sent. - */ - private List<Notification> notifications; + /** + * Removes a {@link BrowserWindowResizeListener} from this root. The + * listener will no longer be notified when the browser window is + * resized. + * + * @param resizeListener + * the listener to remove + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public void removeListener(BrowserWindowResizeListener resizeListener) { + getPage().removeListener(resizeListener); + } + + /** + * Gets the last known height of the browser window in which this root + * resides. + * + * @return the browser window height in pixels + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public int getBrowserWindowHeight() { + return getPage().getBrowserWindowHeight(); + } + + /** + * Gets the last known width of the browser window in which this root + * resides. + * + * @return the browser window width in pixels + * + * @deprecated As of 7.0, use the similarly named api in Page instead + */ + @Deprecated + public int getBrowserWindowWidth() { + return getPage().getBrowserWindowWidth(); + } + + /** + * Shows a notification message on the middle of the root. The message + * automatically disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * is rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption) { + getPage().showNotification(new Notification(caption)); + } + + /** + * Shows a notification message the root. The position and behavior of + * the message depends on the type, which is one of the basic types + * defined in {@link Notification}, for instance + * Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * is rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message + * @param type + * The message type + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, int type) { + getPage().showNotification(new Notification(caption, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description on the middle of the root. The message automatically + * disappears ("humanized message"). + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * and description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description) { + getPage().showNotification(new Notification(caption, description)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification} + * , for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to to avoid XSS vulnerabilities as the caption + * and description are rendered as html. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The caption of the message + * @param description + * The message description + * @param type + * The message type + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description, + int type) { + getPage().showNotification( + new Notification(caption, description, type)); + } + + /** + * Shows a notification consisting of a bigger caption and a smaller + * description. The position and behavior of the message depends on the + * type, which is one of the basic types defined in {@link Notification} + * , for instance Notification.TYPE_WARNING_MESSAGE. + * + * Care should be taken to avoid XSS vulnerabilities if html content is + * allowed. + * + * @see #showNotification(Notification) + * @see Notification + * + * @param caption + * The message caption + * @param description + * The message description + * @param type + * The type of message + * @param htmlContentAllowed + * Whether html in the caption and description should be + * displayed as html or as plain text + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(String caption, String description, + int type, boolean htmlContentAllowed) { + getPage().showNotification( + new Notification(caption, description, type, + htmlContentAllowed)); + } + + /** + * Shows a notification message. + * + * @see Notification + * @see #showNotification(String) + * @see #showNotification(String, int) + * @see #showNotification(String, String) + * @see #showNotification(String, String, int) + * + * @param notification + * The notification message to show + * + * @deprecated As of 7.0, use Notification.show instead + */ + @Deprecated + public void showNotification(Notification notification) { + getPage().showNotification(notification); + } + + /** + * Executes JavaScript in this window. + * + * <p> + * This method allows one to inject javascript from the server to + * client. A client implementation is not required to implement this + * functionality, but currently all web-based clients do implement this. + * </p> + * + * <p> + * Executing javascript this way often leads to cross-browser + * compatibility issues and regressions that are hard to resolve. Use of + * this method should be avoided and instead it is recommended to create + * new widgets with GWT. For more info on creating own, reusable + * client-side widgets in Java, read the corresponding chapter in Book + * of Vaadin. + * </p> + * + * @param script + * JavaScript snippet that will be executed. + * + * @deprecated as of 7.0, use JavaScript.getCurrent().execute(String) + * instead + */ + @Deprecated + public void executeJavaScript(String script) { + getPage().getJavaScript().execute(script); + } + + @Override + public void setCaption(String caption) { + // Override to provide backwards compatibility + getState().setCaption(caption); + getPage().setTitle(caption); + } + + } /** - * A list of javascript commands that are waiting to be sent to the client. - * Cleared (set to null) when the commands have been sent. + * The application to which this root belongs */ - private List<String> jsExecQueue = null; + private Application application; /** * List of windows in this root. @@ -368,12 +532,6 @@ public abstract class Root extends AbstractComponentContainer implements private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>(); /** - * Resources to be opened automatically on next repaint. The list is - * automatically cleared when it has been sent to the client. - */ - private final LinkedList<OpenResource> openList = new LinkedList<OpenResource>(); - - /** * The component that should be scrolled into view after the next repaint. * Null if nothing should be scrolled into view. */ @@ -399,16 +557,13 @@ public abstract class Root extends AbstractComponentContainer implements */ private static final ThreadLocal<Root> currentRoot = new ThreadLocal<Root>(); - private int browserWindowWidth = -1; - private int browserWindowHeight = -1; - /** Identifies the click event */ private static final String CLICK_EVENT_ID = VRoot.CLICK_EVENT_ID; private DirtyConnectorTracker dirtyConnectorTracker = new DirtyConnectorTracker( this); - private JavascriptManager javascriptManager; + private Page page = new Page(this); private RootServerRpc rpc = new RootServerRpc() { public void click(MouseEventDetails mouseDetails) { @@ -504,68 +659,7 @@ public abstract class Root extends AbstractComponentContainer implements } public void paintContent(PaintTarget target) throws PaintException { - // Open requested resource - synchronized (openList) { - if (!openList.isEmpty()) { - for (final Iterator<OpenResource> i = openList.iterator(); i - .hasNext();) { - (i.next()).paintContent(target); - } - openList.clear(); - } - } - - // Paint notifications - if (notifications != null) { - target.startTag("notifications"); - for (final Iterator<Notification> it = notifications.iterator(); it - .hasNext();) { - final Notification n = it.next(); - target.startTag("notification"); - if (n.getCaption() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_CAPTION, - n.getCaption()); - } - if (n.getDescription() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_MESSAGE, - n.getDescription()); - } - if (n.getIcon() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_ICON, - n.getIcon()); - } - if (!n.isHtmlContentAllowed()) { - target.addAttribute( - VRoot.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true); - } - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_POSITION, - n.getPosition()); - target.addAttribute(VNotification.ATTRIBUTE_NOTIFICATION_DELAY, - n.getDelayMsec()); - if (n.getStyleName() != null) { - target.addAttribute( - VNotification.ATTRIBUTE_NOTIFICATION_STYLE, - n.getStyleName()); - } - target.endTag("notification"); - } - target.endTag("notifications"); - notifications = null; - } - - // Add executable javascripts if needed - if (jsExecQueue != null) { - for (String script : jsExecQueue) { - target.startTag("execJS"); - target.addAttribute("script", script); - target.endTag("execJS"); - } - jsExecQueue = null; - } + page.paintContent(target); if (scrollIntoView != null) { target.addAttribute("scrollTo", scrollIntoView); @@ -586,10 +680,6 @@ public abstract class Root extends AbstractComponentContainer implements actionManager.paintActions(null, target); } - if (fragment != null) { - target.addAttribute(VRoot.FRAGMENT_VARIABLE, fragment); - } - if (isResizeLazy()) { target.addAttribute(VRoot.RESIZE_LAZY, true); } @@ -620,23 +710,14 @@ public abstract class Root extends AbstractComponentContainer implements if (variables.containsKey(VRoot.FRAGMENT_VARIABLE)) { String fragment = (String) variables.get(VRoot.FRAGMENT_VARIABLE); - setFragment(fragment, true); + getPage().setFragment(fragment, true); } - boolean sendResizeEvent = false; - if (variables.containsKey("height")) { - browserWindowHeight = ((Integer) variables.get("height")) - .intValue(); - sendResizeEvent = true; - } - if (variables.containsKey("width")) { - browserWindowWidth = ((Integer) variables.get("width")).intValue(); - sendResizeEvent = true; - } - if (sendResizeEvent) { - fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth, - browserWindowHeight)); + if (variables.containsKey("height") || variables.containsKey("width")) { + getPage().setBrowserWindowSize((Integer) variables.get("width"), + (Integer) variables.get("height")); } + } /* @@ -817,11 +898,6 @@ public abstract class Root extends AbstractComponentContainer implements */ private Focusable pendingFocus; - /** - * The current URI fragment. - */ - private String fragment; - private boolean resizeLazy = false; /** @@ -843,175 +919,6 @@ public abstract class Root extends AbstractComponentContainer implements } /** - * Shows a notification message on the middle of the root. The message - * automatically disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message - */ - public void showNotification(String caption) { - addNotification(new Notification(caption)); - } - - /** - * Shows a notification message the root. The position and behavior of the - * message depends on the type, which is one of the basic types defined in - * {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption is - * rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message - * @param type - * The message type - */ - public void showNotification(String caption, int type) { - addNotification(new Notification(caption, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description on the middle of the root. The message automatically - * disappears ("humanized message"). - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * - */ - public void showNotification(String caption, String description) { - addNotification(new Notification(caption, description)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to to avoid XSS vulnerabilities as the caption and - * description are rendered as html. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The caption of the message - * @param description - * The message description - * @param type - * The message type - */ - public void showNotification(String caption, String description, int type) { - addNotification(new Notification(caption, description, type)); - } - - /** - * Shows a notification consisting of a bigger caption and a smaller - * description. The position and behavior of the message depends on the - * type, which is one of the basic types defined in {@link Notification}, - * for instance Notification.TYPE_WARNING_MESSAGE. - * - * Care should be taken to avoid XSS vulnerabilities if html content is - * allowed. - * - * @see #showNotification(Notification) - * @see Notification - * - * @param caption - * The message caption - * @param description - * The message description - * @param type - * The type of message - * @param htmlContentAllowed - * Whether html in the caption and description should be - * displayed as html or as plain text - */ - public void showNotification(String caption, String description, int type, - boolean htmlContentAllowed) { - addNotification(new Notification(caption, description, type, - htmlContentAllowed)); - } - - /** - * Shows a notification message. - * - * @see Notification - * @see #showNotification(String) - * @see #showNotification(String, int) - * @see #showNotification(String, String) - * @see #showNotification(String, String, int) - * - * @param notification - * The notification message to show - */ - public void showNotification(Notification notification) { - addNotification(notification); - } - - /** - * Internal helper method to actually add a notification. - * - * @param notification - * the notification to add - */ - private void addNotification(Notification notification) { - if (notifications == null) { - notifications = new LinkedList<Notification>(); - } - notifications.add(notification); - requestRepaint(); - } - - /** - * Executes JavaScript in this root. - * - * <p> - * This method allows one to inject javascript from the server to client. A - * client implementation is not required to implement this functionality, - * but currently all web-based clients do implement this. - * </p> - * - * <p> - * Executing javascript this way often leads to cross-browser compatibility - * issues and regressions that are hard to resolve. Use of this method - * should be avoided and instead it is recommended to create new widgets - * with GWT. For more info on creating own, reusable client-side widgets in - * Java, read the corresponding chapter in Book of Vaadin. - * </p> - * - * @param script - * JavaScript snippet that will be executed. - */ - public void executeJavaScript(String script) { - if (jsExecQueue == null) { - jsExecQueue = new ArrayList<String>(); - } - - jsExecQueue.add(script); - - requestRepaint(); - } - - /** * Scrolls any component between the component and root to a suitable * position so the component is visible to the user. The given component * must belong to this root. @@ -1125,10 +1032,7 @@ public abstract class Root extends AbstractComponentContainer implements * the initialization request */ public void doInit(WrappedRequest request) { - BrowserDetails browserDetails = request.getBrowserDetails(); - if (browserDetails != null) { - fragment = browserDetails.getUriFragment(); - } + getPage().init(request); // Call the init overridden by the application developer init(request); @@ -1187,186 +1091,6 @@ public abstract class Root extends AbstractComponentContainer implements return currentRoot.get(); } - /** - * Opens the given resource in this root. The contents of this Root is - * replaced by the {@code Resource}. - * - * @param resource - * the resource to show in this root - */ - public void open(Resource resource) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, null, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } - - /* ********************************************************************* */ - - /** - * Opens the given resource in a window with the given name. - * <p> - * The supplied {@code windowName} is used as the target name in a - * window.open call in the client. This means that special values such as - * "_blank", "_self", "_top", "_parent" have special meaning. An empty or - * <code>null</code> window name is also a special case. - * </p> - * <p> - * "", null and "_self" as {@code windowName} all causes the resource to be - * opened in the current window, replacing any old contents. For - * downloadable content you should avoid "_self" as "_self" causes the - * client to skip rendering of any other changes as it considers them - * irrelevant (the page will be replaced by the resource). This can speed up - * the opening of a resource, but it might also put the client side into an - * inconsistent state if the window content is not completely replaced e.g., - * if the resource is downloaded instead of displayed in the browser. - * </p> - * <p> - * "_blank" as {@code windowName} causes the resource to always be opened in - * a new window or tab (depends on the browser and browser settings). - * </p> - * <p> - * "_top" and "_parent" as {@code windowName} works as specified by the HTML - * standard. - * </p> - * <p> - * Any other {@code windowName} will open the resource in a window with that - * name, either by opening a new window/tab in the browser or by replacing - * the contents of an existing window with that name. - * </p> - * - * @param resource - * the resource. - * @param windowName - * the name of the window. - */ - public void open(Resource resource, String windowName) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, -1, -1, - BORDER_DEFAULT)); - } - } - requestRepaint(); - } - - /** - * Opens the given resource in a window with the given size, border and - * name. For more information on the meaning of {@code windowName}, see - * {@link #open(Resource, String)}. - * - * @param resource - * the resource. - * @param windowName - * the name of the window. - * @param width - * the width of the window in pixels - * @param height - * the height of the window in pixels - * @param border - * the border style of the window. See {@link #BORDER_NONE - * Window.BORDER_* constants} - */ - public void open(Resource resource, String windowName, int width, - int height, int border) { - synchronized (openList) { - if (!openList.contains(resource)) { - openList.add(new OpenResource(resource, windowName, width, - height, border)); - } - } - requestRepaint(); - } - - /** - * Private class for storing properties related to opening resources. - */ - private class OpenResource implements Serializable { - - /** - * The resource to open - */ - private final Resource resource; - - /** - * The name of the target window - */ - private final String name; - - /** - * The width of the target window - */ - private final int width; - - /** - * The height of the target window - */ - private final int height; - - /** - * The border style of the target window - */ - private final int border; - - /** - * Creates a new open resource. - * - * @param resource - * The resource to open - * @param name - * The name of the target window - * @param width - * The width of the target window - * @param height - * The height of the target window - * @param border - * The border style of the target window - */ - private OpenResource(Resource resource, String name, int width, - int height, int border) { - this.resource = resource; - this.name = name; - this.width = width; - this.height = height; - this.border = border; - } - - /** - * Paints the open request. Should be painted inside the window. - * - * @param target - * the paint target - * @throws PaintException - * if the paint operation fails - */ - private void paintContent(PaintTarget target) throws PaintException { - target.startTag("open"); - target.addAttribute("src", resource); - if (name != null && name.length() > 0) { - target.addAttribute("name", name); - } - if (width >= 0) { - target.addAttribute("width", width); - } - if (height >= 0) { - target.addAttribute("height", height); - } - switch (border) { - case BORDER_MINIMAL: - target.addAttribute("border", "minimal"); - break; - case BORDER_NONE: - target.addAttribute("border", "none"); - break; - } - - target.endTag("open"); - } - } - public void setScrollTop(int scrollTop) { throw new RuntimeException("Not yet implemented"); } @@ -1454,110 +1178,6 @@ public abstract class Root extends AbstractComponentContainer implements removeListener(CLICK_EVENT_ID, ClickEvent.class, listener); } - public void addListener(FragmentChangedListener listener) { - addListener(FragmentChangedEvent.class, listener, - FRAGMENT_CHANGED_METHOD); - } - - public void removeListener(FragmentChangedListener listener) { - removeListener(FragmentChangedEvent.class, listener, - FRAGMENT_CHANGED_METHOD); - } - - /** - * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent} - * - * @param newFragment - * id of the new fragment - * @param fireEvent - * true to fire event - * @see FragmentChangedEvent - * @see FragmentChangedListener - */ - public void setFragment(String newFragment, boolean fireEvents) { - if (newFragment == null) { - throw new NullPointerException("The fragment may not be null"); - } - if (!newFragment.equals(fragment)) { - fragment = newFragment; - if (fireEvents) { - fireEvent(new FragmentChangedEvent(this, newFragment)); - } - requestRepaint(); - } - } - - /** - * Sets URI fragment. This method fires a {@link FragmentChangedEvent} - * - * @param newFragment - * id of the new fragment - * @see FragmentChangedEvent - * @see FragmentChangedListener - */ - public void setFragment(String newFragment) { - setFragment(newFragment, true); - } - - /** - * Gets currently set URI fragment. - * <p> - * To listen changes in fragment, hook a {@link FragmentChangedListener}. - * - * @return the current fragment in browser uri or null if not known - */ - public String getFragment() { - return fragment; - } - - /** - * Adds a new {@link BrowserWindowResizeListener} to this root. The listener - * will be notified whenever the browser window within which this root - * resides is resized. - * - * @param resizeListener - * the listener to add - * - * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent) - * @see #setResizeLazy(boolean) - */ - public void addListener(BrowserWindowResizeListener resizeListener) { - addListener(BrowserWindowResizeEvent.class, resizeListener, - BROWSWER_RESIZE_METHOD); - } - - /** - * Removes a {@link BrowserWindowResizeListener} from this root. The - * listener will no longer be notified when the browser window is resized. - * - * @param resizeListener - * the listener to remove - */ - public void removeListener(BrowserWindowResizeListener resizeListener) { - removeListener(BrowserWindowResizeEvent.class, resizeListener, - BROWSWER_RESIZE_METHOD); - } - - /** - * Gets the last known height of the browser window in which this root - * resides. - * - * @return the browser window height in pixels - */ - public int getBrowserWindowHeight() { - return browserWindowHeight; - } - - /** - * Gets the last known width of the browser window in which this root - * resides. - * - * @return the browser window width in pixels - */ - public int getBrowserWindowWidth() { - return browserWindowWidth; - } - /** * Notifies the child components and windows that the root is attached to * the application. @@ -1592,14 +1212,21 @@ public abstract class Root extends AbstractComponentContainer implements return dirtyConnectorTracker; } - public JavascriptManager getJavascriptManager() { - if (javascriptManager == null) { - // Create and attach on first use - javascriptManager = new JavascriptManager(); - addExtension(javascriptManager); - } + public Page getPage() { + return page; + } - return javascriptManager; + /** + * Setting the caption of a Root is not supported. To set the title of the + * HTML page, use Page.setTitle + * + * @deprecated as of 7.0.0, use {@link Page#setTitle(String)} + */ + @Override + @Deprecated + public void setCaption(String caption) { + throw new IllegalStateException( + "You can not set the title of a Root. To set the title of the HTML page, use Page.setTitle"); } } diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java index 23dee15359..061809de67 100644 --- a/src/com/vaadin/ui/TabSheet.java +++ b/src/com/vaadin/ui/TabSheet.java @@ -108,6 +108,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, setWidth(100, UNITS_PERCENTAGE); setImmediate(true); setCloseHandler(new CloseHandler() { + public void onTabClose(TabSheet tabsheet, Component c) { tabsheet.removeComponent(c); } @@ -120,6 +121,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * * @return the unmodifiable Iterator of the tab content components */ + public Iterator<Component> getComponentIterator() { return Collections.unmodifiableList(components).iterator(); } @@ -130,6 +132,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * * @return the number of contained components */ + public int getComponentCount() { return components.size(); } @@ -143,6 +146,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @param c * the component to be removed. */ + @Override public void removeComponent(Component c) { if (c != null && components.contains(c)) { @@ -193,6 +197,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @param c * the component to be added. */ + @Override public void addComponent(Component c) { addTab(c); @@ -334,6 +339,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @param source * the container components are removed from. */ + @Override public void moveComponentsFrom(ComponentContainer source) { for (final Iterator<Component> i = source.getComponentIterator(); i @@ -359,6 +365,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @throws PaintException * if the paint operation failed. */ + public void paintContent(PaintTarget target) throws PaintException { if (areTabsHidden()) { @@ -683,6 +690,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, } // inherits javadoc + public void changeVariables(Object source, Map<String, Object> variables) { if (variables.containsKey("selected")) { setSelectedTab(keyMapper.get((String) variables.get("selected"))); @@ -719,6 +727,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * * {@inheritDoc} */ + public void replaceComponent(Component oldComponent, Component newComponent) { if (selected == oldComponent) { @@ -729,25 +738,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, Tab newTab = tabs.get(newComponent); Tab oldTab = tabs.get(oldComponent); - // Gets the captions - String oldCaption = null; - Resource oldIcon = null; - String newCaption = null; - Resource newIcon = null; - - if (oldTab != null) { - oldCaption = oldTab.getCaption(); - oldIcon = oldTab.getIcon(); - } - - if (newTab != null) { - newCaption = newTab.getCaption(); - newIcon = newTab.getIcon(); - } else { - newCaption = newComponent.getCaption(); - newIcon = newComponent.getIcon(); - } - // Gets the locations int oldLocation = -1; int newLocation = -1; @@ -769,35 +759,21 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, addComponent(newComponent); } else if (newLocation == -1) { removeComponent(oldComponent); - keyMapper.remove(oldComponent); - newTab = addTab(newComponent); - components.remove(newComponent); - components.add(oldLocation, newComponent); - newTab.setCaption(oldCaption); - newTab.setIcon(oldIcon); + newTab = addTab(newComponent, oldLocation); + // Copy all relevant metadata to the new tab (#8793) + // TODO Should reuse the old tab instance instead? + copyTabMetadata(oldTab, newTab); } else { - if (oldLocation > newLocation) { - components.remove(oldComponent); - components.add(newLocation, oldComponent); - components.remove(newComponent); - components.add(oldLocation, newComponent); - } else { - components.remove(newComponent); - components.add(oldLocation, newComponent); - components.remove(oldComponent); - components.add(newLocation, oldComponent); - } + components.set(oldLocation, newComponent); + components.set(newLocation, oldComponent); - if (newTab != null) { - // This should always be true - newTab.setCaption(oldCaption); - newTab.setIcon(oldIcon); - } - if (oldTab != null) { - // This should always be true - oldTab.setCaption(newCaption); - oldTab.setIcon(newIcon); - } + // Tab associations are not changed, but metadata is swapped between + // the instances + // TODO Should reassociate the instances instead? + Tab tmp = new TabSheetTabImpl(null, null); + copyTabMetadata(newTab, tmp); + copyTabMetadata(oldTab, newTab); + copyTabMetadata(tmp, oldTab); requestRepaint(); } @@ -1106,6 +1082,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, /** * Returns the tab caption. Can never be null. */ + public String getCaption() { return caption; } @@ -1300,4 +1277,23 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, public boolean isComponentVisible(Component childComponent) { return childComponent == getSelectedTab(); } + + /** + * Copies properties from one Tab to another. + * + * @param from + * The tab whose data to copy. + * @param to + * The tab to which copy the data. + */ + private static void copyTabMetadata(Tab from, Tab to) { + to.setCaption(from.getCaption()); + to.setIcon(from.getIcon()); + to.setDescription(from.getDescription()); + to.setVisible(from.isVisible()); + to.setEnabled(from.isEnabled()); + to.setClosable(from.isClosable()); + to.setStyleName(from.getStyleName()); + to.setComponentError(from.getComponentError()); + } } diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index fc736bfa93..5d4f919704 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -39,7 +39,6 @@ import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DragSource; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.acceptcriteria.ClientCriterion; import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion; import com.vaadin.terminal.KeyMapper; import com.vaadin.terminal.LegacyPaint; @@ -47,7 +46,6 @@ import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers; import com.vaadin.terminal.gwt.client.ui.table.VScrollTable; /** @@ -78,8 +76,7 @@ public class Table extends AbstractSelect implements Action.Container, Container.Ordered, Container.Sortable, ItemClickNotifier, DragSource, DropTarget, HasComponents { - private static final Logger logger = Logger - .getLogger(Table.class.getName()); + private transient Logger logger = null; /** * Modes that Table support as drag sourse. @@ -331,7 +328,8 @@ public class Table extends AbstractSelect implements Action.Container, private static final double CACHE_RATE_DEFAULT = 2; private static final String ROW_HEADER_COLUMN_KEY = "0"; - private static final Object ROW_HEADER_FAKE_PROPERTY_ID = new Object(); + private static final Object ROW_HEADER_FAKE_PROPERTY_ID = new UniqueSerializable() { + }; /* Private table extensions to Select */ @@ -356,6 +354,11 @@ public class Table extends AbstractSelect implements Action.Container, private LinkedList<Object> visibleColumns = new LinkedList<Object>(); /** + * Holds noncollapsible columns. + */ + private HashSet<Object> noncollapsibleColumns = new HashSet<Object>(); + + /** * Holds propertyIds of currently collapsed columns. */ private final HashSet<Object> collapsedColumns = new HashSet<Object>(); @@ -1248,6 +1251,9 @@ public class Table extends AbstractSelect implements Action.Container, if (!isColumnCollapsingAllowed()) { throw new IllegalStateException("Column collapsing not allowed!"); } + if (collapsed && noncollapsibleColumns.contains(propertyId)) { + throw new IllegalStateException("The column is noncollapsible!"); + } if (collapsed) { collapsedColumns.add(propertyId); @@ -1287,6 +1293,41 @@ public class Table extends AbstractSelect implements Action.Container, } /** + * Sets whether the given column is collapsible. Note that collapsible + * columns can only be actually collapsed (via UI or with + * {@link #setColumnCollapsed(Object, boolean) setColumnCollapsed()}) if + * {@link #isColumnCollapsingAllowed()} is true. By default all columns are + * collapsible. + * + * @param propertyId + * the propertyID identifying the column. + * @param collapsible + * true if the column should be collapsible, false otherwise. + */ + public void setColumnCollapsible(Object propertyId, boolean collapsible) { + if (collapsible) { + noncollapsibleColumns.remove(propertyId); + } else { + noncollapsibleColumns.add(propertyId); + collapsedColumns.remove(propertyId); + } + refreshRowCache(); + } + + /** + * Checks if the given column is collapsible. Note that even if this method + * returns <code>true</code>, the column can only be actually collapsed (via + * UI or with {@link #setColumnCollapsed(Object, boolean) + * setColumnCollapsed()}) if {@link #isColumnCollapsingAllowed()} is also + * true. + * + * @return true if the column can be collapsed; false otherwise. + */ + public boolean isColumnCollapsible(Object propertyId) { + return !noncollapsibleColumns.contains(propertyId); + } + + /** * Checks if column reordering is allowed. * * @return true if columns can be reordered; false otherwise. @@ -1569,6 +1610,13 @@ public class Table extends AbstractSelect implements Action.Container, } } else { // initial load + + // #8805 send one extra row in the beginning in case a partial + // row is shown on the UI + if (firstIndex > 0) { + firstIndex = firstIndex - 1; + rows = rows + 1; + } firstToBeRenderedInClient = firstIndex; } if (totalRows > 0) { @@ -1597,6 +1645,7 @@ public class Table extends AbstractSelect implements Action.Container, * this method has been called. See {@link #refreshRowCache()} for forcing * an update of the contents. */ + @Override public void requestRepaint() { // Overridden only for javadoc @@ -1714,8 +1763,9 @@ public class Table extends AbstractSelect implements Action.Container, * @return */ private Object[][] getVisibleCellsInsertIntoCache(int firstIndex, int rows) { - logger.finest("Insert " + rows + " rows at index " + firstIndex - + " to existing page buffer requested"); + getLogger().finest( + "Insert " + rows + " rows at index " + firstIndex + + " to existing page buffer requested"); // Page buffer must not become larger than pageLength*cacheRate before // or after the current page @@ -1818,11 +1868,14 @@ public class Table extends AbstractSelect implements Action.Container, } } pageBuffer = newPageBuffer; - logger.finest("Page Buffer now contains " - + pageBuffer[CELL_ITEMID].length + " rows (" - + pageBufferFirstIndex + "-" - + (pageBufferFirstIndex + pageBuffer[CELL_ITEMID].length - 1) - + ")"); + getLogger().finest( + "Page Buffer now contains " + + pageBuffer[CELL_ITEMID].length + + " rows (" + + pageBufferFirstIndex + + "-" + + (pageBufferFirstIndex + + pageBuffer[CELL_ITEMID].length - 1) + ")"); return cells; } @@ -1839,8 +1892,9 @@ public class Table extends AbstractSelect implements Action.Container, */ private Object[][] getVisibleCellsNoCache(int firstIndex, int rows, boolean replaceListeners) { - logger.finest("Render visible cells for rows " + firstIndex + "-" - + (firstIndex + rows - 1)); + getLogger().finest( + "Render visible cells for rows " + firstIndex + "-" + + (firstIndex + rows - 1)); final Object[] colids = getVisibleColumns(); final int cols = colids.length; @@ -2022,8 +2076,9 @@ public class Table extends AbstractSelect implements Action.Container, } protected void registerComponent(Component component) { - logger.finest("Registered " + component.getClass().getSimpleName() - + ": " + component.getCaption()); + getLogger().finest( + "Registered " + component.getClass().getSimpleName() + ": " + + component.getCaption()); if (component.getParent() != this) { component.setParent(this); } @@ -2054,8 +2109,9 @@ public class Table extends AbstractSelect implements Action.Container, * @param count */ private void unregisterComponentsAndPropertiesInRows(int firstIx, int count) { - logger.finest("Unregistering components in rows " + firstIx + "-" - + (firstIx + count - 1)); + getLogger().finest( + "Unregistering components in rows " + firstIx + "-" + + (firstIx + count - 1)); Object[] colids = getVisibleColumns(); if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) { int bufSize = pageBuffer[CELL_ITEMID].length; @@ -2135,8 +2191,9 @@ public class Table extends AbstractSelect implements Action.Container, * a set of components that should be unregistered. */ protected void unregisterComponent(Component component) { - logger.finest("Unregistered " + component.getClass().getSimpleName() - + ": " + component.getCaption()); + getLogger().finest( + "Unregistered " + component.getClass().getSimpleName() + ": " + + component.getCaption()); component.setParent(null); /* * Also remove property data sources to unregister listeners keeping the @@ -2446,6 +2503,7 @@ public class Table extends AbstractSelect implements Action.Container, * @see com.vaadin.ui.Select#changeVariables(java.lang.Object, * java.util.Map) */ + @Override public void changeVariables(Object source, Map<String, Object> variables) { @@ -2505,7 +2563,7 @@ public class Table extends AbstractSelect implements Action.Container, .get("lastToBeRendered")).intValue(); } catch (Exception e) { // FIXME: Handle exception - logger.log(Level.FINER, + getLogger().log(Level.FINER, "Could not parse the first and/or last rows.", e); } @@ -2525,8 +2583,9 @@ public class Table extends AbstractSelect implements Action.Container, } } } - logger.finest("Client wants rows " + reqFirstRowToPaint + "-" - + (reqFirstRowToPaint + reqRowsToPaint - 1)); + getLogger().finest( + "Client wants rows " + reqFirstRowToPaint + "-" + + (reqFirstRowToPaint + reqRowsToPaint - 1)); clientNeedsContentRefresh = true; } @@ -2572,7 +2631,7 @@ public class Table extends AbstractSelect implements Action.Container, } } catch (final Exception e) { // FIXME: Handle exception - logger.log(Level.FINER, + getLogger().log(Level.FINER, "Could not determine column collapsing state", e); } clientNeedsContentRefresh = true; @@ -2594,7 +2653,7 @@ public class Table extends AbstractSelect implements Action.Container, } } catch (final Exception e) { // FIXME: Handle exception - logger.log(Level.FINER, + getLogger().log(Level.FINER, "Could not determine column reordering state", e); } clientNeedsContentRefresh = true; @@ -2767,6 +2826,7 @@ public class Table extends AbstractSelect implements Action.Container, * @see com.vaadin.ui.AbstractSelect#paintContent(com.vaadin. * terminal.PaintTarget) */ + @Override public void paintContent(PaintTarget target) throws PaintException { /* @@ -2884,8 +2944,9 @@ public class Table extends AbstractSelect implements Action.Container, target.startTag("prows"); if (!shouldHideAddedRows()) { - logger.finest("Paint rows for add. Index: " + firstIx + ", count: " - + count + "."); + getLogger().finest( + "Paint rows for add. Index: " + firstIx + ", count: " + + count + "."); // Partial row additions bypass the normal caching mechanism. Object[][] cells = getVisibleCellsInsertIntoCache(firstIx, count); @@ -2908,8 +2969,9 @@ public class Table extends AbstractSelect implements Action.Container, indexInRowbuffer, itemId); } } else { - logger.finest("Paint rows for remove. Index: " + firstIx - + ", count: " + count + "."); + getLogger().finest( + "Paint rows for remove. Index: " + firstIx + ", count: " + + count + "."); removeRowsFromCacheAndFillBottom(firstIx, count); target.addAttribute("hide", true); } @@ -3108,7 +3170,17 @@ public class Table extends AbstractSelect implements Action.Container, } } target.addVariable(this, "collapsedcolumns", collapsedKeys); + + final String[] noncollapsibleKeys = new String[noncollapsibleColumns + .size()]; + nextColumn = 0; + for (Object colId : noncollapsibleColumns) { + noncollapsibleKeys[nextColumn++] = columnIdMap.key(colId); + } + target.addVariable(this, "noncollapsiblecolumns", + noncollapsibleKeys); } + } private void paintActions(PaintTarget target, final Set<Action> actionSet) @@ -3613,6 +3685,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler) */ + public void addActionHandler(Action.Handler actionHandler) { if (actionHandler != null) { @@ -3639,6 +3712,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler) */ + public void removeActionHandler(Action.Handler actionHandler) { if (actionHandlers != null && actionHandlers.contains(actionHandler)) { @@ -3678,6 +3752,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent) */ + @Override public void valueChange(Property.ValueChangeEvent event) { if (event.getProperty() == this @@ -3708,6 +3783,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.ui.Component#attach() */ + @Override public void attach() { super.attach(); @@ -3720,6 +3796,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.ui.Component#detach() */ + @Override public void detach() { super.detach(); @@ -3730,6 +3807,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container#removeAllItems() */ + @Override public boolean removeAllItems() { currentPageFirstItemId = null; @@ -3742,6 +3820,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container#removeItem(Object) */ + @Override public boolean removeItem(Object itemId) { final Object nextItemId = nextItemId(itemId); @@ -3760,6 +3839,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container#removeContainerProperty(Object) */ + @Override public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException { @@ -3786,6 +3866,7 @@ public class Table extends AbstractSelect implements Action.Container, * @see com.vaadin.data.Container#addContainerProperty(Object, Class, * Object) */ + @Override public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException { @@ -3941,6 +4022,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.ui.Select#getVisibleItemIds() */ + @Override public Collection<?> getVisibleItemIds() { @@ -3964,6 +4046,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) */ + @Override public void containerItemSetChange(Container.ItemSetChangeEvent event) { super.containerItemSetChange(event); @@ -3980,6 +4063,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) */ + @Override public void containerPropertySetChange( Container.PropertySetChangeEvent event) { @@ -4023,6 +4107,7 @@ public class Table extends AbstractSelect implements Action.Container, * if set to true. * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean) */ + @Override public void setNewItemsAllowed(boolean allowNewOptions) throws UnsupportedOperationException { @@ -4036,6 +4121,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) */ + public Object nextItemId(Object itemId) { return ((Container.Ordered) items).nextItemId(itemId); } @@ -4046,6 +4132,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) */ + public Object prevItemId(Object itemId) { return ((Container.Ordered) items).prevItemId(itemId); } @@ -4055,6 +4142,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#firstItemId() */ + public Object firstItemId() { return ((Container.Ordered) items).firstItemId(); } @@ -4064,6 +4152,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#lastItemId() */ + public Object lastItemId() { return ((Container.Ordered) items).lastItemId(); } @@ -4074,6 +4163,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) */ + public boolean isFirstId(Object itemId) { return ((Container.Ordered) items).isFirstId(itemId); } @@ -4084,6 +4174,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) */ + public boolean isLastId(Object itemId) { return ((Container.Ordered) items).isLastId(itemId); } @@ -4093,6 +4184,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) */ + public Object addItemAfter(Object previousItemId) throws UnsupportedOperationException { Object itemId = ((Container.Ordered) items) @@ -4109,6 +4201,7 @@ public class Table extends AbstractSelect implements Action.Container, * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, * java.lang.Object) */ + public Item addItemAfter(Object previousItemId, Object newItemId) throws UnsupportedOperationException { Item item = ((Container.Ordered) items).addItemAfter(previousItemId, @@ -4201,6 +4294,7 @@ public class Table extends AbstractSelect implements Action.Container, * boolean[]) * */ + public void sort(Object[] propertyId, boolean[] ascending) throws UnsupportedOperationException { final Container c = getContainerDataSource(); @@ -4236,6 +4330,7 @@ public class Table extends AbstractSelect implements Action.Container, * * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() */ + public Collection<?> getSortableContainerPropertyIds() { final Container c = getContainerDataSource(); if (c instanceof Container.Sortable && !isSortDisabled()) { @@ -4436,6 +4531,7 @@ public class Table extends AbstractSelect implements Action.Container, } // Identical to AbstractCompoenentContainer.setEnabled(); + @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); @@ -4560,7 +4656,6 @@ public class Table extends AbstractSelect implements Action.Container, * initialized from server and no subsequent requests requests are needed * during that drag and drop operation. */ - @ClientCriterion(VLazyInitItemIdentifiers.class) public static abstract class TableDropCriterion extends ServerSideCriterion { private Table table; @@ -4574,6 +4669,7 @@ public class Table extends AbstractSelect implements Action.Container, * com.vaadin.event.dd.acceptcriteria.ServerSideCriterion#getIdentifier * () */ + @Override protected String getIdentifier() { return TableDropCriterion.class.getCanonicalName(); @@ -4605,6 +4701,7 @@ public class Table extends AbstractSelect implements Action.Container, * com.vaadin.event.dd.acceptcriteria.AcceptCriterion#paintResponse( * com.vaadin.terminal.PaintTarget) */ + @Override public void paintResponse(PaintTarget target) throws PaintException { /* @@ -5276,4 +5373,11 @@ public class Table extends AbstractSelect implements Action.Container, public boolean isComponentVisible(Component childComponent) { return true; } + + private final Logger getLogger() { + if (logger == null) { + logger = Logger.getLogger(Table.class.getName()); + } + return logger; + } } diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java index db738fee58..dacb3a2027 100644 --- a/src/com/vaadin/ui/Tree.java +++ b/src/com/vaadin/ui/Tree.java @@ -34,7 +34,6 @@ import com.vaadin.event.dd.DragSource; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.DropTarget; import com.vaadin.event.dd.TargetDetails; -import com.vaadin.event.dd.acceptcriteria.ClientCriterion; import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion; import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion; import com.vaadin.event.dd.acceptcriteria.TargetDetailIs; @@ -43,8 +42,6 @@ import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Resource; import com.vaadin.terminal.gwt.client.MouseEventDetails; -import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers; -import com.vaadin.terminal.gwt.client.ui.dd.VTargetInSubtree; import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; import com.vaadin.terminal.gwt.client.ui.tree.TreeConnector; import com.vaadin.terminal.gwt.client.ui.tree.VTree; @@ -1396,7 +1393,6 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, * initialized from server and no subsequent requests requests are needed * during that drag and drop operation. */ - @ClientCriterion(VLazyInitItemIdentifiers.class) public static abstract class TreeDropCriterion extends ServerSideCriterion { private Tree tree; @@ -1513,7 +1509,6 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, * <p> * The root items is also consider to be valid target. */ - @ClientCriterion(VTargetInSubtree.class) public class TargetInSubtree extends ClientSideCriterion { private Object rootId; diff --git a/src/com/vaadin/ui/TreeTable.java b/src/com/vaadin/ui/TreeTable.java index 9607add2c9..3294f6fab0 100644 --- a/src/com/vaadin/ui/TreeTable.java +++ b/src/com/vaadin/ui/TreeTable.java @@ -49,9 +49,6 @@ import com.vaadin.ui.Tree.ExpandListener; @SuppressWarnings({ "serial" }) public class TreeTable extends Table implements Hierarchical { - private static final Logger logger = Logger.getLogger(TreeTable.class - .getName()); - private interface ContainerStrategy extends Serializable { public int size(); @@ -84,6 +81,7 @@ public class TreeTable extends Table implements Hierarchical { * Consider adding getDepth to {@link Collapsible}, might help * scalability with some container implementations. */ + public int getDepth(Object itemId) { int depth = 0; Hierarchical hierarchicalContainer = getContainerDataSource(); @@ -222,9 +220,9 @@ public class TreeTable extends Table implements Hierarchical { boolean removed = openItems.remove(itemId); if (!removed) { openItems.add(itemId); - logger.finest("Item " + itemId + " is now expanded"); + getLogger().finest("Item " + itemId + " is now expanded"); } else { - logger.finest("Item " + itemId + " is now collapsed"); + getLogger().finest("Item " + itemId + " is now collapsed"); } clearPreorderCache(); } @@ -789,4 +787,8 @@ public class TreeTable extends Table implements Hierarchical { requestRepaint(); } + private static final Logger getLogger() { + return Logger.getLogger(TreeTable.class.getName()); + } + } diff --git a/src/com/vaadin/ui/UniqueSerializable.java b/src/com/vaadin/ui/UniqueSerializable.java new file mode 100644 index 0000000000..828b285538 --- /dev/null +++ b/src/com/vaadin/ui/UniqueSerializable.java @@ -0,0 +1,30 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +import java.io.Serializable; + +/** + * A base class for generating an unique object that is serializable. + * <p> + * This class is abstract but has no abstract methods to force users to create + * an anonymous inner class. Otherwise each instance will not be unique. + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0 + * + */ +public abstract class UniqueSerializable implements Serializable { + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return getClass() == obj.getClass(); + } +} diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index 3c17baf414..02556c9961 100644 --- a/src/com/vaadin/ui/Window.java +++ b/src/com/vaadin/ui/Window.java @@ -24,6 +24,7 @@ import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Vaadin6Component; import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.ui.root.VRoot; import com.vaadin.terminal.gwt.client.ui.window.WindowServerRpc; import com.vaadin.terminal.gwt.client.ui.window.WindowState; @@ -83,6 +84,10 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, } }; + private int browserWindowWidth = -1; + + private int browserWindowHeight = -1; + /** * Creates a new unnamed window with a default layout. */ @@ -119,6 +124,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * * @see com.vaadin.ui.Panel#addComponent(com.vaadin.ui.Component) */ + @Override public void addComponent(Component c) { if (c instanceof Window) { @@ -136,6 +142,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * * @see com.vaadin.ui.Panel#paintContent(com.vaadin.terminal.PaintTarget) */ + @Override public synchronized void paintContent(PaintTarget target) throws PaintException { @@ -153,6 +160,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * * @see com.vaadin.ui.Panel#changeVariables(java.lang.Object, java.util.Map) */ + @Override public void changeVariables(Object source, Map<String, Object> variables) { @@ -161,15 +169,29 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, // size is handled in super class, but resize events only in windows -> // so detect if size change occurs before super.changeVariables() if (variables.containsKey("height") - && (getHeightUnits() != UNITS_PIXELS || (Integer) variables + && (getHeightUnits() != Unit.PIXELS || (Integer) variables .get("height") != getHeight())) { sizeHasChanged = true; } if (variables.containsKey("width") - && (getWidthUnits() != UNITS_PIXELS || (Integer) variables + && (getWidthUnits() != Unit.PIXELS || (Integer) variables .get("width") != getWidth())) { sizeHasChanged = true; } + Integer browserHeightVar = (Integer) variables + .get(VRoot.BROWSER_HEIGHT_VAR); + if (browserHeightVar != null + && browserHeightVar.intValue() != browserWindowHeight) { + browserWindowHeight = browserHeightVar.intValue(); + sizeHasChanged = true; + } + Integer browserWidthVar = (Integer) variables + .get(VRoot.BROWSER_WIDTH_VAR); + if (browserWidthVar != null + && browserWidthVar.intValue() != browserWindowWidth) { + browserWindowWidth = browserWidthVar.intValue(); + sizeHasChanged = true; + } super.changeVariables(source, variables); @@ -604,8 +626,13 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, } /** - * Request to center this window on the screen. <b>Note:</b> affects - * sub-windows only. + * Sets this window to be centered relative to its parent window. Affects + * sub-windows only. If the window is resized as a result of the size of its + * content changing, it will keep itself centered as long as its position is + * not explicitly changed programmatically or by the user. + * <p> + * <b>NOTE:</b> This method has several issues as currently implemented. + * Please refer to http://dev.vaadin.com/ticket/8971 for details. */ public void center() { getState().setCentered(true); @@ -788,6 +815,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * * @see com.vaadin.event.FieldEvents.FocusNotifier#addListener(com.vaadin.event.FieldEvents.FocusListener) */ + public void addListener(FocusListener listener) { addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, FocusListener.focusMethod); @@ -804,6 +832,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * * @see com.vaadin.event.FieldEvents.BlurNotifier#addListener(com.vaadin.event.FieldEvents.BlurListener) */ + public void addListener(BlurListener listener) { addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, BlurListener.blurMethod); @@ -819,6 +848,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * If the window is a sub-window focusing will cause the sub-window to be * brought on top of other sub-windows on gain keyboard focus. */ + @Override public void focus() { /* @@ -834,5 +864,4 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, public WindowState getState() { return (WindowState) super.getState(); } - } diff --git a/src/com/vaadin/ui/themes/ChameleonTheme.java b/src/com/vaadin/ui/themes/ChameleonTheme.java index bfb9686018..5ae8cd4e57 100644 --- a/src/com/vaadin/ui/themes/ChameleonTheme.java +++ b/src/com/vaadin/ui/themes/ChameleonTheme.java @@ -5,7 +5,7 @@ package com.vaadin.ui.themes; public class ChameleonTheme extends BaseTheme { - public static final String THEME_NAME = "Chameleon"; + public static final String THEME_NAME = "chameleon"; /*************************************************************************** * Label styles diff --git a/tests/server-side/com/vaadin/tests/VaadinClasses.java b/tests/server-side/com/vaadin/tests/VaadinClasses.java index b74af660e4..0ee193e8f1 100644 --- a/tests/server-side/com/vaadin/tests/VaadinClasses.java +++ b/tests/server-side/com/vaadin/tests/VaadinClasses.java @@ -15,8 +15,6 @@ import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; -import org.junit.Test; - import com.vaadin.Application; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; @@ -29,6 +27,9 @@ import com.vaadin.ui.PopupView; import com.vaadin.ui.Root; import com.vaadin.ui.VerticalSplitPanel; import com.vaadin.ui.Window; +import com.vaadin.ui.themes.BaseTheme; + +import org.junit.Test; @SuppressWarnings("deprecation") public class VaadinClasses { @@ -71,6 +72,15 @@ public class VaadinClasses { } } + public static List<Class<? extends BaseTheme>> getThemeClasses() { + try { + return findClasses(BaseTheme.class, "com.vaadin.ui.themes"); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + public static List<Class<? extends Object>> getAllServerSideClasses() { try { return findClassesNoTests(Object.class, "com.vaadin", new String[] { diff --git a/tests/server-side/com/vaadin/tests/server/TestThemeNames.java b/tests/server-side/com/vaadin/tests/server/TestThemeNames.java new file mode 100644 index 0000000000..22fe315730 --- /dev/null +++ b/tests/server-side/com/vaadin/tests/server/TestThemeNames.java @@ -0,0 +1,38 @@ +package com.vaadin.tests.server; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.List; + +import junit.framework.TestCase; + +import com.vaadin.tests.VaadinClasses; +import com.vaadin.ui.themes.BaseTheme; + +public class TestThemeNames extends TestCase { + public void testThemeNames() { + File baseDir = new File(SourceFileChecker.getBaseDir() + + "WebContent/VAADIN/themes/"); + + List<Class<? extends BaseTheme>> themeClasses = VaadinClasses + .getThemeClasses(); + for (Class<? extends BaseTheme> themeClass : themeClasses) { + try { + Field field = themeClass.getField("THEME_NAME"); + String themeName = (String) field.get(null); + + File themeDir = new File(baseDir, themeName); + File styleFile = new File(themeDir, "styles.css"); + + assertTrue("Can't find " + styleFile + " for theme " + + themeClass.getName(), styleFile.exists()); + + // Test that casing matches + assertEquals(themeDir.getCanonicalFile().getName(), themeName); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + +} diff --git a/tests/server-side/com/vaadin/tests/server/component/table/TableSerialization.java b/tests/server-side/com/vaadin/tests/server/component/table/TableSerialization.java new file mode 100644 index 0000000000..44dcd60fa5 --- /dev/null +++ b/tests/server-side/com/vaadin/tests/server/component/table/TableSerialization.java @@ -0,0 +1,24 @@ +package com.vaadin.tests.server.component.table; + +import junit.framework.TestCase; + +import org.apache.commons.lang.SerializationUtils; + +import com.vaadin.ui.Table; + +public class TableSerialization extends TestCase { + + public void testSerialization() { + Table t = new Table(); + byte[] ser = SerializationUtils.serialize(t); + Table t2 = (Table) SerializationUtils.deserialize(ser); + + } + public void testSerializationWithRowHeaders() { + Table t = new Table(); + t.setRowHeaderMode(Table.ROW_HEADER_MODE_EXPLICIT); + t.setColumnWidth(null, 100); + byte[] ser = SerializationUtils.serialize(t); + Table t2 = (Table) SerializationUtils.deserialize(ser); + } +} diff --git a/tests/server-side/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java b/tests/server-side/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java index 40d0ffd17d..0ef8ae5a76 100644 --- a/tests/server-side/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java +++ b/tests/server-side/com/vaadin/tests/server/component/tabsheet/TestTabSheet.java @@ -2,6 +2,8 @@ package com.vaadin.tests.server.component.tabsheet; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import java.util.Iterator; @@ -158,4 +160,65 @@ public class TestTabSheet { tabSheet.setSelectedTab(123); assertEquals(tab1.getComponent(), tabSheet.getSelectedTab()); } + + @Test + public void replaceComponent() { + TabSheet tabSheet = new TabSheet(); + Label lbl1 = new Label("aaa"); + Label lbl2 = new Label("bbb"); + Label lbl3 = new Label("ccc"); + Label lbl4 = new Label("ddd"); + + Tab tab1 = tabSheet.addTab(lbl1); + tab1.setCaption("tab1"); + tab1.setClosable(true); + Tab tab2 = tabSheet.addTab(lbl2); + tab2.setDescription("description"); + tab2.setEnabled(false); + + // Replace component not in tabsheet with one already in tabsheet - + // should be no-op + tabSheet.replaceComponent(lbl3, lbl2); + assertEquals(2, tabSheet.getComponentCount()); + assertSame(tab1, tabSheet.getTab(lbl1)); + assertSame(tab2, tabSheet.getTab(lbl2)); + assertNull(tabSheet.getTab(lbl3)); + + // Replace component not in tabsheet with one not in tabsheet either + // should add lbl4 as last tab + tabSheet.replaceComponent(lbl3, lbl4); + assertEquals(3, tabSheet.getComponentCount()); + assertSame(tab1, tabSheet.getTab(lbl1)); + assertSame(tab2, tabSheet.getTab(lbl2)); + assertEquals(2, tabSheet.getTabPosition(tabSheet.getTab(lbl4))); + + // Replace component in tabsheet with another + // should swap places, tab association should stay the same but tabs + // should swap metadata + tabSheet.replaceComponent(lbl1, lbl2); + assertSame(tab1, tabSheet.getTab(lbl1)); + assertSame(tab2, tabSheet.getTab(lbl2)); + assertEquals(false, tab1.isClosable()); + assertEquals(true, tab2.isClosable()); + assertEquals(false, tab1.isEnabled()); + assertEquals(true, tab2.isEnabled()); + assertEquals("description", tab1.getDescription()); + assertEquals(null, tab2.getDescription()); + assertEquals(3, tabSheet.getComponentCount()); + assertEquals(1, tabSheet.getTabPosition(tabSheet.getTab(lbl1))); + assertEquals(0, tabSheet.getTabPosition(tabSheet.getTab(lbl2))); + + // Replace component in tabsheet with one not in tabsheet + // should create a new tab instance for the new component, old tab + // instance should become unattached + // tab metadata should be copied from old to new + tabSheet.replaceComponent(lbl1, lbl3); + assertEquals(3, tabSheet.getComponentCount()); + assertNull(tabSheet.getTab(lbl1)); + assertNull(tab1.getComponent()); + assertNotNull(tabSheet.getTab(lbl3)); + assertEquals(false, tabSheet.getTab(lbl3).isEnabled()); + assertEquals("description", tab1.getDescription()); + assertEquals(1, tabSheet.getTabPosition(tabSheet.getTab(lbl3))); + } } diff --git a/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java b/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java index ab983b4022..03f49d4ab6 100644 --- a/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java +++ b/tests/server-side/com/vaadin/tests/server/navigator/NavigatorTest.java @@ -19,9 +19,9 @@ import com.vaadin.navigator.ViewChangeListener; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.navigator.ViewDisplay; import com.vaadin.navigator.ViewProvider; +import com.vaadin.terminal.Page; import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView; import com.vaadin.tests.server.navigator.ClassBasedViewProviderTest.TestView2; -import com.vaadin.ui.Root; public class NavigatorTest extends TestCase { @@ -366,9 +366,9 @@ public class NavigatorTest extends TestCase { public void testDefaultDisplayType() { IMocksControl control = EasyMock.createControl(); - Root root = control.createMock(Root.class); + Page page = control.createMock(Page.class); - Navigator navigator = new Navigator(root); + Navigator navigator = new Navigator(page); assertEquals("Default display should be a SimpleViewDisplay", SimpleViewDisplay.class, navigator.getDisplay().getClass()); diff --git a/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java b/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java index cfbf50f256..65294b2913 100644 --- a/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java +++ b/tests/server-side/com/vaadin/tests/server/navigator/UriFragmentManagerTest.java @@ -11,20 +11,20 @@ import org.easymock.IMocksControl; import com.vaadin.navigator.Navigator; import com.vaadin.navigator.Navigator.UriFragmentManager; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; public class UriFragmentManagerTest extends TestCase { public void testGetSetFragment() { - Root root = EasyMock.createMock(Root.class); - UriFragmentManager manager = new UriFragmentManager(root, null); + Page page = EasyMock.createMock(Page.class); + UriFragmentManager manager = new UriFragmentManager(page, null); // prepare mock - EasyMock.expect(root.getFragment()).andReturn(""); - root.setFragment("test"); - EasyMock.expect(root.getFragment()).andReturn("test"); - EasyMock.replay(root); + EasyMock.expect(page.getFragment()).andReturn(""); + page.setFragment("test"); + EasyMock.expect(page.getFragment()).andReturn("test"); + EasyMock.replay(page); // test manager using the mock assertEquals("Incorrect fragment value", "", manager.getFragment()); @@ -36,15 +36,15 @@ public class UriFragmentManagerTest extends TestCase { // create mocks IMocksControl control = EasyMock.createControl(); Navigator navigator = control.createMock(Navigator.class); - Root root = control.createMock(Root.class); + Page page = control.createMock(Page.class); - UriFragmentManager manager = new UriFragmentManager(root, navigator); + UriFragmentManager manager = new UriFragmentManager(page, navigator); - EasyMock.expect(root.getFragment()).andReturn("test"); + EasyMock.expect(page.getFragment()).andReturn("test"); navigator.navigateTo("test"); control.replay(); - FragmentChangedEvent event = root.new FragmentChangedEvent(root, + FragmentChangedEvent event = page.new FragmentChangedEvent(page, "oldtest"); manager.fragmentChanged(event); } diff --git a/tests/server-side/com/vaadin/tests/util/UniqueSerializableTest.java b/tests/server-side/com/vaadin/tests/util/UniqueSerializableTest.java new file mode 100644 index 0000000000..578d983c4d --- /dev/null +++ b/tests/server-side/com/vaadin/tests/util/UniqueSerializableTest.java @@ -0,0 +1,33 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.util; + +import java.io.Serializable; + +import junit.framework.TestCase; + +import org.apache.commons.lang.SerializationUtils; + +import com.vaadin.ui.UniqueSerializable; + +public class UniqueSerializableTest extends TestCase implements Serializable { + + public void testUniqueness() { + UniqueSerializable o1 = new UniqueSerializable() { + }; + UniqueSerializable o2 = new UniqueSerializable() { + }; + assertFalse(o1 == o2); + assertFalse(o1.equals(o2)); + } + + public void testSerialization() { + UniqueSerializable o1 = new UniqueSerializable() { + }; + UniqueSerializable d1 = (UniqueSerializable) SerializationUtils + .deserialize(SerializationUtils.serialize(o1)); + assertTrue(d1.equals(o1)); + } + +} diff --git a/tests/test.xml b/tests/test.xml index 090e5129f6..222fe0a452 100644 --- a/tests/test.xml +++ b/tests/test.xml @@ -114,6 +114,8 @@ <path refid="classpath" /> <pathelement path="${class-dir}" /> </classpath> + + <formatter usefile="false" type="plain"/> <jvmarg value="-Dcom.vaadin.testbench.tester.host=${com.vaadin.testbench.tester.host}" /> <jvmarg value="-Dcom.vaadin.testbench.deployment.url=${com.vaadin.testbench.deployment.url}" /> diff --git a/tests/testbench/com/vaadin/launcher/ApplicationRunnerServlet.java b/tests/testbench/com/vaadin/launcher/ApplicationRunnerServlet.java index 33d63b0413..dd93b1a8b6 100644 --- a/tests/testbench/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/tests/testbench/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -9,7 +9,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.LinkedHashSet; -import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -45,9 +44,6 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { } } - private static final Logger logger = Logger - .getLogger(ApplicationRunnerServlet.class.getName()); - /** * The name of the application class currently used. Only valid within one * request. @@ -241,8 +237,10 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { // Ignore as this is expected for many packages } catch (Exception e2) { // TODO: handle exception - logger.log(Level.FINE, "Failed to find application class " - + pkg + "." + baseName, e2); + getLogger().log( + Level.FINE, + "Failed to find application class " + pkg + "." + + baseName, e2); } if (appClass != null) { return appClass; @@ -289,4 +287,8 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { }; } + private Logger getLogger() { + return Logger.getLogger(ApplicationRunnerServlet.class.getName()); + } + } diff --git a/tests/testbench/com/vaadin/tests/TestBench.java b/tests/testbench/com/vaadin/tests/TestBench.java index c3bb24cbef..1ac497e574 100644 --- a/tests/testbench/com/vaadin/tests/TestBench.java +++ b/tests/testbench/com/vaadin/tests/TestBench.java @@ -16,6 +16,8 @@ import com.vaadin.Application; import com.vaadin.data.Property; import com.vaadin.data.util.HierarchicalContainer; import com.vaadin.terminal.ExternalResource; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.HorizontalSplitPanel; @@ -23,8 +25,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.Layout; import com.vaadin.ui.Link; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; @@ -119,7 +119,7 @@ public class TestBench extends com.vaadin.Application.LegacyApplication VerticalLayout lo = new VerticalLayout(); lo.addComponent(menu); - mainWindow.addListener(new Root.FragmentChangedListener() { + mainWindow.getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent source) { String fragment = source.getFragment(); if (fragment != null && !"".equals(fragment)) { diff --git a/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java b/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java index 48eff0336e..c63c0caf16 100644 --- a/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java +++ b/tests/testbench/com/vaadin/tests/TestComponentAddAndRecursion.java @@ -10,7 +10,6 @@ import com.vaadin.ui.GridLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; import com.vaadin.ui.VerticalLayout; /** @@ -92,12 +91,10 @@ public class TestComponentAddAndRecursion extends CustomComponent { public void buttonClick(ClickEvent event) { try { p3.addComponent(p2); - Root.getCurrentRoot().showNotification("ERROR", - "This should have failed", + Notification.show("ERROR", "This should have failed", Notification.TYPE_ERROR_MESSAGE); } catch (Exception e) { - Root.getCurrentRoot().showNotification("OK", - "threw, as expected", + Notification.show("OK", "threw, as expected", Notification.TYPE_ERROR_MESSAGE); } } @@ -111,12 +108,10 @@ public class TestComponentAddAndRecursion extends CustomComponent { p.addComponent(p2); try { p3.addComponent(p); - Root.getCurrentRoot().showNotification("ERROR", - "This should have failed", + Notification.show("ERROR", "This should have failed", Notification.TYPE_ERROR_MESSAGE); } catch (Exception e) { - Root.getCurrentRoot().showNotification("OK", - "threw, as expected", + Notification.show("OK", "threw, as expected", Notification.TYPE_ERROR_MESSAGE); } } diff --git a/tests/testbench/com/vaadin/tests/TestForWindowOpen.java b/tests/testbench/com/vaadin/tests/TestForWindowOpen.java index c9dbf8dabe..76154f2419 100644 --- a/tests/testbench/com/vaadin/tests/TestForWindowOpen.java +++ b/tests/testbench/com/vaadin/tests/TestForWindowOpen.java @@ -24,7 +24,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r); + Root.getCurrentRoot().getPage().open(r); } @@ -36,7 +36,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r, "mytarget"); + Root.getCurrentRoot().getPage().open(r, "mytarget"); } @@ -48,7 +48,7 @@ public class TestForWindowOpen extends CustomComponent { public void buttonClick(ClickEvent event) { final ExternalResource r = new ExternalResource( "http://www.google.com"); - Root.getCurrentRoot().open(r, "secondtarget"); + Root.getCurrentRoot().getPage().open(r, "secondtarget"); } diff --git a/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java b/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java index 7d5e298286..58faec35f0 100644 --- a/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java +++ b/tests/testbench/com/vaadin/tests/appengine/GAESyncTest.java @@ -91,7 +91,8 @@ public class GAESyncTest extends Application.LegacyApplication { public void buttonClick(ClickEvent event) { if (getRoot() == getMainWindow()) { - getRoot().showNotification("main"); + getRoot().getPage().showNotification( + new Notification("main")); try { Thread.sleep((5000)); } catch (InterruptedException e) { diff --git a/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.html b/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.html new file mode 100644 index 0000000000..f20967c8de --- /dev/null +++ b/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.html @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>TabSheetWithDisappearingContent</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TabSheetWithDisappearingContent</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.application.TerminalErrorNotification?restartApplication&debug</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsapplicationTerminalErrorNotification::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>vaadin=runcomvaadintestsapplicationTerminalErrorNotification::Root/VNotification[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationTerminalErrorNotification::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>Got an exception: You asked for it</td> +</tr> +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.java b/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.java new file mode 100644 index 0000000000..f2ae7a3891 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/application/TerminalErrorNotification.java @@ -0,0 +1,57 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.application; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Root; + +public class TerminalErrorNotification extends TestBase { + + @Override + protected void setup() { + Button button = new Button("Throw exception", + new Button.ClickListener() { + + public void buttonClick(ClickEvent event) { + throw new RuntimeException("You asked for it"); + } + }); + + addComponent(button); + } + + @Override + public void terminalError(com.vaadin.terminal.Terminal.ErrorEvent event) { + event.getThrowable().printStackTrace(); + + Root mainWindow = getMainWindow(); + if (mainWindow != null) { + Throwable throwable = event.getThrowable(); + + // Find the root cause + while (throwable.getCause() != null) { + throwable = throwable.getCause(); + } + + Notification.show("Got an exception: " + throwable.getMessage(), + Notification.TYPE_ERROR_MESSAGE); + } else { + System.out.println("No main window found"); + } + } + + @Override + protected String getDescription() { + return "Showing a notification in the terminalError method should make the notification appear in the browser."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8778); + } + +} diff --git a/tests/testbench/com/vaadin/tests/application/WebBrowserSizeTest.java b/tests/testbench/com/vaadin/tests/application/WebBrowserSizeTest.java index eacf2a0e53..a3f11f2cd3 100644 --- a/tests/testbench/com/vaadin/tests/application/WebBrowserSizeTest.java +++ b/tests/testbench/com/vaadin/tests/application/WebBrowserSizeTest.java @@ -21,8 +21,10 @@ public class WebBrowserSizeTest extends TestBase { public void buttonClick(ClickEvent event) { screenSizeLabel.setValue(getBrowser().getScreenWidth() + " x " + getBrowser().getScreenHeight()); - browserSizeLabel.setValue(getBrowser().getClientWidth() + " x " - + getBrowser().getClientHeight()); + browserSizeLabel.setValue(getMainWindow() + .getBrowserWindowWidth() + + " x " + + getMainWindow().getBrowserWindowHeight()); } }); diff --git a/tests/testbench/com/vaadin/tests/applicationservlet/NoApplicationClass.html b/tests/testbench/com/vaadin/tests/applicationservlet/NoApplicationClass.html new file mode 100644 index 0000000000..70bb8cc8f3 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/applicationservlet/NoApplicationClass.html @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/ClassThatIsNotPresent?restartApplication</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>//pre[1]</td> + <td>java.lang.InstantiationException: Failed to load application class: ClassThatIsNotPresent</td> +</tr> +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java b/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java index fd90cf2d6e..72cbcd386e 100644 --- a/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java +++ b/tests/testbench/com/vaadin/tests/components/AbstractTestRoot.java @@ -15,7 +15,7 @@ public abstract class AbstractTestRoot extends Root { @Override public void init(WrappedRequest request) { - setCaption(getClass().getName()); + getPage().setTitle(getClass().getName()); Label label = new Label(getTestDescription(), ContentMode.XHTML); label.setWidth("100%"); diff --git a/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.html b/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.html new file mode 100644 index 0000000000..ac3a4f0cb0 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.html @@ -0,0 +1,250 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>DisableEnableCascadeStyles</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">DisableEnableCascadeStyles</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.DisableEnableCascadeStyles?restartApplication</td> + <td></td> +</tr> +<!--disable tabsheet--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<!--enable tabsheet--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<!--disable layout containing components--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<!--enable layout containing components--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[2]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<!--disable all bottom level components--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[3]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<!--enable all bottom level components--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VButton[3]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--assert css class names for bottom level components--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VNativeButton[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextField[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/VTextArea[0]</td> + <td>v-disabled</td> +</tr> +<!--assert css class name for component captions--> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[2]/domChild[0]</td> + <td>v-disabled</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestscomponentsDisableEnableCascadeStyles::/VVerticalLayout[0]/VVerticalLayout[0]/VPanel[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[3]/domChild[0]</td> + <td>v-disabled</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.java b/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.java new file mode 100644 index 0000000000..f3391afd1f --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/DisableEnableCascadeStyles.java @@ -0,0 +1,142 @@ +package com.vaadin.tests.components; + +import java.util.Iterator; + +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Component; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +public class DisableEnableCascadeStyles extends TestBase { + + private Panel outerPanel; + private TabSheet innerTabsheet; + private Button button; + private TextArea textArea; + private TextField textField; + private VerticalLayout layout; + private NativeButton nativeButton; + private Button enableDisablePanelButton; + private Button enableDisableTabSheetButton; + private Button enableDisableLayoutButton; + private Button enableDisableComponentsButton; + + @Override + protected void setup() { + + outerPanel = new Panel("Outer panel, enabled"); + innerTabsheet = new TabSheet(); + innerTabsheet.setCaption("Inner Tabsheet, enabled"); + + button = new Button("Button, enabled"); + nativeButton = new NativeButton("NativeButton, enabled"); + textField = new TextField("TextField with caption and value, enabled"); + textField.setValue("Text"); + textArea = new TextArea("TextArea with caption and value, enabled"); + textArea.setValue("Text"); + layout = new VerticalLayout(); + layout.setCaption("VerticalLayout, enabled"); + layout.addComponent(button); + layout.addComponent(nativeButton); + layout.addComponent(textField); + layout.addComponent(textArea); + + outerPanel.setContent(innerTabsheet); + innerTabsheet.addTab(layout, "Tab containing layout"); + + addComponent(outerPanel); + + enableDisablePanelButton = new Button("Disable panel", + new ClickListener() { + + public void buttonClick(ClickEvent event) { + enableDisable(outerPanel, enableDisablePanelButton); + + } + }); + + enableDisableTabSheetButton = new Button("Disable TabSheet", + new ClickListener() { + + public void buttonClick(ClickEvent event) { + enableDisable(innerTabsheet, + enableDisableTabSheetButton); + + } + }); + + enableDisableLayoutButton = new Button("Disable Tab content (Layout)", + new ClickListener() { + + public void buttonClick(ClickEvent event) { + enableDisable(layout, enableDisableLayoutButton); + + } + }); + enableDisableComponentsButton = new Button("Disable Layout Components", + new ClickListener() { + + public void buttonClick(ClickEvent event) { + for (Iterator<Component> i = layout + .getComponentIterator(); i.hasNext();) { + final Component c = i.next(); + if (c.isEnabled()) { + c.setEnabled(false); + c.setCaption(c.getCaption().replace("enabled", + "disabled")); + } else { + c.setEnabled(true); + c.setCaption(c.getCaption().replace("disabled", + "enabled")); + } + } + if (layout.getComponent(0).isEnabled()) { + enableDisableComponentsButton + .setCaption(enableDisableComponentsButton + .getCaption().replace("Enable", + "Disable")); + } else { + enableDisableComponentsButton + .setCaption(enableDisableComponentsButton + .getCaption().replace("Disable", + "Enable")); + } + } + }); + addComponent(enableDisablePanelButton); + addComponent(enableDisableTabSheetButton); + addComponent(enableDisableLayoutButton); + addComponent(enableDisableComponentsButton); + } + + protected void enableDisable(Component target, Button button) { + if (target.isEnabled()) { + target.setEnabled(false); + button.setCaption(button.getCaption().replace("Disable", "Enable")); + target.setCaption(target.getCaption() + .replace("enabled", "disabled")); + } else { + target.setEnabled(true); + button.setCaption(button.getCaption().replace("Enable", "Disable")); + target.setCaption(target.getCaption() + .replace("disabled", "enabled")); + } + } + + @Override + protected String getDescription() { + return "Tests the disable state is cascaded correctly to children components that can be disabled. The children and their captions must get the v-disabled style name."; + } + + @Override + protected Integer getTicketNumber() { + return 8708; + } + +}
\ No newline at end of file diff --git a/tests/testbench/com/vaadin/tests/components/TestBase.java b/tests/testbench/com/vaadin/tests/components/TestBase.java index 6524a30fb7..b3c0f63dcb 100644 --- a/tests/testbench/com/vaadin/tests/components/TestBase.java +++ b/tests/testbench/com/vaadin/tests/components/TestBase.java @@ -26,6 +26,16 @@ public abstract class TestBase extends AbstractTestCase { } private LegacyWindow window; + + @Override + public void setMainWindow(LegacyWindow mainWindow) { + if (mainWindow != window) { + throw new IllegalStateException( + "You should not set your own main window when using TestBase. If you need to use a custom Window as the main window, use AbstractTestCase instead."); + } + super.setMainWindow(mainWindow); + } + private VerticalLayout layout; public TestBase() { diff --git a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java index 053691e738..8ad12da85f 100644 --- a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java +++ b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java @@ -24,6 +24,7 @@ import com.vaadin.ui.CssLayout; import com.vaadin.ui.HorizontalSplitPanel; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.TabSheet; import com.vaadin.ui.Table; @@ -189,7 +190,7 @@ public class TouchScrollables extends TestBase { } public void handleAction(Action action, Object sender, Object target) { - getLayout().getRoot().showNotification(action.getCaption()); + Notification.show(action.getCaption()); } }); diff --git a/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html new file mode 100644 index 0000000000..5ec33f09fa --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.button.ButtonEnterWithWindowShortcut?restartApplication</td> + <td></td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]</td> + <td>enter</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td> + <td>1. button click listener fired</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::</td> + <td>enter</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td> + <td>2. enter pressed in window</td> +</tr> +<!-- Can't test using space because of #8827 --> +<!-- <tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td> + <td>3. button click listener fired</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td> + <td>4. space pressed in window</td> +</tr> --> +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java new file mode 100644 index 0000000000..7efd40ca5d --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java @@ -0,0 +1,55 @@ +package com.vaadin.tests.components.button; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.event.ShortcutAction; +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.Log; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; + +public class ButtonEnterWithWindowShortcut extends TestBase { + Log log = new Log(5); + + @Override + protected void setup() { + getMainWindow().addActionHandler(new Handler() { + private static final long serialVersionUID = -4976129418325394913L; + + public void handleAction(Action action, Object sender, Object target) { + log.log(action.getCaption() + " pressed in window"); + } + + public Action[] getActions(Object target, Object sender) { + ShortcutAction enter = new ShortcutAction("enter", + ShortcutAction.KeyCode.ENTER, null); + ShortcutAction space = new ShortcutAction("space", + ShortcutAction.KeyCode.SPACEBAR, null); + return new Action[] { enter, space }; + } + }); + + Button button = new Button("Focus me and press enter", + new ClickListener() { + public void buttonClick(ClickEvent event) { + log.log("button click listener fired"); + } + }); + button.focus(); + + addComponent(log); + addComponent(button); + } + + @Override + protected String getDescription() { + return "Pressing enter or space with the button focused should trigger the button click listener and not the shortcut action on the window."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(5433); + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/combobox/ComboBoxInvalidNullSelection.html b/tests/testbench/com/vaadin/tests/components/combobox/ComboBoxInvalidNullSelection.html index bbe5d5d717..1459a30985 100644 --- a/tests/testbench/com/vaadin/tests/components/combobox/ComboBoxInvalidNullSelection.html +++ b/tests/testbench/com/vaadin/tests/components/combobox/ComboBoxInvalidNullSelection.html @@ -33,6 +33,11 @@ </tr> <tr> <td>click</td> + <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxInvalidNullSelection::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxInvalidNullSelection::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> diff --git a/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java b/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java index 55e61e3980..02c080e8fd 100644 --- a/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java +++ b/tests/testbench/com/vaadin/tests/components/customfield/AddressFormExample.java @@ -4,6 +4,7 @@ import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.Address; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; /** * Demonstrate a custom field which is a form, and contains another custom field @@ -23,10 +24,9 @@ public class AddressFormExample extends TestBase { public void buttonClick(ClickEvent event) { field.commit(); Address address = field.getValue(); - field.getRoot().showNotification( - "Address saved: " + address.getStreetAddress() + ", " - + address.getPostalCode() + ", " - + address.getCity()); + Notification.show("Address saved: " + + address.getStreetAddress() + ", " + + address.getPostalCode() + ", " + address.getCity()); } }); addComponent(commitButton); diff --git a/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java b/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java index 2f9720a1c1..694c5b54f9 100644 --- a/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java +++ b/tests/testbench/com/vaadin/tests/components/customfield/BooleanFieldExample.java @@ -10,6 +10,7 @@ import com.vaadin.ui.Component; import com.vaadin.ui.DefaultFieldFactory; import com.vaadin.ui.Field; import com.vaadin.ui.Form; +import com.vaadin.ui.Notification; import com.vaadin.ui.VerticalLayout; public class BooleanFieldExample extends TestBase { @@ -62,13 +63,10 @@ public class BooleanFieldExample extends TestBase { Button submit = new Button("Submit", new ClickListener() { public void buttonClick(ClickEvent event) { form.commit(); - layout.getRoot() - .showNotification( - "The custom boolean field value is " - + data.isCustom() - + ".<br>" - + "The checkbox (default boolean field) value is " - + data.isNormal() + "."); + Notification.show("The custom boolean field value is " + + data.isCustom() + ".<br>" + + "The checkbox (default boolean field) value is " + + data.isNormal() + "."); } }); layout.addComponent(submit); diff --git a/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html new file mode 100644 index 0000000000..3e7a7cb0a7 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>DragStartModes</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">DragStartModes</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.draganddropwrapper.DragStartModes?restartApplication</td> + <td></td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::PID_SlabelCOMPONENT</td> + <td>50,10</td> +</tr> +<tr> + <td>mouseMoveAt</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> + <td>50,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>drag-mode-component</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> + <td>50,10</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::PID_SlabelWRAPPER</td> + <td>50,10</td> +</tr> +<tr> + <td>mouseMoveAt</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> + <td>50,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>drag-mode-wrapper</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> + <td>50,10</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java new file mode 100644 index 0000000000..d23c502a45 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java @@ -0,0 +1,46 @@ +package com.vaadin.tests.components.draganddropwrapper; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.TestUtils; +import com.vaadin.ui.Component; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.Label; + +public class DragStartModes extends TestBase { + + @Override + protected void setup() { + + TestUtils.injectCSS(getMainWindow(), + ".v-ddwrapper { background: #ACF; }"); + + addComponent(makeWrapper(DragStartMode.NONE)); + addComponent(makeWrapper(DragStartMode.COMPONENT)); + addComponent(makeWrapper(DragStartMode.WRAPPER)); + addComponent(makeWrapper(DragStartMode.HTML5)); + + addComponent(new Label("Drop here")); + } + + private Component makeWrapper(DragStartMode mode) { + Label label = new Label("Drag start mode: " + mode); + label.setDebugId("label" + mode); + DragAndDropWrapper wrapper = new DragAndDropWrapper(label); + wrapper.setHTML5DataFlavor("Text", "HTML5!"); + wrapper.setDragStartMode(mode); + wrapper.setWidth("200px"); + return wrapper; + } + + @Override + protected String getDescription() { + return "Different drag start modes should show correct drag images"; + } + + @Override + protected Integer getTicketNumber() { + return 8949; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.html b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.html new file mode 100644 index 0000000000..08dc608787 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.html @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>TooltipHandlingWhenNotDefined</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TooltipHandlingWhenNotDefined</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.draganddropwrapper.TooltipHandlingWhenNotDefined?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseOver</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperTooltipHandlingWhenNotDefined::PID_StooltipLabel</td> + <td></td> +</tr> +<tr> + <td>pause</td> + <td></td> + <td>3000</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>tooltip-shown</td> +</tr> +</tbody> +</table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.java b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.java new file mode 100644 index 0000000000..0735b3e622 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/TooltipHandlingWhenNotDefined.java @@ -0,0 +1,41 @@ +package com.vaadin.tests.components.draganddropwrapper; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.Label; + +public class TooltipHandlingWhenNotDefined extends TestBase { + + @Override + protected void setup() { + + CssLayout wrapperLayout = new CssLayout(); + wrapperLayout.setWidth("100%"); + + Label label = new Label("Can I has the tooltip?", Label.CONTENT_XHTML); + label.setDebugId("tooltipLabel"); + label.setDescription("Good! Tooltip works!"); + label.setSizeUndefined(); + wrapperLayout.addComponent(label); + + DragAndDropWrapper wrapper = new DragAndDropWrapper(wrapperLayout); + wrapper.setWidth("100%"); + wrapper.setDragStartMode(DragStartMode.WRAPPER); + + addComponent(wrapper); + + } + + @Override + protected String getDescription() { + return "Wrapper most not prevent child from showing tooltip"; + } + + @Override + protected Integer getTicketNumber() { + return 7766; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/gridlayout/GridLayoutInForm.java b/tests/testbench/com/vaadin/tests/components/gridlayout/GridLayoutInForm.java new file mode 100644 index 0000000000..648bbd2d52 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/gridlayout/GridLayoutInForm.java @@ -0,0 +1,78 @@ +package com.vaadin.tests.components.gridlayout; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.util.PropertysetItem; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Form; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Panel; + +public class GridLayoutInForm extends TestBase { + + @Override + protected void setup() { + final List<String> propertyIds = new ArrayList<String>(); + for (int i = 0; i < 50; i++) { + propertyIds.add("property " + i); + } + + GridLayout gridLayout = new GridLayout(); + gridLayout.setSizeUndefined(); + gridLayout.setColumns(2); + gridLayout.setSpacing(true); + + PropertysetItem item = new PropertysetItem(); + for (String propertyId : propertyIds) { + item.addItemProperty(propertyId, new ObjectProperty<String>( + propertyId)); + } + + final Form form = new Form(gridLayout); + form.setItemDataSource(item); + + form.setSizeUndefined(); + + Panel panel = new Panel(); + panel.addComponent(form); + panel.setHeight("500px"); + + addComponent(panel); + + addComponent(new Button("Use 15 first fields", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + form.setVisibleItemProperties(propertyIds + .subList(0, 15)); + } + })); + addComponent(new Button("Use 15 last fields", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + form.setVisibleItemProperties(propertyIds.subList(35, + 50)); + } + })); + + addComponent(new Button("Use all fields", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + form.setVisibleItemProperties(propertyIds); + } + })); + } + + @Override + protected String getDescription() { + return "Changing the number of visible fields in a Form using a GridLayout with spacing should not cause additional empty space in the end of the GridLayout"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8855); + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java index 2240fc246b..5f2f945c8b 100644 --- a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java @@ -7,21 +7,24 @@ import java.util.Arrays; import java.util.List; import com.vaadin.annotations.LoadScripts; +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.ComponentState; import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.AbstractJavascriptComponent; -import com.vaadin.ui.Root; +import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.JavaScriptCallback; +import com.vaadin.ui.Notification; @LoadScripts({ "/statictestfiles/jsconnector.js" }) -public class BasicJavascriptComponent extends AbstractTestRoot { +public class BasicJavaScriptComponent extends AbstractTestRoot { public interface ExampleClickRpc extends ServerRpc { public void onClick(String message); } - public static class SpecialState extends ComponentState { + public static class SpecialState extends JavaScriptComponentState { private List<String> data; public List<String> getData() { @@ -33,12 +36,17 @@ public class BasicJavascriptComponent extends AbstractTestRoot { } } - public static class ExampleWidget extends AbstractJavascriptComponent { + public static class ExampleWidget extends AbstractJavaScriptComponent { public ExampleWidget() { registerRpc(new ExampleClickRpc() { public void onClick(String message) { - Root.getCurrentRoot().showNotification( - "Got a click: " + message); + Notification.show("Got a click: " + message); + } + }); + registerCallback("onclick", new JavaScriptCallback() { + public void call(JSONArray arguments) throws JSONException { + Notification.show("Got a callback: " + + arguments.getString(0)); } }); getState().setData(Arrays.asList("a", "b", "c")); diff --git a/tests/testbench/com/vaadin/tests/components/notification/Notifications.java b/tests/testbench/com/vaadin/tests/components/notification/Notifications.java index 27aef918d1..a36fbe3121 100644 --- a/tests/testbench/com/vaadin/tests/components/notification/Notifications.java +++ b/tests/testbench/com/vaadin/tests/components/notification/Notifications.java @@ -6,7 +6,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.TextArea; public class Notifications extends TestBase implements ClickListener { @@ -53,7 +52,6 @@ public class Notifications extends TestBase implements ClickListener { public void buttonClick(ClickEvent event) { Notification n = new Notification(tf.getValue(), (Integer) type.getValue()); - Root.getCurrentRoot().showNotification(n); - + n.show(); } } diff --git a/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.html b/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.html new file mode 100644 index 0000000000..35d22da46e --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.html @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>NotificationsAndModalWindow</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">NotificationsAndModalWindow</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.notification.NotificationsAndModalWindow?restartApplication</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsAndModalWindow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsAndModalWindow::Root/VNotification[1]</td> + <td>0,0</td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsAndModalWindow::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsAndModalWindow::Root/VNotification[0]</td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.java b/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.java new file mode 100644 index 0000000000..547ef3077b --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/notification/NotificationsAndModalWindow.java @@ -0,0 +1,39 @@ +package com.vaadin.tests.components.notification; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Window; + +public class NotificationsAndModalWindow extends TestBase { + + @Override + protected void setup() { + getMainWindow().showNotification("Notification 1", + Notification.TYPE_WARNING_MESSAGE); + getMainWindow().showNotification("Notification 2", + Notification.TYPE_WARNING_MESSAGE); + + Button b = new Button("Button"); + b.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Window w = new Window("This is a window"); + w.setModal(true); + getMainWindow().addWindow(w); + } + }); + addComponent(b); + } + + @Override + protected String getDescription() { + return "Press the button when both two notifications are visible to add a modal window to the app. When the modal window is visible, the notifications should disappear normally."; + } + + @Override + protected Integer getTicketNumber() { + return 7136; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java b/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java index 152688d109..a16b8edcde 100644 --- a/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java +++ b/tests/testbench/com/vaadin/tests/components/notification/NotificationsHtmlAllowed.java @@ -6,7 +6,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -46,15 +45,13 @@ public class NotificationsHtmlAllowed extends TestBase implements ClickListener public void buttonClick(ClickEvent event) { Notification n = makeNotification(); - Root.getCurrentRoot().showNotification(n); - + n.show(); } private Notification makeNotification() { - Notification n = new Notification((String) captionField.getValue(), - (String) messageField.getValue(), - Notification.TYPE_HUMANIZED_MESSAGE, - (Boolean) htmlAllowedBox.getValue()); + Notification n = new Notification(captionField.getValue(), + messageField.getValue(), Notification.TYPE_HUMANIZED_MESSAGE, + htmlAllowedBox.getValue()); return n; } } diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html index ea0a039dbe..f0fd1568b1 100644 --- a/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html +++ b/tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutClickListenerTest.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> +<link rel="selenium.base" href="http://localhost:8070" /> <title>LayoutClickListenerTest</title> </head> <body> @@ -19,67 +19,67 @@ <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VTextField[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[1]/VLink[0]/domChild[0]/domChild[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[2]/VFilterSelect[0]/domChild[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VTextField[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VLink[0]/domChild[0]/domChild[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/domChild[1]</td> - <td></td> + <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[3]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]</td> + <td>396,87</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[1]/VTextField[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[2]/VLink[0]/domChild[0]/domChild[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VVerticalLayout[0]/ChildComponentContainer[3]/VHorizontalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td></td> + <td>5,5</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VGridLayout[0]/domChild[0]</td> - <td></td> + <td>vaadin=runcomvaadintestscomponentsorderedlayoutLayoutClickListenerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VGridLayout[0]</td> + <td>1135,146</td> </tr> <tr> <td>screenCapture</td> diff --git a/tests/testbench/com/vaadin/tests/components/panel/PanelClickListenerRelativeCoordinates.html b/tests/testbench/com/vaadin/tests/components/panel/PanelClickListenerRelativeCoordinates.html index eb40765d03..4b71c5a9a9 100644 --- a/tests/testbench/com/vaadin/tests/components/panel/PanelClickListenerRelativeCoordinates.html +++ b/tests/testbench/com/vaadin/tests/components/panel/PanelClickListenerRelativeCoordinates.html @@ -28,10 +28,10 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentspanelPanelClickListenerRelativeCoordinates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]</td> - <td>287,25</td> + <td>vaadin=runcomvaadintestscomponentspanelPanelClickListenerRelativeCoordinates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPanel[0]/VVerticalLayout[0]</td> + <td>287,6</td> </tr> -<!-- Should really be 287, 25 but due to v-view border-top it is not always... <tr> +<!-- Should really be 287, 25 but due to v-view border-top it is not always... Additional differences caused by targeting the click on the child element to make it behave like a real click (#4120)<tr> <td>assertText</td> <td>vaadin=runcomvaadintestscomponentspanelPanelClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[0]</td> <td>287, 25</td> diff --git a/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java b/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java index 95691ef9d7..98f31cd68c 100644 --- a/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java +++ b/tests/testbench/com/vaadin/tests/components/richtextarea/RichTextAreaWithKeyboardShortcuts.java @@ -6,6 +6,7 @@ import com.vaadin.event.ShortcutAction; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.RichTextArea; import com.vaadin.ui.Window; @@ -30,7 +31,7 @@ public class RichTextAreaWithKeyboardShortcuts extends TestBase { String string = f.getValue().toString(); msg += " Value: " + string; - f.getRoot().showNotification(msg); + Notification.show(msg); } diff --git a/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java b/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java index 6078161996..251672fb9a 100644 --- a/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java +++ b/tests/testbench/com/vaadin/tests/components/root/UriFragmentTest.java @@ -1,5 +1,7 @@ package com.vaadin.tests.components.root; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; @@ -14,7 +16,7 @@ public class UriFragmentTest extends AbstractTestRoot { protected void setup(WrappedRequest request) { addComponent(fragmentLabel); updateLabel(); - addListener(new FragmentChangedListener() { + getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent event) { updateLabel(); } @@ -22,13 +24,13 @@ public class UriFragmentTest extends AbstractTestRoot { addComponent(new Button("Navigate to #test", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - setFragment("test"); + getPage().setFragment("test"); } })); } private void updateLabel() { - String fragment = getFragment(); + String fragment = getPage().getFragment(); if (fragment == null) { fragmentLabel.setValue("No URI fragment set"); } else { diff --git a/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.html b/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.html new file mode 100644 index 0000000000..48adf2edfe --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.html @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>StylingPopupOpener</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">StylingPopupOpener</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.select.StylingPopupOpener?restartApplication</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsselectStylingPopupOpener::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.java b/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.java new file mode 100644 index 0000000000..b3911f19c7 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/select/StylingPopupOpener.java @@ -0,0 +1,38 @@ +package com.vaadin.tests.components.select; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.TestUtils; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Select; + +public class StylingPopupOpener extends TestBase { + + @Override + protected void setup() { + TestUtils + .injectCSS( + getMainWindow(), + ".v-filterselect-mystyle .v-filterselect-button { width: 50px; background-color: red; } "); + + final Select select = new Select(); + addComponent(select); + + addComponent(new Button("Update style", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + select.setStyleName("mystyle"); + } + })); + } + + @Override + protected String getDescription() { + return "VFilterSelect popup opener width is not updated when the style or theme changes"; + } + + @Override + protected Integer getTicketNumber() { + return 8801; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/slider/SliderOrientation.html b/tests/testbench/com/vaadin/tests/components/slider/SliderOrientation.html new file mode 100644 index 0000000000..174ddca016 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/slider/SliderOrientation.html @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>SliderOrientation</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">SliderOrientation</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.slider.SliderTest?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::PID_Smenu#item0</td> + <td>5,6</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[0]/VMenuBar[0]#item4</td> + <td>41,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[1]/VMenuBar[0]#item3</td> + <td>37,3</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[2]/VMenuBar[0]#item1</td> + <td>19,7</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>change-orientation-to-vertical</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::PID_Smenu#item0</td> + <td>33,1</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[0]/VMenuBar[0]#item4</td> + <td>63,11</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[1]/VMenuBar[0]#item3</td> + <td>30,1</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[2]/VMenuBar[0]#item0</td> + <td>10,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>change-orientation-to-horizontal</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/slider/SliderTooltip.html b/tests/testbench/com/vaadin/tests/components/slider/SliderTooltip.html new file mode 100644 index 0000000000..4e8296050f --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/slider/SliderTooltip.html @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://arturwin.office.itmill.com:9999/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.slider.SliderTest?debug&restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::PID_Smenu#item0</td> + <td>24,2</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[0]/VMenuBar[0]#item1</td> + <td>35,12</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[1]/VMenuBar[0]#item1</td> + <td>74,3</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VOverlay[2]/VMenuBar[0]#item2</td> + <td>30,6</td> +</tr> +<tr> + <td>showTooltip</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::PID_StestComponent/domChild[2]/domChild[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>waitForElementPresent</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>This is a semi-long text that might wrap.</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>40,16</td> +</tr> +<tr> + <td>waitForElementNotPresent</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelSplitterClick.html b/tests/testbench/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelSplitterClick.html index e8be62015f..d91b3d8c4a 100644 --- a/tests/testbench/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelSplitterClick.html +++ b/tests/testbench/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelSplitterClick.html @@ -78,18 +78,19 @@ <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentssplitpanelHorizontalSplitPanels::PID_StestComponent/domChild[0]/domChild[2]/domChild[0]</td> - <td>10,15</td> + <td>5,5</td> </tr> <tr> <td>assertText</td> <td>vaadin=runcomvaadintestscomponentssplitpanelHorizontalSplitPanels::PID_SLog_row_0</td> - <td>3. SplitterClickEvent: left at 10,15</td> + <td>3. SplitterClickEvent: left at 5,5</td> </tr> <tr> <td>screenCapture</td> <td></td> <td>reverseSplitterClicked</td> </tr> + </tbody></table> </body> </html> diff --git a/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.html b/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.html new file mode 100644 index 0000000000..70d619edac --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.html @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>SplitPanelWithMinimumAndMaximum</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">SplitPanelWithMinimumAndMaximum</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.splitpanel.SplitPanelWithMinimumAndMaximum?restartApplication</td> + <td></td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-239,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-340,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-300,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[3]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-79,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[4]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-179,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[5]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-78,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[6]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-150,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[7]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-371,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>horizontal-splits-left</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>418,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>418,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>450,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[3]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>450,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[4]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>418,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[5]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>418,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[6]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>450,0</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[7]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>450,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>horizontal-splits-right</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> + <td>44,2</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-206</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-348</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[2]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-300</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[3]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-55</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[4]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-155</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[5]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-13</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[7]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-300</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[6]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,-300</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>vertical-splits-up</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,361</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,361</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[2]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,350</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[3]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,350</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[4]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,361</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[5]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,361</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[6]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,300</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VHorizontalLayout[0]/ChildComponentContainer[7]/VSplitPanelVertical[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>0,300</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>vertical-splits-down</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td> + <td>25,5</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-239,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>togglable-to-min-with-limit-enabled</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>-60,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>togglable-to-min-with-limit-disabled</td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>478,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>togglable-to-max-with-limit-enabled</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>dragAndDrop</td> + <td>vaadin=runcomvaadintestscomponentssplitpanelSplitPanelWithMinimumAndMaximum::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VSplitPanelHorizontal[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>113,0</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>togglable-to-max-with-limit-disabled</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.java b/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.java new file mode 100644 index 0000000000..f7c3dd84e4 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/splitpanel/SplitPanelWithMinimumAndMaximum.java @@ -0,0 +1,332 @@ +package com.vaadin.tests.components.splitpanel; + +import com.vaadin.terminal.Sizeable; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.VerticalSplitPanel; + +public class SplitPanelWithMinimumAndMaximum extends TestBase { + + @Override + protected void setup() { + TabSheet tabs = new TabSheet(); + + VerticalLayout horizontalSplitsLayout = new VerticalLayout(); + horizontalSplitsLayout.setCaption("Horizontal splits"); + + HorizontalSplitPanel percentagePositionWithPercentageLimitsHorizontal = new HorizontalSplitPanel(); + percentagePositionWithPercentageLimitsHorizontal.setMinSplitPosition( + 10, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsHorizontal.setMaxSplitPosition( + 80, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsHorizontal + .setFirstComponent(new Label("Min 10 % - 50 % position")); + percentagePositionWithPercentageLimitsHorizontal + .setSecondComponent(new Label("Max 80 %")); + percentagePositionWithPercentageLimitsHorizontal.setSplitPosition(50, + Sizeable.UNITS_PERCENTAGE); + horizontalSplitsLayout + .addComponent(percentagePositionWithPercentageLimitsHorizontal); + + HorizontalSplitPanel pixelPositionWithPercentageLimitsHorizontal = new HorizontalSplitPanel(); + pixelPositionWithPercentageLimitsHorizontal.setMinSplitPosition(10, + Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsHorizontal.setMaxSplitPosition(80, + Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsHorizontal + .setFirstComponent(new Label("Min 10 % - 400 px position")); + pixelPositionWithPercentageLimitsHorizontal + .setSecondComponent(new Label("Max 80 %")); + pixelPositionWithPercentageLimitsHorizontal.setSplitPosition(400, + Sizeable.UNITS_PIXELS); + horizontalSplitsLayout + .addComponent(pixelPositionWithPercentageLimitsHorizontal); + + HorizontalSplitPanel pixelPositionWithPixelLimitsHorizontal = new HorizontalSplitPanel(); + pixelPositionWithPixelLimitsHorizontal.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsHorizontal.setMaxSplitPosition(550, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsHorizontal.setFirstComponent(new Label( + "Min 100 px - 400 px position")); + pixelPositionWithPixelLimitsHorizontal.setSecondComponent(new Label( + "Max 550 px")); + pixelPositionWithPixelLimitsHorizontal.setSplitPosition(400, + Sizeable.UNITS_PIXELS); + horizontalSplitsLayout + .addComponent(pixelPositionWithPixelLimitsHorizontal); + + HorizontalSplitPanel percentagePositionWithPixelLimitsHorizontal = new HorizontalSplitPanel(); + percentagePositionWithPixelLimitsHorizontal.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsHorizontal.setMaxSplitPosition(550, + Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsHorizontal + .setFirstComponent(new Label("Min 100 px - 30 % position")); + percentagePositionWithPixelLimitsHorizontal + .setSecondComponent(new Label("Max 550 px")); + percentagePositionWithPixelLimitsHorizontal.setSplitPosition(30, + Sizeable.UNITS_PERCENTAGE); + horizontalSplitsLayout + .addComponent(percentagePositionWithPixelLimitsHorizontal); + + HorizontalSplitPanel percentagePositionWithPercentageLimitsHorizontalResersed = new HorizontalSplitPanel(); + percentagePositionWithPercentageLimitsHorizontalResersed + .setMinSplitPosition(10, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsHorizontalResersed + .setMaxSplitPosition(80, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsHorizontalResersed + .setFirstComponent(new Label( + "Max 80 % - Reversed 50 % position")); + percentagePositionWithPercentageLimitsHorizontalResersed + .setSecondComponent(new Label("Min 10 %")); + percentagePositionWithPercentageLimitsHorizontalResersed + .setSplitPosition(50, Sizeable.UNITS_PERCENTAGE, true); + horizontalSplitsLayout + .addComponent(percentagePositionWithPercentageLimitsHorizontalResersed); + + HorizontalSplitPanel pixelPositionWithPercentageLimitsHorizontalResersed = new HorizontalSplitPanel(); + pixelPositionWithPercentageLimitsHorizontalResersed + .setMinSplitPosition(10, Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsHorizontalResersed + .setMaxSplitPosition(80, Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsHorizontalResersed + .setFirstComponent(new Label( + "Max 80 % - Reversed 400 px position")); + pixelPositionWithPercentageLimitsHorizontalResersed + .setSecondComponent(new Label("Min 10 %")); + pixelPositionWithPercentageLimitsHorizontalResersed.setSplitPosition( + 400, Sizeable.UNITS_PIXELS, true); + horizontalSplitsLayout + .addComponent(pixelPositionWithPercentageLimitsHorizontalResersed); + + HorizontalSplitPanel pixelPositionWithPixelLimitsHorizontalResersed = new HorizontalSplitPanel(); + pixelPositionWithPixelLimitsHorizontalResersed.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsHorizontalResersed.setMaxSplitPosition(550, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsHorizontalResersed + .setFirstComponent(new Label( + "Max 550 px - Reversed 400 px position")); + pixelPositionWithPixelLimitsHorizontalResersed + .setSecondComponent(new Label("Min 100 px")); + pixelPositionWithPixelLimitsHorizontalResersed.setSplitPosition(400, + Sizeable.UNITS_PIXELS, true); + horizontalSplitsLayout + .addComponent(pixelPositionWithPixelLimitsHorizontalResersed); + + HorizontalSplitPanel percentagePositionWithPixelLimitsHorizontalResersed = new HorizontalSplitPanel(); + percentagePositionWithPixelLimitsHorizontalResersed + .setMinSplitPosition(100, Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsHorizontalResersed + .setMaxSplitPosition(550, Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsHorizontalResersed + .setFirstComponent(new Label( + "Max 550 px - Reversed 30 % position")); + percentagePositionWithPixelLimitsHorizontalResersed + .setSecondComponent(new Label("Min 100 px")); + percentagePositionWithPixelLimitsHorizontalResersed.setSplitPosition( + 30, Sizeable.UNITS_PERCENTAGE, true); + horizontalSplitsLayout + .addComponent(percentagePositionWithPixelLimitsHorizontalResersed); + + horizontalSplitsLayout.setSizeFull(); + tabs.addComponent(horizontalSplitsLayout); + + HorizontalLayout verticalSplitsLayout = new HorizontalLayout(); + verticalSplitsLayout.setCaption("Vertical splits"); + + VerticalSplitPanel percentagePositionWithPercentageLimitsVertical = new VerticalSplitPanel(); + percentagePositionWithPercentageLimitsVertical.setMinSplitPosition(10, + Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsVertical.setMaxSplitPosition(80, + Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsVertical + .setFirstComponent(new Label("Min 10 % - 50 % position")); + percentagePositionWithPercentageLimitsVertical + .setSecondComponent(new Label("Max 80 %")); + percentagePositionWithPercentageLimitsVertical.setSplitPosition(50, + Sizeable.UNITS_PERCENTAGE); + verticalSplitsLayout + .addComponent(percentagePositionWithPercentageLimitsVertical); + + VerticalSplitPanel pixelPositionWithPercentageLimitsVertical = new VerticalSplitPanel(); + pixelPositionWithPercentageLimitsVertical.setMinSplitPosition(10, + Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsVertical.setMaxSplitPosition(80, + Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsVertical.setFirstComponent(new Label( + "Min 10 % - 400 px position")); + pixelPositionWithPercentageLimitsVertical.setSecondComponent(new Label( + "Max 80 %")); + pixelPositionWithPercentageLimitsVertical.setSplitPosition(400, + Sizeable.UNITS_PIXELS); + verticalSplitsLayout + .addComponent(pixelPositionWithPercentageLimitsVertical); + + VerticalSplitPanel pixelPositionWithPixelLimitsVertical = new VerticalSplitPanel(); + pixelPositionWithPixelLimitsVertical.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsVertical.setMaxSplitPosition(450, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsVertical.setFirstComponent(new Label( + "Min 100 px - 400 px position")); + pixelPositionWithPixelLimitsVertical.setSecondComponent(new Label( + "Max 450 px")); + pixelPositionWithPixelLimitsVertical.setSplitPosition(400, + Sizeable.UNITS_PIXELS); + verticalSplitsLayout.addComponent(pixelPositionWithPixelLimitsVertical); + + VerticalSplitPanel percentagePositionWithPixelLimitsVertical = new VerticalSplitPanel(); + percentagePositionWithPixelLimitsVertical.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsVertical.setMaxSplitPosition(450, + Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsVertical.setFirstComponent(new Label( + "Min 100 px - 30 % position")); + percentagePositionWithPixelLimitsVertical.setSecondComponent(new Label( + "Max 450 px")); + percentagePositionWithPixelLimitsVertical.setSplitPosition(30, + Sizeable.UNITS_PERCENTAGE); + verticalSplitsLayout + .addComponent(percentagePositionWithPixelLimitsVertical); + + VerticalSplitPanel percentagePositionWithPercentageLimitsVerticalReversed = new VerticalSplitPanel(); + percentagePositionWithPercentageLimitsVerticalReversed + .setMinSplitPosition(10, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsVerticalReversed + .setMaxSplitPosition(80, Sizeable.UNITS_PERCENTAGE); + percentagePositionWithPercentageLimitsVerticalReversed + .setFirstComponent(new Label( + "Max 80 % - Reversed 50 % position")); + percentagePositionWithPercentageLimitsVerticalReversed + .setSecondComponent(new Label("Min 10 %")); + percentagePositionWithPercentageLimitsVerticalReversed + .setSplitPosition(50, Sizeable.UNITS_PERCENTAGE, true); + verticalSplitsLayout + .addComponent(percentagePositionWithPercentageLimitsVerticalReversed); + + VerticalSplitPanel pixelPositionWithPercentageLimitsVerticalReversed = new VerticalSplitPanel(); + pixelPositionWithPercentageLimitsVerticalReversed.setMinSplitPosition( + 10, Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsVerticalReversed.setMaxSplitPosition( + 80, Sizeable.UNITS_PERCENTAGE); + pixelPositionWithPercentageLimitsVerticalReversed + .setFirstComponent(new Label( + "Max 80 % - Reversed 400 px position")); + pixelPositionWithPercentageLimitsVerticalReversed + .setSecondComponent(new Label("Min 10 %")); + pixelPositionWithPercentageLimitsVerticalReversed.setSplitPosition(400, + Sizeable.UNITS_PIXELS, true); + verticalSplitsLayout + .addComponent(pixelPositionWithPercentageLimitsVerticalReversed); + + VerticalSplitPanel pixelPositionWithPixelLimitsVerticalReversed = new VerticalSplitPanel(); + pixelPositionWithPixelLimitsVerticalReversed.setMinSplitPosition(100, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsVerticalReversed.setMaxSplitPosition(400, + Sizeable.UNITS_PIXELS); + pixelPositionWithPixelLimitsVerticalReversed + .setFirstComponent(new Label( + "Max 400 px - Reversed 300 px position")); + pixelPositionWithPixelLimitsVerticalReversed + .setSecondComponent(new Label("Min 100 px")); + pixelPositionWithPixelLimitsVerticalReversed.setSplitPosition(300, + Sizeable.UNITS_PIXELS, true); + verticalSplitsLayout + .addComponent(pixelPositionWithPixelLimitsVerticalReversed); + + VerticalSplitPanel percentagePositionWithPixelLimitsVerticalReversed = new VerticalSplitPanel(); + percentagePositionWithPixelLimitsVerticalReversed.setMinSplitPosition( + 100, Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsVerticalReversed.setMaxSplitPosition( + 400, Sizeable.UNITS_PIXELS); + percentagePositionWithPixelLimitsVerticalReversed + .setFirstComponent(new Label( + "Max 400 px - Reversed 30 % position")); + percentagePositionWithPixelLimitsVerticalReversed + .setSecondComponent(new Label("Min 100 px")); + percentagePositionWithPixelLimitsVerticalReversed.setSplitPosition(30, + Sizeable.UNITS_PERCENTAGE, true); + verticalSplitsLayout + .addComponent(percentagePositionWithPixelLimitsVerticalReversed); + + tabs.addComponent(verticalSplitsLayout); + verticalSplitsLayout.setSizeFull(); + + final VerticalLayout togglableSplitPanelLayout = new VerticalLayout(); + togglableSplitPanelLayout.setCaption("Togglable minimum/maximum"); + + final HorizontalSplitPanel togglableSplitPanel = new HorizontalSplitPanel(); + togglableSplitPanel.setMinSplitPosition(10, Sizeable.UNITS_PERCENTAGE); + togglableSplitPanel.setMaxSplitPosition(80, Sizeable.UNITS_PERCENTAGE); + togglableSplitPanel.setFirstComponent(new Label( + "Min 10 % - 50 % position")); + togglableSplitPanel.setSecondComponent(new Label("Max 80 %")); + togglableSplitPanel.setSplitPosition(50, Sizeable.UNITS_PERCENTAGE); + togglableSplitPanel.setHeight("250px"); + togglableSplitPanelLayout.addComponent(togglableSplitPanel); + + final HorizontalLayout buttonLayout = new HorizontalLayout(); + + Button disableMinimum = new Button("Disable min limit", + new Button.ClickListener() { + public void buttonClick(Button.ClickEvent event) { + togglableSplitPanel.setMinSplitPosition(0, + Sizeable.UNITS_PERCENTAGE); + + } + }); + Button enableMinimum = new Button("Enable min limit", + new Button.ClickListener() { + public void buttonClick(Button.ClickEvent event) { + togglableSplitPanel.setMinSplitPosition(10, + Sizeable.UNITS_PERCENTAGE); + + } + }); + Button disableMaximum = new Button("Disable max limit", + new Button.ClickListener() { + public void buttonClick(Button.ClickEvent event) { + togglableSplitPanel.setMaxSplitPosition(100, + Sizeable.UNITS_PERCENTAGE); + + } + }); + Button enableMaximum = new Button("Enable max limit", + new Button.ClickListener() { + public void buttonClick(Button.ClickEvent event) { + togglableSplitPanel.setMaxSplitPosition(80, + Sizeable.UNITS_PERCENTAGE); + + } + }); + buttonLayout.addComponent(disableMinimum); + buttonLayout.addComponent(enableMinimum); + buttonLayout.addComponent(disableMaximum); + buttonLayout.addComponent(enableMaximum); + + togglableSplitPanelLayout.addComponent(buttonLayout); + tabs.addComponent(togglableSplitPanelLayout); + + addComponent(tabs); + tabs.setHeight("550px"); + tabs.setWidth("600px"); + getLayout().setSizeFull(); + } + + @Override + protected String getDescription() { + return "SplitPanel could have setMaxSplitPosition and setMinSplitPosition methods as a way to set maximum and minimum limits for the split position. This is not a very critical feature but could be useful in some situations."; + } + + @Override + protected Integer getTicketNumber() { + return 1744; + } +} diff --git a/tests/testbench/com/vaadin/tests/components/splitpanel/VerticalSplitPanelSplitterClick.html b/tests/testbench/com/vaadin/tests/components/splitpanel/VerticalSplitPanelSplitterClick.html index d8a101b0a5..cc384b6de6 100644 --- a/tests/testbench/com/vaadin/tests/components/splitpanel/VerticalSplitPanelSplitterClick.html +++ b/tests/testbench/com/vaadin/tests/components/splitpanel/VerticalSplitPanelSplitterClick.html @@ -78,18 +78,19 @@ <tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentssplitpanelVerticalSplitPanels::PID_StestComponent/domChild[0]/domChild[2]/domChild[0]</td> - <td>12,13</td> + <td>5,5</td> </tr> <tr> <td>assertText</td> <td>vaadin=runcomvaadintestscomponentssplitpanelVerticalSplitPanels::PID_SLog_row_0</td> - <td>3. SplitterClickEvent: left at 12,13</td> + <td>3. SplitterClickEvent: left at 5,5</td> </tr> <tr> <td>screenCapture</td> <td></td> <td>reverseSplitterClicked</td> </tr> + </tbody></table> </body> </html> diff --git a/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java b/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java index 9178b284f3..6773f0a96c 100644 --- a/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java +++ b/tests/testbench/com/vaadin/tests/components/table/MultiSelectWithNotIdentityEqualIds.java @@ -5,6 +5,7 @@ import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; @SuppressWarnings("serial") @@ -20,8 +21,7 @@ public class MultiSelectWithNotIdentityEqualIds extends TestBase { t.setImmediate(true); t.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { - t.getRoot() - .showNotification("Selected: " + event.getProperty()); + Notification.show("Selected: " + event.getProperty()); } }); diff --git a/tests/testbench/com/vaadin/tests/components/table/RowUpdateShouldRetainContextMenu.html b/tests/testbench/com/vaadin/tests/components/table/RowUpdateShouldRetainContextMenu.html index e13aa5a3e5..65487d8fa8 100644 --- a/tests/testbench/com/vaadin/tests/components/table/RowUpdateShouldRetainContextMenu.html +++ b/tests/testbench/com/vaadin/tests/components/table/RowUpdateShouldRetainContextMenu.html @@ -22,6 +22,11 @@ <td>10,10</td> </tr> <tr> + <td>pause</td> + <td>1000</td> + <td></td> +</tr> +<tr> <td>assertText</td> <td>vaadin=runRowUpdateShouldRetainContextMenu::Root/VContextMenu[0]#option0</td> <td>Action 1</td> diff --git a/tests/testbench/com/vaadin/tests/components/table/ScrollCausesRequestLoop.java b/tests/testbench/com/vaadin/tests/components/table/ScrollCausesRequestLoop.java index c140e7e412..75468af247 100644 --- a/tests/testbench/com/vaadin/tests/components/table/ScrollCausesRequestLoop.java +++ b/tests/testbench/com/vaadin/tests/components/table/ScrollCausesRequestLoop.java @@ -4,16 +4,16 @@ import java.util.ArrayList; import java.util.List; import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.util.Person; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Table; -public class ScrollCausesRequestLoop extends TestBase { +public class ScrollCausesRequestLoop extends AbstractTestCase { @Override - protected void setup() { + public void init() { setMainWindow(new LegacyWindow("", new TestView())); } diff --git a/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java b/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java index 3b0234d805..44367d0fe1 100644 --- a/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java +++ b/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java @@ -46,6 +46,7 @@ public class ScrollDetachSynchronization extends TestBase { mainLayout.setExpandRatio(firstLayout, 1); first.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { if (mainLayout.getComponent(1).equals(secondLayout)) { mainLayout.replaceComponent(secondLayout, firstLayout); @@ -54,6 +55,7 @@ public class ScrollDetachSynchronization extends TestBase { } }); second.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { if (mainLayout.getComponent(1).equals(firstLayout)) { mainLayout.replaceComponent(firstLayout, secondLayout); diff --git a/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java b/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java index ff5aa89d84..79a7eca852 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java +++ b/tests/testbench/com/vaadin/tests/components/table/TableClickValueChangeInteraction.java @@ -60,6 +60,7 @@ public class TableClickValueChangeInteraction extends TestBase { table.setHeight("100px"); if (listenClicks) { table.addListener(new ItemClickListener() { + public void itemClick(ItemClickEvent event) { table.requestRepaint(); clickLabel.setValue("Click " + event.getItemId()); @@ -68,6 +69,7 @@ public class TableClickValueChangeInteraction extends TestBase { } if (listenValueChanges) { table.addListener(new ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { valueChangeLabel.setValue("Value " + event.getProperty().getValue()); diff --git a/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java b/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java index 16323e5024..06afd406ef 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java +++ b/tests/testbench/com/vaadin/tests/components/table/TableContextMenu.java @@ -2,6 +2,7 @@ package com.vaadin.tests.components.table; import com.vaadin.event.Action; import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; public class TableContextMenu extends TestBase { @@ -16,7 +17,7 @@ public class TableContextMenu extends TestBase { table.addActionHandler(new Action.Handler() { public void handleAction(Action action, Object sender, Object target) { - getLayout().getRoot().showNotification("Done that :-)"); + Notification.show("Done that :-)"); } public Action[] getActions(Object target, Object sender) { diff --git a/tests/testbench/com/vaadin/tests/components/table/TableFirstRowFlicker.java b/tests/testbench/com/vaadin/tests/components/table/TableFirstRowFlicker.java new file mode 100644 index 0000000000..3101615cfd --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/TableFirstRowFlicker.java @@ -0,0 +1,85 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.Application.LegacyApplication; +import com.vaadin.data.Container; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.ui.Label; +import com.vaadin.ui.ProgressIndicator; +import com.vaadin.ui.Root.LegacyWindow; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +public class TableFirstRowFlicker extends LegacyApplication { + + Table t; + + @Override + public void init() { + LegacyWindow mainWindow = new LegacyWindow(getClass().getName()); + setMainWindow(mainWindow); + mainWindow.getContent().setSizeFull(); + + t = new Table(); + t.setSizeFull(); + t.setSelectable(true); + t.setContainerDataSource(buildContainer()); + mainWindow.addComponent(t); + ((VerticalLayout) mainWindow.getContent()).setExpandRatio(t, 1); + + // Button button = new Button("Refresh"); + // button.addListener(new Button.ClickListener() { + // public void buttonClick(ClickEvent event) { + // t.refreshRowCache(); + // } + // }); + // mainWindow.addComponent(button); + + ProgressIndicator pi = new ProgressIndicator(); + pi.setPollingInterval(1000); + pi.setIndeterminate(true); + mainWindow.addComponent(pi); + + Thread r = new Thread() { + @Override + public void run() { + while (t != null) { + synchronized (t.getApplication()) { + int firstId = t.getCurrentPageFirstItemIndex(); + Object selected = t.getValue(); + t.setContainerDataSource(buildContainer()); + t.setValue(selected); + t.setCurrentPageFirstItemIndex(firstId); + // lighter alternative for all of above + // t.refreshRowCache(); + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("Table update thread stopped"); + } + }; + r.start(); + } + + @Override + public void close() { + t = null; + super.close(); + } + + private Container buildContainer() { + IndexedContainer cont = new IndexedContainer(); + cont.addContainerProperty("name", Label.class, null); + for (int i = 0; i < 10000; i++) { + cont.addItem(i); + Label l = new Label("Item " + i); + l.setHeight("50px"); + cont.getContainerProperty(i, "name").setValue(l); + } + return cont; + } + +}
\ No newline at end of file diff --git a/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java b/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java index a1686dee3f..d64bc0035d 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java +++ b/tests/testbench/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.java @@ -27,10 +27,8 @@ public class TableShouldNotEatValueChanges extends TestBase { ItemClickListener l = new ItemClickListener() { public void itemClick(ItemClickEvent event) { - tf.getRoot().showNotification( - "TF Value on the server:" + tf.getValue(), + Notification.show("TF Value on the server:" + tf.getValue(), Notification.TYPE_WARNING_MESSAGE); - } }; t.addListener(l); diff --git a/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.html b/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.html new file mode 100644 index 0000000000..e3c9a8423b --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.html @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>TableWithNoncollapsibleColumns</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TableWithNoncollapsibleColumns</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.table.TableWithNoncollapsibleColumns?restartApplication</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>column-3-collapsed</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>column-3-noncollapsible</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[0]/domChild[1]</td> + <td>9,7</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>column-menu-after-collapsing-all-columns</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::Root/VContextMenu[0]#option2</td> + <td>93,4</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithNoncollapsibleColumns::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[0]/domChild[1]</td> + <td>7,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>column-menu-after-expanding-column-2</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.java b/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.java new file mode 100644 index 0000000000..404ba5d779 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/TableWithNoncollapsibleColumns.java @@ -0,0 +1,83 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +public class TableWithNoncollapsibleColumns extends TestBase { + + @Override + protected void setup() { + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + addComponent(layout); + + final Table table = new Table(); + table.setWidth("100%"); + table.setHeight("300px"); + table.setColumnCollapsingAllowed(true); + + table.addContainerProperty("Column 1 - noncollapsible", String.class, + null); + table.addContainerProperty("Column 2 - collapsible", String.class, null); + table.addContainerProperty("Column 3 - toggle collapsing", + String.class, null); + + table.setColumnCollapsible("Column 1 - noncollapsible", false); + layout.addComponent(table); + + final Button button1 = new Button("Column 1: collapse/show", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setColumnCollapsed( + "Column 1 - noncollapsible", + !table.isColumnCollapsed("Column 1 - noncollapsible")); + } + }); + final Button button2 = new Button("Column 2: collapse/show", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setColumnCollapsed( + "Column 2 - collapsible", + !table.isColumnCollapsed("Column 2 - collapsible")); + } + }); + + final Button button3 = new Button("Column 3: collapse/show", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setColumnCollapsed( + "Column 3 - toggle collapsing", + !table.isColumnCollapsed("Column 3 - toggle collapsing")); + } + }); + final Button button4 = new Button( + "Column 3: make noncollapsible/collapsible", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setColumnCollapsible( + "Column 3 - toggle collapsing", + !table.isColumnCollapsible("Column 3 - toggle collapsing")); + } + }); + + layout.addComponent(button1); + layout.addComponent(button2); + layout.addComponent(button3); + layout.addComponent(button4); + + } + + @Override + protected String getDescription() { + return "Often a table has one column that identifies the row better than any other and it would not make sense to collapse that one. Make it possible from the server side api to disable collapsing for some properties. These properties could appear as grayed out in the collapse drop down menu."; + } + + @Override + protected Integer getTicketNumber() { + return 7495; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/table/Tables.java b/tests/testbench/com/vaadin/tests/components/table/Tables.java index 47c858f441..11ffff0655 100644 --- a/tests/testbench/com/vaadin/tests/components/table/Tables.java +++ b/tests/testbench/com/vaadin/tests/components/table/Tables.java @@ -78,6 +78,14 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T> } }; + private Command<T, Boolean> columnCollapsibleCommand = new Command<T, Boolean>() { + + public void execute(T c, Boolean collapsible, Object propertyId) { + c.setColumnCollapsible(propertyId, collapsible); + + } + }; + protected Command<T, Boolean> columnResizeListenerCommand = new Command<T, Boolean>() { public void execute(Table c, Boolean value, Object data) { @@ -648,6 +656,9 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T> createSelectAction("Expand ratio", category, expandOptions, "- remove -", columnExpandRatioCommand, propertyId); t.log("Expand"); + createBooleanAction("Collapsible", category, true, + columnCollapsibleCommand, propertyId); + // Footer text (move) // Header text (move) diff --git a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html index ac06706aa5..451e9b9c8d 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html +++ b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> +<link rel="selenium.base" href="http://localhost:8067/" /> <title>TestCurrentPageFirstItem</title> </head> <body> @@ -36,6 +36,41 @@ <td></td> <td></td> </tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td></td> +</tr> </tbody></table> </body> diff --git a/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.html b/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.html new file mode 100644 index 0000000000..d61a2cbc62 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.html @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8070" /> +<title>TabSheetWithDisappearingContent</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TabSheetWithDisappearingContent</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.tabsheet.TabSheetWithDisappearingContent?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetWithDisappearingContent::/VVerticalLayout[0]/VVerticalLayout[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td> + <td>14,7</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetWithDisappearingContent::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Content 1</td> +</tr> +<tr> + <td>assertVisible</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetWithDisappearingContent::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.java b/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.java new file mode 100644 index 0000000000..aed273dd64 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/tabsheet/TabSheetWithDisappearingContent.java @@ -0,0 +1,34 @@ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.TabSheet.Tab; +import com.vaadin.ui.VerticalLayout; + +public class TabSheetWithDisappearingContent extends TestBase { + + @Override + protected void setup() { + final TabSheet t = new TabSheet(); + + for (int i = 1; i < 4; i++) { + VerticalLayout v = new VerticalLayout(); + v.addComponent(new Label("Content " + i)); + Tab tab = t.addTab(v, "Tab " + i); + tab.setClosable(true); + } + addComponent(t); + } + + @Override + protected String getDescription() { + return "In some browsers, when trying to close the last tab of a tabsheet an IndexOutOfBoundException happens. After that, although an other tab is visually active, no contents are shown."; + } + + @Override + protected Integer getTicketNumber() { + return 7686; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/treetable/ComponentsInTreeTable.java b/tests/testbench/com/vaadin/tests/components/treetable/ComponentsInTreeTable.java new file mode 100644 index 0000000000..5b7700bc6e --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/treetable/ComponentsInTreeTable.java @@ -0,0 +1,50 @@ +package com.vaadin.tests.components.treetable; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Component; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Layout; +import com.vaadin.ui.TreeTable; + +public class ComponentsInTreeTable extends TestBase { + + @Override + protected void setup() { + TreeTable tt = new TreeTable(); + tt.setWidth("300px"); + addComponent(tt); + + Object id, id2; + + tt.addContainerProperty("foo", Component.class, ""); + tt.addContainerProperty("bar", String.class, "bar"); + tt.addContainerProperty("baz", String.class, "baz"); + + id = tt.addItem(); + Layout l = new HorizontalLayout(); + l.addComponent(new Label("bar")); + l.addComponent(new Label("bar")); + tt.getContainerProperty(id, "foo").setValue(l); + + id = tt.addItem(); + Label lbl = new Label("<b>foo</b><br/><i>bar</i>"); + lbl.setContentMode(Label.CONTENT_XHTML); + tt.getContainerProperty(id, "foo").setValue(lbl); + + id2 = tt.addItem(); + tt.setParent(id2, id); + tt.getContainerProperty(id2, "foo").setValue(new Button("Test")); + } + + @Override + protected String getDescription() { + return "Components in TreeTable cells should be rendered inline with the expand/collapse arrow"; + } + + @Override + protected Integer getTicketNumber() { + return 7387; + } +} diff --git a/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java b/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java index 2f84c8a68d..447ce6c465 100644 --- a/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java +++ b/tests/testbench/com/vaadin/tests/components/treetable/ProgrammaticCollapse.java @@ -4,6 +4,7 @@ import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Notification; import com.vaadin.ui.TreeTable; import com.vaadin.ui.VerticalLayout; @@ -31,8 +32,7 @@ public class ProgrammaticCollapse extends TestBase { new ClickListener() { public void buttonClick(ClickEvent event) { boolean collapsed = !table.isCollapsed(1); - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); table.setCollapsed(1, collapsed); } })); @@ -40,8 +40,7 @@ public class ProgrammaticCollapse extends TestBase { new ClickListener() { public void buttonClick(ClickEvent event) { boolean collapsed = !table.isCollapsed(100); - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); table.setCollapsed(100, collapsed); } })); @@ -51,8 +50,7 @@ public class ProgrammaticCollapse extends TestBase { public void buttonClick(ClickEvent event) { collapsed = !collapsed; - table.getRoot().showNotification( - "set collapsed: " + collapsed); + Notification.show("set collapsed: " + collapsed); for (int i = 0; i < 50; ++i) { table.setCollapsed(i * 2, collapsed); } diff --git a/tests/testbench/com/vaadin/tests/components/treetable/RowAnimation.html b/tests/testbench/com/vaadin/tests/components/treetable/RowAnimation.html new file mode 100644 index 0000000000..64ff061c13 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/treetable/RowAnimation.html @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>TestAnimatedExpandCollapse</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TestAnimatedExpandCollapse</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.treetable.TreeTableTest?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_Smenu#item0</td> + <td>38,10</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[0]/VMenuBar[0]#item0</td> + <td>35,5</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[1]/VMenuBar[0]#item7</td> + <td>30,12</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>12,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> + <td>31,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td> + <td>29,8</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]/domChild[0]</td> + <td>30,6</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> + <td>Item 4,1</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td> + <td>Item 5,1</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td> + <td>Item 6,1</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[4]/domChild[0]/domChild[0]</td> + <td>Item 7,1</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html b/tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html index b22d77a94c..499c30c86a 100644 --- a/tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html +++ b/tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html @@ -238,44 +238,44 @@ <td>9,-995</td> </tr> <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td> - <td>93,-991</td> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>20. Row Item TestBean [col1=40 (children), col2=AN] expanded. Row index: 39</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td> - <td>123,-991</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td> + <td>93,-991</td> </tr> <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td> - <td>114,-1000</td> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>21. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td> - <td>118,-993</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td> + <td>123,-991</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_4</td> - <td>20. Row Item TestBean [col1=40 (children), col2=AN] expanded. Row index: 39</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>22. Button Item TestBean [col1=40.1, col2=AN.A]/col3 clicked. Row index: 40</td> </tr> <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td> - <td>21. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[40]/VNativeButton[0]</td> + <td>114,-1000</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td> - <td>22. Button Item TestBean [col1=40.1, col2=AN.A]/col3 clicked. Row index: 40</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>23. Button Item TestBean [col1=40.6, col2=AN.F]/col3 clicked. Row index: 45</td> </tr> <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td> - <td>23. Button Item TestBean [col1=40.10, col2=AN.J]/col3 clicked. Row index: 49</td> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td> + <td>118,-993</td> </tr> <tr> <td>assertText</td> @@ -288,29 +288,34 @@ <td>9,-998</td> </tr> <tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>25. Row Item TestBean [col1=40 (children), col2=AN] collapsed. Row index: 39</td> +</tr> +<tr> <td>mouseClick</td> <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td> <td>42,-990</td> </tr> <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[29]/VNativeButton[0]</td> - <td>84,-990</td> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>26. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td> - <td>98,-998</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[29]/VNativeButton[0]</td> + <td>84,-990</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td> - <td>26. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td> + <td>27. Button Item TestBean [col1=35, col2=AI]/col3 clicked. Row index: 34</td> </tr> <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td> - <td>27. Button Item TestBean [col1=35, col2=AI]/col3 clicked. Row index: 34</td> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td> + <td>98,-998</td> </tr> <tr> <td>assertText</td> diff --git a/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java b/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java new file mode 100644 index 0000000000..ca9c31513f --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java @@ -0,0 +1,45 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.terminal.ExternalResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Table; + +public class DownloadAndUpdate extends TestBase { + + @Override + protected void setup() { + addComponent(new Button("Download and update", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + downloadAndUpdate(); + } + })); + } + + protected void downloadAndUpdate() { + getMainWindow().open( + new ExternalResource("/statictestfiles/dummy.zip", "_new")); + + // Any component sending an UIDL request when rendered will likely do + Table table = new Table(); + table.addContainerProperty("A", String.class, ""); + for (int i = 0; i < 100; i++) { + table.addItem(new Object[] { Integer.toString(i) }, + Integer.valueOf(i)); + } + addComponent(table); + } + + @Override + protected String getDescription() { + return "There should be no problems downloading a file from the same request that triggers another request, even in webkit browsers."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8781); + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java b/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java index 49da6758ea..9eaabf7340 100644 --- a/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java +++ b/tests/testbench/com/vaadin/tests/components/window/LazyWindowResize.java @@ -2,14 +2,14 @@ package com.vaadin.tests.components.window; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; +import com.vaadin.terminal.Page.BrowserWindowResizeListener; import com.vaadin.terminal.gwt.client.ui.label.ContentMode; import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.tests.util.Log; import com.vaadin.tests.util.LoremIpsum; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Label; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; -import com.vaadin.ui.Root.BrowserWindowResizeListener; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Window; import com.vaadin.ui.Window.ResizeEvent; diff --git a/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java b/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java index 988d47e29f..1e342abe01 100644 --- a/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java +++ b/tests/testbench/com/vaadin/tests/components/window/SubWindowFocusAndBlurListeners.java @@ -10,6 +10,7 @@ import com.vaadin.event.ShortcutAction; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; import com.vaadin.ui.Root; import com.vaadin.ui.TextField; import com.vaadin.ui.Window; @@ -36,15 +37,13 @@ public class SubWindowFocusAndBlurListeners extends TestBase { window.addComponent(new TextField()); window.addListener(new FocusListener() { public void focus(FocusEvent event) { - event.getComponent().getRoot() - .showNotification("Focused window"); + Notification.show("Focused window"); } }); window.addListener(new BlurListener() { public void blur(BlurEvent event) { - event.getComponent().getRoot() - .showNotification("Blurred window"); + Notification.show("Blurred window"); } }); @@ -57,7 +56,7 @@ public class SubWindowFocusAndBlurListeners extends TestBase { } public void handleAction(Action action, Object sender, Object target) { - window.getRoot().showNotification("Action!"); + Notification.show("Action!"); } }); diff --git a/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.html b/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.html new file mode 100644 index 0000000000..a3b56cd12a --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.html @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>UndefinedHeightSubWindowAndContent</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">UndefinedHeightSubWindowAndContent</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.window.UndefinedHeightSubWindowAndContent?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentswindowUndefinedHeightSubWindowAndContent::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>52,11</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestscomponentswindowUndefinedHeightSubWindowAndContent::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>invalid</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentswindowUndefinedHeightSubWindowAndContent::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>enter</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>form_full_width_1_error</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestscomponentswindowUndefinedHeightSubWindowAndContent::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>valid</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runcomvaadintestscomponentswindowUndefinedHeightSubWindowAndContent::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VForm[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>enter</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>form_full_width_2_valid</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.java b/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.java new file mode 100644 index 0000000000..ed259b2f4c --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/window/UndefinedHeightSubWindowAndContent.java @@ -0,0 +1,58 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.data.Validator; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Form; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +public class UndefinedHeightSubWindowAndContent extends TestBase { + + @Override + protected void setup() { + Window subWindow = new Window("No scrollbars!"); + subWindow.setWidth("300px"); + subWindow.center(); + subWindow.setModal(true); + VerticalLayout layout = new VerticalLayout(); + layout.setWidth("100%"); + subWindow.setContent(layout); + + final Form form = new Form(); + form.setImmediate(true); + form.setValidationVisible(true); + form.setCaption("This is a form"); + form.setDescription("How do you do?"); + final TextField field1 = new TextField("Write here"); + field1.setImmediate(true); + field1.addValidator(new Validator() { + + public void validate(Object value) throws InvalidValueException { + if (!isValid(value)) { + throw new InvalidValueException("FAIL!"); + } + } + + public boolean isValid(Object value) { + return field1.getValue().equals("valid"); + } + }); + form.addField("Field 1", field1); + layout.addComponent(form); + + getMainWindow().addWindow(subWindow); + subWindow.bringToFront(); + } + + @Override + protected String getDescription() { + return "When both window and its content have undefined height, window must not reserve space for a scroll bar when it is not needed."; + } + + @Override + protected Integer getTicketNumber() { + return 8852; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/window/WindowClickEvents.html b/tests/testbench/com/vaadin/tests/components/window/WindowClickEvents.html index f679779d4b..af5b9ec180 100644 --- a/tests/testbench/com/vaadin/tests/components/window/WindowClickEvents.html +++ b/tests/testbench/com/vaadin/tests/components/window/WindowClickEvents.html @@ -3,13 +3,13 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> +<link rel="selenium.base" href="http://localhost:8070" /> +<title>WindowClickEvents</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">WindowClickEvents</td></tr> </thead><tbody> <tr> <td>setSpeed</td> @@ -23,8 +23,8 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowClickEvents::/VVerticalLayout[0]/domChild[0]</td> - <td>154,150</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowClickEvents::/VVerticalLayout[0]/VLabel[0]</td> + <td>150,5</td> </tr> <tr> <td>assertText</td> @@ -72,6 +72,7 @@ <td>vaadin=runcomvaadintestscomponentswindowWindowClickEvents::PID_SLog_row_1</td> <td>4. Click using left on Sub window</td> </tr> + </tbody></table> </body> </html> diff --git a/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java b/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java index c6563f200f..ac6c313d29 100644 --- a/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java +++ b/tests/testbench/com/vaadin/tests/components/window/WindowResizeListener.java @@ -2,13 +2,13 @@ package com.vaadin.tests.components.window; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; import com.vaadin.ui.Window; public class WindowResizeListener extends TestBase { @@ -33,7 +33,7 @@ public class WindowResizeListener extends TestBase { final Label l = new Label(); getLayout().addComponent(l); - getMainWindow().addListener(new Root.BrowserWindowResizeListener() { + getMainWindow().addListener(new Page.BrowserWindowResizeListener() { public void browserWindowResized(BrowserWindowResizeEvent event) { l.setValue("Current browser window size: " + getMainWindow().getBrowserWindowWidth() + " x " diff --git a/tests/testbench/com/vaadin/tests/containers/TableWithFileSystemContainer.java b/tests/testbench/com/vaadin/tests/containers/TableWithFileSystemContainer.java index 459c234c24..25d0053fb2 100644 --- a/tests/testbench/com/vaadin/tests/containers/TableWithFileSystemContainer.java +++ b/tests/testbench/com/vaadin/tests/containers/TableWithFileSystemContainer.java @@ -4,7 +4,6 @@ import java.io.File; import com.vaadin.data.util.FilesystemContainer; import com.vaadin.tests.components.TestBase; -import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Table; public class TableWithFileSystemContainer extends TestBase { @@ -13,7 +12,6 @@ public class TableWithFileSystemContainer extends TestBase { @Override public void setup() { - setMainWindow(new LegacyWindow("")); Table table = new Table("Documents", new FilesystemContainer(new File( testPath))); table.setWidth("100%"); diff --git a/tests/testbench/com/vaadin/tests/dd/NotPaintedAcceptSourceInTabSheet.java b/tests/testbench/com/vaadin/tests/dd/NotPaintedAcceptSourceInTabSheet.java new file mode 100644 index 0000000000..ac92193764 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/dd/NotPaintedAcceptSourceInTabSheet.java @@ -0,0 +1,77 @@ +package com.vaadin.tests.dd; + +import com.vaadin.data.Item; +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.event.dd.acceptcriteria.SourceIs; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.TableDragMode; +import com.vaadin.ui.Table.TableTransferable; + +public class NotPaintedAcceptSourceInTabSheet extends TestBase { + + @Override + protected void setup() { + final Table source1 = createTable("Source 1"); + final Table source2 = createTable("Source 2"); + final Table target = createTable("Target"); + + source1.setDragMode(TableDragMode.ROW); + source2.setDragMode(TableDragMode.ROW); + + target.setDropHandler(new DropHandler() { + public AcceptCriterion getAcceptCriterion() { + return new SourceIs(source1, source2); + } + + public void drop(DragAndDropEvent event) { + TableTransferable transferable = (TableTransferable) event + .getTransferable(); + Item item = transferable.getSourceComponent().getItem( + transferable.getItemId()); + Object value = item.getItemProperty("value").getValue(); + AbstractSelectTargetDetails targetDetails = (AbstractSelectTargetDetails) event + .getTargetDetails(); + Object targetItemId = targetDetails.getItemIdOver(); + Object addItemAfter = target.addItemAfter(targetItemId); + target.getItem(addItemAfter).getItemProperty("value") + .setValue(value); + transferable.getSourceComponent().removeItem( + transferable.getItemId()); + } + }); + + TabSheet tabSheet = new TabSheet(); + tabSheet.addComponent(source1); + tabSheet.addComponent(source2); + + addComponent(tabSheet); + addComponent(target); + } + + private Table createTable(String caption) { + Table table = new Table(caption); + table.addContainerProperty("value", String.class, ""); + for (int i = 0; i < 10; i++) { + table.addItem(new Object[] { caption + " value " + i }, + Integer.valueOf(i)); + } + table.setWidth("300px"); + return table; + } + + @Override + protected String getDescription() { + return "Including a component in an accept criterion when the actual component is in a TabSheet and has not yet been painted should still allow painting the component properly when the tab is opened."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8730); + } + +} diff --git a/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.html.disabled diff --git a/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java new file mode 100644 index 0000000000..093e12f84a --- /dev/null +++ b/tests/testbench/com/vaadin/tests/dd/ScrolledDropTarget.java @@ -0,0 +1,67 @@ +package com.vaadin.tests.dd; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.Log; +import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails; +import com.vaadin.ui.AbstractSelect.VerticalLocationIs; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.TableDragMode; + +public class ScrolledDropTarget extends TestBase { + private final Log log = new Log(5); + + @Override + protected void setup() { + + Table table = new Table(); + table.addContainerProperty("A", String.class, ""); + for (int i = 0; i < 100; i++) { + table.addItem(new Object[] { Integer.toString(i) }, + Integer.valueOf(i)); + } + + table.setDragMode(TableDragMode.ROW); + table.setDropHandler(new DropHandler() { + public AcceptCriterion getAcceptCriterion() { + return VerticalLocationIs.MIDDLE; + } + + public void drop(DragAndDropEvent event) { + AbstractSelectTargetDetails targetDetails = (AbstractSelectTargetDetails) event + .getTargetDetails(); + VerticalDropLocation dropLocation = targetDetails + .getDropLocation(); + log.log("Drop at " + dropLocation + " relative to " + + targetDetails.getItemIdOver()); + } + }); + + addComponent(table); + addComponent(new Button("Scroll body", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + getMainWindow().executeJavaScript( + "document.body.style.overflow = 'auto';" + + "document.body.style.height = '200%';" + + "window.scrollTo(0,18)"); + } + })); + addComponent(log); + } + + @Override + protected String getDescription() { + return "Vertical location for drags should work even when the browser window is scrolled"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(6021); + } + +} diff --git a/tests/testbench/com/vaadin/tests/debug/DebugWindowPresent.html b/tests/testbench/com/vaadin/tests/debug/DebugWindowPresent.html index d396c1778e..11640ef6c3 100644 --- a/tests/testbench/com/vaadin/tests/debug/DebugWindowPresent.html +++ b/tests/testbench/com/vaadin/tests/debug/DebugWindowPresent.html @@ -13,7 +13,17 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&debug</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&debug&otherparam</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?debug&restartApplication</td> <td></td> </tr> <tr> @@ -31,6 +41,66 @@ <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> <td></td> </tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&mode=debug</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?nodebug&restartApplication</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&nodebug</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&debug=quiet</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?debug=quiet&restartApplication</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.debug.DebugWindowPresent?restartApplication&debug=quiet#/asdf</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestsdebugDebugWindowPresent::Root/VDebugConsole[0]</td> + <td></td> +</tr> </tbody></table> </body> </html> diff --git a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java index c84d37cd0f..65f0735ab5 100644 --- a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java +++ b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java @@ -10,7 +10,8 @@ import com.vaadin.external.json.JSONObject; import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.tests.util.Log; -import com.vaadin.ui.JavascriptCallback; +import com.vaadin.ui.JavaScript; +import com.vaadin.ui.JavaScriptCallback; public class JavascriptManagerTest extends AbstractTestRoot { @@ -19,7 +20,8 @@ public class JavascriptManagerTest extends AbstractTestRoot { @Override protected void setup(WrappedRequest request) { addComponent(log); - getJavascriptManager().addCallback("testing", new JavascriptCallback() { + final JavaScript js = JavaScript.getCurrent(); + js.addCallback("testing.doTest", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { log.log("Got " + arguments.length() + " arguments"); log.log("Argument 1 as a number: " + arguments.getInt(0)); @@ -28,9 +30,10 @@ public class JavascriptManagerTest extends AbstractTestRoot { + arguments.getJSONObject(2).getBoolean("p")); log.log("Argument 4 is JSONObject.NULL: " + (arguments.get(3) == JSONObject.NULL)); + js.removeCallback("testing.doTest"); } }); - executeJavaScript("window.testing(42, 'text', {p: true}, null)"); + js.execute("window.testing.doTest(42, 'text', {p: true}, null)"); } @Override diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java new file mode 100644 index 0000000000..bbfe3f0f46 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java @@ -0,0 +1,116 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.extensions; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.JavaScriptExtensionState; +import com.vaadin.terminal.gwt.client.communication.ClientRpc; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.JavaScriptCallback; +import com.vaadin.ui.Notification; + +@LoadScripts({ "/statictestfiles/jsextension.js" }) +public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { + + public static class SimpleJavaScriptExtensionState extends + JavaScriptExtensionState { + private String prefix; + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + } + + public static interface SimpleJavaScriptExtensionClientRpc extends + ClientRpc { + public void greet(String message); + } + + public static interface SimpleJavaScriptExtensionServerRpc extends + ServerRpc { + public void greet(String message); + } + + public static class SimpleJavascriptExtension extends + AbstractJavaScriptExtension { + + public SimpleJavascriptExtension() { + registerRpc(new SimpleJavaScriptExtensionServerRpc() { + public void greet(String message) { + Notification.show(getState().getPrefix() + message); + } + }); + registerCallback("greetToServer", new JavaScriptCallback() { + public void call(JSONArray arguments) throws JSONException { + Notification.show(getState().getPrefix() + + arguments.getString(0)); + } + }); + } + + @Override + public SimpleJavaScriptExtensionState getState() { + return (SimpleJavaScriptExtensionState) super.getState(); + } + + public void setPrefix(String prefix) { + getState().setPrefix(prefix); + requestRepaint(); + } + + public void greetRpc(String message) { + getRpcProxy(SimpleJavaScriptExtensionClientRpc.class) + .greet(message); + } + + public void greetCallback(String message) { + invokeCallback("greetToClient", message); + } + } + + @Override + protected void setup(WrappedRequest request) { + final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); + simpleJavascriptExtension.setPrefix("Prefix: "); + addExtension(simpleJavascriptExtension); + addComponent(new Button("Send rpc greeting", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension.greetRpc("Rpc greeting"); + } + })); + addComponent(new Button("Send callback greeting", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension + .greetCallback("Callback greeting"); + } + })); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java deleted file mode 100644 index 92c134efb0..0000000000 --- a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.tests.extensions; - -import com.vaadin.annotations.LoadScripts; -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.communication.ClientRpc; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.client.communication.SharedState; -import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Root; - -@LoadScripts({ "/statictestfiles/jsextension.js" }) -public class SimpleJavascriptExtensionTest extends AbstractTestRoot { - - public static class SimpleJavascriptExtensionState extends SharedState { - private String prefix; - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getPrefix() { - return prefix; - } - } - - public static interface SimpleJavascriptExtensionClientRpc extends - ClientRpc { - public void greet(String message); - } - - public static interface SimpleJavascriptExtensionServerRpc extends - ServerRpc { - public void greet(String message); - } - - public static class SimpleJavascriptExtension extends - AbstractJavascriptExtension { - - public SimpleJavascriptExtension() { - registerRpc(new SimpleJavascriptExtensionServerRpc() { - public void greet(String message) { - Root.getCurrentRoot().showNotification( - getState().getPrefix() + message); - } - }); - } - - @Override - public SimpleJavascriptExtensionState getState() { - return (SimpleJavascriptExtensionState) super.getState(); - } - - public void setPrefix(String prefix) { - getState().setPrefix(prefix); - requestRepaint(); - } - - public void greet(String message) { - getRpcProxy(SimpleJavascriptExtensionClientRpc.class) - .greet(message); - } - } - - @Override - protected void setup(WrappedRequest request) { - final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); - simpleJavascriptExtension.setPrefix("Prefix: "); - addExtension(simpleJavascriptExtension); - addComponent(new Button("Send greeting", new Button.ClickListener() { - public void buttonClick(ClickEvent event) { - simpleJavascriptExtension.greet("Greeted by button"); - } - })); - } - - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java b/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java index 584ce0ec36..b73a29efea 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/AbstractBeanFieldGroupTest.java @@ -7,7 +7,7 @@ import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; public abstract class AbstractBeanFieldGroupTest extends TestBase { @@ -64,7 +64,7 @@ public abstract class AbstractBeanFieldGroupTest extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java b/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java index f95c172348..c86cb6f5e8 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/BasicPersonForm.java @@ -18,8 +18,8 @@ import com.vaadin.tests.data.bean.Sex; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -125,7 +125,7 @@ public class BasicPersonForm extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java b/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java index 9ff553ce61..6c6cd8024b 100644 --- a/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java +++ b/tests/testbench/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java @@ -13,7 +13,7 @@ import com.vaadin.tests.data.bean.Sex; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; @@ -52,7 +52,7 @@ public class FieldBinderWithBeanValidation extends TestBase { } catch (CommitException e) { msg = "Commit failed: " + e.getMessage(); } - Root.getCurrentRoot().showNotification(msg); + Notification.show(msg); log.log(msg); } diff --git a/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java b/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java index eb26faacc0..1b6d384e70 100644 --- a/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java +++ b/tests/testbench/com/vaadin/tests/integration/EmbedSizeTest.java @@ -2,11 +2,12 @@ package com.vaadin.tests.integration; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.BrowserWindowResizeEvent; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.util.Log; import com.vaadin.ui.CheckBox; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.BrowserWindowResizeEvent; +import com.vaadin.ui.Root.LegacyWindow; public class EmbedSizeTest extends TestBase { @@ -14,14 +15,13 @@ public class EmbedSizeTest extends TestBase { @Override protected void setup() { - Root mainWindow = getMainWindow(); + LegacyWindow mainWindow = getMainWindow(); mainWindow.setSizeUndefined(); mainWindow.getContent().setSizeUndefined(); mainWindow.setImmediate(true); CheckBox lazyCheckBox = new CheckBox("Lazy resize"); lazyCheckBox.addListener(new ValueChangeListener() { - public void valueChange(ValueChangeEvent event) { CheckBox cb = (CheckBox) event.getProperty(); Boolean resizeLazy = cb.getValue(); @@ -34,11 +34,10 @@ public class EmbedSizeTest extends TestBase { addComponent(lazyCheckBox); addComponent(log); - mainWindow.addListener(new Root.BrowserWindowResizeListener() { + mainWindow.addListener(new Page.BrowserWindowResizeListener() { public void browserWindowResized(BrowserWindowResizeEvent event) { log.log("Resize event: " + event.getWidth() + " x " + event.getHeight()); - } }); } diff --git a/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java b/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java index e022a8bf30..913ce8f54c 100644 --- a/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java +++ b/tests/testbench/com/vaadin/tests/integration/JSR286PortletRoot.java @@ -86,7 +86,7 @@ public class JSR286PortletRoot extends Root { .getContext(); ctx.addPortletListener(getApplication(), new DemoPortletListener()); } else { - showNotification("Not inited via Portal!", + Notification.show("Not inited via Portal!", Notification.TYPE_ERROR_MESSAGE); } @@ -109,7 +109,7 @@ public class JSR286PortletRoot extends Root { tf.setEnabled((request.getPortletMode() == PortletMode.EDIT)); // Show notification about current mode and state - showNotification( + Notification.show( "Portlet status", "Mode: " + request.getPortletMode() + " State: " + request.getWindowState(), diff --git a/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java b/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java index 0250658bc9..8b7f498b0e 100644 --- a/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java +++ b/tests/testbench/com/vaadin/tests/integration/LiferayThemeDemo.java @@ -595,10 +595,7 @@ public class LiferayThemeDemo extends Application.LegacyApplication { Button show = new Button("Humanized Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), - message.getValue()); + Notification.show(title.getValue(), message.getValue()); } }); @@ -607,10 +604,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Warning", ContentMode.XHTML)); show = new Button("Warning Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_WARNING_MESSAGE); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_WARNING_MESSAGE); } }); @@ -619,10 +614,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Error", ContentMode.XHTML)); show = new Button("Error Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_ERROR_MESSAGE); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_ERROR_MESSAGE); } }); @@ -631,10 +624,8 @@ public class LiferayThemeDemo extends Application.LegacyApplication { l.addComponent(new Label("Tray", ContentMode.XHTML)); show = new Button("Tray Notification", new Button.ClickListener() { public void buttonClick(ClickEvent event) { - event.getButton() - .getRoot() - .showNotification(title.getValue(), message.getValue(), - Notification.TYPE_TRAY_NOTIFICATION); + Notification.show(title.getValue(), message.getValue(), + Notification.TYPE_TRAY_NOTIFICATION); } }); diff --git a/tests/testbench/com/vaadin/tests/integration/PortletSizeInLiferayFreeformLayoutApplication.java b/tests/testbench/com/vaadin/tests/integration/PortletSizeInLiferayFreeformLayoutApplication.java new file mode 100644 index 0000000000..20967203bc --- /dev/null +++ b/tests/testbench/com/vaadin/tests/integration/PortletSizeInLiferayFreeformLayoutApplication.java @@ -0,0 +1,31 @@ +package com.vaadin.tests.integration; + +import com.vaadin.Application.LegacyApplication; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root.LegacyWindow; +import com.vaadin.ui.VerticalLayout; + +/** + * On Liferay in a freeform layout, this application should get its height from + * the height of the portlet container in the Liferay layout. + * + * See ticket #5521. + */ +public class PortletSizeInLiferayFreeformLayoutApplication extends + LegacyApplication { + @Override + public void init() { + LegacyWindow mainWindow = new LegacyWindow("Portlet5521 Application"); + ((VerticalLayout) mainWindow.getContent()).setMargin(false); + ((VerticalLayout) mainWindow.getContent()).setSizeFull(); + // ((VerticalLayout) mainWindow.getContent()).setHeight("200px"); + Label label = new Label("Hello Vaadin user"); + mainWindow.addComponent(label); + for (int i = 0; i < 50; ++i) { + mainWindow.addComponent(new Label("Label " + i)); + } + mainWindow.setSizeFull(); + setMainWindow(mainWindow); + } + +} diff --git a/tests/testbench/com/vaadin/tests/layouts/GridLayoutCaptions.java b/tests/testbench/com/vaadin/tests/layouts/GridLayoutCaptions.java index 1fe33d62ca..9ad9adb43a 100644 --- a/tests/testbench/com/vaadin/tests/layouts/GridLayoutCaptions.java +++ b/tests/testbench/com/vaadin/tests/layouts/GridLayoutCaptions.java @@ -28,6 +28,7 @@ public class GridLayoutCaptions extends TestBase { private CssLayout wrapper2 = new CssLayout(); private FormFieldFactory fff = new FormFieldFactory() { + public Field<?> createField(Item item, Object propertyId, Component uiContext) { @@ -177,11 +178,10 @@ public class GridLayoutCaptions extends TestBase { @Override protected void setup() { - LegacyWindow mainWindow = new LegacyWindow( - "Formlayoutcaptionboom Application"); + LegacyWindow mainWindow = getMainWindow(); + Label label = new Label("Hello Vaadin user"); mainWindow.addComponent(label); - setMainWindow(mainWindow); DataPOJO forDemo = new DataPOJO(); @@ -194,6 +194,7 @@ public class GridLayoutCaptions extends TestBase { mainWindow.addComponent(aFormWithGl); Button b = new Button("Give me an error!", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { aFormWithGl.createErrors(); @@ -203,6 +204,7 @@ public class GridLayoutCaptions extends TestBase { Button b2 = new Button("Get rid of an error!", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { aFormWithGl.clearErrors(); diff --git a/tests/testbench/com/vaadin/tests/layouts/GridLayoutExpandRatioModification.java b/tests/testbench/com/vaadin/tests/layouts/GridLayoutExpandRatioModification.java index f7f4ac2d4c..314a8d7b03 100644 --- a/tests/testbench/com/vaadin/tests/layouts/GridLayoutExpandRatioModification.java +++ b/tests/testbench/com/vaadin/tests/layouts/GridLayoutExpandRatioModification.java @@ -21,10 +21,10 @@ public class GridLayoutExpandRatioModification extends TestBase implements @Override public void setup() { - LegacyWindow main = new LegacyWindow("The Main Window"); + LegacyWindow main = getMainWindow(); + mainLayout = new GridLayout(3, 3); main.setContent(mainLayout); - setMainWindow(main); // The upper layout vl1 = new VerticalLayout(); diff --git a/tests/testbench/com/vaadin/tests/layouts/TestLayoutClickListeners.html b/tests/testbench/com/vaadin/tests/layouts/TestLayoutClickListeners.html index 317e13ac80..2cc695e4fa 100644 --- a/tests/testbench/com/vaadin/tests/layouts/TestLayoutClickListeners.html +++ b/tests/testbench/com/vaadin/tests/layouts/TestLayoutClickListeners.html @@ -59,8 +59,8 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/domChild[0]</td> - <td>87,42</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/domChild[0]/domChild[0]</td> + <td>491,79</td> </tr> <tr> <td>waitForVaadin</td> @@ -185,6 +185,130 @@ <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> <td>exact:Button A button with its own click listener was clicked</td> </tr> +<!--Drag in GridLayout--> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>40,8</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>40,8</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:GridLayout: left click on This is label 1</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>24,7</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>46,13</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:GridLayout: left click on This is label 1</td> +</tr> +<!--Drag in VerticalLayout--> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>25,9</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>25,9</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:VerticalLayout: left click on This is tf5</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[8]/domChild[0]/domChild[0]</td> + <td>28,11</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VTextField[0]</td> + <td>39,7</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:VerticalLayout: left click on This is tf5</td> +</tr> +<!--Drag in AbsoluteLayout--> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> + <td>21,9</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> + <td>21,9</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:AbsoluteLayout: left click on This is its caption</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[0]/VTextField[0]</td> + <td>54,7</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[1]/VTextField[0]</td> + <td>52,10</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:AbsoluteLayout: left click on This is its caption</td> +</tr> +<!--Drag in CSSLayout--> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[0]</td> + <td>51,7</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[0]</td> + <td>51,7</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:CSSLayout: left click on This is its caption</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]</td> + <td>31,7</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[1]</td> + <td>33,7</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td> + <td>exact:CSSLayout: left click on This is its caption</td> +</tr> </tbody></table> </body> </html> diff --git a/tests/testbench/com/vaadin/tests/layouts/VerticalLayoutExpandRatioModification.java b/tests/testbench/com/vaadin/tests/layouts/VerticalLayoutExpandRatioModification.java index d41b288e03..44a1e27cb8 100644 --- a/tests/testbench/com/vaadin/tests/layouts/VerticalLayoutExpandRatioModification.java +++ b/tests/testbench/com/vaadin/tests/layouts/VerticalLayoutExpandRatioModification.java @@ -20,10 +20,10 @@ public class VerticalLayoutExpandRatioModification extends TestBase implements @Override public void setup() { - LegacyWindow main = new LegacyWindow("The Main Window"); + LegacyWindow main = getMainWindow(); + mainLayout = new VerticalLayout(); main.setContent(mainLayout); - setMainWindow(main); // The upper layout vl1 = new VerticalLayout(); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/AutoGeneratingForm.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/AutoGeneratingForm.java new file mode 100644 index 0000000000..8eef5c08e8 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/AutoGeneratingForm.java @@ -0,0 +1,77 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.data.fieldgroup.BeanFieldGroup; +import com.vaadin.data.fieldgroup.FieldGroup; +import com.vaadin.data.util.BeanItem; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Root; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Auto%20generating%20 + * a%20form%20based%20on%20a%20bean%20-%20Vaadin%206%20style%20Form + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class AutoGeneratingForm extends Root { + + @Override + protected void init(WrappedRequest request) { + FieldGroup fieldGroup = new BeanFieldGroup<Person>(Person.class); + + // We need an item data source before we create the fields to be able to + // find the properties, otherwise we have to specify them by hand + fieldGroup.setItemDataSource(new BeanItem<Person>(new Person("John", + "Doe", 34))); + + // Loop through the properties, build fields for them and add the fields + // to this root + for (Object propertyId : fieldGroup.getUnboundPropertyIds()) { + addComponent(fieldGroup.buildAndBind(propertyId)); + } + } + +} + +class Person { + private String firstName, lastName; + private int age; + + // + setters and getters + + public Person(String firstName, String lastName, int age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/BasicApplication.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/BasicApplication.java new file mode 100644 index 0000000000..3907209097 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/BasicApplication.java @@ -0,0 +1,28 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root; +import com.vaadin.ui.VerticalLayout; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Creating%20a%20basic%20application + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class BasicApplication extends Root { + + @Override + protected void init(WrappedRequest request) { + VerticalLayout view = new VerticalLayout(); + view.addComponent(new Label("Hello Vaadin!")); + setContent(view); + } +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java new file mode 100644 index 0000000000..c175fd6065 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java @@ -0,0 +1,31 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Root; +import com.vaadin.ui.TextField; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Creating%20an%20application + * %20that%20preserves%20state%20on%20refresh + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class CreatingPreserveState extends Root { + private static int windowCounter = 0; + + @Override + public void init(WrappedRequest request) { + TextField tf = new TextField("Window #" + (++windowCounter)); + tf.setImmediate(true); + getContent().addComponent(tf); + getApplication().setRootPreserved(true); + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/CustomConverterFactoryRoot.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/CustomConverterFactoryRoot.java index de32a817a1..89b4a0f8db 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/CustomConverterFactoryRoot.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/CustomConverterFactoryRoot.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DefineRootTheme.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DefineRootTheme.java new file mode 100644 index 0000000000..3bd17547fa --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DefineRootTheme.java @@ -0,0 +1,31 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.annotations.Theme; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root; +import com.vaadin.ui.VerticalLayout; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Defining%20the%20theme%20for%20a%20Root + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +@Theme("hello-theme") +public class DefineRootTheme extends Root { + + @Override + protected void init(WrappedRequest request) { + VerticalLayout view = new VerticalLayout(); + view.addComponent(new Label("Hello Vaadin")); + setContent(view); + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java new file mode 100644 index 0000000000..cf4c3b9267 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java @@ -0,0 +1,63 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.Application; +import com.vaadin.RootRequiresMoreInformationException; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.WrappedRequest.BrowserDetails; +import com.vaadin.terminal.gwt.server.WebBrowser; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Creating%20an%20application + * %20with%20different%20features%20for%20different%20clients + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class DifferentFeaturesForDifferentClients extends Application { + + @Override + protected Root getRoot(WrappedRequest request) + throws RootRequiresMoreInformationException { + BrowserDetails browserDetails = request.getBrowserDetails(); + // This is a limitation of 7.0.0.alpha1 that there is no better way to + // check if WebBrowser has been fully initialized + if (browserDetails.getUriFragment() == null) { + throw new RootRequiresMoreInformationException(); + } + + // could also use screen size, browser version etc. + if (browserDetails.getWebBrowser().isTouchDevice()) { + return new TouchRoot(); + } else { + return new DefaultRoot(); + } + } +} + +class DefaultRoot extends Root { + @Override + protected void init(WrappedRequest request) { + getContent().addComponent( + new Label("This browser does not support touch events")); + } +} + +class TouchRoot extends Root { + @Override + protected void init(WrappedRequest request) { + WebBrowser webBrowser = request.getBrowserDetails().getWebBrowser(); + String screenSize = "" + webBrowser.getScreenWidth() + "x" + + webBrowser.getScreenHeight(); + getContent().addComponent( + new Label("Using a touch enabled device with screen size" + + screenSize)); + } +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/DynamicImageRoot.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DynamicImageRoot.java index a0e6a54c41..9ed2bd2c75 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/DynamicImageRoot.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/DynamicImageRoot.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import java.awt.image.BufferedImage; import java.io.IOException; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FindCurrentRootAndApplication.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FindCurrentRootAndApplication.java new file mode 100644 index 0000000000..c6e609c5ee --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FindCurrentRootAndApplication.java @@ -0,0 +1,44 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.Application; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Root; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Finding%20the%20current + * %20Root%20and%20Application + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class FindCurrentRootAndApplication extends Root { + + @Override + protected void init(WrappedRequest request) { + Button helloButton = new Button("Say Hello"); + helloButton.addListener(new ClickListener() { + public void buttonClick(ClickEvent event) { + String msg = "Running in "; + msg += Application.getCurrentApplication().isProductionMode() ? "production" + : "debug"; + msg += " mode in a Root with the caption " + + Root.getCurrentRoot().getCaption(); + + Notification.show(msg); + } + }); + + addComponent(helloButton); + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/FormUsingExistingLayout.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FormUsingExistingLayout.java index 9d20867d24..1e460b2f6e 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/FormUsingExistingLayout.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FormUsingExistingLayout.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.fieldgroup.PropertyId; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/FormatTableValue.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java index aba1447d2c..e487c6d3c4 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/FormatTableValue.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import java.text.NumberFormat; import java.util.Locale; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/IntegerTextFieldDataSource.java index 5c0efea3ea..dd32242062 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldDataSource.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/IntegerTextFieldDataSource.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.data.Property; import com.vaadin.data.util.BeanItem; @@ -8,7 +8,7 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Label; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class IntegerTextFieldDataSource extends AbstractTestRoot { @@ -40,12 +40,9 @@ public class IntegerTextFieldDataSource extends AbstractTestRoot { Integer propertyValue = integerProperty.getValue(); int dataModelValue = myBean.getValue(); - Root.getCurrentRoot().showNotification( - "UI value (String): " + uiValue - + "<br />Property value (Integer): " - + propertyValue - + "<br />Data model value (int): " - + dataModelValue); + Notification.show("UI value (String): " + uiValue + + "<br />Property value (Integer): " + propertyValue + + "<br />Data model value (int): " + dataModelValue); } }); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/IntegerTextFieldStandalone.java index 45bc49ba72..9c720e45a5 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/IntegerTextFieldStandalone.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/IntegerTextFieldStandalone.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.data.util.converter.Converter.ConversionException; import com.vaadin.data.util.converter.StringToIntegerConverter; @@ -8,7 +8,7 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Label; -import com.vaadin.ui.Root; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class IntegerTextFieldStandalone extends AbstractTestRoot { @@ -24,14 +24,12 @@ public class IntegerTextFieldStandalone extends AbstractTestRoot { try { Integer convertedValue = (Integer) textField .getConvertedValue(); - Root.getCurrentRoot().showNotification( - "UI value (String): " + uiValue - + "<br />Converted value (Integer): " - + convertedValue); + Notification.show("UI value (String): " + uiValue + + "<br />Converted value (Integer): " + + convertedValue); } catch (ConversionException e) { e.printStackTrace(); - Root.getCurrentRoot().showNotification( - "Could not convert value: " + uiValue); + Notification.show("Could not convert value: " + uiValue); } } }); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MultiTabApplication.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MultiTabApplication.java new file mode 100644 index 0000000000..89c6ef52c4 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MultiTabApplication.java @@ -0,0 +1,51 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.terminal.ExternalResource; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Label; +import com.vaadin.ui.Link; +import com.vaadin.ui.Root; +import com.vaadin.ui.VerticalLayout; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Creating%20multi%20tab%20applications + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class MultiTabApplication extends Root { + + private class MainView extends VerticalLayout { + public MainView() { + addComponent(new Link("Edit person 1", new ExternalResource( + "?editPerson=person1"))); + addComponent(new Link("Edit person 2", new ExternalResource( + "?editPerson=person2"))); + } + } + + private class EditPersonView extends VerticalLayout { + + public EditPersonView(String person) { + addComponent(new Label("Editor for " + person)); + } + + } + + @Override + public void init(WrappedRequest request) { + String person = request.getParameter("editPerson"); + if (person == null) { + setContent(new MainView()); + } else { + setContent(new EditPersonView(person)); + } + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/MyConverterFactory.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MyConverterFactory.java index 456654e10a..17c37f2115 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/MyConverterFactory.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MyConverterFactory.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.DefaultConverterFactory; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/MyStringToDoubleConverter.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MyStringToDoubleConverter.java index 38268bdf68..483f841ce2 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/MyStringToDoubleConverter.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/MyStringToDoubleConverter.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import java.text.NumberFormat; import java.util.Locale; diff --git a/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/StringMyTypeConverter.java index e28788f743..4ccd73b2b3 100644 --- a/tests/testbench/com/vaadin/tests/minitutorials/StringMyTypeConverter.java +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/StringMyTypeConverter.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.minitutorials; +package com.vaadin.tests.minitutorials.v7a1; import java.util.Locale; @@ -9,6 +9,7 @@ import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; public class StringMyTypeConverter extends AbstractTestRoot { @@ -26,12 +27,11 @@ public class StringMyTypeConverter extends AbstractTestRoot { public void buttonClick(ClickEvent event) { try { Name name = (Name) textField.getConvertedValue(); - getRoot().showNotification( - "First name: " + name.getFirstName() - + "<br />Last name: " + name.getLastName()); + Notification.show("First name: " + name.getFirstName() + + "<br />Last name: " + name.getLastName()); } catch (ConversionException e) { e.printStackTrace(); - getRoot().showNotification(e.getCause().getMessage()); + Notification.show(e.getCause().getMessage()); } } })); diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingBeanValidation.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingBeanValidation.java new file mode 100644 index 0000000000..eb297ebd36 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingBeanValidation.java @@ -0,0 +1,74 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; + +import com.vaadin.data.util.BeanItem; +import com.vaadin.data.validator.BeanValidator; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Root; +import com.vaadin.ui.TextField; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Using%20Bean%20Validation + * %20to%20validate%20input + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class UsingBeanValidation extends Root { + class Person { + + @Size(min = 5, max = 50) + private String name; + + @Min(0) + @Max(100) + private int age; + + // + constructor + setters + getters + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + private void setN() { + // TODO Auto-generated method stub + + } + } + + @Override + protected void init(WrappedRequest request) { + Person person = new Person("John", 26); + BeanItem<Person> item = new BeanItem<Person>(person); + + TextField firstName = new TextField("First name", + item.getItemProperty("name")); + firstName.setImmediate(true); + addComponent(firstName); + + firstName.addValidator(new BeanValidator(Person.class, "name")); + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingUriFragments.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingUriFragments.java new file mode 100644 index 0000000000..e98b698c07 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingUriFragments.java @@ -0,0 +1,54 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.terminal.Page.FragmentChangedEvent; +import com.vaadin.terminal.Page.FragmentChangedListener; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Using%20URI%20fragments + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class UsingUriFragments extends Root { + + @Override + protected void init(WrappedRequest request) { + Label label = new Label("Hello, your fragment is " + + request.getBrowserDetails().getUriFragment()); + getContent().addComponent(label); + + // React to fragment changes + getPage().addListener(new FragmentChangedListener() { + public void fragmentChanged(FragmentChangedEvent source) { + handleFragment(source.getFragment()); + } + }); + + // Handle the fragment received in the initial request + handleFragment(request.getBrowserDetails().getUriFragment()); + + addComponent(new Button("Show and set fragment", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + handleFragment(getPage().getFragment()); + getPage().setFragment("customFragment"); + } + })); + } + + private void handleFragment(String uriFragment) { + addComponent(new Label("Got new fragment: " + uriFragment)); + } + +} diff --git a/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingXyzWhenInitializing.java b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingXyzWhenInitializing.java new file mode 100644 index 0000000000..426ef3525e --- /dev/null +++ b/tests/testbench/com/vaadin/tests/minitutorials/v7a1/UsingXyzWhenInitializing.java @@ -0,0 +1,52 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.minitutorials.v7a1; + +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.ui.Label; +import com.vaadin.ui.Root; + +/** + * Mini tutorial code for + * https://vaadin.com/wiki/-/wiki/Main/Using%20URI%20or%20 + * parameters%20or%20screen%20size%20when%20initializing%20an%20application + * + * @author Vaadin Ltd + * @version @VERSION@ + * @since 7.0.0 + */ +public class UsingXyzWhenInitializing extends Root { + + @Override + protected void init(WrappedRequest request) { + String name = request.getParameter("name"); + if (name == null) { + name = "Unknown"; + } + + getContent().addComponent(new Label("Hello " + name)); + + String pathInfo = request.getRequestPathInfo(); + if ("/viewSource".equals(pathInfo)) { + getContent().addComponent(new Label("This is the source")); + } else { + getContent().addComponent(new Label("Welcome to my application")); + } + + // WebBrowser browser = request.getBrowserDetails().getWebBrowser(); + // String resolution = "Your browser window on startup was " + // + browser.getClientWidth() + "x" + browser.getClientHeight(); + // if (browser.getClientWidth() > 1024) { + // getContent().addComponent( + // new Label("The is the large version of the application. " + // + resolution)); + // } else { + // getContent().addComponent( + // new Label("This is the small version of the application. " + // + resolution)); + // } + } + +} diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java b/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java index 9459c7cc85..9a777d655c 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket1465ModalNotification.java @@ -5,7 +5,6 @@ import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; -import com.vaadin.ui.Root; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Window; @@ -25,7 +24,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_ERROR_MESSAGE); @@ -37,7 +36,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_WARNING_MESSAGE); } @@ -48,7 +47,7 @@ public class Ticket1465ModalNotification extends Application.LegacyApplication { new Button.ClickListener() { public void buttonClick(ClickEvent event) { - Root.getCurrentRoot().showNotification( + Notification.show( "Try clicking the button in main window!", Notification.TYPE_HUMANIZED_MESSAGE); } diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java b/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java index 6cf5c8f754..a3ff6808dc 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket2998.java @@ -20,6 +20,7 @@ import com.vaadin.ui.Field; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Layout; import com.vaadin.ui.ListSelect; +import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.Table; @@ -181,8 +182,7 @@ public class Ticket2998 extends Application.LegacyApplication { @SuppressWarnings("unused") float f = Float.parseFloat((String) value); } catch (Exception e) { - f.getRoot() - .showNotification("Bad number value"); + Notification.show("Bad number value"); f.setValue(0); } } diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket34.java b/tests/testbench/com/vaadin/tests/tickets/Ticket34.java index 1c55bcbe7d..f6fbe05e38 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket34.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket34.java @@ -4,13 +4,13 @@ import java.util.HashMap; import java.util.Map; import com.vaadin.Application; +import com.vaadin.terminal.Page; +import com.vaadin.terminal.Page.FragmentChangedEvent; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; -import com.vaadin.ui.Root; -import com.vaadin.ui.Root.FragmentChangedEvent; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; @@ -32,7 +32,7 @@ public class Ticket34 extends Application.LegacyApplication { "Test app for URI fragment management/reading", mainLayout); setMainWindow(mainWin); - mainWin.addListener(new Root.FragmentChangedListener() { + mainWin.getPage().addListener(new Page.FragmentChangedListener() { public void fragmentChanged(FragmentChangedEvent event) { getMainWindow().showNotification( @@ -93,7 +93,7 @@ public class Ticket34 extends Application.LegacyApplication { public void buttonClick(ClickEvent event) { String viewName = tf.getValue().toString(); // fragmentChangedListener will change the view if possible - event.getButton().getRoot().setFragment(viewName); + event.getButton().getRoot().getPage().setFragment(viewName); } }); diff --git a/tests/testbench/com/vaadin/tests/tickets/Ticket6002.java b/tests/testbench/com/vaadin/tests/tickets/Ticket6002.java index 0875e3de48..c68dc9d534 100644 --- a/tests/testbench/com/vaadin/tests/tickets/Ticket6002.java +++ b/tests/testbench/com/vaadin/tests/tickets/Ticket6002.java @@ -13,8 +13,7 @@ public class Ticket6002 extends TestBase { @Override public void setup() { - LegacyWindow main = new LegacyWindow("The Main Window"); - setMainWindow(main); + LegacyWindow main = getMainWindow(); final VerticalLayout mainLayout = new VerticalLayout(); main.setContent(mainLayout); @@ -32,6 +31,7 @@ public class Ticket6002 extends TestBase { final TextField tf1 = new TextField( "Changing this field modifies only the textfield", property1); tf1.addListener(new Property.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { // This value change event is called twice if the new // input value is an integer. The second time is during @@ -56,6 +56,7 @@ public class Ticket6002 extends TestBase { "Changing this field modifies the layout - do it twice", property2); tf2.addListener(new Property.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { // This value change event is called twice if the new // input value is an integer. The second time is during diff --git a/tests/testbench/com/vaadin/tests/util/TestUtils.java b/tests/testbench/com/vaadin/tests/util/TestUtils.java index 551e7a7ed8..a9e1518c54 100644 --- a/tests/testbench/com/vaadin/tests/util/TestUtils.java +++ b/tests/testbench/com/vaadin/tests/util/TestUtils.java @@ -112,7 +112,7 @@ public class TestUtils { + "document.body.style.WebkitAppearance=='string') /* webkit only */ ? 'innerText' " + ": 'innerHTML'] = '" + cssString + "';}"; - w.executeJavaScript(script); + w.getPage().getJavaScript().execute(script); } public static IndexedContainer getISO3166Container() { diff --git a/tests/testbench/com/vaadin/tests/validation/RequiredErrorMessage.java b/tests/testbench/com/vaadin/tests/validation/RequiredErrorMessage.java index e18b8ffd4e..7b03bc7ec2 100644 --- a/tests/testbench/com/vaadin/tests/validation/RequiredErrorMessage.java +++ b/tests/testbench/com/vaadin/tests/validation/RequiredErrorMessage.java @@ -1,12 +1,12 @@ package com.vaadin.tests.validation; -import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.components.AbstractTestCase; import com.vaadin.ui.Form; import com.vaadin.ui.Root.LegacyWindow; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -public class RequiredErrorMessage extends TestBase { +public class RequiredErrorMessage extends AbstractTestCase { @Override protected Integer getTicketNumber() { @@ -19,7 +19,7 @@ public class RequiredErrorMessage extends TestBase { } @Override - public void setup() { + public void init() { final LegacyWindow main = new LegacyWindow(getClass().getName()); setMainWindow(main); |