summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2013-03-21 08:59:51 +0200
committerArtur Signell <artur@vaadin.com>2013-03-21 08:59:51 +0200
commitbd3bb24a36a0ad02ffb9cee2e46afc445a354191 (patch)
tree00d9248c84f8b7b60768552c822279c9cf151f45
parent320b4e3776976e5dad822f01542f338cf76140bb (diff)
parente4c9eda51082a443822b66864df2fe14be7dc6d7 (diff)
downloadvaadin-framework-bd3bb24a36a0ad02ffb9cee2e46afc445a354191.tar.gz
vaadin-framework-bd3bb24a36a0ad02ffb9cee2e46afc445a354191.zip
Merge commit 'e4c9eda51082a443822b66864df2fe14be7dc6d7'
Conflicts: uitest/test.xml Change-Id: I2c82fa7117b21bddad313abdd2f3f43143317c12
-rw-r--r--WebContent/VAADIN/vaadinBootstrap.js34
-rw-r--r--WebContent/release-notes.html4
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java1
-rw-r--r--client/src/com/vaadin/client/ui/AbstractComponentConnector.java17
-rw-r--r--client/src/com/vaadin/client/ui/FocusUtil.java94
-rw-r--r--client/src/com/vaadin/client/ui/MediaBaseConnector.java25
-rw-r--r--client/src/com/vaadin/client/ui/VMediaBase.java26
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java24
-rw-r--r--client/src/com/vaadin/client/ui/VTextArea.java122
-rw-r--r--client/src/com/vaadin/client/ui/VTextField.java4
-rw-r--r--client/src/com/vaadin/client/ui/VTree.java2
-rw-r--r--client/src/com/vaadin/client/ui/VUI.java25
-rw-r--r--client/src/com/vaadin/client/ui/VWindow.java34
-rw-r--r--client/src/com/vaadin/client/ui/audio/AudioConnector.java48
-rw-r--r--client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java4
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java8
-rw-r--r--common.xml2
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java185
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java130
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java207
-rw-r--r--server/src/com/vaadin/ui/AbstractComponentContainer.java6
-rw-r--r--server/src/com/vaadin/ui/CheckBox.java17
-rw-r--r--server/src/com/vaadin/ui/Table.java71
-rw-r--r--server/src/com/vaadin/ui/UI.java17
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java23
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/UIState.java6
-rw-r--r--uitest/integration-testscripts/GateIn-3/integration-test-GateIn-3.1.0-portlet2.html148
-rw-r--r--uitest/integration-testscripts/Liferay-6/integration-test-liferay-6.0.5.html27
-rw-r--r--uitest/integration_base_files/base.xml14
-rw-r--r--uitest/src/com/vaadin/tests/components/AbstractTestUIWithLog.java36
-rw-r--r--uitest/src/com/vaadin/tests/components/TestBase.java6
-rw-r--r--uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.html82
-rw-r--r--uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.java65
-rw-r--r--uitest/src/com/vaadin/tests/components/media/AudioTest.html66
-rw-r--r--uitest/src/com/vaadin/tests/components/media/AudioTest.java86
-rw-r--r--uitest/src/com/vaadin/tests/components/media/bip.mp3bin0 -> 13837 bytes
-rw-r--r--uitest/src/com/vaadin/tests/components/media/bip.oggbin0 -> 15137 bytes
-rw-r--r--uitest/src/com/vaadin/tests/components/media/toyphone_dialling.mp3bin0 -> 80083 bytes
-rw-r--r--uitest/src/com/vaadin/tests/components/media/toyphone_dialling.oggbin0 -> 77861 bytes
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.html83
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.java57
-rw-r--r--uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.html169
-rw-r--r--uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.java89
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UITabIndex.html57
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UITabIndex.java51
-rw-r--r--uitest/test.xml2
46 files changed, 1798 insertions, 376 deletions
diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js
index f5c00a0b65..40f9ce470f 100644
--- a/WebContent/VAADIN/vaadinBootstrap.js
+++ b/WebContent/VAADIN/vaadinBootstrap.js
@@ -55,19 +55,45 @@
pendingApps: []
};
};
-
+
+ var isInitializedInDom = function(appId) {
+ var appDiv = document.getElementById(appId);
+ if (!appDiv) {
+ return false;
+ }
+ for ( var i = 0; i < appDiv.childElementCount; i++) {
+ var className = appDiv.childNodes[i].className;
+ // If the app div contains a child with the class
+ // "v-app-loading" we have only received the HTML
+ // but not yet started the widget set
+ // (UIConnector removes the v-app-loading div).
+ if (className && className.contains("v-app-loading")) {
+ return false;
+ }
+ }
+ return true;
+ };
+
window.vaadin = window.vaadin || {
initApplication: function(appId, config) {
+ var testbenchId = appId.replace(/-\d+$/, '');
+
if (apps[appId]) {
- throw "Application " + appId + " already initialized";
+ if (window.vaadin && window.vaadin.clients && window.vaadin.clients[testbenchId] && window.vaadin.clients[testbenchId].initializing) {
+ throw "Application " + appId + " is already being initialized";
+ }
+ if (isInitializedInDom(appId)) {
+ throw "Application " + appId + " already initialized";
+ }
}
+
log("init application", appId, config);
- var testbenchId = appId.replace(/-\d+$/, '');
window.vaadin.clients[testbenchId] = {
isActive: function() {
return true;
- }
+ },
+ initializing: true
};
var getConfig = function(name) {
diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html
index 39b6652532..0f49e819b0 100644
--- a/WebContent/release-notes.html
+++ b/WebContent/release-notes.html
@@ -658,12 +658,12 @@
</p>
<ul>
- <li>Mozilla Firefox 18</li>
+ <li>Mozilla Firefox 18-19</li>
<li>Mozilla Firefox 17 ESR</li>
<li>Internet Explorer 8-10</li>
<li>Safari 6</li>
<li>Opera 12</li>
- <li>Google Chrome 23</li>
+ <li>Google Chrome 23-25</li>
</ul>
<p>
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 62827feffb..4ddbd7c39b 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -510,6 +510,7 @@ public class ApplicationConnection {
client.getPathForElement = $entry(function(element) {
return componentLocator.@com.vaadin.client.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element);
});
+ client.initializing = false;
$wnd.vaadin.clients[TTAppId] = client;
}-*/;
diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
index 694db6f02c..ecd6abae08 100644
--- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
+++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java
@@ -137,10 +137,19 @@ public abstract class AbstractComponentConnector extends AbstractConnector
* implementation).
*/
Profiler.enter("AbstractComponentConnector.onStateChanged update tab index");
- if (getState() instanceof TabIndexState
- && getWidget() instanceof Focusable) {
- ((Focusable) getWidget())
- .setTabIndex(((TabIndexState) getState()).tabIndex);
+ if (getState() instanceof TabIndexState) {
+ if (getWidget() instanceof Focusable) {
+ ((Focusable) getWidget())
+ .setTabIndex(((TabIndexState) getState()).tabIndex);
+ } else {
+ /*
+ * TODO Enable this error when all widgets have been fixed to
+ * properly support tabIndex, i.e. implement Focusable
+ */
+ // VConsole.error("Tab index received for "
+ // + Util.getSimpleName(getWidget())
+ // + " which does not implement Focusable");
+ }
}
Profiler.leave("AbstractComponentConnector.onStateChanged update tab index");
diff --git a/client/src/com/vaadin/client/ui/FocusUtil.java b/client/src/com/vaadin/client/ui/FocusUtil.java
new file mode 100644
index 0000000000..8de3f767bd
--- /dev/null
+++ b/client/src/com/vaadin/client/ui/FocusUtil.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.ui;
+
+import com.google.gwt.user.client.ui.Focusable;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * A helper class used to make it easier for {@link Widget}s to implement
+ * {@link Focusable}.
+ *
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.3
+ *
+ */
+public class FocusUtil {
+
+ /**
+ * Sets the access key property
+ *
+ * @param focusable
+ * The widget for which we want to set the access key.
+ * @param key
+ * The access key to set
+ */
+ public static void setAccessKey(Widget focusable, char key) {
+ assert (focusable != null && focusable.getElement() != null) : "Can't setAccessKey for a widget without an element";
+ focusable.getElement().setPropertyString("accessKey", "" + key);
+ }
+
+ /**
+ * Explicitly focus/unfocus the given widget. Only one widget can have focus
+ * at a time, and the widget that does will receive all keyboard events.
+ *
+ * @param focusable
+ * the widget to focus/unfocus
+ * @param focused
+ * whether this widget should take focus or release it
+ */
+ public static void setFocus(Widget focusable, boolean focus) {
+ assert (focusable != null && focusable.getElement() != null) : "Can't setFocus for a widget without an element";
+
+ if (focus) {
+ focusable.getElement().focus();
+ } else {
+ focusable.getElement().blur();
+ }
+ }
+
+ /**
+ * Sets the widget's position in the tab index. If more than one widget has
+ * the same tab index, each such widget will receive focus in an arbitrary
+ * order. Setting the tab index to <code>-1</code> will cause the widget to
+ * be removed from the tab order.
+ *
+ * @param focusable
+ * The widget
+ * @param tabIndex
+ * the widget's tab index
+ */
+ public static void setTabIndex(Widget focusable, int tabIndex) {
+ assert (focusable != null && focusable.getElement() != null) : "Can't setTabIndex for a widget without an element";
+
+ focusable.getElement().setTabIndex(tabIndex);
+ }
+
+ /**
+ * Gets the widget's position in the tab index.
+ *
+ * @param focusable
+ * The widget
+ *
+ * @return the widget's tab index
+ */
+ public static int getTabIndex(Widget focusable) {
+ assert (focusable != null && focusable.getElement() != null) : "Can't getTabIndex for a widget without an element";
+
+ return focusable.getElement().getTabIndex();
+ }
+}
diff --git a/client/src/com/vaadin/client/ui/MediaBaseConnector.java b/client/src/com/vaadin/client/ui/MediaBaseConnector.java
index 6824caff78..8614977be1 100644
--- a/client/src/com/vaadin/client/ui/MediaBaseConnector.java
+++ b/client/src/com/vaadin/client/ui/MediaBaseConnector.java
@@ -46,15 +46,26 @@ public abstract class MediaBaseConnector extends AbstractComponentConnector {
}
@Override
- public void onStateChanged(StateChangeEvent stateChangeEvent) {
- super.onStateChanged(stateChangeEvent);
+ public void onStateChanged(StateChangeEvent event) {
+ super.onStateChanged(event);
- for (int i = 0; i < getState().sources.size(); i++) {
- URLReference source = getState().sources.get(i);
- String sourceType = getState().sourceTypes.get(i);
- getWidget().addSource(source.getURL(), sourceType);
+ final VMediaBase widget = getWidget();
+ final AbstractMediaState state = getState();
+
+ setAltText(state.altText); // must do before loading sources
+ widget.setAutoplay(state.autoplay);
+ widget.setMuted(state.muted);
+ widget.setControls(state.showControls);
+
+ if (event.hasPropertyChanged("sources")) {
+ widget.removeAllSources();
+ for (int i = 0; i < state.sources.size(); i++) {
+ URLReference source = state.sources.get(i);
+ String sourceType = state.sourceTypes.get(i);
+ widget.addSource(source.getURL(), sourceType);
+ }
+ widget.load();
}
- setAltText(getState().altText);
}
@Override
diff --git a/client/src/com/vaadin/client/ui/VMediaBase.java b/client/src/com/vaadin/client/ui/VMediaBase.java
index 8d40775c8d..b77e8bb161 100644
--- a/client/src/com/vaadin/client/ui/VMediaBase.java
+++ b/client/src/com/vaadin/client/ui/VMediaBase.java
@@ -18,12 +18,16 @@ package com.vaadin.client.ui;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.MediaElement;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.dom.client.SourceElement;
+import com.google.gwt.dom.client.Text;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
public abstract class VMediaBase extends Widget {
private MediaElement media;
+ private Text altText;
/**
* Sets the MediaElement that is to receive all commands and properties.
@@ -44,7 +48,12 @@ public abstract class VMediaBase extends Widget {
}
public void setAltText(String alt) {
- media.appendChild(Document.get().createTextNode(alt));
+ if (altText == null) {
+ altText = Document.get().createTextNode(alt);
+ media.appendChild(altText);
+ } else {
+ altText.setNodeValue(alt);
+ }
}
public void setControls(boolean shouldShowControls) {
@@ -59,8 +68,21 @@ public abstract class VMediaBase extends Widget {
media.setMuted(mediaMuted);
}
+ public void removeAllSources() {
+ NodeList<com.google.gwt.dom.client.Element> l = media
+ .getElementsByTagName(SourceElement.TAG);
+ for (int i = l.getLength() - 1; i >= 0; i--) {
+ media.removeChild(l.getItem(i));
+ }
+
+ }
+
+ public void load() {
+ media.load();
+ }
+
public void addSource(String sourceUrl, String sourceType) {
- Element src = Document.get().createElement("source").cast();
+ Element src = Document.get().createElement(SourceElement.TAG).cast();
src.setAttribute("src", sourceUrl);
src.setAttribute("type", sourceType);
media.appendChild(src);
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index 6f9fd6da88..4d61fba429 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -3056,7 +3056,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.hasNext(); columnIndex++) {
if (it.next() == this) {
break;
- }
+ }
}
}
final int cw = scrollBody.getColWidth(columnIndex);
@@ -3266,10 +3266,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
if (col.hasAttribute("width")) {
- final String widthStr = col.getStringAttribute("width");
// Make sure to accomodate for the sort indicator if
// necessary.
- int width = Integer.parseInt(widthStr);
+ int width = col.getIntAttribute("width");
int widthWithoutAddedIndent = width;
// get min width with indent, no padding
@@ -3301,12 +3300,25 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// save min width without indent
c.setWidth(widthWithoutAddedIndent, true);
}
+ } else if (col.hasAttribute("er")) {
+ c.setExpandRatio(col.getFloatAttribute("er"));
+
} else if (recalcWidths) {
c.setUndefinedWidth();
+
+ } else {
+ boolean hadExpandRatio = c.getExpandRatio() > 0;
+ boolean hadDefinedWidth = c.isDefinedWidth();
+ if (hadExpandRatio || hadDefinedWidth) {
+ // Someone has removed a expand width or the defined
+ // width on the server side (setting it to -1), make the
+ // column undefined again and measure columns again.
+ c.setUndefinedWidth();
+ c.setExpandRatio(0);
+ refreshContentWidths = true;
+ }
}
- if (col.hasAttribute("er")) {
- c.setExpandRatio(col.getFloatAttribute("er"));
- }
+
if (col.hasAttribute("collapsed")) {
// ensure header is properly removed from parent (case when
// collapsing happens via servers side api)
diff --git a/client/src/com/vaadin/client/ui/VTextArea.java b/client/src/com/vaadin/client/ui/VTextArea.java
index 6e93a076d9..45e0532451 100644
--- a/client/src/com/vaadin/client/ui/VTextArea.java
+++ b/client/src/com/vaadin/client/ui/VTextArea.java
@@ -18,6 +18,7 @@ package com.vaadin.client.ui;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.Overflow;
+import com.google.gwt.dom.client.Style.WhiteSpace;
import com.google.gwt.dom.client.TextAreaElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
@@ -62,6 +63,120 @@ public class VTextArea extends VTextField {
getTextAreaElement().setRows(rows);
}
+ @Override
+ public void setSelectionRange(int pos, int length) {
+ super.setSelectionRange(pos, length);
+ final String value = getValue();
+ /*
+ * Align position to index inside string value
+ */
+ int index = pos;
+ if (index < 0) {
+ index = 0;
+ }
+ if (index > value.length()) {
+ index = value.length();
+ }
+ // Get pixels count required to scroll textarea vertically
+ int scrollTop = getScrollTop(value, index);
+ int scrollLeft = -1;
+ /*
+ * Check if textarea has wrap attribute set to "off". In the latter case
+ * horizontal scroll is also required.
+ */
+ if (!isWordwrap()) {
+ // Get pixels count required to scroll textarea horizontally
+ scrollLeft = getScrollLeft(value, index);
+ }
+ // Set back original text if previous methods calls changed it
+ if (!isWordwrap() || index < value.length()) {
+ setValue(value, false);
+ }
+ /*
+ * Call original method to set cursor position. In most browsers it
+ * doesn't lead to scrolling.
+ */
+ super.setSelectionRange(pos, length);
+ /*
+ * Align vertical scroll to middle of textarea view (height) if
+ * scrolling is reqiured at all.
+ */
+ if (scrollTop > 0) {
+ scrollTop += getElement().getClientHeight() / 2;
+ }
+ /*
+ * Align horizontal scroll to middle of textarea view (widht) if
+ * scrolling is reqiured at all.
+ */
+ if (scrollLeft > 0) {
+ scrollLeft += getElement().getClientWidth() / 2;
+ }
+ /*
+ * Scroll if computed scrollTop is greater than scroll after cursor
+ * setting
+ */
+ if (getElement().getScrollTop() < scrollTop) {
+ getElement().setScrollTop(scrollTop);
+ }
+ /*
+ * Scroll if computed scrollLeft is greater than scroll after cursor
+ * setting
+ */
+ if (getElement().getScrollLeft() < scrollLeft) {
+ getElement().setScrollLeft(scrollLeft);
+ }
+ }
+
+ /*
+ * Get horizontal scroll value required to get position visible. Method is
+ * called only when text wrapping is off. There is need to scroll
+ * horizontally in case words are wrapped.
+ */
+ private int getScrollLeft(String value, int index) {
+ String beginning = value.substring(0, index);
+ // Compute beginning of the current line
+ int begin = beginning.lastIndexOf('\n');
+ String line = value.substring(begin + 1);
+ index = index - begin - 1;
+ if (index < line.length()) {
+ index++;
+ }
+ line = line.substring(0, index);
+ /*
+ * Now <code>line</code> contains current line up to index position
+ */
+ setValue(line.trim(), false); // Set this line to the textarea.
+ /*
+ * Scroll textarea up to the end of the line (maximum possible
+ * horizontal scrolling value). Now the end line becomes visible.
+ */
+ getElement().setScrollLeft(getElement().getScrollWidth());
+ // Return resulting horizontal scrolling value.
+ return getElement().getScrollLeft();
+ }
+
+ /*
+ * Get vertical scroll value required to get position visible
+ */
+ private int getScrollTop(String value, int index) {
+ /*
+ * Trim text after position and set this trimmed text if index is not
+ * very end.
+ */
+ if (index < value.length()) {
+ String beginning = value.substring(0, index);
+ setValue(beginning, false);
+ }
+ /*
+ * Now textarea contains trimmed text and could be scrolled up to the
+ * top. Scroll it to maximum possible value to get end of the text
+ * visible.
+ */
+ getElement().setScrollTop(getElement().getScrollHeight());
+ // Return resulting vertical scrolling value.
+ return getElement().getScrollTop();
+ }
+
private class MaxLengthHandler implements KeyUpHandler, ChangeHandler {
@Override
@@ -154,13 +269,18 @@ public class VTextArea extends VTextField {
if (wordwrap) {
getElement().removeAttribute("wrap");
getElement().getStyle().clearOverflow();
+ getElement().getStyle().clearWhiteSpace();
} else {
getElement().setAttribute("wrap", "off");
getElement().getStyle().setOverflow(Overflow.AUTO);
+ getElement().getStyle().setWhiteSpace(WhiteSpace.PRE);
}
- if (BrowserInfo.get().isOpera()) {
+ if (BrowserInfo.get().isOpera()
+ || (BrowserInfo.get().isWebkit() && wordwrap)) {
// Opera fails to dynamically update the wrap attribute so we detach
// and reattach the whole TextArea.
+ // Webkit fails to properly reflow the text when enabling wrapping,
+ // same workaround
Util.detachAttach(getElement());
}
this.wordwrap = wordwrap;
diff --git a/client/src/com/vaadin/client/ui/VTextField.java b/client/src/com/vaadin/client/ui/VTextField.java
index 9b85dd22da..60dc5a8f2a 100644
--- a/client/src/com/vaadin/client/ui/VTextField.java
+++ b/client/src/com/vaadin/client/ui/VTextField.java
@@ -450,4 +450,8 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
this.inputPrompt = inputPrompt;
}
+ protected boolean isWordwrap() {
+ String wrap = getElement().getAttribute("wrap");
+ return !"off".equals(wrap);
+ }
}
diff --git a/client/src/com/vaadin/client/ui/VTree.java b/client/src/com/vaadin/client/ui/VTree.java
index 809ed9c82d..624dce4f13 100644
--- a/client/src/com/vaadin/client/ui/VTree.java
+++ b/client/src/com/vaadin/client/ui/VTree.java
@@ -189,7 +189,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
* handler, other browsers handle it correctly when using a key down
* handler
*/
- if (BrowserInfo.get().isGecko() || BrowserInfo.get().isOpera()) {
+ if (BrowserInfo.get().isGecko()) {
addKeyPressHandler(this);
} else {
addKeyDownHandler(this);
diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java
index b627d4a2a9..b07593896f 100644
--- a/client/src/com/vaadin/client/ui/VUI.java
+++ b/client/src/com/vaadin/client/ui/VUI.java
@@ -53,7 +53,8 @@ import com.vaadin.shared.ui.ui.UIConstants;
*/
public class VUI extends SimplePanel implements ResizeHandler,
Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
- HasResizeHandlers, HasScrollHandlers {
+ com.google.gwt.user.client.ui.Focusable, HasResizeHandlers,
+ HasScrollHandlers {
private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
@@ -437,7 +438,7 @@ public class VUI extends SimplePanel implements ResizeHandler,
@Override
public void focus() {
- getElement().focus();
+ setFocus(true);
}
/**
@@ -462,4 +463,24 @@ public class VUI extends SimplePanel implements ResizeHandler,
return addHandler(scrollHandler, ScrollEvent.getType());
}
+ @Override
+ public int getTabIndex() {
+ return FocusUtil.getTabIndex(this);
+ }
+
+ @Override
+ public void setAccessKey(char key) {
+ FocusUtil.setAccessKey(this, key);
+ }
+
+ @Override
+ public void setFocus(boolean focused) {
+ FocusUtil.setFocus(this, focused);
+ }
+
+ @Override
+ public void setTabIndex(int index) {
+ FocusUtil.setTabIndex(this, index);
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java
index bd9493c761..fd2a701334 100644
--- a/client/src/com/vaadin/client/ui/VWindow.java
+++ b/client/src/com/vaadin/client/ui/VWindow.java
@@ -22,6 +22,9 @@ import java.util.Comparator;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
@@ -35,6 +38,7 @@ 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.Window;
+import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
@@ -423,6 +427,36 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
// Remove window from windowOrder to avoid references being left
// hanging.
windowOrder.remove(this);
+
+ /*
+ * If the window has a RichTextArea and the RTA is focused at the time
+ * of hiding in IE8 only the window will have some problems returning
+ * the focus to the correct place. Curiously the focus will be returned
+ * correctly if clicking on the "close" button in the window header but
+ * closing the window from a button for example in the window will fail.
+ * Symptom described in #10776
+ *
+ * The problematic part is that for the focus to be returned correctly
+ * an input element needs to be focused in the root panel. Focusing some
+ * other element apparently won't work.
+ */
+ if (BrowserInfo.get().isIE8()) {
+ fixIE8FocusCaptureIssue();
+ }
+ }
+
+ private void fixIE8FocusCaptureIssue() {
+ Element e = DOM.createInputText();
+ Style elemStyle = e.getStyle();
+ elemStyle.setPosition(Position.ABSOLUTE);
+ elemStyle.setLeft(-10, Unit.PX);
+ elemStyle.setWidth(0, Unit.PX);
+ elemStyle.setHeight(0, Unit.PX);
+
+ Element rootPanel = RootPanel.getBodyElement();
+ rootPanel.appendChild(e);
+ e.focus();
+ rootPanel.removeChild(e);
}
/** For internal use only. May be removed or replaced in the future. */
diff --git a/client/src/com/vaadin/client/ui/audio/AudioConnector.java b/client/src/com/vaadin/client/ui/audio/AudioConnector.java
index c7d20ef585..5a90cab09d 100644
--- a/client/src/com/vaadin/client/ui/audio/AudioConnector.java
+++ b/client/src/com/vaadin/client/ui/audio/AudioConnector.java
@@ -30,23 +30,6 @@ import com.vaadin.ui.Audio;
public class AudioConnector extends MediaBaseConnector {
@Override
- public void onStateChanged(StateChangeEvent stateChangeEvent) {
- super.onStateChanged(stateChangeEvent);
-
- Style style = getWidget().getElement().getStyle();
-
- // Make sure that the controls are not clipped if visible.
- if (getState().showControls
- && (style.getHeight() == null || "".equals(style.getHeight()))) {
- if (BrowserInfo.get().isChrome()) {
- style.setHeight(32, Unit.PX);
- } else {
- style.setHeight(25, Unit.PX);
- }
- }
- }
-
- @Override
protected Widget createWidget() {
return GWT.create(VAudio.class);
}
@@ -55,4 +38,35 @@ public class AudioConnector extends MediaBaseConnector {
protected String getDefaultAltHtml() {
return "Your browser does not support the <code>audio</code> element.";
}
+
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ super.onStateChanged(stateChangeEvent);
+
+ // Opera (12.14) has a bug where an audio element w/o controls is shown
+ // as 150x300px, which is not usually desired. However, in order to show
+ // the error/alt message, we only do this in the exact situation.
+ if (BrowserInfo.get().isOpera()
+ && stateChangeEvent.hasPropertyChanged("showControls")) {
+ Style style = getWidget().getElement().getStyle();
+ if (!getState().showControls) {
+ if (isUndefinedHeight() && isUndefinedWidth()
+ && getWidget().getOffsetHeight() == 150
+ && getWidget().getOffsetWidth() == 300) {
+ // only if no size set and 150x300
+ style.setWidth(0, Unit.PX);
+ style.setHeight(0, Unit.PX);
+ }
+ } else {
+ // clear sizes if it's supposed to be undefined
+ if (isUndefinedHeight()) {
+ style.clearHeight();
+ }
+ if (isUndefinedWidth()) {
+ style.clearWidth();
+ }
+ }
+ }
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
index 014ea849a2..772419e730 100644
--- a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
+++ b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java
@@ -143,11 +143,13 @@ public class CheckBoxConnector extends AbstractFieldConnector implements
return;
}
+ getState().checked = getWidget().getValue();
+
// Add mouse details
MouseEventDetails details = MouseEventDetailsBuilder
.buildMouseEventDetails(event.getNativeEvent(), getWidget()
.getElement());
- getRpcProxy(CheckBoxServerRpc.class).setChecked(getWidget().getValue(),
+ getRpcProxy(CheckBoxServerRpc.class).setChecked(getState().checked,
details);
}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index c8210e3a09..4f0ea2de37 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -421,10 +421,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN
| Event.ONSCROLL);
- // iview is focused when created so element needs tabIndex
- // 1 due 0 is at the end of natural tabbing order
- DOM.setElementProperty(getWidget().getElement(), "tabIndex", "1");
-
RootPanel root = RootPanel.get(rootPanelId);
// Remove the v-app-loading or any splash screen added inside the div by
@@ -437,6 +433,10 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
root.add(getWidget());
+ // Set default tab index before focus call. State change handler
+ // will update this later if needed.
+ getWidget().setTabIndex(1);
+
if (applicationConnection.getConfiguration().isStandalone()) {
// set focus to iview element by default to listen possible keyboard
// shortcuts. For embedded applications this is unacceptable as we
diff --git a/common.xml b/common.xml
index f575c3606d..eceb0b9077 100644
--- a/common.xml
+++ b/common.xml
@@ -316,7 +316,7 @@
<exclude name="com/vaadin/tests/data/bean/*" />
<exclude name="com/vaadin/tests/util/*" />
<exclude name="**/VaadinClasses.java" />
- <exclude name="**TestRunner.java" />
+ <exclude name="**/*TestRunner.java" />
<exclude name="**/SQLTestsConstants.java" />
</fileset>
</batchtest>
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
new file mode 100644
index 0000000000..3264118732
--- /dev/null
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/AbstractTransactionalQuery.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.data.util.sqlcontainer.query;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+/**
+ * Common base class for database query classes that handle connections and
+ * transactions.
+ *
+ * @author Vaadin Ltd
+ * @since 6.8.9
+ */
+abstract class AbstractTransactionalQuery implements Serializable {
+
+ private JDBCConnectionPool connectionPool;
+ private transient Connection activeConnection;
+
+ AbstractTransactionalQuery() {
+ }
+
+ AbstractTransactionalQuery(JDBCConnectionPool connectionPool) {
+ this.connectionPool = connectionPool;
+ }
+
+ /**
+ * Reserves a connection with auto-commit off if no transaction is in
+ * progress.
+ *
+ * @throws IllegalStateException
+ * if a transaction is already open
+ * @throws SQLException
+ * if a connection could not be obtained or configured
+ */
+ public void beginTransaction() throws UnsupportedOperationException,
+ SQLException {
+ if (isInTransaction()) {
+ throw new IllegalStateException("A transaction is already active!");
+ }
+ activeConnection = connectionPool.reserveConnection();
+ activeConnection.setAutoCommit(false);
+ }
+
+ /**
+ * Commits (if not in auto-commit mode) and releases the active connection.
+ *
+ * @throws SQLException
+ * if not in a transaction managed by this query
+ */
+ public void commit() throws UnsupportedOperationException, SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction");
+ }
+ if (!activeConnection.getAutoCommit()) {
+ activeConnection.commit();
+ }
+ connectionPool.releaseConnection(activeConnection);
+ activeConnection = null;
+ }
+
+ /**
+ * Rolls back and releases the active connection.
+ *
+ * @throws SQLException
+ * if not in a transaction managed by this query
+ */
+ public void rollback() throws UnsupportedOperationException, SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction");
+ }
+ activeConnection.rollback();
+ connectionPool.releaseConnection(activeConnection);
+ activeConnection = null;
+ }
+
+ /**
+ * Check that a transaction is active.
+ *
+ * @throws SQLException
+ * if no active transaction
+ */
+ protected void ensureTransaction() throws SQLException {
+ if (!isInTransaction()) {
+ throw new SQLException("No active transaction!");
+ }
+ }
+
+ /**
+ * Closes a statement and a resultset, then releases the connection if it is
+ * not part of an active transaction. A failure in closing one of the
+ * parameters does not prevent closing the rest.
+ *
+ * If the statement is a {@link PreparedStatement}, its parameters are
+ * cleared prior to closing the statement.
+ *
+ * Although JDBC specification does state that closing a statement closes
+ * its result set and closing a connection closes statements and result
+ * sets, this method does try to close the result set and statement
+ * explicitly whenever not null. This can guard against bugs in certain JDBC
+ * drivers and reduce leaks in case e.g. closing the result set succeeds but
+ * closing the statement or connection fails.
+ *
+ * @param conn
+ * the connection to release
+ * @param statement
+ * the statement to close, may be null to skip closing
+ * @param rs
+ * the result set to close, may be null to skip closing
+ * @throws SQLException
+ * if closing the result set or the statement fails
+ */
+ protected void releaseConnection(Connection conn, Statement statement,
+ ResultSet rs) throws SQLException {
+ try {
+ try {
+ if (null != rs) {
+ rs.close();
+ }
+ } finally {
+ if (null != statement) {
+ if (statement instanceof PreparedStatement) {
+ try {
+ ((PreparedStatement) statement).clearParameters();
+ } catch (Exception e) {
+ // will be closed below anyway
+ }
+ }
+ statement.close();
+ }
+ }
+ } finally {
+ releaseConnection(conn);
+ }
+ }
+
+ /**
+ * Returns the currently active connection, reserves and returns a new
+ * connection if no active connection.
+ *
+ * @return previously active or newly reserved connection
+ * @throws SQLException
+ */
+ protected Connection getConnection() throws SQLException {
+ if (activeConnection != null) {
+ return activeConnection;
+ }
+ return connectionPool.reserveConnection();
+ }
+
+ protected boolean isInTransaction() {
+ return activeConnection != null;
+ }
+
+ /**
+ * Releases the connection if it is not part of an active transaction.
+ *
+ * @param conn
+ * the connection to release
+ */
+ private void releaseConnection(Connection conn) {
+ if (conn != activeConnection && conn != null) {
+ connectionPool.releaseConnection(conn);
+ }
+ }
+}
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
index 299183f5e6..6895e02147 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
@@ -34,13 +34,12 @@ import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
@SuppressWarnings("serial")
-public class FreeformQuery implements QueryDelegate {
+public class FreeformQuery extends AbstractTransactionalQuery implements
+ QueryDelegate {
FreeformQueryDelegate delegate = null;
private String queryString;
private List<String> primaryKeyColumns;
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection = null;
/**
* Prevent no-parameters instantiation of FreeformQuery
@@ -67,6 +66,7 @@ public class FreeformQuery implements QueryDelegate {
@Deprecated
public FreeformQuery(String queryString, List<String> primaryKeyColumns,
JDBCConnectionPool connectionPool) {
+ super(connectionPool);
if (primaryKeyColumns == null) {
primaryKeyColumns = new ArrayList<String>();
}
@@ -83,7 +83,6 @@ public class FreeformQuery implements QueryDelegate {
this.queryString = queryString;
this.primaryKeyColumns = Collections
.unmodifiableList(primaryKeyColumns);
- this.connectionPool = connectionPool;
}
/**
@@ -189,13 +188,6 @@ public class FreeformQuery implements QueryDelegate {
return count;
}
- private Connection getConnection() throws SQLException {
- if (activeConnection != null) {
- return activeConnection;
- }
- return connectionPool.reserveConnection();
- }
-
/**
* Fetches the results for the query. This implementation always fetches the
* entire record set, ignoring the offset and page length parameters. In
@@ -210,9 +202,7 @@ public class FreeformQuery implements QueryDelegate {
@Override
@SuppressWarnings({ "deprecation", "finally" })
public ResultSet getResults(int offset, int pagelength) throws SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction!");
- }
+ ensureTransaction();
String query = queryString;
if (delegate != null) {
/* First try using prepared statement */
@@ -220,8 +210,8 @@ public class FreeformQuery implements QueryDelegate {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getQueryStatement(offset, pagelength);
- PreparedStatement pstmt = activeConnection
- .prepareStatement(sh.getQueryString());
+ PreparedStatement pstmt = getConnection().prepareStatement(
+ sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
return pstmt.executeQuery();
} catch (UnsupportedOperationException e) {
@@ -234,7 +224,7 @@ public class FreeformQuery implements QueryDelegate {
// This is fine, we'll just use the default queryString.
}
}
- Statement statement = activeConnection.createStatement();
+ Statement statement = getConnection().createStatement();
ResultSet rs;
try {
rs = statement.executeQuery(query);
@@ -322,14 +312,14 @@ public class FreeformQuery implements QueryDelegate {
*/
@Override
public int storeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
+ if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot store items fetched with a read-only freeform query!");
}
if (delegate != null) {
- return delegate.storeRow(activeConnection, row);
+ return delegate.storeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
@@ -345,68 +335,36 @@ public class FreeformQuery implements QueryDelegate {
*/
@Override
public boolean removeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
+ if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot remove items fetched with a read-only freeform query!");
}
if (delegate != null) {
- return delegate.removeRow(activeConnection, row);
+ return delegate.removeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#beginTransaction()
- */
@Override
public synchronized void beginTransaction()
throws UnsupportedOperationException, SQLException {
- if (activeConnection != null) {
- throw new IllegalStateException("A transaction is already active!");
- }
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
+ super.beginTransaction();
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#commit()
- */
@Override
public synchronized void commit() throws UnsupportedOperationException,
SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- if (!activeConnection.getAutoCommit()) {
- activeConnection.commit();
- }
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
+ super.commit();
}
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#rollback()
- */
@Override
public synchronized void rollback() throws UnsupportedOperationException,
SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
+ super.rollback();
}
/*
@@ -492,66 +450,6 @@ public class FreeformQuery implements QueryDelegate {
return contains;
}
- /**
- * Releases the connection if it is not part of an active transaction.
- *
- * @param conn
- * the connection to release
- */
- private void releaseConnection(Connection conn) {
- if (conn != activeConnection) {
- connectionPool.releaseConnection(conn);
- }
- }
-
- /**
- * Closes a statement and a resultset, then releases the connection if it is
- * not part of an active transaction. A failure in closing one of the
- * parameters does not prevent closing the rest.
- *
- * If the statement is a {@link PreparedStatement}, its parameters are
- * cleared prior to closing the statement.
- *
- * Although JDBC specification does state that closing a statement closes
- * its result set and closing a connection closes statements and result
- * sets, this method does try to close the result set and statement
- * explicitly whenever not null. This can guard against bugs in certain JDBC
- * drivers and reduce leaks in case e.g. closing the result set succeeds but
- * closing the statement or connection fails.
- *
- * @param conn
- * the connection to release
- * @param statement
- * the statement to close, may be null to skip closing
- * @param rs
- * the result set to close, may be null to skip closing
- * @throws SQLException
- * if closing the result set or the statement fails
- */
- private void releaseConnection(Connection conn, Statement statement,
- ResultSet rs) throws SQLException {
- try {
- try {
- if (null != rs) {
- rs.close();
- }
- } finally {
- if (null != statement) {
- if (statement instanceof PreparedStatement) {
- try {
- ((PreparedStatement) statement).clearParameters();
- } catch (Exception e) {
- // will be closed below anyway
- }
- }
- statement.close();
- }
- }
- } finally {
- releaseConnection(conn);
- }
- }
-
private String modifyWhereClause(Object... keys) {
// Build the where rules for the provided keys
StringBuffer where = new StringBuffer();
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
index 63e4b3362c..caed5526e3 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
@@ -47,8 +47,8 @@ import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
@SuppressWarnings("serial")
-public class TableQuery implements QueryDelegate,
- QueryDelegate.RowIdChangeNotifier {
+public class TableQuery extends AbstractTransactionalQuery implements
+ QueryDelegate, QueryDelegate.RowIdChangeNotifier {
/** Table name, primary key column name(s) and version column name */
private String tableName;
@@ -62,18 +62,13 @@ public class TableQuery implements QueryDelegate,
/** SQLGenerator instance to use for generating queries */
private SQLGenerator sqlGenerator;
- /** Fields related to Connection and Transaction handling */
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection;
- private boolean transactionOpen;
-
/** Row ID change listeners */
private LinkedList<RowIdChangeListener> rowIdChangeListeners;
/** Row ID change events, stored until commit() is called */
private final List<RowIdChangeEvent> bufferedEvents = new ArrayList<RowIdChangeEvent>();
/** Set to true to output generated SQL Queries to System.out */
- private boolean debug = false;
+ private final boolean debug = false;
/** Prevent no-parameters instantiation of TableQuery */
@SuppressWarnings("unused")
@@ -93,6 +88,7 @@ public class TableQuery implements QueryDelegate,
*/
public TableQuery(String tableName, JDBCConnectionPool connectionPool,
SQLGenerator sqlGenerator) {
+ super(connectionPool);
if (tableName == null || tableName.trim().length() < 1
|| connectionPool == null || sqlGenerator == null) {
throw new IllegalArgumentException(
@@ -100,7 +96,6 @@ public class TableQuery implements QueryDelegate,
}
this.tableName = tableName;
this.sqlGenerator = sqlGenerator;
- this.connectionPool = connectionPool;
fetchMetaData();
}
@@ -129,17 +124,27 @@ public class TableQuery implements QueryDelegate,
StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
filters, null, 0, 0, "COUNT(*)");
boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
+ if (!isInTransaction()) {
shouldCloseTransaction = true;
beginTransaction();
}
- ResultSet r = executeQuery(sh);
- r.next();
- int count = r.getInt(1);
- r.getStatement().close();
- r.close();
- if (shouldCloseTransaction) {
- commit();
+ ResultSet r = null;
+ int count = -1;
+ try {
+ r = executeQuery(sh);
+ r.next();
+ count = r.getInt(1);
+ } finally {
+ try {
+ if (r != null) {
+ releaseConnection(r.getStatement().getConnection(),
+ r.getStatement(), r);
+ }
+ } finally {
+ if (shouldCloseTransaction) {
+ commit();
+ }
+ }
}
return count;
}
@@ -240,28 +245,30 @@ public class TableQuery implements QueryDelegate,
setVersionColumnFlagInProperty(row);
/* Generate query */
StatementHelper sh = sqlGenerator.generateInsertQuery(tableName, row);
- PreparedStatement pstmt = activeConnection.prepareStatement(
- sh.getQueryString(), primaryKeyColumns.toArray(new String[0]));
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
- int result = pstmt.executeUpdate();
- if (result > 0) {
- /*
- * If affected rows exist, we'll get the new RowId, commit the
- * transaction and return the new RowId.
- */
- ResultSet generatedKeys = pstmt.getGeneratedKeys();
- RowId newId = getNewRowId(row, generatedKeys);
- generatedKeys.close();
- pstmt.clearParameters();
- pstmt.close();
+ Connection connection = null;
+ PreparedStatement pstmt = null;
+ ResultSet generatedKeys = null;
+ connection = getConnection();
+ try {
+ pstmt = connection.prepareStatement(sh.getQueryString(),
+ primaryKeyColumns.toArray(new String[0]));
+ sh.setParameterValuesToStatement(pstmt);
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
+ int result = pstmt.executeUpdate();
+ RowId newId = null;
+ if (result > 0) {
+ /*
+ * If affected rows exist, we'll get the new RowId, commit the
+ * transaction and return the new RowId.
+ */
+ generatedKeys = pstmt.getGeneratedKeys();
+ newId = getNewRowId(row, generatedKeys);
+ }
+ // transaction has to be closed in any case
commit();
return newId;
- } else {
- pstmt.clearParameters();
- pstmt.close();
- /* On failure return null */
- return null;
+ } finally {
+ releaseConnection(connection, pstmt, generatedKeys);
}
}
@@ -307,14 +314,8 @@ public class TableQuery implements QueryDelegate,
@Override
public void beginTransaction() throws UnsupportedOperationException,
SQLException {
- if (transactionOpen && activeConnection != null) {
- throw new IllegalStateException();
- }
-
getLogger().log(Level.FINE, "DB -> begin transaction");
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
- transactionOpen = true;
+ super.beginTransaction();
}
/*
@@ -324,14 +325,8 @@ public class TableQuery implements QueryDelegate,
*/
@Override
public void commit() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> commit");
- activeConnection.commit();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
+ getLogger().log(Level.FINE, "DB -> commit");
+ super.commit();
/* Handle firing row ID change events */
RowIdChangeEvent[] unFiredEvents = bufferedEvents
@@ -353,14 +348,8 @@ public class TableQuery implements QueryDelegate,
*/
@Override
public void rollback() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> rollback");
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
+ getLogger().log(Level.FINE, "DB -> rollback");
+ super.rollback();
}
/*
@@ -402,16 +391,18 @@ public class TableQuery implements QueryDelegate,
* @throws SQLException
*/
private ResultSet executeQuery(StatementHelper sh) throws SQLException {
- Connection c = null;
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- throw new SQLException("No active transaction!");
+ ensureTransaction();
+ Connection connection = getConnection();
+ PreparedStatement pstmt = null;
+ try {
+ pstmt = connection.prepareStatement(sh.getQueryString());
+ sh.setParameterValuesToStatement(pstmt);
+ getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
+ return pstmt.executeQuery();
+ } catch (SQLException e) {
+ releaseConnection(null, pstmt, null);
+ throw e;
}
- PreparedStatement pstmt = c.prepareStatement(sh.getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
- return pstmt.executeQuery();
}
/**
@@ -426,27 +417,17 @@ public class TableQuery implements QueryDelegate,
* @throws SQLException
*/
private int executeUpdate(StatementHelper sh) throws SQLException {
- Connection c = null;
PreparedStatement pstmt = null;
+ Connection connection = null;
try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString());
+ connection = getConnection();
+ pstmt = connection.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
int retval = pstmt.executeUpdate();
return retval;
} finally {
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
+ releaseConnection(connection, pstmt, null);
}
}
@@ -467,16 +448,12 @@ public class TableQuery implements QueryDelegate,
*/
private int executeUpdateReturnKeys(StatementHelper sh, RowItem row)
throws SQLException {
- Connection c = null;
PreparedStatement pstmt = null;
ResultSet genKeys = null;
+ Connection connection = null;
try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString(),
+ connection = getConnection();
+ pstmt = connection.prepareStatement(sh.getQueryString(),
primaryKeyColumns.toArray(new String[0]));
sh.setParameterValuesToStatement(pstmt);
getLogger().log(Level.FINE, "DB -> {0}", sh.getQueryString());
@@ -486,16 +463,7 @@ public class TableQuery implements QueryDelegate,
bufferedEvents.add(new RowIdChangeEvent(row.getId(), newId));
return result;
} finally {
- if (genKeys != null) {
- genKeys.close();
- }
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
+ releaseConnection(connection, pstmt, genKeys);
}
}
@@ -505,13 +473,15 @@ public class TableQuery implements QueryDelegate,
* Also tries to get the escape string to be used in search strings.
*/
private void fetchMetaData() {
- Connection c = null;
+ Connection connection = null;
+ ResultSet rs = null;
+ ResultSet tables = null;
try {
- c = connectionPool.reserveConnection();
- DatabaseMetaData dbmd = c.getMetaData();
+ connection = getConnection();
+ DatabaseMetaData dbmd = connection.getMetaData();
if (dbmd != null) {
tableName = SQLUtil.escapeSQL(tableName);
- ResultSet tables = dbmd.getTables(null, null, tableName, null);
+ tables = dbmd.getTables(null, null, tableName, null);
if (!tables.next()) {
tables = dbmd.getTables(null, null,
tableName.toUpperCase(), null);
@@ -525,7 +495,7 @@ public class TableQuery implements QueryDelegate,
}
}
tables.close();
- ResultSet rs = dbmd.getPrimaryKeys(null, null, tableName);
+ rs = dbmd.getPrimaryKeys(null, null, tableName);
List<String> names = new ArrayList<String>();
while (rs.next()) {
names.add(rs.getString("COLUMN_NAME"));
@@ -554,7 +524,15 @@ public class TableQuery implements QueryDelegate,
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
- connectionPool.releaseConnection(c);
+ try {
+ releaseConnection(connection, null, rs);
+ } catch (SQLException ignore) {
+ } finally {
+ try {
+ tables.close();
+ } catch (SQLException ignore) {
+ }
+ }
}
}
@@ -648,7 +626,7 @@ public class TableQuery implements QueryDelegate,
filtersAndKeys, orderBys, 0, 0, "*");
boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
+ if (!isInTransaction()) {
shouldCloseTransaction = true;
beginTransaction();
}
@@ -658,14 +636,15 @@ public class TableQuery implements QueryDelegate,
boolean contains = rs.next();
return contains;
} finally {
- if (rs != null) {
- if (rs.getStatement() != null) {
- rs.getStatement().close();
+ try {
+ if (rs != null) {
+ releaseConnection(rs.getStatement().getConnection(),
+ rs.getStatement(), rs);
+ }
+ } finally {
+ if (shouldCloseTransaction) {
+ commit();
}
- rs.close();
- }
- if (shouldCloseTransaction) {
- commit();
}
}
}
diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/com/vaadin/ui/AbstractComponentContainer.java
index ca83286311..4aacad680f 100644
--- a/server/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/server/src/com/vaadin/ui/AbstractComponentContainer.java
@@ -339,6 +339,12 @@ public abstract class AbstractComponentContainer extends AbstractComponent
true);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated As of 7.0, use {@link #iterator()} instead.
+ */
+ @Deprecated
@Override
public Iterator<Component> getComponentIterator() {
return iterator();
diff --git a/server/src/com/vaadin/ui/CheckBox.java b/server/src/com/vaadin/ui/CheckBox.java
index 0ace0a4f26..ac33f5e410 100644
--- a/server/src/com/vaadin/ui/CheckBox.java
+++ b/server/src/com/vaadin/ui/CheckBox.java
@@ -16,6 +16,8 @@
package com.vaadin.ui;
+import org.json.JSONException;
+
import com.vaadin.data.Property;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
@@ -37,6 +39,21 @@ public class CheckBox extends AbstractField<Boolean> {
return;
}
+ /*
+ * Client side updates the state before sending the event so we need
+ * to make sure the cached state is updated to match the client. If
+ * we do not do this, a reverting setValue() call in a listener will
+ * not cause the new state to be sent to the client.
+ *
+ * See #11028, #10030.
+ */
+ try {
+ getUI().getConnectorTracker().getDiffState(CheckBox.this)
+ .put("checked", checked);
+ } catch (JSONException e) {
+ throw new RuntimeException(e);
+ }
+
final Boolean oldValue = getValue();
final Boolean newValue = checked;
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index 641c0ff1f6..3d7cb42050 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -396,10 +396,14 @@ public class Table extends AbstractSelect implements Action.Container,
private HashMap<Object, Align> columnAlignments = new HashMap<Object, Align>();
/**
- * Holds column widths in pixels (Integer) or expand ratios (Float) for
- * visible columns (by propertyId).
+ * Holds column widths in pixels for visible columns (by propertyId).
*/
- private final HashMap<Object, Object> columnWidths = new HashMap<Object, Object>();
+ private final HashMap<Object, Integer> columnWidths = new HashMap<Object, Integer>();
+
+ /**
+ * Holds column expand rations for visible columns (by propertyId).
+ */
+ private final HashMap<Object, Float> columnExpandRatios = new HashMap<Object, Float>();
/**
* Holds column generators
@@ -886,10 +890,14 @@ public class Table extends AbstractSelect implements Action.Container,
// id to store the width of the row header.
propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
}
+
+ // Setting column width should remove any expand ratios as well
+ columnExpandRatios.remove(propertyId);
+
if (width < 0) {
columnWidths.remove(propertyId);
} else {
- columnWidths.put(propertyId, Integer.valueOf(width));
+ columnWidths.put(propertyId, width);
}
markAsDirty();
}
@@ -930,21 +938,39 @@ public class Table extends AbstractSelect implements Action.Container,
* the expandRatio used to divide excess space for this column
*/
public void setColumnExpandRatio(Object propertyId, float expandRatio) {
+ if (propertyId == null) {
+ // Since propertyId is null, this is the row header. Use the magic
+ // id to store the width of the row header.
+ propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
+ }
+
+ // Setting the column expand ratio should remove and defined column
+ // width
+ columnWidths.remove(propertyId);
+
if (expandRatio < 0) {
- columnWidths.remove(propertyId);
+ columnExpandRatios.remove(propertyId);
} else {
- columnWidths.put(propertyId, new Float(expandRatio));
+ columnExpandRatios.put(propertyId, expandRatio);
}
+
+ requestRepaint();
}
+ /**
+ * Gets the column expand ratio for a columnd. See
+ * {@link #setColumnExpandRatio(Object, float)}
+ *
+ * @param propertyId
+ * columns property id
+ * @return the expandRatio used to divide excess space for this column
+ */
public float getColumnExpandRatio(Object propertyId) {
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Float)) {
+ final Float width = columnExpandRatios.get(propertyId);
+ if (width == null) {
return -1;
}
- final Float value = (Float) width;
- return value.floatValue();
-
+ return width.floatValue();
}
/**
@@ -959,12 +985,11 @@ public class Table extends AbstractSelect implements Action.Container,
// id to retrieve the width of the row header.
propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
}
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Integer)) {
+ final Integer width = columnWidths.get(propertyId);
+ if (width == null) {
return -1;
}
- final Integer value = (Integer) width;
- return value.intValue();
+ return width.intValue();
}
/**
@@ -3434,6 +3459,7 @@ public class Table extends AbstractSelect implements Action.Container,
target.startTag("column");
target.addAttribute("cid", ROW_HEADER_COLUMN_KEY);
paintColumnWidth(target, ROW_HEADER_FAKE_PROPERTY_ID);
+ paintColumnExpandRatio(target, ROW_HEADER_FAKE_PROPERTY_ID);
target.endTag("column");
}
final Collection<?> sortables = getSortableContainerPropertyIds();
@@ -3461,6 +3487,7 @@ public class Table extends AbstractSelect implements Action.Container,
.toString());
}
paintColumnWidth(target, colId);
+ paintColumnExpandRatio(target, colId);
target.endTag("column");
}
}
@@ -3706,12 +3733,14 @@ public class Table extends AbstractSelect implements Action.Container,
private void paintColumnWidth(PaintTarget target, final Object columnId)
throws PaintException {
if (columnWidths.containsKey(columnId)) {
- if (getColumnWidth(columnId) > -1) {
- target.addAttribute("width",
- String.valueOf(getColumnWidth(columnId)));
- } else {
- target.addAttribute("er", getColumnExpandRatio(columnId));
- }
+ target.addAttribute("width", getColumnWidth(columnId));
+ }
+ }
+
+ private void paintColumnExpandRatio(PaintTarget target,
+ final Object columnId) throws PaintException {
+ if (columnExpandRatios.containsKey(columnId)) {
+ target.addAttribute("er", getColumnExpandRatio(columnId));
}
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index d12c8d89c9..796d1f08ea 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -78,7 +78,7 @@ import com.vaadin.util.CurrentInstance;
* @since 7.0
*/
public abstract class UI extends AbstractSingleComponentContainer implements
- Action.Container, Action.Notifier, LegacyComponent {
+ Action.Container, Action.Notifier, LegacyComponent, Focusable {
/**
* The application to which this UI belongs
@@ -184,6 +184,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
@Override
+ protected UIState getState(boolean markAsDirty) {
+ return (UIState) super.getState(markAsDirty);
+ }
+
+ @Override
public Class<? extends UIState> getStateType() {
// This is a workaround for a problem with creating the correct state
// object during build
@@ -1039,4 +1044,14 @@ public abstract class UI extends AbstractSingleComponentContainer implements
}
super.setContent(content);
}
+
+ @Override
+ public void setTabIndex(int tabIndex) {
+ getState().tabIndex = tabIndex;
+ }
+
+ @Override
+ public int getTabIndex() {
+ return getState(false).tabIndex;
+ }
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java b/server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java
index c1d7653c01..634e6a86f3 100644
--- a/server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/tree/TreeTest.java
@@ -1,24 +1,31 @@
package com.vaadin.tests.server.component.tree;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
import java.lang.reflect.Field;
import java.util.HashSet;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
import com.vaadin.data.Container;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Tree;
-public class TreeTest extends TestCase {
+public class TreeTest {
private Tree tree;
private Tree tree2;
private Tree tree3;
private Tree tree4;
- @Override
- protected void setUp() {
+ @Before
+ public void setUp() {
tree = new Tree();
tree.addItem("parent");
tree.addItem("child");
@@ -44,6 +51,7 @@ public class TreeTest extends TestCase {
tree4.setParent("child", "parent");
}
+ @Test
public void testRemoveChildren() {
assertTrue(tree.hasChildren("parent"));
tree.removeItem("child");
@@ -62,6 +70,7 @@ public class TreeTest extends TestCase {
assertFalse(tree4.hasChildren("parent"));
}
+ @Test
public void testContainerTypeIsHierarchical() {
assertTrue(HierarchicalContainer.class.isAssignableFrom(tree
.getContainerDataSource().getClass()));
@@ -75,6 +84,11 @@ public class TreeTest extends TestCase {
.getContainerDataSource().getClass()));
}
+ @Ignore("This test tests that item ids which are removed are also "
+ + "removed from the expand list to prevent a memory leak. "
+ + "Fixing the memory leak cannot be done without changing some API (see #11053) "
+ + "so ignoring this test for the 7.0.x series.")
+ @Test
public void testRemoveExpandedItems() throws Exception {
tree.expandItem("parent");
tree.expandItem("child");
@@ -113,6 +127,7 @@ public class TreeTest extends TestCase {
assertNull(expandedItemId);
}
+ @Test
public void testRemoveExpandedItemsOnContainerChange() throws Exception {
tree.expandItem("parent");
tree.expandItem("child");
diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java
index aa862ae31a..9abaf47f4b 100644
--- a/shared/src/com/vaadin/shared/ui/ui/UIState.java
+++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java
@@ -15,10 +15,12 @@
*/
package com.vaadin.shared.ui.ui;
-import com.vaadin.shared.AbstractComponentState;
+import com.vaadin.shared.ui.TabIndexState;
-public class UIState extends AbstractComponentState {
+public class UIState extends TabIndexState {
{
primaryStyleName = "v-ui";
+ // Default is 1 for legacy reasons
+ tabIndex = 1;
}
} \ No newline at end of file
diff --git a/uitest/integration-testscripts/GateIn-3/integration-test-GateIn-3.1.0-portlet2.html b/uitest/integration-testscripts/GateIn-3/integration-test-GateIn-3.1.0-portlet2.html
index 4bc3e6a2cf..5d2d4c3445 100644
--- a/uitest/integration-testscripts/GateIn-3/integration-test-GateIn-3.1.0-portlet2.html
+++ b/uitest/integration-testscripts/GateIn-3/integration-test-GateIn-3.1.0-portlet2.html
@@ -17,11 +17,6 @@
<td></td>
</tr>
<tr>
- <td>setSpeed</td>
- <td>100</td>
- <td>100</td>
-</tr>
-<tr>
<td>mouseClickAndWait</td>
<td>link=Administrator</td>
<td>27,7</td>
@@ -32,24 +27,94 @@
<td>93,13</td>
</tr>
<tr>
- <td>expectDialog</td>
- <td>//div[2]/div[2]/div[1]/div[1]/div[2]</td>
- <td>73,18</td>
+ <td>mouseClick</td>
+ <td>link=Portlet</td>
+ <td>33,11</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Vaadin Portlet 2.0 Test</td>
+ <td>59,9</td>
</tr>
<tr>
- <td>assertConfirmation</td>
- <td>This action will automatically create categories and import all the gadgets and portlets on it.</td>
+ <td>mouseClick</td>
+ <td>link=Vaadin Portlet 2.0 Test</td>
+ <td>59,9</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Click here to add into categories</td>
<td></td>
</tr>
<tr>
+ <td>mouseClick</td>
+ <td>link=Click here to add into categories</td>
+ <td>48,3</td>
+</tr>
+<tr>
<td>waitForElementPresent</td>
- <td>link=demo</td>
+ <td>name=category_Gadgets</td>
<td></td>
</tr>
<tr>
- <td>mouseClickAndWait</td>
- <td>link=Home</td>
- <td>65,18</td>
+ <td>mouseClick</td>
+ <td>name=category_Gadgets</td>
+ <td>10,16</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Save</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>link=Save</td>
+ <td>4,6</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Vaadin Liferay Theme</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>link=Vaadin Liferay Theme</td>
+ <td>64,13</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Click here to add into categories</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>link=Click here to add into categories</td>
+ <td>96,9</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>name=category_Gadgets</td>
+ <td>7,12</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>name=category_Gadgets</td>
+ <td>7,12</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Save</td>
+ <td>4,6</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>link=Save</td>
+ <td>4,6</td>
+</tr>
+<tr>
+ <td>waitForElementPresent</td>
+ <td>link=Add New Page</td>
+ <td>55,11</td>
</tr>
<tr>
<td>mouseClick</td>
@@ -86,24 +151,15 @@
<td>//div[@id='UIPageCreationWizard']/div/div[3]/div/div/div/div[2]/div/table/tbody/tr/td/div[2]/div/div/div</td>
<td>21,13</td>
</tr>
+<!--Drag JSR286 test portlet to page-->
<tr>
<td>waitForElementPresent</td>
- <td>//div[@id='UIPageEditor']/div[1]/div/div/div/div[2]</td>
- <td></td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>//div[@onclick=&quot;javascript:ajaxGet('/portal/private/classic/home?portal:componentId=UIApplicationList&amp;portal:action=SelectCategory&amp;objectId=demo&amp;ajaxRequest=true')&quot;]</td>
- <td>51,11</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>300</td>
+ <td>//div[@id='Gadgets/JSR286TestPortlet']/div/div/div/div</td>
<td></td>
</tr>
<tr>
<td>drag</td>
- <td>//div[@id='demo/JSR286TestPortlet']/div/div/div[1]/div[2]</td>
+ <td>//div[@id='Gadgets/JSR286TestPortlet']/div/div/div/div</td>
<td></td>
</tr>
<tr>
@@ -112,49 +168,25 @@
<td>113,9</td>
</tr>
<tr>
- <td>mouseClickAndWait</td>
- <td>//a[@onclick='eXo.core.DOMUtil.disableOnClick(this);']</td>
- <td>13,5</td>
-</tr>
-<tr>
- <td>mouseClickAndWait</td>
- <td>//div[@id='UIPage']/div/div/div[2]/div/div/div/div/div/div/div[2]/div[5]/div/a</td>
- <td>10,10</td>
-</tr>
-<tr>
- <td>closeNotification</td>
- <td>//body/div[2]</td>
- <td>0,0</td>
-</tr>
-<tr>
- <td>pause</td>
- <td>500</td>
+ <td>waitForTextPresent</td>
+ <td>Vaadin Portlet 2.0 Test</td>
<td></td>
</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>Edit_mode</td>
-</tr>
+<!--Switch to view mode-->
<tr>
<td>mouseClickAndWait</td>
- <td>//div[@id='UIPage']/div/div/div[2]/div/div/div/div/div/div/div[2]/div[5]/div/a</td>
- <td>15,8</td>
-</tr>
-<tr>
- <td>closeNotification</td>
- <td>//body/div[2]</td>
- <td>0,0</td>
+ <td>//a[@onclick='eXo.core.DOMUtil.disableOnClick(this);']</td>
+ <td>13,5</td>
</tr>
<tr>
- <td>pause</td>
- <td>500</td>
+ <td>waitForElementPresent</td>
+ <td>//div[2]/div/div[2]/img</td>
<td></td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
- <td>done</td>
+ <td>view</td>
</tr>
</tbody></table>
</body>
diff --git a/uitest/integration-testscripts/Liferay-6/integration-test-liferay-6.0.5.html b/uitest/integration-testscripts/Liferay-6/integration-test-liferay-6.0.5.html
index 88cac6cd74..037ce23865 100644
--- a/uitest/integration-testscripts/Liferay-6/integration-test-liferay-6.0.5.html
+++ b/uitest/integration-testscripts/Liferay-6/integration-test-liferay-6.0.5.html
@@ -36,8 +36,6 @@
<td>//input[@value='Sign In']</td>
<td>43,18</td>
</tr>
-
-<!-- -->
<tr>
<td>mouseClickAndWait</td>
<td>//input[@type='submit']</td>
@@ -144,19 +142,34 @@
<td>10,10</td>
</tr>
<tr>
- <td>pause</td>
- <td>5000</td>
+ <td>waitForTextPresent</td>
+ <td>Normal Label</td>
<td></td>
</tr>
<tr>
- <td>waitForVaadin</td>
+ <td>screenCapture</td>
+ <td></td>
+ <td>theme</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>//td[3]/div/div/div</td>
+ <td>22,7</td>
+</tr>
+<tr>
+ <td>assertTextPresent</td>
+ <td>Normal TextField</td>
<td></td>
+</tr>
+<tr>
+ <td>assertTextPresent</td>
+ <td>Normal TextArea</td>
<td></td>
</tr>
<tr>
- <td>screenCapture</td>
+ <td>assertTextNotPresent</td>
+ <td>Normal Label</td>
<td></td>
- <td>theme</td>
</tr>
</tbody></table>
</body>
diff --git a/uitest/integration_base_files/base.xml b/uitest/integration_base_files/base.xml
index f9c2ff3d6b..5196aecfa9 100644
--- a/uitest/integration_base_files/base.xml
+++ b/uitest/integration_base_files/base.xml
@@ -28,6 +28,20 @@
</target>
<target name="deployStatic">
+ <unzip src="${war}" dest="${staticDeployDir}/tmp-unpack-jar/">
+ <patternset>
+ <include name="WEB-INF/lib/*.jar" />
+ </patternset>
+ </unzip>
+ <unzip dest="${staticDeployDir}">
+ <fileset dir="${staticDeployDir}/tmp-unpack-jar/WEB-INF/lib" includes="*.jar" />
+
+ <patternset>
+ <include name="VAADIN/**" />
+ </patternset>
+ </unzip>
+ <delete dir="${staticDeployDir}/tmp-unpack-jar/" />
+
<unzip src="${war}" dest="${staticDeployDir}">
<patternset>
<include name="VAADIN/**" />
diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestUIWithLog.java b/uitest/src/com/vaadin/tests/components/AbstractTestUIWithLog.java
new file mode 100644
index 0000000000..cace7c3404
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/AbstractTestUIWithLog.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.VerticalLayout;
+
+public abstract class AbstractTestUIWithLog extends AbstractTestUI {
+
+ protected Log log = new Log(5);
+
+ @Override
+ public void init(VaadinRequest request) {
+ super.init(request);
+ ((VerticalLayout) getContent()).addComponent(log, 0);
+ }
+
+ protected void log(String message) {
+ log.log(message);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/TestBase.java b/uitest/src/com/vaadin/tests/components/TestBase.java
index d267d80669..15f39f6e5d 100644
--- a/uitest/src/com/vaadin/tests/components/TestBase.java
+++ b/uitest/src/com/vaadin/tests/components/TestBase.java
@@ -6,6 +6,12 @@ import com.vaadin.ui.Label;
import com.vaadin.ui.LegacyWindow;
import com.vaadin.ui.VerticalLayout;
+/**
+ *
+ * @deprecated Use {@link AbstractTestUI} or {@link AbstractTestUIWithLog}
+ * instead. TestBase is a LegacyApplication
+ */
+@Deprecated
public abstract class TestBase extends AbstractTestCase {
@Override
diff --git a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.html b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.html
new file mode 100644
index 0000000000..ea5849f99f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.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="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/com.vaadin.tests.components.checkbox.CheckBoxRevertValueChange?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VCheckBox[0]/domChild[0]</td>
+ <td>10,5</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::PID_SLog_row_0</td>
+ <td>1. I said no checking!</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VCheckBox[0]/domChild[0]</td>
+ <td>off</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VCheckBox[0]/domChild[1]</td>
+ <td>93,10</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::PID_SLog_row_0</td>
+ <td>2. I said no checking!</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VCheckBox[0]/domChild[0]</td>
+ <td>off</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>5,8</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::PID_SLog_row_0</td>
+ <td>3. I said no unchecking!</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>on</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[1]</td>
+ <td>78,12</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::PID_SLog_row_0</td>
+ <td>4. I said no unchecking!</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentscheckboxCheckBoxRevertValueChange::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>on</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.java b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.java
new file mode 100644
index 0000000000..5b086fb935
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRevertValueChange.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.checkbox;
+
+import com.vaadin.annotations.PreserveOnRefresh;
+import com.vaadin.data.Property;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.CheckBox;
+
+@PreserveOnRefresh
+public class CheckBoxRevertValueChange extends AbstractTestUIWithLog {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final CheckBox alwaysUnchecked = new CheckBox("You may not check me");
+ alwaysUnchecked
+ .addValueChangeListener(new Property.ValueChangeListener() {
+ public void valueChange(Property.ValueChangeEvent event) {
+ if (alwaysUnchecked.getValue()) {
+ log("I said no checking!");
+ alwaysUnchecked.setValue(false);
+ }
+ }
+ });
+ final CheckBox alwaysChecked = new CheckBox("You may not uncheck me");
+ alwaysChecked.setValue(true);
+ alwaysChecked
+ .addValueChangeListener(new Property.ValueChangeListener() {
+ public void valueChange(Property.ValueChangeEvent event) {
+ if (!alwaysChecked.getValue()) {
+ log("I said no unchecking!");
+ alwaysChecked.setValue(true);
+ }
+ }
+ });
+
+ addComponent(alwaysUnchecked);
+ addComponent(alwaysChecked);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Ensure checking of a checkbox can be reverted on the server side without making the client go out of sync";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11028;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/media/AudioTest.html b/uitest/src/com/vaadin/tests/components/media/AudioTest.html
new file mode 100644
index 0000000000..8425cad38a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/AudioTest.html
@@ -0,0 +1,66 @@
+<?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>AudioTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">AudioTest</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/AudioTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>3000</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>shortAtEndUnmuted</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runAudioTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VCheckBox[0]/domChild[0]</td>
+ <td>11,7</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runAudioTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VCheckBox[0]/domChild[0]</td>
+ <td>6,7</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runAudioTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>5000</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>longerAtEndMuted</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runAudioTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+ <td>69,9</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>controlsHidden</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/media/AudioTest.java b/uitest/src/com/vaadin/tests/components/media/AudioTest.java
new file mode 100644
index 0000000000..28d1a7716f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/AudioTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.tests.components.media;
+
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.server.ClassResource;
+import com.vaadin.server.Resource;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Audio;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.CheckBox;
+
+public class AudioTest extends TestBase {
+
+ @Override
+ protected void setup() {
+
+ // Public domain sounds from pdsounds.org 27.2.2013
+
+ final Resource[] s1 = { new ClassResource(getClass(), "bip.mp3"),
+ new ClassResource(getClass(), "bip.ogg") };
+ final Resource[] s2 = {
+ new ClassResource(getClass(), "toyphone_dialling.mp3"),
+ new ClassResource(getClass(), "toyphone_dialling.ogg") };
+
+ final Audio audio = new Audio();
+
+ audio.setSources(s1);
+ audio.setShowControls(true);
+ audio.setHtmlContentAllowed(true);
+ audio.setAltText("Can't <b>play</b> media");
+ audio.setAutoplay(true);
+
+ addComponent(audio);
+
+ CheckBox checkBox = new CheckBox("Show controls",
+ new MethodProperty<Boolean>(audio, "showControls"));
+ addComponent(checkBox);
+ checkBox = new CheckBox("HtmlContentAllowed",
+ new MethodProperty<Boolean>(audio, "htmlContentAllowed"));
+ addComponent(checkBox);
+ checkBox = new CheckBox("muted", new MethodProperty<Boolean>(audio,
+ "muted"));
+ addComponent(checkBox);
+ checkBox = new CheckBox("autoplay", new MethodProperty<Boolean>(audio,
+ "autoplay"));
+ addComponent(checkBox);
+
+ Button b = new Button("Change", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ audio.setSources(s2);
+ }
+ });
+ addComponent(b);
+ getLayout().setHeight("400px");
+ getLayout().setExpandRatio(b, 1.0f);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Should autoplay, manipulating checkboxes should do appropriate thing, button changes file.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11160;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/media/bip.mp3 b/uitest/src/com/vaadin/tests/components/media/bip.mp3
new file mode 100644
index 0000000000..2c7e790cf7
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/bip.mp3
Binary files differ
diff --git a/uitest/src/com/vaadin/tests/components/media/bip.ogg b/uitest/src/com/vaadin/tests/components/media/bip.ogg
new file mode 100644
index 0000000000..4e5014d92f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/bip.ogg
Binary files differ
diff --git a/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.mp3 b/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.mp3
new file mode 100644
index 0000000000..1788026856
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.mp3
Binary files differ
diff --git a/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.ogg b/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.ogg
new file mode 100644
index 0000000000..a042da5795
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/media/toyphone_dialling.ogg
Binary files differ
diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.html b/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.html
new file mode 100644
index 0000000000..75d98ce2e6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.html
@@ -0,0 +1,83 @@
+<?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/com.vaadin.tests.components.table.TableColumnWidthsAndExpandRatios?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>initial-all-columns-undefined</td>
+</tr>
+<!--Resize column 1 making it defined size-->
+<tr>
+ <td>dragAndDrop</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>-300,0</td>
+</tr>
+<!--Resize column 2 making it defined size-->
+<tr>
+ <td>dragAndDrop</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td>
+ <td>-300,0</td>
+</tr>
+<!--Resize column 3 making it defined size-->
+<tr>
+ <td>dragAndDrop</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]</td>
+ <td>-300,0</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>columns-defined-width</td>
+</tr>
+<!--Reset column 1 width-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VNativeButton[0]</td>
+ <td>114,4</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>column1-undefined</td>
+</tr>
+<!--Reset column2 width-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VNativeButton[0]</td>
+ <td>98,13</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>column2-undefined</td>
+</tr>
+<!--Reset column 3 width-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableColumnWidthsAndExpandRatios::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VNativeButton[0]</td>
+ <td>40,10</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>columns-undefined-width</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.java b/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.java
new file mode 100644
index 0000000000..747c99468f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableColumnWidthsAndExpandRatios.java
@@ -0,0 +1,57 @@
+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.HorizontalLayout;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.Table;
+
+public class TableColumnWidthsAndExpandRatios extends TestBase {
+
+ @Override
+ protected void setup() {
+ getLayout().setSizeFull();
+
+ final Table table = new Table();
+ table.setSizeFull();
+
+ table.addContainerProperty("column1", String.class, "Humpty");
+ table.addContainerProperty("column2", String.class, "Dumpty");
+ table.addContainerProperty("column3", String.class, "Doe");
+
+ for (int row = 0; row < 100; row++) {
+ table.addItem();
+ }
+
+ HorizontalLayout buttons = new HorizontalLayout();
+ for (Object col : table.getContainerPropertyIds()) {
+ buttons.addComponent(createResetButton(col, table));
+ }
+
+ addComponent(table);
+ addComponent(buttons);
+ }
+
+ private NativeButton createResetButton(final Object property,
+ final Table table) {
+ return new NativeButton("Reset " + property + " width",
+ new Button.ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ table.setColumnWidth(property, -1);
+ }
+ });
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Changing column width to -1 should remove any previous size measurements";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 7922;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.html b/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.html
new file mode 100644
index 0000000000..9eaa1ceada
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.html
@@ -0,0 +1,169 @@
+<?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/com.vaadin.tests.components.textarea.ScrollCursor?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td>
+ <td>191,94</td>
+</tr>
+<tr>
+<!-- set begin position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position-->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>wrap-start</td>
+</tr>
+<tr>
+<!-- set middle position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position-->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>wrap-middle</td>
+</tr>
+<tr>
+<!-- set end position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position-->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>wrap-end</td>
+</tr>
+<tr>
+<!-- set start position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position : check that scrolling works from the end to the beginning-->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>wrap-end-start</td>
+</tr>
+<tr>
+<!-- set no wrap -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set start position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>nowrap-start</td>
+</tr>
+<tr>
+<!-- set middle position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>nowrap-middle</td>
+</tr>
+<tr>
+<!-- set end position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/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>nowrap-end</td>
+</tr>
+<tr>
+<!-- set start position value -->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+<!-- set cursor position : check scrolling from the end to the beginning-->
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaScrollCursor::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>nowrap-end-start</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.java b/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.java
new file mode 100644
index 0000000000..c95731d94f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textarea/ScrollCursor.java
@@ -0,0 +1,89 @@
+package com.vaadin.tests.components.textarea;
+
+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.TextArea;
+
+/**
+ * @author denis
+ *
+ */
+public class ScrollCursor extends TestBase {
+
+ private TextArea textArea;
+ private int position;
+
+ @Override
+ protected void setup() {
+ textArea = new TextArea();
+ textArea.setValue("saddddddddddd fdgdfgfdgfd\n"
+ + "aasddddddddddd\n" + "dsaffffffdsf\n" + "sdf\n"
+ + "dsfsdfsdfsdfsd\n\n" + "ffffffffffffffffffff\n"
+ + "sdfdsfdsfsdfsdfsd xxxxxxxxxxxxxxxx\n" + "sdgfsd\n"
+ + "dsf\n" + "ds\n" + "fds\n" + "fds\nfs");
+ addComponent(textArea);
+ Button button = new Button("Scroll");
+ button.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ textArea.setCursorPosition(getPosition());
+ }
+ });
+ Button wrap = new Button("Set wrap");
+ wrap.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ textArea.setWordwrap(false);
+ }
+ });
+
+ Button toBegin = new Button("To begin");
+ toBegin.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ position = 3;
+ }
+ });
+
+ Button toMiddle = new Button("To middle");
+ toMiddle.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ position = 130;
+ }
+ });
+
+ Button toEnd = new Button("To end");
+ toEnd.addListener(new ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ position = textArea.getValue().toString().length();
+ }
+ });
+
+ addComponent(button);
+ addComponent(wrap);
+ addComponent(toBegin);
+ addComponent(toMiddle);
+ addComponent(toEnd);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Tests scrolling for TextArea with different word wrapping settings. "
+ + "Sets cursor position at the beginning, middle and the end "
+ + "of text and checks textarea is scrolled.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 8769;
+ }
+
+ private int getPosition() {
+ return position;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/UITabIndex.html b/uitest/src/com/vaadin/tests/components/ui/UITabIndex.html
new file mode 100644
index 0000000000..fa083f1489
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/UITabIndex.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="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/com.vaadin.tests.components.ui.UITabIndex?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertAttribute</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::@tabIndex</td>
+ <td>1</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertAttribute</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::@tabIndex</td>
+ <td>-1</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertAttribute</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::@tabIndex</td>
+ <td>0</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertAttribute</td>
+ <td>vaadin=runcomvaadintestscomponentsuiUITabIndex::@tabIndex</td>
+ <td>1</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/ui/UITabIndex.java b/uitest/src/com/vaadin/tests/components/ui/UITabIndex.java
new file mode 100644
index 0000000000..083eaf3f7d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/UITabIndex.java
@@ -0,0 +1,51 @@
+package com.vaadin.tests.components.ui;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+
+public class UITabIndex extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ Button b;
+
+ b = new Button("Set tabIndex to -1");
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setTabIndex(-1);
+ }
+ });
+ addComponent(b);
+ b = new Button("Set tabIndex to 0");
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setTabIndex(0);
+ }
+ });
+ addComponent(b);
+ b = new Button("Set tabIndex to 1");
+ b.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setTabIndex(1);
+ }
+ });
+ addComponent(b);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Tests tab index handling for UI";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11129;
+ }
+
+}
diff --git a/uitest/test.xml b/uitest/test.xml
index e2c14b53af..5ff39c425d 100644
--- a/uitest/test.xml
+++ b/uitest/test.xml
@@ -8,7 +8,7 @@
<!-- Configuration -->
<!-- ================================================================== -->
<!-- Browsers to use for testing -->
- <property name="browsers-windows" value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-safari5,winxp-googlechrome21,winxp-opera11" />
+ <property name="browsers-windows" value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-safari5,winxp-googlechrome21,winxp-opera12" />
<property name="browsers-linux" value="linux-firefox3,linux-opera10,linux-googlechrome8" />
<property name="browsers-mac" value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" />