Browse Source

Merge remote-tracking branch 'origin/6.8'

+ add @Override

Conflicts:
	src/com/vaadin/terminal/gwt/client/Util.java
	src/com/vaadin/terminal/gwt/client/ui/VOverlay.java
	src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java
	src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java
	src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
	src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
	src/com/vaadin/ui/LoginForm.java
	src/com/vaadin/ui/Table.java
	tests/test.xml
tags/7.0.0.beta1
Leif Åstrand 11 years ago
parent
commit
94f81dc795

+ 14
- 0
WebContent/statictestfiles/LoginFormIframe.html View File

@@ -0,0 +1,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>LoginForm</title>
<script type="text/javascript">
window.name="LoginForm";
</script>
</head>
<body>
<p>Tests that LoginForm can be submitted even when the Application is embedded inside an iframe</p>
<iframe src="/run/com.vaadin.tests.components.loginform.LoginFormTest?restartApplication" name="LoginForm" height="500px" width="500px"></iframe>
</body>
</html>

+ 2
- 0
src/com/vaadin/Application.java View File

@@ -1066,6 +1066,7 @@ public class Application implements Terminal.ErrorListener, Serializable {
* @see com.vaadin.terminal.Terminal.ErrorListener#terminalError(com.vaadin.terminal.Terminal.ErrorEvent)
*/

@Override
public void terminalError(Terminal.ErrorEvent event) {
final Throwable t = event.getThrowable();
if (t instanceof SocketException) {
@@ -1810,6 +1811,7 @@ public class Application implements Terminal.ErrorListener, Serializable {
this.throwable = throwable;
}

@Override
public Throwable getThrowable() {
return throwable;
}

+ 22
- 23
src/com/vaadin/terminal/gwt/client/Util.java View File

@@ -834,30 +834,29 @@ public class Util {
ServerConnector connector = ConnectorMap.get(c).getConnector(id);
if (connector != null) {
VConsole.log("\t" + id + " (" + connector.getClass() + ") :");
for (MethodInvocation invocation : invocations) {
Object[] parameters = invocation.getParameters();
String formattedParams = null;
if (ApplicationConnection.UPDATE_VARIABLE_METHOD
.equals(invocation.getMethodName())
&& parameters.length == 2) {
// name, value
Object value = parameters[1];
// TODO paintables inside lists/maps get rendered as
// components in the debug console
String formattedValue = value instanceof ServerConnector ? ((ServerConnector) value)
.getConnectorId() : String.valueOf(value);
formattedParams = parameters[0] + " : " + formattedValue;
}
if (null == formattedParams) {
formattedParams = (null != parameters) ? Arrays
.toString(parameters) : null;
}
VConsole.log("\t\t" + invocation.getInterfaceName() + "."
+ invocation.getMethodName() + "(" + formattedParams
+ ")");
}
} else {
VConsole.log("\t" + id + ": Warning: no corresponding connector!");
VConsole.log("\t" + id
+ ": Warning: no corresponding connector for id " + id);
}
for (MethodInvocation invocation : invocations) {
Object[] parameters = invocation.getParameters();
String formattedParams = null;
if (ApplicationConnection.UPDATE_VARIABLE_METHOD.equals(invocation
.getMethodName()) && parameters.length == 2) {
// name, value
Object value = parameters[1];
// TODO paintables inside lists/maps get rendered as
// components in the debug console
String formattedValue = value instanceof ServerConnector ? ((ServerConnector) value)
.getConnectorId() : String.valueOf(value);
formattedParams = parameters[0] + " : " + formattedValue;
}
if (null == formattedParams) {
formattedParams = (null != parameters) ? Arrays
.toString(parameters) : null;
}
VConsole.log("\t\t" + invocation.getInterfaceName() + "."
+ invocation.getMethodName() + "(" + formattedParams + ")");
}
}


+ 161
- 53
src/com/vaadin/terminal/gwt/client/ui/VOverlay.java View File

@@ -6,7 +6,10 @@ package com.vaadin.terminal.gwt.client.ui;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.IFrameElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
@@ -24,6 +27,49 @@ import com.vaadin.terminal.gwt.client.BrowserInfo;
*/
public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {

public static class PositionAndSize {
private int left, top, width, height;

public int getLeft() {
return left;
}

public void setLeft(int left) {
this.left = left;
}

public int getTop() {
return top;
}

public void setTop(int top) {
this.top = top;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public void setAnimationFromCenterProgress(double progress) {
left += (int) (width * (1.0 - progress) / 2.0);
top += (int) (height * (1.0 - progress) / 2.0);
width = (int) (width * progress);
height = (int) (height * progress);
}
}

/*
* The z-index value from where all overlays live. This can be overridden in
* any extending class.
@@ -52,6 +98,12 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
*/
private Widget owner;

/**
* The shim iframe behind the overlay, allowing PDFs and applets to be
* covered by overlays.
*/
private IFrameElement shimElement;

/**
* The HTML snippet that is used to render the actual shadow. In consists of
* nine different DIV-elements with the following class names:
@@ -73,6 +125,11 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
*/
private static final String SHADOW_HTML = "<div class=\"top-left\"></div><div class=\"top\"></div><div class=\"top-right\"></div><div class=\"left\"></div><div class=\"center\"></div><div class=\"right\"></div><div class=\"bottom-left\"></div><div class=\"bottom\"></div><div class=\"bottom-right\"></div>";

/**
* Matches {@link PopupPanel}.ANIMATION_DURATION
*/
private static final int POPUP_PANEL_ANIMATION_DURATION = 200;

private boolean sinkShadowEvents = false;

public VOverlay() {
@@ -123,9 +180,15 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return shadow != null;
}

private void removeShim() {
if (shimElement != null) {
shimElement.removeFromParent();
}
}

private void removeShadowIfPresent() {
if (isShadowAttached()) {
shadow.getParentElement().removeChild(shadow);
shadow.removeFromParent();

// Remove event listener from the shadow
unsinkShadowEvents();
@@ -136,6 +199,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
return isShadowEnabled() && shadow.getParentElement() != null;
}

private boolean isShimAttached() {
return shimElement != null && shimElement.hasParentElement();
}

private void adjustZIndex() {
setZIndex(Z_INDEX);
}
@@ -163,7 +230,46 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
style.setMarginLeft(-adjustByRelativeLeftBodyMargin(), Unit.PX);
style.setMarginTop(-adjustByRelativeTopBodyMargin(), Unit.PX);
super.setPopupPosition(left, top);
updateShadowSizeAndPosition(isAnimationEnabled() ? 0 : 1);
sizeOrPositionUpdated(isAnimationEnabled() ? 0 : 1);
}

private IFrameElement getShimElement() {
if (shimElement == null) {
shimElement = Document.get().createIFrameElement();

// Insert shim iframe before the main overlay element. It does not
// matter if it is in front or behind the shadow as we cannot put a
// shim behind the shadow due to its transparency.
shimElement.getStyle().setPosition(Position.ABSOLUTE);
shimElement.getStyle().setBorderStyle(BorderStyle.NONE);
shimElement.setFrameBorder(0);
shimElement.setMarginHeight(0);
}
return shimElement;
}

private int getActualTop() {
int y = getAbsoluteTop();

/* This is needed for IE7 at least */
// Account for the difference between absolute position and the
// body's positioning context.
y -= Document.get().getBodyOffsetTop();
y -= adjustByRelativeTopBodyMargin();

return y;
}

private int getActualLeft() {
int x = getAbsoluteLeft();

/* This is needed for IE7 at least */
// Account for the difference between absolute position and the
// body's positioning context.
x -= Document.get().getBodyOffsetLeft();
x -= adjustByRelativeLeftBodyMargin();

return x;
}

private static int adjustByRelativeTopBodyMargin() {
@@ -196,13 +302,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
@Override
public void show() {
super.show();
if (isShadowEnabled()) {
if (isAnimationEnabled()) {
ShadowAnimation sa = new ShadowAnimation();
sa.run(200);
} else {
updateShadowSizeAndPosition(1.0);
}
if (isAnimationEnabled()) {
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION);
} else {
sizeOrPositionUpdated(1.0);
}
}

@@ -212,6 +315,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {

// Always ensure shadow is removed when the overlay is removed.
removeShadowIfPresent();
removeShim();
}

@Override
@@ -226,13 +330,13 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
@Override
public void setWidth(String width) {
super.setWidth(width);
updateShadowSizeAndPosition(1.0);
sizeOrPositionUpdated(1.0);
}

@Override
public void setHeight(String height) {
super.setHeight(height);
updateShadowSizeAndPosition(1.0);
sizeOrPositionUpdated(1.0);
}

/**
@@ -251,28 +355,29 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}
}

/*
/**
* Extending classes should always call this method after they change the
* size of overlay without using normal 'setWidth(String)' and
* 'setHeight(String)' methods (if not calling super.setWidth/Height).
*
*/
public void updateShadowSizeAndPosition() {
updateShadowSizeAndPosition(1.0);
public void sizeOrPositionUpdated() {
sizeOrPositionUpdated(1.0);
}

/**
* Recalculates proper position and dimensions for the shadow element. Can
* be used to animate the shadow, using the 'progress' parameter (used to
* animate the shadow in sync with GWT PopupPanel's default animation
* 'PopupPanel.AnimationType.CENTER').
* Recalculates proper position and dimensions for the shadow and shim
* elements. Can be used to animate the related elements, using the
* 'progress' parameter (used to animate the shadow in sync with GWT
* PopupPanel's default animation 'PopupPanel.AnimationType.CENTER').
*
* @param progress
* A value between 0.0 and 1.0, indicating the progress of the
* animation (0=start, 1=end).
*/
private void updateShadowSizeAndPosition(final double progress) {
private void sizeOrPositionUpdated(final double progress) {
// Don't do anything if overlay element is not attached
if (!isAttached() || shadow == null) {
if (!isAttached()) {
return;
}
// Calculate proper z-index
@@ -295,37 +400,26 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
getOffsetWidth();
}

int x = getAbsoluteLeft();
int y = getAbsoluteTop();
PositionAndSize positionAndSize = new PositionAndSize();
positionAndSize.left = getActualLeft();
positionAndSize.top = getActualTop();
positionAndSize.width = getOffsetWidth();
positionAndSize.height = getOffsetHeight();

/* This is needed for IE7 at least */
// Account for the difference between absolute position and the
// body's positioning context.
x -= Document.get().getBodyOffsetLeft();
y -= Document.get().getBodyOffsetTop();
x -= adjustByRelativeLeftBodyMargin();
y -= adjustByRelativeTopBodyMargin();

int width = getOffsetWidth();
int height = getOffsetHeight();

if (width < 0) {
width = 0;
if (positionAndSize.width < 0) {
positionAndSize.width = 0;
}
if (height < 0) {
height = 0;
if (positionAndSize.height < 0) {
positionAndSize.height = 0;
}

// Animate the shadow size
x += (int) (width * (1.0 - progress) / 2.0);
y += (int) (height * (1.0 - progress) / 2.0);
width = (int) (width * progress);
height = (int) (height * progress);
// Animate the size
positionAndSize.setAnimationFromCenterProgress(progress);

// Opera needs some shaking to get parts of the shadow showing
// properly
// (ticket #2704)
if (BrowserInfo.get().isOpera()) {
if (BrowserInfo.get().isOpera() && isShadowEnabled()) {
// Clear the height of all middle elements
DOM.getChild(shadow, 3).getStyle().setProperty("height", "auto");
DOM.getChild(shadow, 4).getStyle().setProperty("height", "auto");
@@ -333,15 +427,17 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}

// Update correct values
DOM.setStyleAttribute(shadow, "zIndex", zIndex);
DOM.setStyleAttribute(shadow, "width", width + "px");
DOM.setStyleAttribute(shadow, "height", height + "px");
DOM.setStyleAttribute(shadow, "top", y + "px");
DOM.setStyleAttribute(shadow, "left", x + "px");
DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none" : "");
if (isShadowEnabled()) {
updateSizeAndPosition(shadow, positionAndSize);
DOM.setStyleAttribute(shadow, "zIndex", zIndex);
DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none"
: "");
}
updateSizeAndPosition((Element) Element.as(getShimElement()),
positionAndSize);

// Opera fix, part 2 (ticket #2704)
if (BrowserInfo.get().isOpera()) {
if (BrowserInfo.get().isOpera() && isShadowEnabled()) {
// We'll fix the height of all the middle elements
DOM.getChild(shadow, 3)
.getStyle()
@@ -358,17 +454,29 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
}

// Attach to dom if not there already
if (!isShadowAttached()) {
if (isShadowEnabled() && !isShadowAttached()) {
RootPanel.get().getElement().insertBefore(shadow, getElement());
sinkShadowEvents();
}
if (!isShimAttached()) {
RootPanel.get().getElement()
.insertBefore(shimElement, getElement());
}

}

private void updateSizeAndPosition(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);
}

protected class ShadowAnimation extends Animation {
protected class ResizeAnimation extends Animation {
@Override
protected void onUpdate(double progress) {
updateShadowSizeAndPosition(progress);
sizeOrPositionUpdated(progress);
}
}


+ 1
- 1
src/com/vaadin/terminal/gwt/client/ui/menubar/VMenuBar.java View File

@@ -603,7 +603,7 @@ public class VMenuBar extends SimpleFocusablePanel implements
// popup
style.setWidth(contentWidth + Util.getNativeScrollbarSize(),
Unit.PX);
popup.updateShadowSizeAndPosition();
popup.sizeOrPositionUpdated();
}
}
return top;

+ 1
- 0
src/com/vaadin/terminal/gwt/client/ui/notification/VNotification.java View File

@@ -163,6 +163,7 @@ public class VNotification extends VOverlay {
super.show();
notifications.add(this);
setPosition(position);
sizeOrPositionUpdated();
/**
* Android 4 fails to render notifications correctly without a little
* nudge (#8551)

+ 2
- 0
src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java View File

@@ -28,6 +28,7 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ComponentConnector;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VCaptionWrapper;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler;
import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
import com.vaadin.terminal.gwt.client.ui.VOverlay;
@@ -246,6 +247,7 @@ public class VPopupView extends HTML {

@Override
public void hide(boolean autoClosed) {
VConsole.log("Hiding popupview");
hiding = true;
syncChildren();
if (popupComponentWidget != null && popupComponentWidget != loading) {

+ 7
- 0
src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java View File

@@ -54,6 +54,7 @@ public class RootConnector extends AbstractComponentContainerConnector
private HandlerRegistration childStateChangeHandlerRegistration;

private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() {
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
// TODO Should use a more specific handler that only reacts to
// size changes
@@ -65,12 +66,14 @@ public class RootConnector extends AbstractComponentContainerConnector
protected void init() {
super.init();
registerRpc(PageClientRpc.class, new PageClientRpc() {
@Override
public void setTitle(String title) {
com.google.gwt.user.client.Window.setTitle(title);
}
});
}

@Override
public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) {
ConnectorMap paintableMap = ConnectorMap.get(getConnection());
getWidget().rendering = true;
@@ -121,6 +124,7 @@ public class RootConnector extends AbstractComponentContainerConnector
// to finish rendering this window in case this is a download
// (and window stays open).
Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
VRoot.goTo(url);
}
@@ -185,6 +189,7 @@ public class RootConnector extends AbstractComponentContainerConnector
if (uidl.hasAttribute("focused")) {
// set focused component when render phase is finished
Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
ComponentConnector paintable = (ComponentConnector) uidl
.getPaintableAttribute("focused", getConnection());
@@ -296,6 +301,7 @@ public class RootConnector extends AbstractComponentContainerConnector

};

@Override
public void updateCaption(ComponentConnector component) {
// NOP The main view never draws caption for its layout
}
@@ -415,6 +421,7 @@ public class RootConnector extends AbstractComponentContainerConnector
}

Scheduler.get().scheduleDeferred(new Command() {
@Override
public void execute() {
componentConnector.getWidget().getElement().scrollIntoView();
}

+ 14
- 0
src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java View File

@@ -248,6 +248,20 @@ public class TableConnector extends AbstractComponentContainerConnector
}
}

/*
* If the server has (re)initialized the rows, our selectionRangeStart
* row will point to an index that the server knows nothing about,
* causing problems if doing multi selection with shift. The field will
* be cleared a little later when the row focus has been restored.
* (#8584)
*/
if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_KEY_MAPPER_RESET)
&& uidl.getBooleanAttribute(VScrollTable.ATTRIBUTE_KEY_MAPPER_RESET)
&& getWidget().selectionRangeStart != null) {
assert !getWidget().selectionRangeStart.isAttached();
getWidget().selectionRangeStart = getWidget().focusedRow;
}

getWidget().tabIndex = uidl.hasAttribute("tabindex") ? uidl
.getIntAttribute("tabindex") : 0;
getWidget().setProperTabIndex();

+ 37
- 3
src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java View File

@@ -131,6 +131,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}

/**
* Tell the client that old keys are no longer valid because the server has
* cleared its key map.
*/
public static final String ATTRIBUTE_KEY_MAPPER_RESET = "clearKeyMap";

private static final String ROW_HEADER_COLUMN_KEY = "0";

public static final String CLASSNAME = "v-table";
@@ -216,7 +222,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/*
* Helper to store selection range start in when using the keyboard
*/
private VScrollTableRow selectionRangeStart;
VScrollTableRow selectionRangeStart;

/*
* Flag for notifying when the selection has changed and should be sent to
@@ -241,6 +247,19 @@ public class VScrollTable extends FlowPanel implements HasWidgets,

private Set<String> noncollapsibleColumns;

/**
* The last known row height used to preserve the height of a table with
* custom row heights and a fixed page length after removing the last row
* from the table.
*
* A new VScrollTableBody instance is created every time the number of rows
* changes causing {@link VScrollTableBody#rowHeight} to be discarded and
* the height recalculated by {@link VScrollTableBody#getRowHeight(boolean)}
* to avoid some rounding problems, e.g. round(2 * 19.8) / 2 = 20 but
* round(3 * 19.8) / 3 = 19.66.
*/
private double lastKnownRowHeight = Double.NaN;

/**
* Represents a select range of rows
*/
@@ -4244,13 +4263,27 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (tBodyMeasurementsDone && !forceUpdate) {
return rowHeight;
} else {

if (tBodyElement.getRows().getLength() > 0) {
int tableHeight = getTableHeight();
int rowCount = tBodyElement.getRows().getLength();
rowHeight = tableHeight / (double) rowCount;
} else {
if (isAttached()) {
// Special cases if we can't just measure the current rows
if (!Double.isNaN(lastKnownRowHeight)) {
// Use previous value if available
if (BrowserInfo.get().isIE()) {
/*
* IE needs to reflow the table element at this
* point to work correctly (e.g.
* com.vaadin.tests.components.table.
* ContainerSizeChange) - the other code paths
* already trigger reflows, but here it must be done
* explicitly.
*/
getTableHeight();
}
rowHeight = lastKnownRowHeight;
} else if (isAttached()) {
// measure row height by adding a dummy row
VScrollTableRow scrollTableRow = new VScrollTableRow();
tBodyElement.appendChild(scrollTableRow.getElement());
@@ -4261,6 +4294,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return DEFAULT_ROW_HEIGHT;
}
}
lastKnownRowHeight = rowHeight;
tBodyMeasurementsDone = true;
return rowHeight;
}

+ 1
- 1
src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java View File

@@ -287,7 +287,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
if (window.centered) {
window.center();
}
window.updateShadowSizeAndPosition();
window.sizeOrPositionUpdated();
}

@Override

+ 1
- 1
src/com/vaadin/ui/LoginForm.java View File

@@ -91,7 +91,7 @@ public class LoginForm extends CustomComponent {
response.setContentType("text/html; charset=utf-8");
response.getWriter()
.write("<html><body>Login form handled."
+ "<script type='text/javascript'>top.vaadin.forceSync();"
+ "<script type='text/javascript'>parent.parent.vaadin.forceSync();"
+ "</script></body></html>");

Map<String, String[]> parameters = request.getParameterMap();

+ 10
- 0
src/com/vaadin/ui/Root.java View File

@@ -419,6 +419,7 @@ public abstract class Root extends AbstractComponentContainer implements
private Page page = new Page(this);

private RootServerRpc rpc = new RootServerRpc() {
@Override
public void click(MouseEventDetails mouseDetails) {
fireEvent(new ClickEvent(Root.this, mouseDetails));
}
@@ -502,6 +503,7 @@ public abstract class Root extends AbstractComponentContainer implements
return this;
}

@Override
public void replaceComponent(Component oldComponent, Component newComponent) {
throw new UnsupportedOperationException();
}
@@ -511,6 +513,7 @@ public abstract class Root extends AbstractComponentContainer implements
return application;
}

@Override
public void paintContent(PaintTarget target) throws PaintException {
page.paintContent(target);

@@ -550,6 +553,7 @@ public abstract class Root extends AbstractComponentContainer implements
fireEvent(new ClickEvent(this, mouseDetails));
}

@Override
@SuppressWarnings("unchecked")
public void changeVariables(Object source, Map<String, Object> variables) {
if (variables.containsKey(CLICK_EVENT_ID)) {
@@ -578,6 +582,7 @@ public abstract class Root extends AbstractComponentContainer implements
*
* @see com.vaadin.ui.ComponentContainer#getComponentIterator()
*/
@Override
public Iterator<Component> getComponentIterator() {
// TODO could directly create some kind of combined iterator instead of
// creating a new ArrayList
@@ -597,6 +602,7 @@ public abstract class Root extends AbstractComponentContainer implements
*
* @see com.vaadin.ui.ComponentContainer#getComponentCount()
*/
@Override
public int getComponentCount() {
return windows.size() + (getContent() == null ? 0 : 1);
}
@@ -956,11 +962,13 @@ public abstract class Root extends AbstractComponentContainer implements
return actionManager;
}

@Override
public <T extends Action & com.vaadin.event.Action.Listener> void addAction(
T action) {
getActionManager().addAction(action);
}

@Override
public <T extends Action & com.vaadin.event.Action.Listener> void removeAction(
T action) {
if (actionManager != null) {
@@ -968,10 +976,12 @@ public abstract class Root extends AbstractComponentContainer implements
}
}

@Override
public void addActionHandler(Handler actionHandler) {
getActionManager().addActionHandler(actionHandler);
}

@Override
public void removeActionHandler(Handler actionHandler) {
if (actionManager != null) {
actionManager.removeActionHandler(actionHandler);

+ 16
- 0
src/com/vaadin/ui/Table.java View File

@@ -538,6 +538,13 @@ public class Table extends AbstractSelect implements Action.Container,

private HashMap<Object, Converter<String, Object>> propertyValueConverters = new HashMap<Object, Converter<String, Object>>();

/**
* Set to true if the client-side should be informed that the key mapper has
* been reset so it can avoid sending back references to keys that are no
* longer present.
*/
private boolean keyMapperReset;

/* Table constructors */

/**
@@ -2890,6 +2897,11 @@ public class Table extends AbstractSelect implements Action.Container,

paintVisibleColumns(target);

if (keyMapperReset) {
keyMapperReset = false;
target.addAttribute(VScrollTable.ATTRIBUTE_KEY_MAPPER_RESET, true);
}

if (dropHandler != null) {
dropHandler.getAcceptCriterion().paint(target);
}
@@ -4053,6 +4065,10 @@ public class Table extends AbstractSelect implements Action.Container,
public void containerItemSetChange(Container.ItemSetChangeEvent event) {
super.containerItemSetChange(event);

// super method clears the key map, must inform client about this to
// avoid getting invalid keys back (#8584)
keyMapperReset = true;

// ensure that page still has first item in page, ignore buffer refresh
// (forced in this method)
setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);

+ 1
- 1
tests/test.xml View File

@@ -11,7 +11,7 @@
<!-- Configuration -->
<!-- ================================================================== -->
<!-- Browsers to use for testing -->
<property name="browsers-windows" value="winxp-ie8,win7-ie9,winxp-firefox12,winxp-safari5,winxp-googlechrome19,winxp-opera11" />
<property name="browsers-windows" value="winxp-ie8,win7-ie9,winxp-firefox12,winxp-safari5,winxp-googlechrome21,winxp-opera11" />
<property name="browsers-linux" value="linux-firefox3,linux-opera10,linux-googlechrome8" />
<property name="browsers-mac" value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" />


+ 1
- 0
tests/testbench/com/vaadin/tests/components/abstractfield/AbstractFieldTest.java View File

@@ -78,6 +78,7 @@ public abstract class AbstractFieldTest<T extends AbstractField<?>> extends

MenuItem sortValueChangesItem = abstractField.addItem(
"Show sorted value changes", new MenuBar.Command() {
@Override
public void menuSelected(MenuItem selectedItem) {
sortValueChanges = selectedItem.isChecked();
log("Show sorted value changes: "

+ 61
- 0
tests/testbench/com/vaadin/tests/components/loginform/LoginFormInIframe.html_disabled View File

@@ -0,0 +1,61 @@
<?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>LoginFormTest</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">LoginFormTest</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/statictestfiles/LoginFormIframe.html</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>LoginForm</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>PID6</td>
<td></td>
</tr>
<tr>
<td>enterCharacter</td>
<td>username</td>
<td>username</td>
</tr>
<tr>
<td>enterCharacter</td>
<td>password</td>
<td>password</td>
</tr>
<tr>
<td>click</td>
<td>//form[@id='loginf']/div[5]/div/span/span</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>relative=top</td>
<td></td>
</tr>
<tr>
<td>selectFrame</td>
<td>LoginForm</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentsloginformLoginFormTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
<td>User 'username', password='password' logged in</td>
</tr>
</tbody></table>
</body>
</html>

+ 150
- 0
tests/testbench/com/vaadin/tests/components/table/MultiSelectWithRemovedRow.html View File

@@ -0,0 +1,150 @@
<?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.MultiSelectWithRemovedRow?restartApplication</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
<td>34,9</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>1. Selection: [Joe]</td>
</tr>
<!--Remove selection + shift select-->
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
<td>19,4:shift</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>2. Selection: [William, Jack, Averell]</td>
</tr>
<!--Remove first + shift select-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
<td>23,13</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td>
<td>26,10:shift</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>3. Selection: [Jack, Averell, Bob]</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td>
<td>34,14:shift</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>4. Selection: [William, Averell, Bob, Grat]</td>
</tr>
<!--Sort + shift select down-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td>
<td>31,15</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td>
<td>36,11</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
<td>30,6:shift</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>5. Selection: [Bob, Emmett, Grat]</td>
</tr>
<!--Sort + shift select up-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
<td>24,8</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td>
<td>11,2</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td>
<td>30,11:shift</td>
</tr>
<tr>
<td>click</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstableMultiSelectWithRemovedRow::PID_SLog_row_0</td>
<td>6. Selection: [Grat, Emmett, Bob]</td>
</tr>
</tbody></table>
</body>
</html>

+ 93
- 0
tests/testbench/com/vaadin/tests/components/table/MultiSelectWithRemovedRow.java View File

@@ -0,0 +1,93 @@
package com.vaadin.tests.components.table;

import java.util.Arrays;
import java.util.Collection;

import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.tests.components.TestBase;
import com.vaadin.tests.util.Log;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Table;

@SuppressWarnings("serial")
public class MultiSelectWithRemovedRow extends TestBase {
public static class Person {
private final String name;

public Person(String name) {
this.name = name;
}

public String getName() {
return name;
}

@Override
public String toString() {
return name;
}
}

@Override
protected void setup() {
final Log log = new Log(5);
addComponent(log);

final BeanItemContainer<Person> container = new BeanItemContainer<Person>(
Person.class, Arrays.asList(new Person("Joe"), new Person(
"William"), new Person("Jack"), new Person("Averell"),
new Person("Bob"), new Person("Grat"), new Person(
"Bill"), new Person("Emmett")));
final Table table = new Table("Table", container);
table.setSelectable(true);
table.setMultiSelect(true);
table.setImmediate(true);
addComponent(table);

Button showButton = new Button("Show selection");
showButton.addListener(new Button.ClickListener() {
@Override
public void buttonClick(Button.ClickEvent clickEvent) {
Collection<?> selection = (Collection<?>) table.getValue();
log.log("Selection: " + selection);
}
});
addComponent(showButton);

Button removeButton = new Button("Remove selection");
removeButton.addListener(new Button.ClickListener() {
@Override
public void buttonClick(Button.ClickEvent clickEvent) {
Collection<?> selection = (Collection<?>) table.getValue();
for (Object selected : selection) {
container.removeItem(selected);
}
}
});
addComponent(removeButton);

addComponent(new Button("Remove first selected row",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
Collection<?> selection = (Collection<?>) table
.getValue();
if (!selection.isEmpty()) {
Object firstSelected = selection.iterator().next();
container.removeItem(firstSelected);
}
}
}));
}

@Override
protected String getDescription() {
return "Multi select using shift should work after removing the currently selected row";
}

@Override
protected Integer getTicketNumber() {
return Integer.valueOf(8584);
}
}

+ 122
- 0
tests/testbench/com/vaadin/tests/components/table/TableRowNoHeightNoRows.html View File

@@ -0,0 +1,122 @@
<?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>29,11</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item5</td>
<td>40,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item1</td>
<td>53,9</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item0</td>
<td>4,6</td>
</tr>
<!--Add generated column-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td>
<td>34,8</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item8</td>
<td>40,6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item4</td>
<td>97,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item0</td>
<td>55,6</td>
</tr>
<!--Screenshot of initial state-->
<tr>
<td>screenCapture</td>
<td></td>
<td>1-no-rows-small</td>
</tr>
<!--Add a row to make the row height increase-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td>
<td>23,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item5</td>
<td>26,1</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item1</td>
<td>68,10</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item1</td>
<td>18,13</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>2-one-row-big</td>
</tr>
<!--Remove the row - height should be retained-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td>
<td>28,10</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item5</td>
<td>34,6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item1</td>
<td>62,4</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item0</td>
<td>25,4</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>3-no-rows-big</td>
</tr>

</tbody></table>
</body>
</html>

Loading…
Cancel
Save