diff options
49 files changed, 915 insertions, 139 deletions
diff --git a/WebContent/VAADIN/themes/base/menubar/menubar.css b/WebContent/VAADIN/themes/base/menubar/menubar.css index 93ff5466b6..52dc6ae545 100644 --- a/WebContent/VAADIN/themes/base/menubar/menubar.css +++ b/WebContent/VAADIN/themes/base/menubar/menubar.css @@ -1,12 +1,14 @@ .v-menubar { float: left; /* Force minimum width */ - overflow: hidden; + white-space: nowrap; } .v-menubar .v-menubar-menuitem { cursor: default; vertical-align: middle; white-space: nowrap; - float: left; + display: inline; + display: inline-block; + zoom: 1; } .v-menubar .v-menubar-menuitem-caption * { vertical-align: middle; @@ -21,6 +23,7 @@ } .v-menubar-submenu .v-menubar-menuitem { cursor: default; + display: block; position: relative; padding-right: 1.5em; } diff --git a/WebContent/VAADIN/themes/base/slider/slider.css b/WebContent/VAADIN/themes/base/slider/slider.css index 7df6a4d667..5ee6cbf31c 100644 --- a/WebContent/VAADIN/themes/base/slider/slider.css +++ b/WebContent/VAADIN/themes/base/slider/slider.css @@ -38,6 +38,21 @@ margin-left: -5px; } +.v-slider-feedback { + padding: 2px 5px; + background: #444; + color: #fff; + font-size: 11px; + line-height: 13px; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + margin: -2px 0 0 2px; + text-shadow: 0 1px 0 #000; +} + /* Disabled by default .v-slider-error .v-slider-base { background: #FFE0E0; diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css index 2c508ca59e..f1840c6bf2 100644 --- a/WebContent/VAADIN/themes/base/styles.css +++ b/WebContent/VAADIN/themes/base/styles.css @@ -647,13 +647,15 @@ div.v-app-loading { .v-menubar { float: left; /* Force minimum width */ - overflow: hidden; + white-space: nowrap; } .v-menubar .v-menubar-menuitem { cursor: default; vertical-align: middle; white-space: nowrap; - float: left; + display: inline; + display: inline-block; + zoom: 1; } .v-menubar .v-menubar-menuitem-caption * { vertical-align: middle; @@ -668,6 +670,7 @@ div.v-app-loading { } .v-menubar-submenu .v-menubar-menuitem { cursor: default; + display: block; position: relative; padding-right: 1.5em; } @@ -1151,6 +1154,21 @@ div.v-progressindicator-indeterminate-disabled { margin-left: -5px; } +.v-slider-feedback { + padding: 2px 5px; + background: #444; + color: #fff; + font-size: 11px; + line-height: 13px; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + margin: -2px 0 0 2px; + text-shadow: 0 1px 0 #000; +} + /* Disabled by default .v-slider-error .v-slider-base { background: #FFE0E0; @@ -1637,7 +1655,7 @@ div.v-tree-node-leaf { font-weight: bold; } /* A more specific selector to make sure padding isn't so easily overridden */ -.div.v-window-header { +div.v-window-header { white-space: nowrap; text-overflow: ellipsis; -ms-text-overflow: ellipsis; @@ -1659,6 +1677,9 @@ div.v-tree-node-leaf { .v-window-contents, x:-moz-any-link, x:default { overflow: visible; } +.v-window-contents > div { + outline: none; +} .v-window-footer { overflow: hidden; zoom: 1; diff --git a/WebContent/VAADIN/themes/base/window/window.css b/WebContent/VAADIN/themes/base/window/window.css index 56adb899e4..d4c03bd82e 100644 --- a/WebContent/VAADIN/themes/base/window/window.css +++ b/WebContent/VAADIN/themes/base/window/window.css @@ -10,7 +10,7 @@ font-weight: bold; } /* A more specific selector to make sure padding isn't so easily overridden */ -.div.v-window-header { +div.v-window-header { white-space: nowrap; text-overflow: ellipsis; -ms-text-overflow: ellipsis; @@ -32,6 +32,9 @@ .v-window-contents, x:-moz-any-link, x:default { overflow: visible; } +.v-window-contents > div { + outline: none; +} .v-window-footer { overflow: hidden; zoom: 1; diff --git a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png Binary files differindex c11ee47f9e..ec72a8b6a3 100644 --- a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png +++ b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png diff --git a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png Binary files differindex 4a4537ac06..c0e29a99f5 100644 --- a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png +++ b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png diff --git a/WebContent/VAADIN/themes/reindeer/menubar/menubar.css b/WebContent/VAADIN/themes/reindeer/menubar/menubar.css index ac60652d11..77903356ce 100644 --- a/WebContent/VAADIN/themes/reindeer/menubar/menubar.css +++ b/WebContent/VAADIN/themes/reindeer/menubar/menubar.css @@ -1,6 +1,5 @@ .v-menubar { height: 23px; - overflow: hidden; background: #323336 repeat-x; background-image: url(img/bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */ color: #d1d3d6; diff --git a/WebContent/VAADIN/themes/reindeer/slider/img/knob-pressed.png b/WebContent/VAADIN/themes/reindeer/slider/img/knob-pressed.png Binary files differindex 3ea2724e77..d5afcb71a0 100644 --- a/WebContent/VAADIN/themes/reindeer/slider/img/knob-pressed.png +++ b/WebContent/VAADIN/themes/reindeer/slider/img/knob-pressed.png diff --git a/WebContent/VAADIN/themes/reindeer/slider/slider.css b/WebContent/VAADIN/themes/reindeer/slider/slider.css index 33ce41ca72..cb5a0f7dbe 100644 --- a/WebContent/VAADIN/themes/reindeer/slider/slider.css +++ b/WebContent/VAADIN/themes/reindeer/slider/slider.css @@ -17,7 +17,7 @@ height: 10px; margin-top: -5px; } -.v-slider-handle:active { +.v-slider-handle-active { background-image: url(img/knob-pressed.png); /** sprite-ref: verticals */ } .v-slider-vertical { diff --git a/WebContent/VAADIN/themes/reindeer/styles.css b/WebContent/VAADIN/themes/reindeer/styles.css index ee9629160e..446c69d7d9 100644 --- a/WebContent/VAADIN/themes/reindeer/styles.css +++ b/WebContent/VAADIN/themes/reindeer/styles.css @@ -647,13 +647,15 @@ div.v-app-loading { .v-menubar { float: left; /* Force minimum width */ - overflow: hidden; + white-space: nowrap; } .v-menubar .v-menubar-menuitem { cursor: default; vertical-align: middle; white-space: nowrap; - float: left; + display: inline; + display: inline-block; + zoom: 1; } .v-menubar .v-menubar-menuitem-caption * { vertical-align: middle; @@ -668,6 +670,7 @@ div.v-app-loading { } .v-menubar-submenu .v-menubar-menuitem { cursor: default; + display: block; position: relative; padding-right: 1.5em; } @@ -1151,6 +1154,21 @@ div.v-progressindicator-indeterminate-disabled { margin-left: -5px; } +.v-slider-feedback { + padding: 2px 5px; + background: #444; + color: #fff; + font-size: 11px; + line-height: 13px; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + margin: -2px 0 0 2px; + text-shadow: 0 1px 0 #000; +} + /* Disabled by default .v-slider-error .v-slider-base { background: #FFE0E0; @@ -1637,7 +1655,7 @@ div.v-tree-node-leaf { font-weight: bold; } /* A more specific selector to make sure padding isn't so easily overridden */ -.div.v-window-header { +div.v-window-header { white-space: nowrap; text-overflow: ellipsis; -ms-text-overflow: ellipsis; @@ -1659,6 +1677,9 @@ div.v-tree-node-leaf { .v-window-contents, x:-moz-any-link, x:default { overflow: visible; } +.v-window-contents > div { + outline: none; +} .v-window-footer { overflow: hidden; zoom: 1; @@ -3083,7 +3104,6 @@ td.v-datefield-calendarpanel-nextyear { .v-menubar { height: 23px; - overflow: hidden; background: #323336 repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); @@ -3650,7 +3670,7 @@ td.v-datefield-calendarpanel-nextyear { height: 10px; margin-top: -5px; } -.v-slider-handle:active { +.v-slider-handle-active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); background-position: left -895px; @@ -4236,6 +4256,7 @@ td.v-datefield-calendarpanel-nextyear { .v-ie .v-tabsheet-tabs .v-errorindicator { zoom: 1; display: inline; + display: inline-block; } /* Tabsheet scroller styles */ @@ -4863,9 +4884,6 @@ input.v-textfield-readonly, .v-window-contents { background: #fff; } -.v-window-contents > div { - outline: none; -} .v-window-modalitycurtain { background: #56595b; } diff --git a/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet-normal-style.css b/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet-normal-style.css index 607b25b794..8cf324be26 100644 --- a/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet-normal-style.css +++ b/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet-normal-style.css @@ -157,4 +157,5 @@ .v-ie .v-tabsheet-tabs .v-errorindicator { zoom: 1; display: inline; + display: inline-block; }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/reindeer/window/window.css b/WebContent/VAADIN/themes/reindeer/window/window.css index 0027fcf9e3..a755654d33 100644 --- a/WebContent/VAADIN/themes/reindeer/window/window.css +++ b/WebContent/VAADIN/themes/reindeer/window/window.css @@ -82,9 +82,6 @@ .v-window-contents { background: #fff; } -.v-window-contents > div { - outline: none; -} .v-window-modalitycurtain { background: #56595b; } diff --git a/WebContent/VAADIN/themes/runo/slider/slider.css b/WebContent/VAADIN/themes/runo/slider/slider.css index 5665a2aaee..07b10dfa17 100644 --- a/WebContent/VAADIN/themes/runo/slider/slider.css +++ b/WebContent/VAADIN/themes/runo/slider/slider.css @@ -51,7 +51,7 @@ height: 12px; margin-left: -5px; } -.v-slider-vertical .v-slider-handle:hover { +.v-slider-vertical .v-slider-handle-active { background-position: left bottom; } diff --git a/WebContent/VAADIN/themes/runo/styles.css b/WebContent/VAADIN/themes/runo/styles.css index 0ae0f686f0..06bce5dfa9 100644 --- a/WebContent/VAADIN/themes/runo/styles.css +++ b/WebContent/VAADIN/themes/runo/styles.css @@ -647,13 +647,15 @@ div.v-app-loading { .v-menubar { float: left; /* Force minimum width */ - overflow: hidden; + white-space: nowrap; } .v-menubar .v-menubar-menuitem { cursor: default; vertical-align: middle; white-space: nowrap; - float: left; + display: inline; + display: inline-block; + zoom: 1; } .v-menubar .v-menubar-menuitem-caption * { vertical-align: middle; @@ -668,6 +670,7 @@ div.v-app-loading { } .v-menubar-submenu .v-menubar-menuitem { cursor: default; + display: block; position: relative; padding-right: 1.5em; } @@ -1151,6 +1154,21 @@ div.v-progressindicator-indeterminate-disabled { margin-left: -5px; } +.v-slider-feedback { + padding: 2px 5px; + background: #444; + color: #fff; + font-size: 11px; + line-height: 13px; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + margin: -2px 0 0 2px; + text-shadow: 0 1px 0 #000; +} + /* Disabled by default .v-slider-error .v-slider-base { background: #FFE0E0; @@ -1637,7 +1655,7 @@ div.v-tree-node-leaf { font-weight: bold; } /* A more specific selector to make sure padding isn't so easily overridden */ -.div.v-window-header { +div.v-window-header { white-space: nowrap; text-overflow: ellipsis; -ms-text-overflow: ellipsis; @@ -1659,6 +1677,9 @@ div.v-tree-node-leaf { .v-window-contents, x:-moz-any-link, x:default { overflow: visible; } +.v-window-contents > div { + outline: none; +} .v-window-footer { overflow: hidden; zoom: 1; @@ -2755,7 +2776,7 @@ div.v-tree-node-leaf { height: 12px; margin-left: -5px; } -.v-slider-vertical .v-slider-handle:hover { +.v-slider-vertical .v-slider-handle-active { background-position: left bottom; } diff --git a/WebContent/VAADIN/themes/sampler/sampler/styles.css b/WebContent/VAADIN/themes/sampler/sampler/styles.css index ca1b09233b..bfe46a4956 100644 --- a/WebContent/VAADIN/themes/sampler/sampler/styles.css +++ b/WebContent/VAADIN/themes/sampler/sampler/styles.css @@ -332,14 +332,20 @@ } .v-app-SamplerApplication .v-label-root-section em { - float: right; - margin-top: 12px; + position: absolute; + right: 20px; + margin-top: 11px; + padding: 2px 10px; + background: #fff; font-style: normal; color: #b4b8bc; font-size: 11px; font-weight: bold; text-transform: uppercase; letter-spacing: 0.02em; + border-radius: 8px; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; } .v-app-SamplerApplication .v-label-root-section h2 { @@ -351,6 +357,7 @@ color: #1e2229; overflow: hidden; text-overflow: ellipsis; + float: left; } .v-app-SamplerApplication .v-label-root-section span { display: block; diff --git a/WebContent/WEB-INF/liferay-display.xml b/WebContent/WEB-INF/liferay-display.xml index 302f9961dd..d83b47d8b0 100644 --- a/WebContent/WEB-INF/liferay-display.xml +++ b/WebContent/WEB-INF/liferay-display.xml @@ -22,5 +22,6 @@ <portlet id="InterPortletEventPortlet" /> <portlet id="VaadinInterPortletEventPortlet" /> --> + <portlet id="Portlet Mode Example"/> </category> </display>
\ No newline at end of file diff --git a/WebContent/WEB-INF/liferay-portlet.xml b/WebContent/WEB-INF/liferay-portlet.xml index 696afaaee8..a3c61dc439 100644 --- a/WebContent/WEB-INF/liferay-portlet.xml +++ b/WebContent/WEB-INF/liferay-portlet.xml @@ -77,6 +77,11 @@ <instanceable>true</instanceable> <ajaxable>false</ajaxable> </portlet> + <portlet> + <portlet-name>Portlet Mode Example</portlet-name> + <instanceable>true</instanceable> + <ajaxable>false</ajaxable> + </portlet> <role-mapper> <role-name>administrator</role-name> diff --git a/WebContent/WEB-INF/portlet.xml b/WebContent/WEB-INF/portlet.xml index 2d58a61ae4..b1a6d4722d 100644 --- a/WebContent/WEB-INF/portlet.xml +++ b/WebContent/WEB-INF/portlet.xml @@ -201,7 +201,27 @@ </supported-publishing-event> <supported-public-render-parameter>HelloState</supported-public-render-parameter> </portlet> - --> + --> + <portlet> + <portlet-name>Portlet Mode Example</portlet-name> + <display-name>Portlet Mode Example</display-name> + <portlet-class>com.vaadin.demo.portlet.PortletModePortlet</portlet-class> + <init-param> + <name>widgetset</name> + <value>com.vaadin.portal.gwt.PortalDefaultWidgetSet</value> + </init-param> + <supports> + <mime-type>text/html</mime-type> + <portlet-mode>view</portlet-mode> + <portlet-mode>edit</portlet-mode> + <portlet-mode>help</portlet-mode> + <portlet-mode>config</portlet-mode> + </supports> + <portlet-info> + <title>PortletModeExample</title> + <short-title>PortletModeExample</short-title> + </portlet-info> + </portlet> <portlet> <portlet-name>AddressBookPortlet</portlet-name> @@ -342,6 +362,13 @@ </security-role-ref> </portlet> + <!-- Used by the Portlet mode demo --> + <custom-portlet-mode> + <description>Custom mode</description> + <portlet-mode>config</portlet-mode> + <portal-managed>false</portal-managed> + </custom-portlet-mode> + <!-- These can be used to customize the event object types. The types must be serializable and have JAXB binding. diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 74f84f9653..0de559fda8 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -132,6 +132,12 @@ public class ColorPicker extends AbstractField {</pre> <ul> <li>Similar to <b>HttpServletRequestListener</b>, but for portlets. Called before and after every portlet request and provides access to <b>PortletRequest</b> and <b>PortletResponse</b>.</li> </ul> + <li>Enhancements for the Portlet 2.0 support (<a href="http://dev.vaadin.com/ticket/3918">#3918</a>)</li> + <ul> + <li>Support for the edit and help modes</li> + <li>Support for custom modes and changing modes programmatically</li> + <li>See <a href="http://dev.vaadin.com/browser/versions/6.2/demo/src/com/vaadin/demo/portlet/PortletModeExample.java"><tt>com/vaadin/demo/portlet/PortletModeExample.java</tt></a> in the demo source code in the installation package for an example</li> + </ul> <li>Enhancements to various components:</li> <ul> <li><b>Window</b>: Additional control over a sub-window: close and drag prevention.</li> diff --git a/src/com/vaadin/data/util/FilesystemContainer.java b/src/com/vaadin/data/util/FilesystemContainer.java index adcfcfe3a7..1c9671d52d 100644 --- a/src/com/vaadin/data/util/FilesystemContainer.java +++ b/src/com/vaadin/data/util/FilesystemContainer.java @@ -32,10 +32,6 @@ import com.vaadin.terminal.Resource; * @VERSION@ * @since 3.0 */ -/** - * @author mattitahvonen - * - */ @SuppressWarnings("serial") public class FilesystemContainer implements Container.Hierarchical { @@ -404,10 +400,9 @@ public class FilesystemContainer implements Container.Hierarchical { for (final Iterator<File> i = ll.iterator(); i.hasNext();) { final File lf = i.next(); + col.add(lf); if (lf.isDirectory()) { addItemIds(col, lf); - } else { - col.add(lf); } } } diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index b246a50a6b..f5dddf5e23 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -362,6 +362,9 @@ public class IndexedContainer implements Container.Indexed, * @see com.vaadin.data.Container#removeItem(java.lang.Object) */ public boolean removeItem(Object itemId) { + if (itemId == null) { + return false; + } if (items.remove(itemId) == null) { return false; diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 8060edfe74..a523e8b00e 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -693,10 +693,9 @@ public class ApplicationConnection { return; } - ApplicationConnection.getConsole() - .log( - "JSON parsing took " - + (new Date().getTime() - start.getTime())); + ApplicationConnection.getConsole().log( + "JSON parsing took " + (new Date().getTime() - start.getTime()) + + "ms"); // Handle redirect if (json.containsKey("redirect")) { String url = json.getValueMap("redirect").getString("url"); @@ -1474,6 +1473,11 @@ public class ApplicationConnection { } } + if (configuration.useDebugIdInDOM() && uidl.getId().startsWith("PID_S")) { + DOM.setElementProperty(component.getElement(), "id", uidl.getId() + .substring(5)); + } + if (!visible) { // component is invisible, delete old size to notify parent, if // later make visible @@ -1575,12 +1579,6 @@ public class ApplicationConnection { parent.updateCaption((Paintable) component, uidl); } } - - if (configuration.useDebugIdInDOM() && uidl.getId().startsWith("PID_S")) { - DOM.setElementProperty(component.getElement(), "id", uidl.getId() - .substring(5)); - } - /* * updateComponentSize need to be after caption update so caption can be * taken into account diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index a46f9fa7d7..ca0165974a 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -548,18 +548,29 @@ public class Util { if ("hidden".equals(originalOverflow)) { return; } + + // check the scrolltop value before hiding the element + final int scrolltop = elem.getScrollTop(); elem.getStyle().setProperty("overflow", "hidden"); DeferredCommand.addCommand(new Command() { public void execute() { // Dough, Safari scroll auto means actually just a moped elem.getStyle().setProperty("overflow", originalOverflow); - if (elem.getScrollTop() > 0) { + + if (scrolltop > 0 || elem.getScrollTop() > 0) { + int scrollvalue = scrolltop; + if (scrolltop == 0) { + // mysterious are the ways of webkits scrollbar + // handling. In some cases webkit reports bad (0) + // scrolltop before hiding the elment temporary, + // sometimes after. + scrollvalue = elem.getScrollTop(); + } // fix another bug where scrollbar remains in wrong // position - int scrolltop = elem.getScrollTop(); - elem.setScrollTop(scrolltop - 1); - elem.setScrollTop(scrolltop); + elem.setScrollTop(scrollvalue - 1); + elem.setScrollTop(scrollvalue); } } }); diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java index b42b4f3bf3..f9a3c70c61 100644 --- a/src/com/vaadin/terminal/gwt/client/VTooltip.java +++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java @@ -91,6 +91,11 @@ public class VTooltip extends VOverlay { if (y + offsetHeight + MARGIN - Window.getScrollTop() > Window .getClientHeight()) { y = tooltipEventMouseY - 5 - offsetHeight; + if (y - Window.getScrollTop() < 0) { + // tooltip does not fit on top of the mouse either, + // put it at the top of the screen + y = Window.getScrollTop(); + } } setPopupPosition(x, y); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/VButton.java index de1d720618..36d9f5ec1e 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VButton.java @@ -394,6 +394,10 @@ public class VButton extends FocusWidget implements Paintable, ClickHandler { int w = Integer .parseInt(width.substring(0, width.length() - 2)); w -= getHorizontalBorderAndPaddingWidth(getElement()); + if (w < 0) { + // validity check for IE + w = 0; + } width = w + "px"; } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java index 3bd6f656f2..389c2210d3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCheckBox.java @@ -4,12 +4,17 @@ package com.vaadin.terminal.gwt.client.ui; +import com.google.gwt.dom.client.InputElement; +import com.google.gwt.dom.client.LabelElement; +import com.google.gwt.dom.client.Node; +import com.google.gwt.dom.client.NodeList; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; @@ -102,6 +107,36 @@ public class VCheckBox extends com.google.gwt.user.client.ui.CheckBox implements } @Override + public void setText(String text) { + super.setText(text); + if (BrowserInfo.get().isIE() && BrowserInfo.get().getIEVersion() < 8) { + + boolean breakLink = text == null || "".equals(text); + + // break or create link between label element and checkbox, to + // enable native focus outline around checkbox element itself, if + // caption is not present + NodeList<Node> childNodes = getElement().getChildNodes(); + String id = null; + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.getItem(i); + if (item.getNodeName().toLowerCase().equals("input")) { + InputElement input = (InputElement) item; + id = input.getId(); + } + if (item.getNodeName().toLowerCase().equals("label")) { + LabelElement label = (LabelElement) item; + if (breakLink) { + label.setHtmlFor(""); + } else { + label.setHtmlFor(id); + } + } + } + } + } + + @Override public void onBrowserEvent(Event event) { if (icon != null && (event.getTypeInt() == Event.ONCLICK) && (DOM.eventGetTarget(event) == icon.getElement())) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index 43ba72dc82..9cad1fbd91 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -86,9 +86,12 @@ public class VMenuBar extends Widget implements Paintable, @Override public void setWidth(String width) { Util.setWidthExcludingPaddingAndBorder(this, width, 0); - hideChildren(); - setSelected(null); - menuVisible = false; + if (!subMenu) { + // Only needed for root level menu + hideChildren(); + setSelected(null); + menuVisible = false; + } } /** @@ -657,7 +660,8 @@ public class VMenuBar extends Widget implements Paintable, protected boolean isSeparator = false; public CustomMenuItem(String html, Command cmd) { - setElement(DOM.createDiv()); + // We need spans to allow inline-block in IE + setElement(DOM.createSpan()); setHTML(html); setCommand(cmd); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 61e35a28bf..3c5ef55a6d 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -194,6 +194,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { : CACHE_RATE_DEFAULT); recalcWidths = uidl.hasAttribute("recalcWidths"); + if (recalcWidths) { + tHead.clear(); + } if (uidl.hasAttribute("pagelength")) { pageLength = uidl.getIntAttribute("pagelength"); @@ -206,8 +209,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (firstvisible != lastRequestedFirstvisible && scrollBody != null) { // received 'surprising' firstvisible from server: scroll there firstRowInViewPort = firstvisible; - bodyContainer.setScrollPosition(firstvisible - * scrollBody.getRowHeight()); + bodyContainer.setScrollPosition((int) (firstvisible * scrollBody + .getRowHeight())); } showRowHeaders = uidl.getBooleanAttribute("rowheaders"); @@ -292,7 +295,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { .getIntAttribute("firstrow"), uidl.getIntAttribute("rows")); bodyContainer.add(scrollBody); initialContentReceived = true; + ApplicationConnection.getConsole().log("foo"); if (isAttached()) { + ApplicationConnection.getConsole().log("bar"); sizeInit(); } scrollBody.restoreRowVisibility(); @@ -709,6 +714,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { * We must force an update of the row height as this point as it * might have been (incorrectly) calculated earlier */ + + int bodyHeight; if (pageLength == totalRows) { /* * A hack to support variable height rows when paging is off. @@ -717,13 +724,17 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { * height. */ // int bodyHeight = scrollBody.getOffsetHeight(); - int bodyHeight = scrollBody.getRequiredHeight(); - bodyContainer.setHeight(bodyHeight + "px"); - Util.runWebkitOverflowAutoFix(bodyContainer.getElement()); + bodyHeight = scrollBody.getRequiredHeight(); } else { - int bodyHeight = (scrollBody.getRowHeight(true) * pageLength); - bodyContainer.setHeight(bodyHeight + "px"); + bodyHeight = (int) Math.round(scrollBody.getRowHeight(true) + * pageLength); } + boolean needsSpaceForHorizontalSrollbar = (total > availW); + if (needsSpaceForHorizontalSrollbar) { + bodyHeight += Util.getNativeScrollbarSize(); + } + bodyContainer.setHeight(bodyHeight + "px"); + Util.runWebkitOverflowAutoFix(bodyContainer.getElement()); } isNewBody = false; @@ -733,8 +744,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { // without DeferredCommand.addCommand(new Command() { public void execute() { - bodyContainer.setScrollPosition(firstvisible - * scrollBody.getRowHeight()); + bodyContainer + .setScrollPosition((int) (firstvisible * scrollBody + .getRowHeight())); firstRowInViewPort = firstvisible; } }); @@ -753,7 +765,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (lastInNewSet > totalRows - 1) { lastInNewSet = totalRows - 1; } - rowRequestHandler.setReqRows(lastInNewSet - firstInNewSet); + rowRequestHandler.setReqRows(lastInNewSet - firstInNewSet + + 1); rowRequestHandler.deferRowFetch(1); } } @@ -772,7 +785,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { return true; } } else { - int fakeheight = scrollBody.getRowHeight() * totalRows; + int fakeheight = (int) Math.round(scrollBody.getRowHeight() + * totalRows); int availableHeight = bodyContainer.getElement().getPropertyInt( "clientHeight"); if (fakeheight > availableHeight) { @@ -1757,7 +1771,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { public static final int DEFAULT_ROW_HEIGHT = 24; - private int rowHeight = -1; + private double rowHeight = -1; private final List<Widget> renderedRows = new ArrayList<Widget>(); @@ -1886,11 +1900,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { reactLastRow = totalRows - 1; } if (lastRendered < reactLastRow) { + ApplicationConnection.getConsole().log("GET BELOW"); // get some cache rows below visible area rowRequestHandler.setReqFirstRow(lastRendered + 1); - rowRequestHandler.setReqRows(reactLastRow - lastRendered - 1); + rowRequestHandler.setReqRows(reactLastRow - lastRendered); rowRequestHandler.deferRowFetch(1); } else if (scrollBody.getFirstRendered() > reactFirstRow) { + ApplicationConnection.getConsole().log("GET ABOVE"); /* * Branch for fetching cache above visible area. * @@ -2023,23 +2039,23 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { } private void fixSpacers() { - int prepx = getRowHeight() * firstRendered; + int prepx = (int) Math.round(getRowHeight() * firstRendered); if (prepx < 0) { prepx = 0; } - DOM.setStyleAttribute(preSpacer, "height", prepx + "px"); - int postpx = getRowHeight() * (totalRows - 1 - lastRendered); + preSpacer.getStyle().setPropertyPx("height", prepx); + int postpx = (int) (getRowHeight() * (totalRows - 1 - lastRendered)); if (postpx < 0) { postpx = 0; } - DOM.setStyleAttribute(postSpacer, "height", postpx + "px"); + postSpacer.getStyle().setPropertyPx("height", postpx); } - public int getRowHeight() { + public double getRowHeight() { return getRowHeight(false); } - public int getRowHeight(boolean forceUpdate) { + public double getRowHeight(boolean forceUpdate) { if (tBodyMeasurementsDone && !forceUpdate) { return rowHeight; } else { @@ -2047,7 +2063,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (tBodyElement.getRows().getLength() > 0) { int tableHeight = getTableHeight(); int rowCount = tBodyElement.getRows().getLength(); - rowHeight = tableHeight / rowCount; + rowHeight = tableHeight / (double) rowCount; } else { if (isAttached()) { // measure row height by adding a dummy row @@ -2602,7 +2618,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { return new RenderSpace(w, 0) { @Override public int getHeight() { - return getRowHeight(); + return (int) getRowHeight(); } }; } @@ -2679,7 +2695,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { return; } - int rowHeight = scrollBody.getRowHeight(); + int rowHeight = (int) scrollBody.getRowHeight(); int bodyH = bodyContainer.getOffsetHeight(); int rowsAtOnce = bodyH / rowHeight; boolean anotherPartlyVisible = ((bodyH % rowHeight) != 0); @@ -2696,10 +2712,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (currentlyVisible < pageLength && currentlyVisible < totalRows) { // shake scrollpanel to fill empty space - bodyContainer.setScrollPosition(bodyContainer - .getScrollPosition() + 1); - bodyContainer.setScrollPosition(bodyContainer - .getScrollPosition() - 1); + bodyContainer.setScrollPosition(scrollTop + 1); + bodyContainer.setScrollPosition(scrollTop - 1); } } } @@ -2804,6 +2818,21 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { } colIndex++; } + if ((height == null || "".equals(height)) + && totalRows == pageLength) { + // fix body height (may vary if lazy loading is offhorizontal + // scrollbar appears/disappears) + int bodyHeight = scrollBody.getRequiredHeight(); + boolean needsSpaceForHorizontalSrollbar = (availW < usedMinimumWidth); + if (needsSpaceForHorizontalSrollbar) { + bodyHeight += Util.getNativeScrollbarSize(); + } + int heightBefore = getOffsetHeight(); + bodyContainer.setHeight(bodyHeight + "px"); + if (heightBefore != getOffsetHeight()) { + Util.notifyParentOfSizeChange(VScrollTable.this, false); + } + } scrollBody.reLayoutComponents(); DeferredCommand.addCommand(new Command() { public void execute() { @@ -2855,6 +2884,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { } private int contentAreaBorderHeight = -1; + private int scrollLeft; + private int scrollTop; /** * @return border top + border bottom of the scrollable area of table @@ -2886,6 +2917,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (initializedAndAttached) { updatePageLength(); } + if (!rendering) { + // Webkit may sometimes get an odd rendering bug (white space + // between header and body), see bug #3875. Running + // overflow hack here to shake body element a bit. + Util.runWebkitOverflowAutoFix(bodyContainer.getElement()); + } } /* @@ -2901,8 +2938,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { if (visible) { DeferredCommand.addCommand(new Command() { public void execute() { - bodyContainer.setScrollPosition(firstRowInViewPort - * scrollBody.getRowHeight()); + bodyContainer + .setScrollPosition((int) (firstRowInViewPort * scrollBody + .getRowHeight())); } }); } @@ -2933,24 +2971,38 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { * user scrolls */ public void onScroll(ScrollEvent event) { - int scrollLeft = bodyContainer.getElement().getScrollLeft(); - int scrollTop = bodyContainer.getScrollPosition(); + scrollLeft = bodyContainer.getElement().getScrollLeft(); + scrollTop = bodyContainer.getScrollPosition(); if (!initializedAndAttached) { return; } if (!enabled) { - bodyContainer.setScrollPosition(firstRowInViewPort - * scrollBody.getRowHeight()); + bodyContainer + .setScrollPosition((int) (firstRowInViewPort * scrollBody + .getRowHeight())); return; } rowRequestHandler.cancel(); + if (BrowserInfo.get().isSafari() && event != null && scrollTop == 0) { + // due to the webkitoverflowworkaround, top may sometimes report 0 + // for webkit, although it really is not. Expecting to have the + // correct + // value available soon. + DeferredCommand.addCommand(new Command() { + public void execute() { + onScroll(null); + } + }); + return; + } + // fix headers horizontal scrolling tHead.setHorizontalScrollPosition(scrollLeft); firstRowInViewPort = (int) Math.ceil(scrollTop - / (double) scrollBody.getRowHeight()); + / scrollBody.getRowHeight()); if (firstRowInViewPort > totalRows - pageLength) { firstRowInViewPort = totalRows - pageLength; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java index 1ca8b814a5..732ba84a3f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java @@ -10,6 +10,7 @@ import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
@@ -43,9 +44,18 @@ public class VSlider extends Widget implements Paintable, Field, private int resolution;
private Double value;
private boolean vertical;
- private int size = -1;
+ private final int size = -1;
private boolean arrows;
+ private final HTML feedback = new HTML("", false);
+ private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
+ @Override
+ public void show() {
+ super.show();
+ updateFeedbackPosition();
+ }
+ };
+
/* DOM element for slider's base */
private final Element base;
private final int BASE_BORDER_WIDTH = 1;
@@ -94,6 +104,9 @@ public class VSlider extends Widget implements Paintable, Field, | Event.ONMOUSEOUT);
DOM.sinkEvents(bigger, Event.ONMOUSEDOWN | Event.ONMOUSEUP
| Event.ONMOUSEOUT);
+
+ feedbackPopup.addStyleName(CLASSNAME + "-feedback");
+ feedbackPopup.setWidget(feedback);
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
@@ -136,6 +149,8 @@ public class VSlider extends Widget implements Paintable, Field, resolution = uidl.getIntAttribute("resolution");
value = new Double(uidl.getDoubleVariable("value"));
+ setFeedbackValue(value);
+
handleSize = uidl.getIntAttribute("hsize");
buildBase();
@@ -154,6 +169,29 @@ public class VSlider extends Widget implements Paintable, Field, }
}
+ private void setFeedbackValue(double value) {
+ String currentValue = "" + value;
+ if (resolution == 0) {
+ currentValue = "" + new Double(value).intValue();
+ }
+ feedback.setText(currentValue);
+ }
+
+ private void updateFeedbackPosition() {
+ if (vertical) {
+ feedbackPopup.setPopupPosition(DOM.getAbsoluteLeft(handle)
+ + handle.getOffsetWidth(), DOM.getAbsoluteTop(handle)
+ + handle.getOffsetHeight() / 2
+ - feedbackPopup.getOffsetHeight() / 2);
+ } else {
+ feedbackPopup.setPopupPosition(DOM.getAbsoluteLeft(handle)
+ + handle.getOffsetWidth() / 2
+ - feedbackPopup.getOffsetWidth() / 2, DOM
+ .getAbsoluteTop(handle)
+ - feedbackPopup.getOffsetHeight());
+ }
+ }
+
private void buildBase() {
final String styleAttribute = vertical ? "height" : "width";
final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
@@ -244,6 +282,7 @@ public class VSlider extends Widget implements Paintable, Field, final int range = baseSize - handleSize;
double v = value.doubleValue();
+
// Round value to resolution
if (resolution > 0) {
v = Math.round(v * Math.pow(10, resolution));
@@ -268,11 +307,9 @@ public class VSlider extends Widget implements Paintable, Field, DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
- // TODO give more detailed info when dragging and do roundup
- DOM.setElementAttribute(handle, "title", "" + v);
-
// Update value
this.value = new Double(v);
+ setFeedbackValue(v);
if (updateToServer) {
updateValueToServer();
@@ -329,7 +366,10 @@ public class VSlider extends Widget implements Paintable, Field, switch (DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
if (!disabled && !readonly) {
+ feedbackPopup.show();
dragging = true;
+ DOM.setElementProperty(handle, "className", CLASSNAME
+ + "-handle " + CLASSNAME + "-handle-active");
DOM.setCapture(getElement());
DOM.eventPreventDefault(event); // prevent selecting text
DOM.eventCancelBubble(event, true);
@@ -337,12 +377,14 @@ public class VSlider extends Widget implements Paintable, Field, break;
case Event.ONMOUSEMOVE:
if (dragging) {
- // DOM.setCapture(getElement());
setValueByEvent(event, false);
+ updateFeedbackPosition();
}
break;
case Event.ONMOUSEUP:
+ feedbackPopup.hide();
dragging = false;
+ DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
DOM.releaseCapture(getElement());
setValueByEvent(event, true);
break;
@@ -381,8 +423,8 @@ public class VSlider extends Widget implements Paintable, Field, .eventGetClientX(event);
final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
- final double handleSize = Integer.parseInt(DOM.getElementProperty(
- handle, domProperty));
+ final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
+ domProperty));
final double baseSize = Integer.parseInt(DOM.getElementProperty(base,
domProperty));
final double baseOffset = vertical ? DOM.getAbsoluteTop(base)
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java index 82839f2f31..ffada53252 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java @@ -434,7 +434,6 @@ public class VSplitPanel extends ComplexPanel implements Container, newX = getOffsetWidth() - getSplitterSize(); } DOM.setStyleAttribute(splitter, "left", newX + "px"); - updateSplitPosition(newX); if (origX != newX) { resized = true; } @@ -450,7 +449,6 @@ public class VSplitPanel extends ComplexPanel implements Container, newY = getOffsetHeight() - getSplitterSize(); } DOM.setStyleAttribute(splitter, "top", newY + "px"); - updateSplitPosition(newY); if (origY != newY) { resized = true; } @@ -463,6 +461,7 @@ public class VSplitPanel extends ComplexPanel implements Container, } resizing = false; onMouseMove(event); + updateSplitPositionToServer(); } /** @@ -593,12 +592,14 @@ public class VSplitPanel extends ComplexPanel implements Container, /** * Updates the new split position back to server. - * - * @param pos - * The new position of the split handle. */ - private void updateSplitPosition(int pos) { + private void updateSplitPositionToServer() { // We always send pixel values to server + final String position = orientation == ORIENTATION_HORIZONTAL ? splitter + .getStyle().getProperty("left") + : splitter.getStyle().getProperty("top"); + final int pos = Integer.parseInt(position.substring(0, position + .length() - 2)); client.updateVariable(id, "position", pos, immediate); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index e8a96c63fb..e1ab149dc5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -795,8 +795,8 @@ public class VWindow extends VOverlay implements Container, ScrollListener { } } - if (type == Event.ONMOUSEDOWN) { - // !DOM.isOrHasChild(contentPanel.getElement(), target) + if (type == Event.ONMOUSEDOWN + && !DOM.isOrHasChild(contentPanel.getElement(), target)) { Util.focus(contentPanel.getElement()); } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index fd31333930..eda9670ff7 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -28,10 +28,12 @@ import javax.portlet.PortalContext; import javax.portlet.PortletConfig; import javax.portlet.PortletContext; import javax.portlet.PortletException; +import javax.portlet.PortletMode; import javax.portlet.PortletRequest; import javax.portlet.PortletResponse; import javax.portlet.PortletSession; import javax.portlet.PortletURL; +import javax.portlet.RenderMode; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.ResourceRequest; @@ -424,7 +426,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet /* * Always use the main window when running inside a portlet. */ - Window window = application.getMainWindow(); + Window window = getPortletWindow(request, application); if (window == null) { throw new PortletException(ERROR_NO_WINDOW_FOUND); } @@ -492,6 +494,28 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } } + /** + * Returns a window for a portlet mode. To define custom content for a + * portlet mode, add (in the application) a window whose name matches the + * portlet mode name. By default, the main window is returned. + * + * Alternatively, a PortletListener can change the main window content. + * + * @param request + * @param application + * @return Window to show in the portlet for the given portlet mode + */ + protected Window getPortletWindow(PortletRequest request, + Application application) { + PortletMode mode = request.getPortletMode(); + Window window = application.getWindow(mode.toString()); + if (window != null) { + return window; + } + // no specific window found + return application.getMainWindow(); + } + private void updateBrowserProperties(WebBrowser browser, PortletRequest request) { browser.updateBrowserProperties(request.getLocale(), null, request @@ -624,12 +648,55 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet handleRequest(request, response); } + /** + * Handles a request for the "view" (default) portlet mode. In Vaadin, the + * basic portlet modes ("view", "edit" and "help") are handled identically, + * and their behavior can be changed by registering windows in the + * application with window names identical to the portlet mode names. + * Alternatively, a PortletListener can change the application main window + * contents. + * + * To implement custom portlet modes, subclass the portlet class and + * implement a method annotated with {@link RenderMode} for the custom mode, + * calling {@link #handleRequest(PortletRequest, PortletResponse)} directly + * from it. + * + * Note that the portlet class in the portlet configuration needs to be + * changed when overriding methods of this class. + * + * @param request + * @param response + * @throws PortletException + * @throws IOException + */ @Override protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { handleRequest(request, response); } + /** + * Handle a request for the "edit" portlet mode. + * + * @see #doView(RenderRequest, RenderResponse) + */ + @Override + protected void doEdit(RenderRequest request, RenderResponse response) + throws PortletException, IOException { + handleRequest(request, response); + } + + /** + * Handle a request for the "help" portlet mode. + * + * @see #doView(RenderRequest, RenderResponse) + */ + @Override + protected void doHelp(RenderRequest request, RenderResponse response) + throws PortletException, IOException { + handleRequest(request, response); + } + @Override public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException { diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java index e0f888e6cb..e745282605 100644 --- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java @@ -1009,13 +1009,11 @@ public class JsonPaintTarget implements PaintTarget { * integer strings to optimized transferred data. */ Class<? extends Paintable> class1 = paintable.getClass(); - ClientWidget annotation = class1.getAnnotation(ClientWidget.class); - while (annotation == null) { + while (!hasClientWidgetMapping(class1)) { Class<?> superclass = class1.getSuperclass(); if (superclass != null && Paintable.class.isAssignableFrom(superclass)) { class1 = (Class<? extends Paintable>) superclass; - annotation = class1.getAnnotation(ClientWidget.class); } else { System.out .append("Warning: no superclass of givent has ClientWidget" @@ -1023,11 +1021,30 @@ public class JsonPaintTarget implements PaintTarget { break; } } + usedPaintableTypes.add(class1); return AbstractCommunicationManager.getTagForType(class1); } + private boolean hasClientWidgetMapping(Class<? extends Paintable> class1) { + try { + ClientWidget annotation = class1.getAnnotation(ClientWidget.class); + return annotation != null; + } catch (RuntimeException e) { + if (e.getStackTrace()[0].getClassName().equals( + "org.glassfish.web.loader.WebappClassLoader")) { + // Glassfish 3 is darn eager to load the value class, even + // though we just want to check if the annotation exists. + // See #3920, remove this hack when fixed in glassfish + return true; + } else { + // throw exception forward + throw e; + } + } + } + Collection<Class<? extends Paintable>> getUsedPaintableTypes() { return usedPaintableTypes; } diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext.java index b8d058d88a..af9ed1b9a6 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext.java @@ -22,9 +22,8 @@ import com.vaadin.Application; /**
* @author marc
- * @deprecated Use Portlet 2.0 class {@link PortletApplicationContext2} instead.
*/
-@SuppressWarnings({"serial", "unchecked"})
+@SuppressWarnings( { "serial", "unchecked" })
@Deprecated
public class PortletApplicationContext extends WebApplicationContext implements
Serializable {
diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index 2471680d29..8effcb6c65 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -13,6 +13,8 @@ import javax.portlet.ActionResponse; import javax.portlet.EventRequest; import javax.portlet.EventResponse; import javax.portlet.MimeResponse; +import javax.portlet.PortletMode; +import javax.portlet.PortletModeException; import javax.portlet.PortletResponse; import javax.portlet.PortletSession; import javax.portlet.PortletURL; @@ -351,4 +353,31 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { "Shared parameters can only be set from a portlet request"); } } + + /** + * Sets the portlet mode. This may trigger a new render request. + * + * Portlet modes used by a portlet need to be declared in portlet.xml . + * + * @param window + * a window in which the render URL can be opened if necessary + * @param portletMode + * the portlet mode to switch to + * @throws PortletModeException + * if the portlet mode is not allowed for some reason + * (configuration, permissions etc.) + */ + public void setPortletMode(Window window, PortletMode portletMode) + throws IllegalStateException, PortletModeException { + if (response instanceof MimeResponse) { + PortletURL url = ((MimeResponse) response).createRenderURL(); + url.setPortletMode(portletMode); + window.open(new ExternalResource(url.toString())); + } else if (response instanceof StateAwareResponse) { + ((StateAwareResponse) response).setPortletMode(portletMode); + } else { + throw new IllegalStateException( + "Portlet mode can only be changed from a portlet request"); + } + } } diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java index 679468dd0b..092bc4c55e 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java @@ -24,9 +24,9 @@ import com.vaadin.ui.Window; /** * TODO document me! - * + * * @author peholmst - * + * */ @SuppressWarnings("serial") public class PortletCommunicationManager extends AbstractCommunicationManager { @@ -165,6 +165,19 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { + themeName + "/" + resource); } + /** + * Find the application window to use based on the portlet mode. For + * internal use only, not in the {@link Callback} interface. + * + * @param request + * @param application + * @return + */ + public Window getPortletWindow(PortletRequest request, + Application application) { + return portlet.getPortletWindow(request, application); + } + } public PortletCommunicationManager(Application application) { @@ -202,8 +215,9 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { ((ActionResponse) response.getWrappedResponse()) .sendRedirect(dummyURL == null ? "http://www.google.com" : dummyURL); - } else + } else { super.sendUploadResponse(request, response); + } } public void handleUidlRequest(ResourceRequest request, @@ -223,4 +237,18 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { new AbstractApplicationPortletWrapper(applicationPortlet)); } + @Override + protected Window doGetApplicationWindow(Request request, Callback callback, + Application application, Window assumedWindow) { + // find window based on portlet mode + if (assumedWindow == null + && callback instanceof AbstractApplicationPortletWrapper + && request.getWrappedRequest() instanceof PortletRequest) { + assumedWindow = ((AbstractApplicationPortletWrapper) callback) + .getPortletWindow((PortletRequest) request + .getWrappedRequest(), application); + } + return super.doGetApplicationWindow(request, callback, application, + assumedWindow); + } } diff --git a/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java b/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java index 43898faa54..f2a3386b13 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java +++ b/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java @@ -11,15 +11,15 @@ import com.vaadin.service.ApplicationContext.TransactionListener; import com.vaadin.terminal.Terminal; /** - * {@link Application} that implements this interface gets notified of request - * start and end by terminal. It is quite similar to + * An {@link Application} that implements this interface gets notified of + * request start and end by the terminal. It is quite similar to the * {@link HttpServletRequestListener}, but the parameters are Portlet specific. - * If Application is used deployed as both Servlet and Portlet, one most likely - * needs to implement both. + * If an Application is deployed as both a Servlet and a Portlet, one most + * likely needs to implement both. * <p> * Only JSR 286 style Portlets are supported. * <p> - * Interface can be used for several helper tasks including: + * The interface can be used for several helper tasks including: * <ul> * <li>Opening and closing database connections * <li>Implementing {@link ThreadLocal} @@ -28,7 +28,7 @@ import com.vaadin.terminal.Terminal; * <p> * Alternatives for implementing similar features are are Servlet {@link Filter} * s and {@link TransactionListener}s in Vaadin. - * + * * @since 6.2 * @see HttpServletRequestListener */ @@ -37,7 +37,7 @@ public interface PortletRequestListener extends Serializable { /** * This method is called before {@link Terminal} applies the request to * Application. - * + * * @param requestData * the {@link PortletRequest} about to change Application state */ diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java index 2727da3ecc..54dc7153dc 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -120,14 +120,10 @@ public class WidgetMapGenerator extends Generator { if (typeOracle.findType(annotation.value().getName()) == null) { // GWT widget not inherited - logger - .log( - Type.WARN, - "Widget implementation for " - + class1.getName() - + " not available for GWT compiler (but mapped " - + "for component found in classpath). If this is not " - + "intentional, check your gwt module definition file."); + logger.log(Type.WARN, "Widget class " + + annotation.value().getName() + + " was not found. The component " + class1.getName() + + " will not be included in the widgetset."); iterator.remove(); } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index 92bf90831b..4619c2ab8d 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -521,7 +521,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource } if (parent != null && this.parent != null) { - throw new IllegalStateException("Component already has a parent."); + throw new IllegalStateException(getClass().getName() + + " already has a parent."); } // Send detach event if the component have been connected to a window diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java index f1195e9ef4..19abe8d142 100644 --- a/src/com/vaadin/ui/GridLayout.java +++ b/src/com/vaadin/ui/GridLayout.java @@ -830,8 +830,9 @@ public class GridLayout extends AbstractLayout implements } /** - * An <code>Exception</code> object which is thrown when two Items occupy - * the same space on a grid. + * Gridlayout does not support laying components on top of each other. An + * <code>OverlapsException</code> is thrown when a component already exists + * (even partly) at the same space on a grid with the new component. * * @author IT Mill Ltd. * @version @@ -851,6 +852,32 @@ public class GridLayout extends AbstractLayout implements this.existingArea = existingArea; } + @Override + public String getMessage() { + StringBuilder sb = new StringBuilder(); + Component component = existingArea.getComponent(); + sb.append(component); + sb.append("( type = "); + sb.append(component.getClass().getName()); + if (component.getCaption() != null) { + sb.append(", caption = \""); + sb.append(component.getCaption()); + sb.append("\""); + } + sb.append(")"); + sb.append(" is already added to "); + sb.append(existingArea.column1); + sb.append(","); + sb.append(existingArea.column1); + sb.append(","); + sb.append(existingArea.row1); + sb.append(","); + sb.append(existingArea.row2); + sb.append("(column1, column2, row1, row2)."); + + return sb.toString(); + } + /** * Gets the area . * diff --git a/src/com/vaadin/ui/SplitPanel.java b/src/com/vaadin/ui/SplitPanel.java index 916c8bb5cc..5e67b93369 100644 --- a/src/com/vaadin/ui/SplitPanel.java +++ b/src/com/vaadin/ui/SplitPanel.java @@ -284,7 +284,7 @@ public class SplitPanel extends AbstractLayout { * the new size of the first region in percentage */ public void setSplitPosition(int pos) { - setSplitPosition(pos, UNITS_PERCENTAGE); + setSplitPosition(pos, UNITS_PERCENTAGE, true); } /** @@ -296,9 +296,27 @@ public class SplitPanel extends AbstractLayout { * the unit (from {@link Sizeable}) in which the size is given. */ public void setSplitPosition(int pos, int unit) { + setSplitPosition(pos, unit, true); + } + + /** + * Moves the position of the splitter. + * + * @param pos + * the new size of the first region in percentage + * @param unit + * the unit (from {@link Sizeable}) in which the size is given. + * @param repaintNotNeeded + * true if client side needs to be updated. Use false if the + * position info has come from the client side, thus it already + * knows the position. + */ + private void setSplitPosition(int pos, int unit, boolean repaintNeeded) { this.pos = pos; posUnit = unit; - requestRepaint(); + if (repaintNeeded) { + requestRepaint(); + } } /** @@ -335,8 +353,8 @@ public class SplitPanel extends AbstractLayout { if (variables.containsKey("position") && !isLocked()) { Integer newPos = (Integer) variables.get("position"); - // Client always sends pixel values - setSplitPosition(newPos, UNITS_PIXELS); + // Client always sends pixel values. Repaint is not needed. + setSplitPosition(newPos, UNITS_PIXELS, false); } if (variables.containsKey(SPLITTER_CLICK_EVENT)) { diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java index e3512a4795..7a3fac9167 100644 --- a/src/com/vaadin/ui/Upload.java +++ b/src/com/vaadin/ui/Upload.java @@ -49,6 +49,11 @@ import com.vaadin.terminal.gwt.client.ui.VUpload; * selected, instead of the common pattern of file selection field and upload * button. * + * <p> + * Note! Because of browser dependent implementations of <input type="file"> + * element, setting size for Upload component is not supported. For some + * browsers setting size may work to some extend. + * * @author IT Mill Ltd. * @version * @VERSION@ diff --git a/tests/integration_tests.xml b/tests/integration_tests.xml index d1473768f4..2e4cafd695 100644 --- a/tests/integration_tests.xml +++ b/tests/integration_tests.xml @@ -135,15 +135,24 @@ <sshexec host="${sshHost}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} stop-jboss-5.0.1" />
</target>
- <target name="start-glassfish">
+ <target name="start-glassfish2">
<sshexec host="${sshHost}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} start-glassfish-2.1.1" />
<copy file="integration-testscripts/sampler_deployment.tpl" tofile="integration-testscripts/integration-test-glassfish-2.1.1-sampler.html" overwrite="true" />
</target>
- <target name="stop-glassfish">
+ <target name="stop-glassfish2">
<sshexec host="${sshHost}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} stop-glassfish-2.1.1" />
</target>
+ <target name="start-glassfish3">
+ <sshexec host="${sshHost}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} start-glassfish-3" />
+ <copy file="integration-testscripts/sampler_deployment.tpl" tofile="integration-testscripts/integration-test-glassfish-3-sampler.html" overwrite="true" />
+ </target>
+
+ <target name="stop-glassfish3">
+ <sshexec host="${sshHost}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} stop-glassfish-3" />
+ </target>
+
<!-- Test liferay sampler -->
<target name="test-liferay">
<fileset dir="integration-testscripts" id="html-test-files" includes="integration-test-liferay-5.2.3-sampler.html" />
@@ -312,12 +321,20 @@ <antcall target="stop-jboss-5"/>
</target>
- <target name="glassfish">
- <antcall target="start-glassfish"/>
+ <target name="glassfish2">
+ <antcall target="start-glassfish2"/>
<antcall target="test-sampler">
<param name="server-name" value="glassfish-2.1.1" />
</antcall>
- <antcall target="stop-glassfish"/>
+ <antcall target="stop-glassfish2"/>
+ </target>
+
+ <target name="glassfish3">
+ <antcall target="start-glassfish3"/>
+ <antcall target="test-sampler">
+ <param name="server-name" value="glassfish-3" />
+ </antcall>
+ <antcall target="stop-glassfish3"/>
</target>
<target name="liferay">
@@ -365,7 +382,8 @@ <antcall target="jboss3" />
<antcall target="jboss4" />
<antcall target="jboss5" />
- <antcall target="glassfish" />
+ <antcall target="glassfish2" />
+ <antcall target="glassfish3" />
<antcall target="liferay" />
<antcall target="weblogic9" />
<antcall target="weblogic10" />
diff --git a/tests/src/com/vaadin/tests/components/button/Buttons.java b/tests/src/com/vaadin/tests/components/button/Buttons.java new file mode 100644 index 0000000000..4b1e7d60d8 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/button/Buttons.java @@ -0,0 +1,130 @@ +package com.vaadin.tests.components.button; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.tests.components.ComponentTestCase; +import com.vaadin.tests.util.LoremIpsum; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.Button.ClickEvent; + +public class Buttons extends ComponentTestCase { + + Button button[] = new Button[20]; + + @Override + protected void setup() { + super.setup(); + + Button l; + for (boolean nat : new boolean[] { false, true }) { + l = createButton("This is an undefined wide button", nat); + l.setWidth(null); + addTestComponent(l); + + l = createButton( + "This is an undefined wide button with fixed 100px height", + nat); + l.setWidth(null); + l.setHeight("100px"); + addTestComponent(l); + + l = createButton( + "This is a 200px wide simple button with a much longer caption", + nat); + l.setWidth("200px"); + addTestComponent(l); + + l = createButton("This is a 100% wide simple button " + + LoremIpsum.get(1500), nat); + l.setWidth("100%"); + addTestComponent(l); + + l = createButton( + "This is a 100% wide button with fixed 65px height. " + + LoremIpsum.get(5000), nat); + l.setWidth("100%"); + l.setHeight("65px"); + addTestComponent(l); + } + + } + + private Component createActionLayout() { + HorizontalLayout actionLayout = new HorizontalLayout(); + actionLayout.setSpacing(true); + actionLayout.setMargin(true); + for (Component c : createActions()) { + actionLayout.addComponent(c); + } + addComponent(actionLayout); + return actionLayout; + } + + private Button createButton(String text, boolean nativeButton) { + Button b; + if (nativeButton) { + b = new NativeButton(text); + } else { + b = new Button(text); + } + + return b; + } + + @Override + protected String getDescription() { + return "A generic test for Buttons in different configurations"; + } + + @Override + protected List<Component> createActions() { + ArrayList<Component> actions = new ArrayList<Component>(); + + CheckBox errorIndicators = new CheckBox("Error indicators", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setErrorIndicators(enabled); + + } + }); + + CheckBox enabled = new CheckBox("Enabled", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setEnabled(enabled); + } + }); + + CheckBox readonly = new CheckBox("Readonly", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setReadOnly(enabled); + } + }); + + errorIndicators.setValue(new Boolean(false)); + readonly.setValue(new Boolean(false)); + enabled.setValue(new Boolean(true)); + + errorIndicators.setImmediate(true); + readonly.setImmediate(true); + enabled.setImmediate(true); + + actions.add(errorIndicators); + actions.add(readonly); + actions.add(enabled); + + return actions; + } + +} diff --git a/tests/src/com/vaadin/tests/components/form/UndefinedWideFormWithRelativeWideFooter.html b/tests/src/com/vaadin/tests/components/form/UndefinedWideFormWithRelativeWideFooter.html new file mode 100644 index 0000000000..ade84de312 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/form/UndefinedWideFormWithRelativeWideFooter.html @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>UndefinedWideFormWithRelativeWideFooter</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">UndefinedWideFormWithRelativeWideFooter</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.form.UndefinedWideFormWithRelativeWideFooter</td> + <td></td> +</tr> +<tr> + <td>waitForVaadin</td> + <td></td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>initial</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/src/com/vaadin/tests/tickets/Ticket3710.java b/tests/src/com/vaadin/tests/components/form/UndefinedWideFormWithRelativeWideFooter.java index 430f3967a0..4c47c8a58d 100644 --- a/tests/src/com/vaadin/tests/tickets/Ticket3710.java +++ b/tests/src/com/vaadin/tests/components/form/UndefinedWideFormWithRelativeWideFooter.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.tickets; +package com.vaadin.tests.components.form; import com.vaadin.Application; import com.vaadin.ui.Button; @@ -8,7 +8,7 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.Window; @SuppressWarnings("serial") -public class Ticket3710 extends Application { +public class UndefinedWideFormWithRelativeWideFooter extends Application { @Override public void init() { @@ -19,6 +19,8 @@ public class Ticket3710 extends Application { final Form f = new Form(); w.addComponent(f); f.setSizeUndefined(); + f.getLayout().setSizeUndefined(); + f.setCaption("Test form with a really long caption"); f.addField("foo", new TextField("Foo")); f.addField("bar", new TextField("A bit longer field caption")); @@ -30,5 +32,4 @@ public class Ticket3710 extends Application { hl.setComponentAlignment(b, "r"); f.setFooter(hl); } - } diff --git a/tests/src/com/vaadin/tests/components/table/FixedHeightTable.html b/tests/src/com/vaadin/tests/components/table/FixedHeightTable.html new file mode 100644 index 0000000000..fb8f7c8b7f --- /dev/null +++ b/tests/src/com/vaadin/tests/components/table/FixedHeightTable.html @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>FixedHeighTable</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.FixedHeightTable</td> + <td></td> +</tr> +<tr> + <td>waitForVaadin</td> + <td></td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>initial</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/tests/src/com/vaadin/tests/components/table/FixedHeightTable.java b/tests/src/com/vaadin/tests/components/table/FixedHeightTable.java new file mode 100644 index 0000000000..e193a8a949 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/table/FixedHeightTable.java @@ -0,0 +1,39 @@ +package com.vaadin.tests.components.table;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class FixedHeightTable extends TestBase {
+
+ private static final long serialVersionUID = -929892889178757852L;
+ Table table;
+ VerticalLayout layout;
+
+ @Override
+ public void setup() {
+
+ table = new Table();
+ table.addContainerProperty("test", String.class, null);
+ table.setSizeFull();
+ // bug: settings rows to 16 or more => last line is not rendered at all
+ // on the client-side.
+ final int maxRows = 16;
+ for (int i = 1; i <= maxRows; i++) {
+ table.addItem(new Object[] { "" + i }, i);
+ }
+
+ getLayout().setHeight("400px");
+ addComponent(table);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "The table contains 16 (1-16) rows which all should be visible";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 3814;
+ }
+}
\ No newline at end of file diff --git a/tests/src/com/vaadin/tests/components/table/SafariRenderingBugWhiteSpace.java b/tests/src/com/vaadin/tests/components/table/SafariRenderingBugWhiteSpace.java new file mode 100644 index 0000000000..384bcecde6 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/table/SafariRenderingBugWhiteSpace.java @@ -0,0 +1,63 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Panel; +import com.vaadin.ui.SplitPanel; +import com.vaadin.ui.Table; + +public class SafariRenderingBugWhiteSpace extends TestBase { + + @Override + protected void setup() { + + final SplitPanel split = new SplitPanel(SplitPanel.ORIENTATION_VERTICAL); + + final Table table = new Table(); + table.addContainerProperty("name", String.class, ""); + table.addContainerProperty("value", String.class, ""); + + table.addItem(new Object[] { "test1", "val1" }, "test1"); + table.addItem(new Object[] { "test2", "val2" }, "test2"); + table.addItem(new Object[] { "test3", "val3" }, "test3"); + table.addItem(new Object[] { "test4", "val4" }, "test4"); + table.addItem(new Object[] { "test5", "val5" }, "test5"); + table.addItem(new Object[] { "test6", "val6" }, "test6"); + table.addItem(new Object[] { "test7", "val7" }, "test7"); + table.addItem(new Object[] { "test8", "val8" }, "test8"); + table.addItem(new Object[] { "test9", "val9" }, "test9"); + table.setSelectable(true); + table.setImmediate(true); + table.setSizeFull(); + table.addListener(new ValueChangeListener() { + + public void valueChange(ValueChangeEvent event) { + if (table.getValue() == null) { + split.setSplitPosition(100, SplitPanel.UNITS_PERCENTAGE); + } else { + split.setSplitPosition(20, SplitPanel.UNITS_PERCENTAGE); + } + } + }); + + split.setFirstComponent(table); + split.setSplitPosition(100, SplitPanel.UNITS_PERCENTAGE); + Panel editor = new Panel("Editor"); + editor.setSizeFull(); + split.setSecondComponent(editor); + getLayout().setSizeFull(); + getLayout().addComponent(split); + } + + @Override + protected String getDescription() { + return "White space between header an content should not appear, when selecting and de-selecting first row"; + } + + @Override + protected Integer getTicketNumber() { + return 3875; + } + +} |