summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebContent/release-notes.html42
-rw-r--r--WebContent/statictestfiles/applet.html5
-rw-r--r--WebContent/statictestfiles/com/vaadin/tests/components/embedded/TestApplet.classbin0 -> 583 bytes
-rw-r--r--build/bin/package-diff.py2
-rw-r--r--build/build.xml1
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java69
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java114
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java18
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java2
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java75
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java30
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java58
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java8
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java105
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java42
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java18
-rw-r--r--tests/server-side/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java131
-rw-r--r--tests/server-side/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java8
-rw-r--r--tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.html17
-rw-r--r--tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.html36
-rw-r--r--tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.java43
-rw-r--r--tests/testbench/com/vaadin/tests/components/embedded/TestApplet.java11
-rw-r--r--tests/testbench/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html2
-rwxr-xr-xtests/testbench/com/vaadin/tests/components/notification/SemiTransparentNotification.java31
-rwxr-xr-xtests/testbench/com/vaadin/tests/components/notification/SemitransparentNotification.html27
-rw-r--r--tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.html152
-rw-r--r--tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java20
-rw-r--r--tests/testbench/com/vaadin/tests/components/table/EmptyTable.html2
-rw-r--r--tests/testbench/com/vaadin/tests/components/table/HorizontalScrollWithNoRows.html86
-rwxr-xr-xtests/testbench/com/vaadin/tests/components/textarea/TextAreaMaxLength.html53
-rw-r--r--tests/testbench/com/vaadin/tests/components/tree/TreeItemClickAndValueChange.html82
-rwxr-xr-xtests/testbench/com/vaadin/tests/components/treetable/AddItemToEmptyTreeTable.html72
34 files changed, 1233 insertions, 191 deletions
diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html
index 1e4016db90..c73f9701c5 100644
--- a/WebContent/release-notes.html
+++ b/WebContent/release-notes.html
@@ -60,6 +60,7 @@
</p>
<ul>
+<<<<<<< HEAD
<li>Vaadin server and client side classes (<tt>/com</tt>)</li>
<li>Vaadin server and client side sources (<tt>/com</tt>)</li>
<li>The default widget set (<tt>/VAADIN/widgetsets</tt>)</li>
@@ -67,6 +68,39 @@
<li>Release notes (<tt>/release-notes.html</tt>)</li>
<li>Licensing information (<tt>/license.html</tt>)</li>
</ul>
+=======
+ <li><a href="http://dev.vaadin.com/ticket/8932">#8932</a>: Custom build from 6.8</li>
+ <li><a href="http://dev.vaadin.com/ticket/8193">#8193</a>: Enter ClickShortcut not working in a PopupView</li>
+ <li><a href="http://dev.vaadin.com/ticket/8584">#8584</a>: Invalid behavior of multiselection for com.vaadin.ui.Table</li>
+ <li><a href="http://dev.vaadin.com/ticket/9136">#9136</a>: Tree throws wrong ItemClickEvent in IE9 (when immediate is set to true)</li>
+ <li><a href="http://dev.vaadin.com/ticket/9139">#9139</a>: TextArea in Internet Explorer</li>
+ <li><a href="http://dev.vaadin.com/ticket/9188">#9188</a>: Error parsing maps with empty string as the last value</li>
+ <li><a href="http://dev.vaadin.com/ticket/7036">#7036</a>: Enable scrollbars on a read-only RichTextArea</li>
+ <li><a href="http://dev.vaadin.com/ticket/8109">#8109</a>: Iterating over Table multiselection causes multiple Vaadin SQLContainer full table scans</li>
+ <li><a href="http://dev.vaadin.com/ticket/8144">#8144</a>: Can't use LoginForm inside an iframe</li>
+ <li><a href="http://dev.vaadin.com/ticket/9202">#9202</a>: Test using Chrome 21</li>
+ <li><a href="http://dev.vaadin.com/ticket/6219">#6219</a>: PDF viewer draws itself over floating Vaadin elements</li>
+ <li><a href="http://dev.vaadin.com/ticket/8230">#8230</a>: TextField's input prompt is persisted if Alt is depressed while in focus (Chrome)</li>
+ <li><a href="http://dev.vaadin.com/ticket/8399">#8399</a>: On IE 8 or Google Chrome 16, VOverlay components aren't display on top of Applet</li>
+ <li><a href="http://dev.vaadin.com/ticket/9148">#9148</a>: Oracle TIMESTAMP not supported in SQLContainer</li>
+ <li><a href="http://dev.vaadin.com/ticket/9189">#9189</a>: Variables sent to the DragAndDropManager are not logged in the debug console</li>
+ <li><a href="http://dev.vaadin.com/ticket/9128">#9128</a>: Typo in vaadin book</li>
+ <li><a href="http://dev.vaadin.com/ticket/8736">#8736</a>: com.vaadin.ui.Table component return null value on multiple selection</li>
+ <li><a href="http://dev.vaadin.com/ticket/9132">#9132</a>: No entries in Table with a defined pageLength causes Table to shrink in height</li>
+ <li><a href="http://dev.vaadin.com/ticket/9147">#9147</a>: SQLContainer Filters - Comparison against NULL value produces error</li>
+ <li><a href="http://dev.vaadin.com/ticket/9154">#9154</a>: NumberFormatException in client-side component VSplitPanel</li>
+ <li><a href="http://dev.vaadin.com/ticket/9171">#9171</a>: StreamVariable never cleaned up in CommunicationManager</li>
+ <li><a href="http://dev.vaadin.com/ticket/9187">#9187</a>: No horizontal scroll bar on empty Table</li>
+ <li><a href="http://dev.vaadin.com/ticket/8838">#8838</a>: Drag and Drop in Google Chrome causes ArrayIndexOutOfBoundsException in AbstractCommunicationManager#convertMap (1612)</li>
+ <li><a href="http://dev.vaadin.com/ticket/8917">#8917</a>: input prompt text is leaking into the component's value</li>
+ </ul>
+
+ <p>
+ The <a
+ href="http://dev.vaadin.com/query?status=closed&resolution=fixed&milestone=Vaadin+@version@&order=priority">full
+ list of the closed issues</a> can be found at <tt>dev.vaadin.com</tt>.
+ </p>
+>>>>>>> remotes/origin/6.8
<h2 id="enhancements">Enhancements in Vaadin @version-minor@</h2>
@@ -348,11 +382,19 @@
</p>
<ul>
+<<<<<<< HEAD
<li>Mozilla Firefox 12</li>
<li>Internet Explorer 8-9</li>
<li>Safari 5</li>
<li>Opera 11</li>
<li>Google Chrome 19</li>
+=======
+ <li>Mozilla Firefox 3-14</li>
+ <li>Internet Explorer 6-9</li>
+ <li>Safari 4-5</li>
+ <li>Opera 10-12</li>
+ <li>Google Chrome 13-21</li>
+>>>>>>> remotes/origin/6.8
</ul>
<p>
diff --git a/WebContent/statictestfiles/applet.html b/WebContent/statictestfiles/applet.html
new file mode 100644
index 0000000000..05e1785e10
--- /dev/null
+++ b/WebContent/statictestfiles/applet.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+ <applet code="com/vaadin/tests/components/embedded/TestApplet/class"></applet>
+</body>
+</html> \ No newline at end of file
diff --git a/WebContent/statictestfiles/com/vaadin/tests/components/embedded/TestApplet.class b/WebContent/statictestfiles/com/vaadin/tests/components/embedded/TestApplet.class
new file mode 100644
index 0000000000..7650e1f870
--- /dev/null
+++ b/WebContent/statictestfiles/com/vaadin/tests/components/embedded/TestApplet.class
Binary files differ
diff --git a/build/bin/package-diff.py b/build/bin/package-diff.py
index a9f29e40a9..27f1ade771 100644
--- a/build/bin/package-diff.py
+++ b/build/bin/package-diff.py
@@ -7,7 +7,7 @@ from sets import Set
# Configuration
################################################################################
downloadsite = "http://vaadin.com/download"
-latestfile = "/release/6.7/LATEST"
+latestfile = "/release/6.8/LATEST"
JAPIZE = "japize"
JAPICOMPAT = "japicompat"
diff --git a/build/build.xml b/build/build.xml
index ba9b93a2ab..2988218c4d 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -531,6 +531,7 @@
<include name="VAADIN/themes/**/*" />
<include name="VAADIN/vaadinBootstrap.js" />
<include name="META-INF/**/*" />
+ <include name="statictestfiles/**" />
</fileset>
</copy>
diff --git a/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java b/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
index de2d9a9cd8..680131c70c 100644
--- a/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
+++ b/client/src/com/vaadin/terminal/gwt/client/BrowserInfo.java
@@ -139,7 +139,7 @@ public class BrowserInfo {
if (browserDetails.isFirefox()) {
browserIdentifier = BROWSER_FIREFOX;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_GECKO;
@@ -151,21 +151,21 @@ public class BrowserInfo {
} else if (browserDetails.isSafari()) {
browserIdentifier = BROWSER_SAFARI;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_WEBKIT;
} else if (browserDetails.isIE()) {
browserIdentifier = BROWSER_IE;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_TRIDENT;
} else if (browserDetails.isOpera()) {
browserIdentifier = BROWSER_OPERA;
majorVersionClass = browserIdentifier
- + browserDetails.getBrowserMajorVersion();
+ + getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_PRESTO;
@@ -222,11 +222,11 @@ public class BrowserInfo {
}
public boolean isIE8() {
- return isIE() && browserDetails.getBrowserMajorVersion() == 8;
+ return isIE() && getBrowserMajorVersion() == 8;
}
public boolean isIE9() {
- return isIE() && browserDetails.getBrowserMajorVersion() == 9;
+ return isIE() && getBrowserMajorVersion() == 9;
}
public boolean isChrome() {
@@ -274,7 +274,7 @@ public class BrowserInfo {
return -1;
}
- return browserDetails.getBrowserMajorVersion();
+ return getBrowserMajorVersion();
}
public float getOperaVersion() {
@@ -282,7 +282,7 @@ public class BrowserInfo {
return -1;
}
- return browserDetails.getBrowserMajorVersion();
+ return getBrowserMajorVersion();
}
public boolean isOpera() {
@@ -290,13 +290,11 @@ public class BrowserInfo {
}
public boolean isOpera10() {
- return browserDetails.isOpera()
- && browserDetails.getBrowserMajorVersion() == 10;
+ return browserDetails.isOpera() && getBrowserMajorVersion() == 10;
}
public boolean isOpera11() {
- return browserDetails.isOpera()
- && browserDetails.getBrowserMajorVersion() == 11;
+ return browserDetails.isOpera() && getBrowserMajorVersion() == 11;
}
public native static String getBrowserString()
@@ -387,4 +385,51 @@ public class BrowserInfo {
private int getOperatingSystemMajorVersion() {
return browserDetails.getOperatingSystemMajorVersion();
}
+
+ /**
+ * Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
+ * 4, 8 for Internet Explorer 8.
+ * <p>
+ * Note that Internet Explorer 8 and newer will return the document mode so
+ * IE8 rendering as IE7 will return 7.
+ * </p>
+ *
+ * @return The major version of the browser.
+ */
+ public int getBrowserMajorVersion() {
+ return browserDetails.getBrowserMajorVersion();
+ }
+
+ /**
+ * Returns the browser minor version e.g., 5 for Firefox 3.5.
+ *
+ * @see #getBrowserMajorVersion()
+ *
+ * @return The minor version of the browser, or -1 if not known/parsed.
+ */
+ public int getBrowserMinorVersion() {
+ return browserDetails.getBrowserMinorVersion();
+ }
+
+ /**
+ * Checks if the browser version is newer or equal to the given major+minor
+ * version.
+ *
+ * @param majorVersion
+ * The major version to check for
+ * @param minorVersion
+ * The minor version to check for
+ * @return true if the browser version is newer or equal to the given
+ * version
+ */
+ public boolean isBrowserVersionNewerOrEqual(int majorVersion,
+ int minorVersion) {
+ if (getBrowserMajorVersion() == majorVersion) {
+ // Same major
+ return (getBrowserMinorVersion() >= minorVersion);
+ }
+
+ // Older or newer major
+ return (getBrowserMajorVersion() > majorVersion);
+ }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java b/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
index aef21ac737..97201de297 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
@@ -42,6 +42,14 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
public static class PositionAndSize {
private int left, top, width, height;
+ public PositionAndSize(int left, int top, int width, int height) {
+ super();
+ setLeft(left);
+ setTop(top);
+ setWidth(width);
+ setHeight(height);
+ }
+
public int getLeft() {
return left;
}
@@ -63,6 +71,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}
public void setWidth(int width) {
+ if (width < 0) {
+ width = 0;
+ }
+
this.width = width;
}
@@ -71,6 +83,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}
public void setHeight(int height) {
+ if (height < 0) {
+ height = 0;
+ }
+
this.height = height;
}
@@ -192,7 +208,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return shadow != null;
}
- private void removeShim() {
+ private void removeShimElement() {
if (shimElement != null) {
shimElement.removeFromParent();
}
@@ -211,7 +227,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return isShadowEnabled() && shadow.getParentElement() != null;
}
- private boolean isShimAttached() {
+ private boolean isShimElementAttached() {
return shimElement != null && shimElement.hasParentElement();
}
@@ -242,11 +258,11 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
style.setMarginLeft(-adjustByRelativeLeftBodyMargin(), Unit.PX);
style.setMarginTop(-adjustByRelativeTopBodyMargin(), Unit.PX);
super.setPopupPosition(left, top);
- sizeOrPositionUpdated(isAnimationEnabled() ? 0 : 1);
+ positionOrSizeUpdated(isAnimationEnabled() ? 0 : 1);
}
private IFrameElement getShimElement() {
- if (shimElement == null) {
+ if (shimElement == null && needsShimElement()) {
shimElement = Document.get().createIFrameElement();
// Insert shim iframe before the main overlay element. It does not
@@ -318,7 +334,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
if (isAnimationEnabled()) {
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION);
} else {
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
}
@@ -328,7 +344,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
// Always ensure shadow is removed when the overlay is removed.
removeShadowIfPresent();
- removeShim();
+ removeShimElement();
}
@Override
@@ -343,13 +359,13 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
@Override
public void setWidth(String width) {
super.setWidth(width);
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
@Override
public void setHeight(String height) {
super.setHeight(height);
- sizeOrPositionUpdated(1.0);
+ positionOrSizeUpdated(1.0);
}
/**
@@ -374,8 +390,16 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* 'setHeight(String)' methods (if not calling super.setWidth/Height).
*
*/
- public void sizeOrPositionUpdated() {
- sizeOrPositionUpdated(1.0);
+ public void positionOrSizeUpdated() {
+ positionOrSizeUpdated(1.0);
+ }
+
+ /**
+ * @deprecated Call {@link #positionOrSizeUpdated()} instead.
+ */
+ @Deprecated
+ protected void updateShadowSizeAndPosition() {
+ positionOrSizeUpdated();
}
/**
@@ -388,7 +412,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* A value between 0.0 and 1.0, indicating the progress of the
* animation (0=start, 1=end).
*/
- private void sizeOrPositionUpdated(final double progress) {
+ private void positionOrSizeUpdated(final double progress) {
// Don't do anything if overlay element is not attached
if (!isAttached()) {
return;
@@ -413,18 +437,8 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
getOffsetWidth();
}
- PositionAndSize positionAndSize = new PositionAndSize();
- positionAndSize.left = getActualLeft();
- positionAndSize.top = getActualTop();
- positionAndSize.width = getOffsetWidth();
- positionAndSize.height = getOffsetHeight();
-
- if (positionAndSize.width < 0) {
- positionAndSize.width = 0;
- }
- if (positionAndSize.height < 0) {
- positionAndSize.height = 0;
- }
+ PositionAndSize positionAndSize = new PositionAndSize(getActualLeft(),
+ getActualTop(), getOffsetWidth(), getOffsetHeight());
// Animate the size
positionAndSize.setAnimationFromCenterProgress(progress);
@@ -441,29 +455,31 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
// Update correct values
if (isShadowEnabled()) {
- updateSizeAndPosition(shadow, positionAndSize);
+ updatePositionAndSize(shadow, positionAndSize);
DOM.setStyleAttribute(shadow, "zIndex", zIndex);
DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none"
: "");
}
- updateSizeAndPosition((Element) Element.as(getShimElement()),
- positionAndSize);
+ if (needsShimElement()) {
+ updatePositionAndSize((Element) Element.as(getShimElement()),
+ positionAndSize);
+ }
// Opera fix, part 2 (ticket #2704)
if (BrowserInfo.get().isOpera() && isShadowEnabled()) {
// We'll fix the height of all the middle elements
DOM.getChild(shadow, 3)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 3).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 3).getOffsetHeight());
DOM.getChild(shadow, 4)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 4).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 4).getOffsetHeight());
DOM.getChild(shadow, 5)
- .getStyle()
- .setPropertyPx("height",
- DOM.getChild(shadow, 5).getOffsetHeight());
+ .getStyle()
+ .setPropertyPx("height",
+ DOM.getChild(shadow, 5).getOffsetHeight());
}
// Attach to dom if not there already
@@ -471,25 +487,37 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
RootPanel.get().getElement().insertBefore(shadow, getElement());
sinkShadowEvents();
}
- if (!isShimAttached()) {
+ if (needsShimElement() && !isShimElementAttached()) {
RootPanel.get().getElement()
- .insertBefore(shimElement, getElement());
+ .insertBefore(getShimElement(), getElement());
}
}
- private void updateSizeAndPosition(Element e,
+ /**
+ * Returns true if we should add a shim iframe below the overlay to deal
+ * with zindex issues with PDFs and applets. Can be overriden to disable
+ * shim iframes if they are not needed.
+ *
+ * @return true if a shim iframe should be added, false otherwise
+ */
+ protected boolean needsShimElement() {
+ BrowserInfo info = BrowserInfo.get();
+ return info.isIE() && info.isBrowserVersionNewerOrEqual(8, 0);
+ }
+
+ private void updatePositionAndSize(Element e,
PositionAndSize positionAndSize) {
- e.getStyle().setLeft(positionAndSize.left, Unit.PX);
- e.getStyle().setTop(positionAndSize.top, Unit.PX);
- e.getStyle().setWidth(positionAndSize.width, Unit.PX);
- e.getStyle().setHeight(positionAndSize.height, Unit.PX);
+ e.getStyle().setLeft(positionAndSize.getLeft(), Unit.PX);
+ e.getStyle().setTop(positionAndSize.getTop(), Unit.PX);
+ e.getStyle().setWidth(positionAndSize.getWidth(), Unit.PX);
+ e.getStyle().setHeight(positionAndSize.getHeight(), Unit.PX);
}
protected class ResizeAnimation extends Animation {
@Override
protected void onUpdate(double progress) {
- sizeOrPositionUpdated(progress);
+ positionOrSizeUpdated(progress);
}
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java b/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
index 9f17b81691..fe47fcca66 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
@@ -56,8 +56,8 @@ import com.vaadin.terminal.gwt.client.ui.VLazyExecutor;
import com.vaadin.terminal.gwt.client.ui.VOverlay;
public class VMenuBar extends SimpleFocusablePanel implements
- CloseHandler<PopupPanel>, KeyPressHandler, KeyDownHandler,
- FocusHandler, SubPartAware {
+CloseHandler<PopupPanel>, KeyPressHandler, KeyDownHandler,
+FocusHandler, SubPartAware {
// The hierarchy of VMenuBar is a bit weird as VMenuBar is the Paintable,
// used for the root menu but also used for the sub menus.
@@ -94,11 +94,11 @@ public class VMenuBar extends SimpleFocusablePanel implements
private VLazyExecutor iconLoadedExecutioner = new VLazyExecutor(100,
new ScheduledCommand() {
- @Override
- public void execute() {
- iLayout(true);
- }
- });
+ @Override
+ public void execute() {
+ iLayout(true);
+ }
+ });
boolean openRootOnHover;
@@ -188,7 +188,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
itemHTML.append("<img src=\""
+ Util.escapeAttribute(client.translateVaadinUri(item
.getStringAttribute("icon"))) + "\" class=\""
- + Icon.CLASSNAME + "\" alt=\"\" />");
+ + Icon.CLASSNAME + "\" alt=\"\" />");
}
String itemText = item.getStringAttribute("text");
if (!htmlContentAllowed) {
@@ -606,7 +606,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
// popup
style.setWidth(contentWidth + Util.getNativeScrollbarSize(),
Unit.PX);
- popup.sizeOrPositionUpdated();
+ popup.positionOrSizeUpdated();
}
}
return top;
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java b/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
index 451e6badbe..6e253c9137 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java
@@ -168,7 +168,7 @@ public class VNotification extends VOverlay {
super.show();
notifications.add(this);
setPosition(position);
- sizeOrPositionUpdated();
+ positionOrSizeUpdated();
/**
* Android 4 fails to render notifications correctly without a little
* nudge (#8551)
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java b/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
index aa7da488d8..345eebc8aa 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
@@ -4122,8 +4122,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
row.addStyleName("v-selected");
}
tBodyElement.appendChild(row.getElement());
- adopt(row);
+ // Add to renderedRows before adopt so iterator() will return also
+ // this row if called in an attach handler (#9264)
renderedRows.add(row);
+ adopt(row);
}
private void insertRowAt(VScrollTableRow row, int index) {
@@ -5780,16 +5782,39 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Hey IE, are you really sure about this?
availW = scrollBody.getAvailableWidth();
int visibleCellCount = tHead.getVisibleCellCount();
- availW -= scrollBody.getCellExtraWidth() * visibleCellCount;
+ int totalExtraWidth = scrollBody.getCellExtraWidth()
+ * visibleCellCount;
if (willHaveScrollbars()) {
- availW -= Util.getNativeScrollbarSize();
+ totalExtraWidth += Util.getNativeScrollbarSize();
}
+ availW -= totalExtraWidth;
+ int forceScrollBodyWidth = -1;
int extraSpace = availW - usedMinimumWidth;
if (extraSpace < 0) {
+ if (getTotalRows() == 0) {
+ /*
+ * Too wide header combined with no rows in the table.
+ *
+ * No horizontal scrollbars would be displayed because
+ * there's no rows that grows too wide causing the
+ * scrollBody container div to overflow. Must explicitely
+ * force a width to a scrollbar. (see #9187)
+ */
+ forceScrollBodyWidth = usedMinimumWidth + totalExtraWidth;
+ }
extraSpace = 0;
}
+ if (forceScrollBodyWidth > 0) {
+ scrollBody.container.getStyle().setWidth(forceScrollBodyWidth,
+ Unit.PX);
+ } else {
+ // Clear width that might have been set to force horizontal
+ // scrolling if there are no rows
+ scrollBody.container.getStyle().clearWidth();
+ }
+
int totalUndefinedNaturalWidths = usedMinimumWidth
- totalExplicitColumnsWidths;
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java b/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
index e061cda1fa..e1df1ba0db 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/textarea/VTextArea.java
@@ -19,6 +19,10 @@ package com.vaadin.terminal.gwt.client.ui.textarea;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.TextAreaElement;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
@@ -38,10 +42,17 @@ import com.vaadin.terminal.gwt.client.ui.textfield.VTextField;
public class VTextArea extends VTextField {
public static final String CLASSNAME = "v-textarea";
private boolean wordwrap = true;
+ private MaxLengthHandler maxLengthHandler = new MaxLengthHandler();
+ private boolean browserSupportsMaxLengthAttribute = browserSupportsMaxLengthAttribute();
public VTextArea() {
super(DOM.createTextArea());
setStyleName(CLASSNAME);
+ if (!browserSupportsMaxLengthAttribute) {
+ addKeyUpHandler(maxLengthHandler);
+ addChangeHandler(maxLengthHandler);
+ sinkEvents(Event.ONPASTE);
+ }
}
public TextAreaElement getTextAreaElement() {
@@ -52,22 +63,28 @@ public class VTextArea extends VTextField {
getTextAreaElement().setRows(rows);
}
- @Override
- protected void setMaxLength(int newMaxLength) {
- super.setMaxLength(newMaxLength);
+ private class MaxLengthHandler implements KeyUpHandler, ChangeHandler {
- boolean hasMaxLength = (newMaxLength >= 0);
+ @Override
+ public void onKeyUp(KeyUpEvent event) {
+ enforceMaxLength();
+ }
- if (hasMaxLength) {
- sinkEvents(Event.ONKEYUP);
- } else {
- unsinkEvents(Event.ONKEYUP);
+ public void onPaste(Event event) {
+ enforceMaxLength();
}
+
+ @Override
+ public void onChange(ChangeEvent event) {
+ // Opera does not support paste events so this enforces max length
+ // for Opera.
+ enforceMaxLength();
+ }
+
}
- @Override
- public void onBrowserEvent(Event event) {
- if (getMaxLength() >= 0 && event.getTypeInt() == Event.ONKEYUP) {
+ protected void enforceMaxLength() {
+ if (getMaxLength() >= 0) {
Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
@@ -77,9 +94,45 @@ public class VTextArea extends VTextField {
}
});
}
+ }
+
+ protected boolean browserSupportsMaxLengthAttribute() {
+ BrowserInfo info = BrowserInfo.get();
+ if (info.isFirefox() && info.isBrowserVersionNewerOrEqual(4, 0)) {
+ return true;
+ }
+ if (info.isSafari() && info.isBrowserVersionNewerOrEqual(5, 0)) {
+ return true;
+ }
+ if (info.isIE() && info.isBrowserVersionNewerOrEqual(10, 0)) {
+ return true;
+ }
+ if (info.isAndroid() && info.isBrowserVersionNewerOrEqual(2, 3)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void updateMaxLength(int maxLength) {
+ if (browserSupportsMaxLengthAttribute) {
+ super.updateMaxLength(maxLength);
+ } else {
+ // Events handled by MaxLengthHandler. This call enforces max length
+ // when the max length value has changed
+ enforceMaxLength();
+ }
+ }
+
+ @Override
+ public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
+ if (event.getTypeInt() == Event.ONPASTE) {
+ maxLengthHandler.onPaste(event);
+ }
}
+
@Override
public int getCursorPos() {
// This is needed so that TextBoxImplIE6 is used to return the correct
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java b/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
index b00210cdd2..8f07c67c96 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/textfield/VTextField.java
@@ -44,7 +44,7 @@ import com.vaadin.terminal.gwt.client.ui.Field;
*
*/
public class VTextField extends TextBoxBase implements Field, ChangeHandler,
- FocusHandler, BlurHandler, KeyDownHandler {
+FocusHandler, BlurHandler, KeyDownHandler {
/**
* The input node CSS classname.
@@ -114,7 +114,7 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
if (listenTextChangeEvents
&& (event.getTypeInt() & TEXTCHANGE_EVENTS) == event
- .getTypeInt()) {
+ .getTypeInt()) {
deferTextChangeEvent();
}
@@ -261,12 +261,32 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
}
protected void setMaxLength(int newMaxLength) {
- if (newMaxLength >= 0) {
+ if (newMaxLength >= 0 && newMaxLength != maxLength) {
maxLength = newMaxLength;
- } else {
+ updateMaxLength(maxLength);
+ } else if (maxLength != -1) {
maxLength = -1;
+ updateMaxLength(maxLength);
+ }
+
+ }
+
+ /**
+ * This method is reponsible for updating the DOM or otherwise ensuring that
+ * the given max length is enforced. Called when the max length for the
+ * field has changed.
+ *
+ * @param maxLength
+ * The new max length
+ */
+ protected void updateMaxLength(int maxLength) {
+ if (maxLength >= 0) {
+ getElement().setPropertyInt("maxLength", maxLength);
+ } else {
+ getElement().removeAttribute("maxLength");
+
}
- setMaxLengthToElement(newMaxLength);
+ setMaxLengthToElement(maxLength);
}
protected void setMaxLengthToElement(int newMaxLength) {
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java b/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
index 9fbaa1d8bf..40c5e4b8af 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/tree/VTree.java
@@ -79,8 +79,8 @@ import com.vaadin.terminal.gwt.client.ui.dd.VTransferable;
*
*/
public class VTree extends FocusElementPanel implements VHasDropHandler,
- FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
- SubPartAware, ActionOwner {
+FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler,
+SubPartAware, ActionOwner {
public static final String CLASSNAME = "v-tree";
@@ -137,12 +137,12 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
public VLazyExecutor iconLoaded = new VLazyExecutor(50,
new ScheduledCommand() {
- @Override
- public void execute() {
- Util.notifyParentOfSizeChange(VTree.this, true);
- }
+ @Override
+ public void execute() {
+ Util.notifyParentOfSizeChange(VTree.this, true);
+ }
- });
+ });
public VTree() {
super();
@@ -601,7 +601,8 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
focus();
}
- ScheduledCommand command = new ScheduledCommand() {
+ executeEventCommand(new ScheduledCommand() {
+
@Override
public void execute() {
@@ -636,17 +637,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
}
}
}
- };
-
- if (BrowserInfo.get().isWebkit() && !treeHasFocus) {
- /*
- * Safari may need to wait for focus. See FocusImplSafari.
- */
- // VConsole.log("Deferring click handling to let webkit gain focus...");
- Scheduler.get().scheduleDeferred(command);
- } else {
- command.execute();
- }
+ });
return true;
}
@@ -677,7 +668,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
&& client.hasEventListeners(VTree.this,
TreeConstants.ITEM_CLICK_EVENT_ID)
- && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
+ && (type == Event.ONDBLCLICK || type == Event.ONMOUSEUP)) {
fireClick(event);
}
if (type == Event.ONCLICK) {
@@ -709,7 +700,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
.getEventTarget().cast())) {
if (dragMode > 0
&& (type == Event.ONTOUCHSTART || event
- .getButton() == NativeEvent.BUTTON_LEFT)) {
+ .getButton() == NativeEvent.BUTTON_LEFT)) {
mouseDownEvent = event; // save event for possible
// dd operation
if (type == Event.ONMOUSEDOWN) {
@@ -790,9 +781,12 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
focus();
}
}
+
final MouseEventDetails details = MouseEventDetailsBuilder
.buildMouseEventDetails(evt);
- ScheduledCommand command = new ScheduledCommand() {
+
+ executeEventCommand(new ScheduledCommand() {
+
@Override
public void execute() {
// Determine if we should send the event immediately to the
@@ -820,14 +814,18 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
client.updateVariable(paintableId, "clickEvent",
details.toString(), sendClickEventNow);
}
- };
- if (treeHasFocus) {
- command.execute();
- } else {
- /*
- * Webkits need a deferring due to FocusImplSafari uses timeout
- */
+ });
+ }
+
+ /*
+ * Must wait for Safari to focus before sending click and value change
+ * events (see #6373, #6374)
+ */
+ private void executeEventCommand(ScheduledCommand command) {
+ if (BrowserInfo.get().isWebkit() && !treeHasFocus) {
Scheduler.get().scheduleDeferred(command);
+ } else {
+ command.execute();
}
}
@@ -1723,7 +1721,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
selectNode(
focusedNode,
(!isMultiselect || multiSelectMode == MULTISELECT_MODE_SIMPLE)
- && selectable);
+ && selectable);
} else {
deselectNode(focusedNode);
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java b/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
index a8621190ae..909acdf85f 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/treetable/VTreeTable.java
@@ -188,8 +188,7 @@ public class VTreeTable extends VScrollTable {
if (isTreeCellAdded) {
return false;
}
- return curColIndex == colIndexOfHierarchy
- + (showRowHeaders ? 1 : 0);
+ return curColIndex == getHierarchyColumnIndex();
}
@Override
@@ -227,6 +226,23 @@ public class VTreeTable extends VScrollTable {
super.onAttach();
if (getIndentWidth() < 0) {
detectIndent(this);
+ // If we detect indent here then the size of the hierarchy
+ // column is still wrong as it has been set when the indent
+ // was not known.
+ int w = getCellWidthFromDom(getHierarchyColumnIndex());
+ if (w >= 0) {
+ setColWidth(getHierarchyColumnIndex(), w);
+ }
+ }
+ }
+
+ private int getCellWidthFromDom(int cellIndex) {
+ final Element cell = DOM.getChild(getElement(), cellIndex);
+ String w = cell.getStyle().getProperty("width");
+ if (w == null || "".equals(w) || !w.endsWith("px")) {
+ return -1;
+ } else {
+ return Integer.parseInt(w.substring(0, w.length() - 2));
}
}
@@ -242,14 +258,21 @@ public class VTreeTable extends VScrollTable {
@Override
protected void setCellWidth(int cellIx, int width) {
- if (cellIx == colIndexOfHierarchy + (showRowHeaders ? 1 : 0)) {
+ if (cellIx == getHierarchyColumnIndex()) {
// take indentation padding into account if this is the
// hierarchy column
- width = Math.max(width - getIndent(), 0);
+ int indent = getIndent();
+ if (indent != -1) {
+ width = Math.max(width - getIndent(), 0);
+ }
}
super.setCellWidth(cellIx, width);
}
+ private int getHierarchyColumnIndex() {
+ return colIndexOfHierarchy + (showRowHeaders ? 1 : 0);
+ }
+
private int getIndent() {
return (depth + 1) * getIndentWidth();
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
index a1bab91618..3ee266b944 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java
@@ -46,8 +46,8 @@ import com.vaadin.terminal.gwt.client.ui.layout.MayScrollChildren;
@Connect(value = com.vaadin.ui.Window.class)
public class WindowConnector extends AbstractComponentContainerConnector
- implements Paintable, BeforeShortcutActionListener,
- SimpleManagedLayout, PostLayoutListener, MayScrollChildren {
+implements Paintable, BeforeShortcutActionListener,
+SimpleManagedLayout, PostLayoutListener, MayScrollChildren {
private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
@Override
@@ -102,7 +102,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
}
if (!getWidget().isAttached()) {
getWidget().setVisible(false); // hide until
- // possible centering
+ // possible centering
getWidget().show();
}
if (getState().isResizable() != getWidget().resizable) {
@@ -299,7 +299,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
if (window.centered) {
window.center();
}
- window.sizeOrPositionUpdated();
+ window.positionOrSizeUpdated();
}
@Override
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java b/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
index 3e55633574..0146c92b5c 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
@@ -20,6 +20,7 @@ import java.sql.Time;
import java.sql.Timestamp;
import com.vaadin.data.Property;
+import com.vaadin.data.util.converter.Converter.ConversionException;
/**
* ColumnProperty represents the value of one column in a RowItem. In addition
@@ -47,6 +48,7 @@ final public class ColumnProperty implements Property {
private boolean modified;
private boolean versionColumn;
+ private boolean primaryKey = false;
/**
* Prevent instantiation without required parameters.
@@ -55,9 +57,50 @@ final public class ColumnProperty implements Property {
private ColumnProperty() {
}
+ /**
+ * Deprecated constructor for ColumnProperty. If this is used the primary
+ * keys are not identified correctly in some cases for some databases (i.e.
+ * Oracle). See http://dev.vaadin.com/ticket/9145.
+ *
+ * @param propertyId
+ * @param readOnly
+ * @param allowReadOnlyChange
+ * @param nullable
+ * @param value
+ * @param type
+ *
+ * @deprecated
+ */
+ @Deprecated
public ColumnProperty(String propertyId, boolean readOnly,
boolean allowReadOnlyChange, boolean nullable, Object value,
Class<?> type) {
+ this(propertyId, readOnly, allowReadOnlyChange, nullable, false, value,
+ type);
+ }
+
+ /**
+ * Creates a new ColumnProperty instance.
+ *
+ * @param propertyId
+ * The ID of this property.
+ * @param readOnly
+ * Whether this property is read-only.
+ * @param allowReadOnlyChange
+ * Whether the read-only status of this property can be changed.
+ * @param nullable
+ * Whether this property accepts null values.
+ * @param primaryKey
+ * Whether this property corresponds to a database primary key.
+ * @param value
+ * The value of this property.
+ * @param type
+ * The type of this property.
+ */
+ public ColumnProperty(String propertyId, boolean readOnly,
+ boolean allowReadOnlyChange, boolean nullable, boolean primaryKey,
+ Object value, Class<?> type) {
+
if (propertyId == null) {
throw new IllegalArgumentException("Properties must be named.");
}
@@ -71,8 +114,15 @@ final public class ColumnProperty implements Property {
this.allowReadOnlyChange = allowReadOnlyChange;
this.nullable = nullable;
this.readOnly = readOnly;
+ this.primaryKey = primaryKey;
}
+ /**
+ * Returns the current value for this property. To get the previous value
+ * (if one exists) for a modified property use {@link #getOldValue()}.
+ *
+ * @return
+ */
@Override
public Object getValue() {
if (isModified()) {
@@ -81,8 +131,20 @@ final public class ColumnProperty implements Property {
return value;
}
+ /**
+ * Returns the original non-modified value of this property if it has been
+ * modified.
+ *
+ * @return The original value if <code>isModified()</code> is true,
+ * <code>getValue()</code> otherwise.
+ */
+ public Object getOldValue() {
+ return value;
+ }
+
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(Object newValue) throws ReadOnlyException,
+ ConversionException {
if (newValue == null && !nullable) {
throw new NotNullableException(
"Null values are not allowed for this property.");
@@ -158,6 +220,17 @@ final public class ColumnProperty implements Property {
return readOnly;
}
+ /**
+ * Returns whether the read-only status of this property can be changed
+ * using {@link #setReadOnly(boolean)}.
+ * <p>
+ * Used to prevent setting to read/write mode a property that is not allowed
+ * to be written by the underlying database. Also used for values like
+ * VERSION and AUTO_INCREMENT fields that might be set to read-only by the
+ * container but the database still allows writes.
+ *
+ * @return true if the read-only status can be changed, false otherwise.
+ */
public boolean isReadOnlyChangeAllowed() {
return allowReadOnlyChange;
}
@@ -169,6 +242,10 @@ final public class ColumnProperty implements Property {
}
}
+ public boolean isPrimaryKey() {
+ return primaryKey;
+ }
+
public String getPropertyId() {
return propertyId;
}
@@ -214,6 +291,32 @@ final public class ColumnProperty implements Property {
}
/**
+ * Return whether the value of this property should be persisted to the
+ * database.
+ *
+ * @return true if the value should be written to the database, false
+ * otherwise.
+ */
+ public boolean isPersistent() {
+ if (isVersionColumn()) {
+ return false;
+ } else if (isReadOnlyChangeAllowed() && !isReadOnly()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether or not this property is used as a row identifier.
+ *
+ * @return true if the property is a row identifier, false otherwise.
+ */
+ public boolean isRowIdentifier() {
+ return isPrimaryKey() || isVersionColumn();
+ }
+
+ /**
* An exception that signals that a <code>null</code> value was passed to
* the <code>setValue</code> method, but the value of this property can not
* be set to <code>null</code>.
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 78700caee9..f772e2701c 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -68,7 +68,9 @@ public class SQLContainer implements Container, Container.Filterable,
private final List<String> propertyIds = new ArrayList<String>();
private final Map<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>();
private final Map<String, Boolean> propertyReadOnly = new HashMap<String, Boolean>();
+ private final Map<String, Boolean> propertyPersistable = new HashMap<String, Boolean>();
private final Map<String, Boolean> propertyNullable = new HashMap<String, Boolean>();
+ private final Map<String, Boolean> propertyPrimaryKey = new HashMap<String, Boolean>();
/** Filters (WHERE) and sorters (ORDER BY) */
private final List<Filter> filters = new ArrayList<Filter>();
@@ -150,11 +152,14 @@ public class SQLContainer implements Container, Container.Filterable,
List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>();
for (String propertyId : propertyIds) {
/* Default settings for new item properties. */
- itemProperties
- .add(new ColumnProperty(propertyId, propertyReadOnly
- .get(propertyId),
- !propertyReadOnly.get(propertyId), propertyNullable
- .get(propertyId), null, getType(propertyId)));
+ ColumnProperty cp = new ColumnProperty(propertyId,
+ propertyReadOnly.get(propertyId),
+ propertyPersistable.get(propertyId),
+ propertyNullable.get(propertyId),
+ propertyPrimaryKey.get(propertyId), null,
+ getType(propertyId));
+
+ itemProperties.add(cp);
}
RowItem newRowItem = new RowItem(this, itemId, itemProperties);
@@ -546,7 +551,9 @@ public class SQLContainer implements Container, Container.Filterable,
@Override
public void removeContainerFilter(Filter filter) {
filters.remove(filter);
- refresh();
+ // TODO this cannot be added before ComboBox is fixed
+ // (Select.requestRepaint() must not affect filter string)
+ // refresh();
}
/**
@@ -1141,14 +1148,22 @@ public class SQLContainer implements Container, Container.Filterable,
*/
boolean readOnly = rsmd.isAutoIncrement(i)
|| rsmd.isReadOnly(i);
- if (delegate instanceof TableQuery
- && rsmd.getColumnLabel(i).equals(
- ((TableQuery) delegate).getVersionColumn())) {
- readOnly = true;
+
+ boolean persistable = !rsmd.isReadOnly(i);
+
+ if (delegate instanceof TableQuery) {
+ if (rsmd.getColumnLabel(i).equals(
+ ((TableQuery) delegate).getVersionColumn())) {
+ readOnly = true;
+ }
}
+
propertyReadOnly.put(colName, readOnly);
+ propertyPersistable.put(colName, persistable);
propertyNullable.put(colName,
rsmd.isNullable(i) == ResultSetMetaData.columnNullable);
+ propertyPrimaryKey.put(colName, delegate.getPrimaryKeyColumns()
+ .contains(rsmd.getColumnLabel(i)));
propertyTypes.put(colName, type);
}
rs.getStatement().close();
@@ -1248,10 +1263,13 @@ public class SQLContainer implements Container, Container.Filterable,
* column.
*/
if (propertiesToAdd.contains(colName)) {
+
cp = new ColumnProperty(colName,
propertyReadOnly.get(colName),
- !propertyReadOnly.get(colName),
- propertyNullable.get(colName), value, type);
+ propertyPersistable.get(colName),
+ propertyNullable.get(colName),
+ propertyPrimaryKey.get(colName), value,
+ type);
itemProperties.add(cp);
propertiesToAdd.remove(colName);
}
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
index c4b640e274..6ebefcd85c 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
@@ -327,10 +327,8 @@ public class DefaultSQLGenerator implements SQLGenerator {
&& cp.getPropertyId().equalsIgnoreCase("rownum")) {
continue;
}
- Object value = cp.getValue() == null ? null : cp.getValue();
- /* Only include properties whose read-only status can be altered */
- if (cp.isReadOnlyChangeAllowed() && !cp.isVersionColumn()) {
- columnToValueMap.put(cp.getPropertyId(), value);
+ if (cp.isPersistent()) {
+ columnToValueMap.put(cp.getPropertyId(), cp.getValue());
}
}
return columnToValueMap;
@@ -345,8 +343,16 @@ public class DefaultSQLGenerator implements SQLGenerator {
&& cp.getPropertyId().equalsIgnoreCase("rownum")) {
continue;
}
- Object value = cp.getValue() == null ? null : cp.getValue();
- if (!cp.isReadOnlyChangeAllowed() || cp.isVersionColumn()) {
+
+ if (cp.isRowIdentifier()) {
+ Object value;
+ if (cp.isPrimaryKey()) {
+ // If the value of a primary key has changed, its old value
+ // should be used to identify the row (#9145)
+ value = cp.getOldValue();
+ } else {
+ value = cp.getValue();
+ }
rowIdentifiers.put(cp.getPropertyId(), value);
}
}
diff --git a/tests/server-side/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java b/tests/server-side/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
index b9621d518a..09f620cc2a 100644
--- a/tests/server-side/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
+++ b/tests/server-side/com/vaadin/data/util/sqlcontainer/ColumnPropertyTest.java
@@ -4,46 +4,48 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Arrays;
-import com.vaadin.data.Property.ReadOnlyException;
-import com.vaadin.data.util.sqlcontainer.ColumnProperty.NotNullableException;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.data.Property.ReadOnlyException;
+import com.vaadin.data.util.sqlcontainer.ColumnProperty.NotNullableException;
+import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
+
public class ColumnPropertyTest {
@Test
public void constructor_legalParameters_shouldSucceed() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertNotNull(cp);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_missingPropertyId_shouldFail() {
- new ColumnProperty(null, false, true, true, "Ville", String.class);
+ new ColumnProperty(null, false, true, true, false, "Ville",
+ String.class);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_missingType_shouldFail() {
- new ColumnProperty("NAME", false, true, true, "Ville", null);
+ new ColumnProperty("NAME", false, true, true, false, "Ville", null);
}
@Test
public void getValue_defaultValue_returnsVille() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertEquals("Ville", cp.getValue());
}
@Test
public void setValue_readWriteNullable_returnsKalle() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }),
Arrays.asList(cp));
@@ -57,7 +59,7 @@ public class ColumnPropertyTest {
@Test(expected = ReadOnlyException.class)
public void setValue_readOnlyNullable_shouldFail() {
ColumnProperty cp = new ColumnProperty("NAME", true, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
new RowItem(container, new RowId(new Object[] { 1 }), Arrays.asList(cp));
EasyMock.replay(container);
@@ -68,7 +70,7 @@ public class ColumnPropertyTest {
@Test
public void setValue_readWriteNullable_nullShouldWork() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }),
Arrays.asList(cp));
@@ -82,7 +84,7 @@ public class ColumnPropertyTest {
@Test(expected = NotNullableException.class)
public void setValue_readWriteNotNullable_nullShouldFail() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, false,
- "Ville", String.class);
+ false, "Ville", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }),
Arrays.asList(cp));
@@ -96,28 +98,28 @@ public class ColumnPropertyTest {
@Test
public void getType_normal_returnsStringClass() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertSame(String.class, cp.getType());
}
@Test
public void isReadOnly_readWriteNullable_returnsTrue() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertFalse(cp.isReadOnly());
}
@Test
public void isReadOnly_readOnlyNullable_returnsTrue() {
ColumnProperty cp = new ColumnProperty("NAME", true, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertTrue(cp.isReadOnly());
}
@Test
public void setReadOnly_readOnlyChangeAllowed_shouldSucceed() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
cp.setReadOnly(true);
Assert.assertTrue(cp.isReadOnly());
}
@@ -125,7 +127,7 @@ public class ColumnPropertyTest {
@Test
public void setReadOnly_readOnlyChangeDisallowed_shouldFail() {
ColumnProperty cp = new ColumnProperty("NAME", false, false, true,
- "Ville", String.class);
+ false, "Ville", String.class);
cp.setReadOnly(true);
Assert.assertFalse(cp.isReadOnly());
}
@@ -133,14 +135,14 @@ public class ColumnPropertyTest {
@Test
public void getPropertyId_normal_returnsNAME() {
ColumnProperty cp = new ColumnProperty("NAME", false, false, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertEquals("NAME", cp.getPropertyId());
}
@Test
public void isModified_valueModified_returnsTrue() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
RowItem owner = new RowItem(container, new RowId(new Object[] { 1 }),
Arrays.asList(cp));
@@ -155,14 +157,14 @@ public class ColumnPropertyTest {
@Test
public void isModified_valueNotModified_returnsFalse() {
ColumnProperty cp = new ColumnProperty("NAME", false, false, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Assert.assertFalse(cp.isModified());
}
@Test
public void setValue_nullOnNullable_shouldWork() {
ColumnProperty cp = new ColumnProperty("NAME", false, true, true,
- "asdf", String.class);
+ false, "asdf", String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
new RowItem(container, new RowId(new Object[] { 1 }), Arrays.asList(cp));
cp.setValue(null);
@@ -171,8 +173,8 @@ public class ColumnPropertyTest {
@Test
public void setValue_resetTonullOnNullable_shouldWork() {
- ColumnProperty cp = new ColumnProperty("NAME", false, true, true, null,
- String.class);
+ ColumnProperty cp = new ColumnProperty("NAME", false, true, true, false,
+ null, String.class);
SQLContainer container = EasyMock.createMock(SQLContainer.class);
new RowItem(container, new RowId(new Object[] { 1 }), Arrays.asList(cp));
cp.setValue("asdf");
@@ -202,7 +204,7 @@ public class ColumnPropertyTest {
}
ColumnProperty property = new ColumnProperty("NAME", false, true, true,
- "Ville", String.class);
+ false, "Ville", String.class);
Statement statement = EasyMock.createNiceMock(Statement.class);
EasyMock.replay(statement);
@@ -229,4 +231,85 @@ public class ColumnPropertyTest {
Assert.assertEquals("Kalle", container.value);
Assert.assertTrue(container.modified);
}
+
+ @Test
+ public void versionColumnsShouldNotBeInValueMap_shouldReturnFalse() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ false, "Ville", String.class);
+ property.setVersionColumn(true);
+
+ Assert.assertFalse(property.isPersistent());
+ }
+
+ @Test
+ public void neverWritableColumnsShouldNotBeInValueMap_shouldReturnFalse() {
+ ColumnProperty property = new ColumnProperty("NAME", true, false, true,
+ false, "Ville", String.class);
+
+ Assert.assertFalse(property.isPersistent());
+ }
+
+ @Test
+ public void writableColumnsShouldBeInValueMap_shouldReturnTrue() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ false, "Ville", String.class);
+
+ Assert.assertTrue(property.isPersistent());
+ }
+
+ @Test
+ public void writableButReadOnlyColumnsShouldNotBeInValueMap_shouldReturnFalse() {
+ ColumnProperty property = new ColumnProperty("NAME", true, true, true,
+ false, "Ville", String.class);
+
+ Assert.assertFalse(property.isPersistent());
+ }
+
+ @Test
+ public void primKeysShouldBeRowIdentifiers_shouldReturnTrue() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ true, "Ville", String.class);
+
+ Assert.assertTrue(property.isRowIdentifier());
+ }
+
+ @Test
+ public void versionColumnsShouldBeRowIdentifiers_shouldReturnTrue() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ false, "Ville", String.class);
+ property.setVersionColumn(true);
+
+ Assert.assertTrue(property.isRowIdentifier());
+ }
+
+ @Test
+ public void nonPrimKeyOrVersionColumnsShouldBeNotRowIdentifiers_shouldReturnFalse() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ false, "Ville", String.class);
+
+ Assert.assertFalse(property.isRowIdentifier());
+ }
+
+ @Test
+ public void getOldValueShouldReturnPreviousValue_shouldReturnVille() {
+ ColumnProperty property = new ColumnProperty("NAME", false, true, true,
+ false, "Ville", String.class);
+
+ // Here we really don't care about the container management, but in
+ // order to set the value for a column the owner (RowItem) must be set
+ // and to create the owner we must have a container...
+ ArrayList<ColumnProperty> properties = new ArrayList<ColumnProperty>();
+ properties.add(property);
+
+ SQLContainer container = EasyMock.createNiceMock(SQLContainer.class);
+ RowItem rowItem = new RowItem(container, new RowId(new Object[] { 1 }),
+ Arrays.asList(property));
+
+ property.setValue("Kalle");
+ // Just check that the new value was actually set...
+ Assert.assertEquals("Kalle", property.getValue());
+ // Assert that old value is the original value...
+ Assert.assertEquals("Ville", property.getOldValue());
+ }
+
}
diff --git a/tests/server-side/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java b/tests/server-side/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
index 657f06ae5e..e135894013 100644
--- a/tests/server-side/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
+++ b/tests/server-side/com/vaadin/data/util/sqlcontainer/query/TableQueryTest.java
@@ -18,15 +18,13 @@ import com.vaadin.data.Container.Filter;
import com.vaadin.data.util.filter.Compare.Equal;
import com.vaadin.data.util.filter.Like;
import com.vaadin.data.util.sqlcontainer.AllTests;
+import com.vaadin.data.util.sqlcontainer.AllTests.DB;
import com.vaadin.data.util.sqlcontainer.DataGenerator;
import com.vaadin.data.util.sqlcontainer.OptimisticLockException;
import com.vaadin.data.util.sqlcontainer.RowItem;
import com.vaadin.data.util.sqlcontainer.SQLContainer;
-import com.vaadin.data.util.sqlcontainer.AllTests.DB;
import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
public class TableQueryTest {
@@ -281,7 +279,9 @@ public class TableQueryTest {
AllTests.sqlGen);
try {
tQuery.containsRowWithKey(new Object[] { null });
- } catch (SQLException e) {
+ org.junit.Assert
+ .fail("null should throw an IllegalArgumentException from StatementHelper");
+ } catch (IllegalArgumentException e) {
// We should now be able to reserve two connections
connectionPool.reserveConnection();
connectionPool.reserveConnection();
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.html b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.html
index 64fe8e2952..2783ed2aa3 100644
--- a/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.html
+++ b/tests/testbench/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRange.html
@@ -24,7 +24,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup1-01-2011</td>
</tr>
<tr>
<td>mouseClick</td>
@@ -34,7 +34,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup1-12-2010</td>
</tr>
<tr>
<td>mouseClick</td>
@@ -44,7 +44,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup1-12-2009</td>
</tr>
<tr>
<td>mouseClick</td>
@@ -64,7 +64,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup2-02-2010</td>
</tr>
<tr>
<td>pressSpecialKey</td>
@@ -79,7 +79,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup2-03-2010</td>
</tr>
<tr>
<td>pressSpecialKey</td>
@@ -94,7 +94,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup2-02-2010-again</td>
</tr>
<tr>
<td>mouseClick</td>
@@ -114,7 +114,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup3-01-2010</td>
</tr>
<tr>
<td>pressSpecialKey</td>
@@ -124,14 +124,13 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td></td>
+ <td>popup3-01-2009</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentsdatefieldPopupDateFieldExtendedRange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VPopupCalendar[0]#popupButton</td>
<td>10,8</td>
</tr>
-
</tbody></table>
</body>
</html>
diff --git a/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.html b/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.html
new file mode 100644
index 0000000000..d8fb0593d1
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>EmbeddedClickListenerRelativeCoordinates</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">EmbeddedClickListenerRelativeCoordinates</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.embedded.EmbeddedApplet?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>with-applet</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedApplet::/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>without-applet</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.java b/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.java
new file mode 100644
index 0000000000..1bb3e7abe2
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/embedded/EmbeddedApplet.java
@@ -0,0 +1,43 @@
+package com.vaadin.tests.components.embedded;
+
+import com.vaadin.terminal.ExternalResource;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Window;
+
+public class EmbeddedApplet extends TestBase {
+
+ @Override
+ protected String getDescription() {
+ return "The sub window should be shown on top of the embedded applet";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 8399;
+ }
+
+ @Override
+ public void setup() {
+ final Embedded applet = new Embedded();
+ applet.setType(Embedded.TYPE_BROWSER);
+ applet.setWidth("400px");
+ applet.setHeight("300px");
+ applet.setSource(new ExternalResource("/statictestfiles/applet.html"));
+ addComponent(applet);
+
+ addComponent(new Button("Remove applet", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ removeComponent(applet);
+ }
+ }));
+
+ Window window = new Window("Testwindow");
+ window.addComponent(new Label("I am inside the window"));
+ applet.getRoot().addWindow(window);
+ }
+}
diff --git a/tests/testbench/com/vaadin/tests/components/embedded/TestApplet.java b/tests/testbench/com/vaadin/tests/components/embedded/TestApplet.java
new file mode 100644
index 0000000000..3cf7cf888b
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/embedded/TestApplet.java
@@ -0,0 +1,11 @@
+package com.vaadin.tests.components.embedded;
+
+import java.applet.Applet;
+import java.awt.Graphics;
+
+public class TestApplet extends Applet {
+ @Override
+ public void paint(Graphics g) {
+ g.drawString("Hello, I am an applet! Look at me!", 10, 20);
+ }
+}
diff --git a/tests/testbench/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html b/tests/testbench/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html
index 288fd65c66..1ab75e1176 100644
--- a/tests/testbench/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html
+++ b/tests/testbench/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html
@@ -34,7 +34,7 @@
<tr>
<td>keyDown</td>
<td>vaadin=runcomvaadintestscomponentsnotificationNotifications::Root/VNotification[0]/HTML[0]/domChild[0]</td>
- <td>\\27</td>
+ <td>\27</td>
</tr>
<!-- Fade delay is 400 ms by default - VNotification -->
<tr>
diff --git a/tests/testbench/com/vaadin/tests/components/notification/SemiTransparentNotification.java b/tests/testbench/com/vaadin/tests/components/notification/SemiTransparentNotification.java
new file mode 100755
index 0000000000..8fefac16a1
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/notification/SemiTransparentNotification.java
@@ -0,0 +1,31 @@
+package com.vaadin.tests.components.notification;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.LoremIpsum;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+
+public class SemiTransparentNotification extends TestBase {
+
+ @Override
+ protected void setup() {
+ Label l = new Label(LoremIpsum.get(10000));
+ getLayout().setSizeFull();
+ addComponent(l);
+ Notification.show("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This should be a <br/><b>SEMI-TRANSPARENT</b><br/> notification",
+ Notification.TYPE_WARNING_MESSAGE);
+ }
+
+ @Override
+ protected String getDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/tests/testbench/com/vaadin/tests/components/notification/SemitransparentNotification.html b/tests/testbench/com/vaadin/tests/components/notification/SemitransparentNotification.html
new file mode 100755
index 0000000000..f125b98ee1
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/notification/SemitransparentNotification.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.notification.SemiTransparentNotification</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>semitransparent-warning</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.html b/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.html
new file mode 100644
index 0000000000..c52bfa634d
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.html
@@ -0,0 +1,152 @@
+<?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:8068/" />
+<title>PopupViewClickShortcut</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">PopupViewClickShortcut</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.popupview.PopupViewClickShortcut?restartApplication=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::</td>
+ <td>ctrl alt M</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]</td>
+ <td>added 5</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_0</td>
+ <td>1. Submitted from Main window</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPopupView[0]</td>
+ <td>57,6</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::</td>
+ <td>ctrl alt P</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]</td>
+ <td>159,142</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]</td>
+ <td>ctrl alt P</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[6]/domChild[0]/domChild[0]</td>
+ <td>added 6</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_1</td>
+ <td>2. Submitted from Popup</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_0</td>
+ <td>3. Submitted from Popup</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]</td>
+ <td>83,151</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]</td>
+ <td>ctrl alt S</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]</td>
+ <td>added 5</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_0</td>
+ <td>4. Submitted from Subwindow</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VPopupView[0]</td>
+ <td>76,4</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]</td>
+ <td>ctrl alt U</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]</td>
+ <td>132,11</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]</td>
+ <td>ctrl alt U</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VPopupView[0]/VPopupView$CustomPopup[0]/VCaptionWrapper[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[6]/domChild[0]/domChild[0]</td>
+ <td>added 6</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_1</td>
+ <td>5. Submitted from Subwindow popup</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_0</td>
+ <td>6. Submitted from Subwindow popup</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::/VVerticalLayout[0]/domChild[0]/domChild[1]</td>
+ <td>279,482</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::</td>
+ <td>ctrl alt P</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::</td>
+ <td>ctrl alt U</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::</td>
+ <td>ctrl alt S</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentspopupviewPopupViewClickShortcut::PID_SLog_row_0</td>
+ <td>6. Submitted from Subwindow popup</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java b/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java
index 6461d10277..ba4fe93b68 100644
--- a/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java
+++ b/tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java
@@ -46,17 +46,17 @@ public class PopupViewClickShortcut extends TestBase {
l.setWidth(null);
Button b = new Button("Submit " + caption + " (Ctrl+Alt+"
- + String.valueOf(Character.toChars(keyCode)) + ")",
- new Button.ClickListener() {
- private int i = 5;
+ + (char) keyCode + ")", new Button.ClickListener() {
+ private int i = 5;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ log.log("Submitted from "
+ + event.getButton().getParent().getCaption());
+ t.addItem(new String[] { "added " + i++ }, i);
+ }
+ });
- @Override
- public void buttonClick(ClickEvent event) {
- log.log("Submitted from "
- + event.getButton().getParent().getCaption());
- t.addItem(new String[] { "added " + i++ }, i);
- }
- });
b.setClickShortcut(keyCode, ModifierKey.CTRL, ModifierKey.ALT);
l.addComponent(t);
diff --git a/tests/testbench/com/vaadin/tests/components/table/EmptyTable.html b/tests/testbench/com/vaadin/tests/components/table/EmptyTable.html
index 58f26cf607..7196771f56 100644
--- a/tests/testbench/com/vaadin/tests/components/table/EmptyTable.html
+++ b/tests/testbench/com/vaadin/tests/components/table/EmptyTable.html
@@ -65,7 +65,7 @@
<tr>
<td>screenCapture</td>
<td></td>
- <td>empty-table</td>
+ <td>empty-table-after-reload</td>
</tr>
</tbody></table>
</body>
diff --git a/tests/testbench/com/vaadin/tests/components/table/HorizontalScrollWithNoRows.html b/tests/testbench/com/vaadin/tests/components/table/HorizontalScrollWithNoRows.html
new file mode 100644
index 0000000000..98629252d9
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/table/HorizontalScrollWithNoRows.html
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.table.Tables?restartApplication</td>
+ <td></td>
+</tr>
+<!--Remove all rows-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td>
+ <td>23,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item5</td>
+ <td>33,5</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item1</td>
+ <td>50,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item0</td>
+ <td>54,10</td>
+</tr>
+<!--Remove log-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item1</td>
+ <td>28,9</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item0</td>
+ <td>29,5</td>
+</tr>
+<!--Resize column, should get scrollbar-->
+<tr>
+ <td>drag</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>0,7</td>
+</tr>
+<tr>
+ <td>drop</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>150,7</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>1-wide-header</td>
+</tr>
+<!--Resize back, scrollbar should disappear-->
+<tr>
+ <td>drag</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>0,7</td>
+</tr>
+<!-- Overcompensate by 2px because of off-by-one bug in testbench -->
+<tr>
+ <td>drop</td>
+ <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+ <td>-152,7</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>2-narrow-header</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/textarea/TextAreaMaxLength.html b/tests/testbench/com/vaadin/tests/components/textarea/TextAreaMaxLength.html
new file mode 100755
index 0000000000..5fe43b7b7a
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/textarea/TextAreaMaxLength.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://arturwin.office.itmill.com:9999/" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.textarea.TextAreaTest?debug&amp;restartApplication</td>
+ <td></td>
+</tr>
+<!--max length 5-->
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::PID_Smenu#item0</td>
+ <td>20,9</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::Root/VOverlay[0]/VMenuBar[0]#item5</td>
+ <td>43,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::Root/VOverlay[1]/VMenuBar[0]#item2</td>
+ <td>70,13</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::Root/VOverlay[2]/VMenuBar[0]#item5</td>
+ <td>40,9</td>
+</tr>
+<tr>
+ <td>enterCharacter</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::PID_StestComponent</td>
+ <td>0123456789</td>
+</tr>
+<tr>
+ <td>assertValue</td>
+ <td>vaadin=runcomvaadintestscomponentstextareaTextAreaTest::PID_StestComponent</td>
+ <td>01234</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/tree/TreeItemClickAndValueChange.html b/tests/testbench/com/vaadin/tests/components/tree/TreeItemClickAndValueChange.html
new file mode 100644
index 0000000000..bf83a1acdb
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/tree/TreeItemClickAndValueChange.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>TreeItemClickAndValueChange</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">TreeItemClickAndValueChange</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/Trees?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::PID_Smenu#item0</td>
+ <td>19,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::Root/VOverlay[0]/VMenuBar[0]#item3</td>
+ <td>23,7</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::Root/VOverlay[1]/VMenuBar[0]#item0</td>
+ <td>38,6</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::PID_Smenu#item0</td>
+ <td>52,12</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::Root/VOverlay[0]/VMenuBar[0]#item3</td>
+ <td>53,12</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::Root/VOverlay[1]/VMenuBar[0]#item4</td>
+ <td>50,4</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::PID_StestComponent#n[0]</td>
+ <td>22,9</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runTrees::PID_StestComponent#n[1]</td>
+ <td>20,6</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runTrees::PID_SLog_row_0</td>
+ <td>5. ValueChangeEvent, new value: '[Item 2]'</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runTrees::PID_SLog_row_1</td>
+ <td>4. left click on source: [Item 1], client: [*];, relative: [-1,-1], itemId: Item 2, propertyId: null</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runTrees::PID_SLog_row_2</td>
+ <td>3. ValueChangeEvent, new value: '[Item 1]'</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runTrees::PID_SLog_row_3</td>
+ <td>2. left click on source: [], client: [*];, relative: [-1,-1], itemId: Item 1, propertyId: null</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/treetable/AddItemToEmptyTreeTable.html b/tests/testbench/com/vaadin/tests/components/treetable/AddItemToEmptyTreeTable.html
new file mode 100755
index 0000000000..15dc0e074d
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/treetable/AddItemToEmptyTreeTable.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>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.treetable.TreeTableTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_Smenu#item0</td>
+ <td>38,10</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[0]/VMenuBar[0]#item5</td>
+ <td>52,6</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[1]/VMenuBar[0]#item1</td>
+ <td>68,8</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>
+ <td>12,4</td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.treetable.TreeTableTest</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_Smenu#item0</td>
+ <td>33,7</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[0]/VMenuBar[0]#item5</td>
+ <td>52,9</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[1]/VMenuBar[0]#item1</td>
+ <td>39,5</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::Root/VOverlay[2]/VMenuBar[0]#item1</td>
+ <td>23,3</td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>item-added-to-empty-treetable</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>