summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebContent/VAADIN/themes/base/common/common.css1
-rw-r--r--src/com/vaadin/terminal/ClassResource.java8
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java2
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/button/VButton.java41
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java153
-rw-r--r--src/com/vaadin/ui/Button.java8
-rw-r--r--tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html62
-rw-r--r--tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java55
8 files changed, 185 insertions, 145 deletions
diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css
index ccdd5190fc..b3bf6084be 100644
--- a/WebContent/VAADIN/themes/base/common/common.css
+++ b/WebContent/VAADIN/themes/base/common/common.css
@@ -247,5 +247,4 @@ div.v-app-loading {
.v-scrollable {
overflow: auto;
- -webkit-overflow-scrolling: touch;
}
diff --git a/src/com/vaadin/terminal/ClassResource.java b/src/com/vaadin/terminal/ClassResource.java
index fa196e90d9..e7419576f1 100644
--- a/src/com/vaadin/terminal/ClassResource.java
+++ b/src/com/vaadin/terminal/ClassResource.java
@@ -60,13 +60,7 @@ public class ClassResource implements ApplicationResource, Serializable {
* the application this resource will be added to.
*/
public ClassResource(String resourceName, Application application) {
- associatedClass = application.getClass();
- this.resourceName = resourceName;
- this.application = application;
- if (resourceName == null) {
- throw new NullPointerException();
- }
- application.addResource(this);
+ this(application.getClass(), resourceName, application);
}
/**
diff --git a/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java b/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java
index 444909c1b1..d9320787e8 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/accordion/VAccordion.java
@@ -353,8 +353,6 @@ public class VAccordion extends VTabsheetBase {
touchScrollHandler.addElement(getContainerElement());
- sinkEvents(Event.MOUSEEVENTS);
-
close();
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
index e5e7dbba8b..584be55bce 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/button/VButton.java
@@ -10,6 +10,7 @@ import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Accessibility;
@@ -61,7 +62,9 @@ public class VButton extends FocusWidget implements ClickHandler {
private boolean isCapturing;
/**
- * If <code>true</code>, this widget has focus with the space bar down.
+ * If <code>true</code>, this widget has focus with the space bar down. This
+ * means that we will get events when the button is released, but we should
+ * trigger the button only if the button is still focused at that point.
*/
private boolean isFocusing;
@@ -74,6 +77,14 @@ public class VButton extends FocusWidget implements ClickHandler {
protected int clickShortcut = 0;
+ private HandlerRegistration focusHandlerRegistration;
+ private HandlerRegistration blurHandlerRegistration;
+
+ /**
+ * If caption should be rendered in HTML
+ */
+ protected boolean htmlCaption = false;
+
public VButton() {
super(DOM.createDiv());
setTabIndex(0);
@@ -229,37 +240,28 @@ public class VButton extends FocusWidget implements ClickHandler {
if ((event.getTypeInt() & Event.KEYEVENTS) != 0) {
switch (type) {
case Event.ONKEYDOWN:
+ // Stop propagation when the user starts pressing a button that
+ // we are handling to prevent actions from getting triggered
if (event.getKeyCode() == 32 /* space */) {
isFocusing = true;
event.preventDefault();
+ event.stopPropagation();
+ } else if (event.getKeyCode() == KeyCodes.KEY_ENTER) {
+ event.stopPropagation();
}
break;
case Event.ONKEYUP:
if (isFocusing && event.getKeyCode() == 32 /* space */) {
isFocusing = false;
-
- /*
- * If click shortcut is space then the shortcut handler will
- * take care of the click.
- */
- if (clickShortcut != 32 /* space */) {
- onClick();
- }
-
+ onClick();
+ event.stopPropagation();
event.preventDefault();
}
break;
case Event.ONKEYPRESS:
if (event.getKeyCode() == KeyCodes.KEY_ENTER) {
-
- /*
- * If click shortcut is enter then the shortcut handler will
- * take care of the click.
- */
- if (clickShortcut != KeyCodes.KEY_ENTER) {
- onClick();
- }
-
+ onClick();
+ event.stopPropagation();
event.preventDefault();
}
break;
@@ -284,6 +286,7 @@ public class VButton extends FocusWidget implements ClickHandler {
* com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
* .dom.client.ClickEvent)
*/
+ @Override
public void onClick(ClickEvent event) {
if (BrowserInfo.get().isSafari()) {
VButton.this.setFocus(true);
diff --git a/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
index bdd1204fa6..4565c28fa5 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/table/VScrollTable.java
@@ -4396,7 +4396,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private String[] actionKeys = null;
private final TableRowElement rowElement;
- private boolean mDown;
private int index;
private Event touchStart;
private static final String ROW_CLASSNAME_EVEN = CLASSNAME + "-row";
@@ -4407,6 +4406,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private Timer dragTouchTimeout;
private int touchStartY;
private int touchStartX;
+ private boolean isDragging = false;
private VScrollTableRow(int rowKey) {
this.rowKey = rowKey;
@@ -4795,40 +4795,24 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- private boolean wasSignificantMove = false;
- private boolean isDragging = false;
-
/**
- * Special handler for touch devices
+ * Special handler for touch devices that support native scrolling
*
- * @param event
+ * @return Whether the event was handled by this method.
*/
- public void onTouchBrowserEvent(final Event event) {
- VConsole.log("-- START ONTOUCHBROWSEREVENT");
- if (enabled) {
+ private boolean handleTouchEvent(final Event event) {
+
+ boolean touchEventHandled = false;
+
+ if (enabled && hasNativeTouchScrolling) {
final Element targetTdOrTr = getEventTargetTdOrTr(event);
final int type = event.getTypeInt();
switch (type) {
- case Event.ONCONTEXTMENU:
- showContextMenu(event);
- if (enabled
- && (actionKeys != null || client
- .hasEventListeners(VScrollTable.this,
- ITEM_CLICK_EVENT_ID))) {
- /*
- * Prevent browser context menu only if there are
- * action handlers or item click listeners
- * registered
- */
- event.stopPropagation();
- event.preventDefault();
- }
- break;
case Event.ONTOUCHSTART:
+ touchEventHandled = true;
touchStart = event;
isDragging = false;
- wasSignificantMove = false;
Touch touch = event.getChangedTouches().get(0);
// save position to fields, touches in events are same
// instance during the operation.
@@ -4841,14 +4825,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void run() {
if (touchStart != null) {
- VConsole.log("DRAGGING");
+ // Start a drag if a finger is held
+ // in place long enough, then moved
isDragging = true;
}
}
};
- VConsole.log("START DRAG TIMEOUT");
- dragTouchTimeout.schedule(TOUCHSCROLL_TIMEOUT);
}
+ dragTouchTimeout.schedule(TOUCHSCROLL_TIMEOUT);
}
if (actionKeys != null) {
@@ -4857,123 +4841,68 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void run() {
if (touchStart != null) {
- VConsole.log("SHOW CONTEXT");
+ // Open the context menu if finger
+ // is held in place long enough.
showContextMenu(touchStart);
event.preventDefault();
touchStart = null;
-
}
}
};
- VConsole.log("START CONTEXT TIMEOUT");
-
- contextTouchTimeout.cancel();
- contextTouchTimeout
- .schedule(TOUCH_CONTEXT_MENU_TIMEOUT);
}
+ contextTouchTimeout
+ .schedule(TOUCH_CONTEXT_MENU_TIMEOUT);
}
break;
case Event.ONTOUCHMOVE:
+ touchEventHandled = true;
if (isSignificantMove(event)) {
- wasSignificantMove = true;
if (contextTouchTimeout != null) {
+ // Moved finger before the context menu timer
+ // expired, so let the browser handle this as a
+ // scroll.
contextTouchTimeout.cancel();
+ contextTouchTimeout = null;
}
if (!isDragging && dragTouchTimeout != null) {
- VConsole.log("CANCEL DRAG TIMEOUT");
+ // Moved finger before the drag timer expired,
+ // so let the browser handle this as a scroll.
dragTouchTimeout.cancel();
dragTouchTimeout = null;
}
- if (isDragging) {
- if (dragmode != 0 && touchStart != null) {
- event.preventDefault();
- event.stopPropagation();
- VConsole.log("START DRAG");
- startRowDrag(touchStart, type, targetTdOrTr);
- }
- isDragging = false;
+
+ if (dragmode != 0 && touchStart != null
+ && isDragging) {
+ event.preventDefault();
+ event.stopPropagation();
+ startRowDrag(touchStart, type, targetTdOrTr);
}
touchStart = null;
}
break;
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
- VConsole.log("ONTOUCHEND");
+ touchEventHandled = true;
if (contextTouchTimeout != null) {
- VConsole.log("CANCEL CONTEXT TIMEOUT");
contextTouchTimeout.cancel();
}
if (dragTouchTimeout != null) {
- VConsole.log("CANCEL DRAG TIMEOUT");
dragTouchTimeout.cancel();
}
if (touchStart != null) {
event.preventDefault();
event.stopPropagation();
+ if (!BrowserInfo.get().isAndroid()) {
+ Util.simulateClickFromTouchEvent(touchStart,
+ this);
+ }
touchStart = null;
}
isDragging = false;
- VConsole.log("END ONTOUCHEND");
break;
- case Event.ONMOUSEDOWN:
- VConsole.log("ONMOUSEDOWN");
- if (targetTdOrTr != null) {
- setRowFocus(this);
- ensureFocus();
- if (dragmode != 0
- && (event.getButton() == NativeEvent.BUTTON_LEFT)) {
- startRowDrag(event, event.getTypeInt(),
- targetTdOrTr);
- } else {
- event.stopPropagation();
- }
-
- event.preventDefault();
- }
- break;
- case Event.ONMOUSEOUT:
- VConsole.log("ONMOUSEOUT");
- break;
- case Event.ONMOUSEUP:
- VConsole.log("ONMOUSEUP");
- if (targetTdOrTr != null) {
- if (isSelectable()) {
- boolean currentlyJustThisRowSelected = selectedRowKeys
- .size() == 1
- && selectedRowKeys.contains(getKey());
-
- if (!currentlyJustThisRowSelected) {
- if (isSingleSelectMode()
- || isMultiSelectModeDefault()) {
- deselectAll();
- }
- toggleSelection();
- } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
- && nullSelectionAllowed) {
- toggleSelection();
- }
-
- selectionRangeStart = this;
- setRowFocus(this);
-
- event.preventDefault();
- event.stopPropagation();
- }
- }
-
- break;
- case Event.ONDBLCLICK:
- if (targetTdOrTr != null) {
- handleClickEvent(event, targetTdOrTr, true);
- }
- break;
- default:
}
}
- VConsole.log("-- SUPER ONBROWSEREVENT");
-
- super.onBrowserEvent(event);
- VConsole.log("-- END ONTOUCHBROWSEREVENT");
+ return touchEventHandled;
}
/*
@@ -4982,12 +4911,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void onBrowserEvent(final Event event) {
- if (hasNativeTouchScrolling) {
- onTouchBrowserEvent(event);
- return;
- }
+ final boolean touchEventHandled = handleTouchEvent(event);
- if (enabled) {
+ if (enabled && !touchEventHandled) {
final int type = event.getTypeInt();
final Element targetTdOrTr = getEventTargetTdOrTr(event);
if (type == Event.ONCONTEXTMENU) {
@@ -5020,7 +4946,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
break;
case Event.ONMOUSEUP:
if (targetCellOrRowFound) {
- mDown = false;
/*
* Queue here, send at the same time as the
* corresponding value change event - see #7127
@@ -5263,9 +5188,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
break;
case Event.ONMOUSEOUT:
- if (targetCellOrRowFound) {
- mDown = false;
- }
break;
default:
break;
@@ -5295,7 +5217,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
protected void startRowDrag(Event event, final int type,
Element targetTdOrTr) {
- mDown = true;
VTransferable transferable = new VTransferable();
transferable.setDragSource(ConnectorMap.get(client)
.getConnector(VScrollTable.this));
diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java
index 876fe593e2..9551cbaaab 100644
--- a/src/com/vaadin/ui/Button.java
+++ b/src/com/vaadin/ui/Button.java
@@ -38,10 +38,12 @@ public class Button extends AbstractComponent implements
Action.ShortcutNotifier {
private ButtonServerRpc rpc = new ButtonServerRpc() {
+ @Override
public void click(MouseEventDetails mouseEventDetails) {
fireClick(mouseEventDetails);
}
+ @Override
public void disableOnClick() {
// Could be optimized so the button is not repainted because of
// this (client side has already disabled the button)
@@ -330,20 +332,24 @@ public class Button extends AbstractComponent implements
fireEvent(new Button.ClickEvent(this, details));
}
+ @Override
public void addListener(BlurListener listener) {
addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
BlurListener.blurMethod);
}
+ @Override
public void removeListener(BlurListener listener) {
removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
}
+ @Override
public void addListener(FocusListener listener) {
addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
FocusListener.focusMethod);
}
+ @Override
public void removeListener(FocusListener listener) {
removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
@@ -469,10 +475,12 @@ public class Button extends AbstractComponent implements
requestRepaint();
}
+ @Override
public int getTabIndex() {
return tabIndex;
}
+ @Override
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
diff --git a/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html
new file mode 100644
index 0000000000..5ec33f09fa
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.button.ButtonEnterWithWindowShortcut?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]</td>
+ <td>enter</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td>
+ <td>1. button click listener fired</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::</td>
+ <td>enter</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td>
+ <td>2. enter pressed in window</td>
+</tr>
+<!-- Can't test using space because of #8827 -->
+<!-- <tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]</td>
+ <td>space</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td>
+ <td>3. button click listener fired</td>
+</tr>
+<tr>
+ <td>pressSpecialKey</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::</td>
+ <td>space</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentsbuttonButtonEnterWithWindowShortcut::PID_SLog_row_0</td>
+ <td>4. space pressed in window</td>
+</tr> -->
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java
new file mode 100644
index 0000000000..7efd40ca5d
--- /dev/null
+++ b/tests/testbench/com/vaadin/tests/components/button/ButtonEnterWithWindowShortcut.java
@@ -0,0 +1,55 @@
+package com.vaadin.tests.components.button;
+
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+
+public class ButtonEnterWithWindowShortcut extends TestBase {
+ Log log = new Log(5);
+
+ @Override
+ protected void setup() {
+ getMainWindow().addActionHandler(new Handler() {
+ private static final long serialVersionUID = -4976129418325394913L;
+
+ public void handleAction(Action action, Object sender, Object target) {
+ log.log(action.getCaption() + " pressed in window");
+ }
+
+ public Action[] getActions(Object target, Object sender) {
+ ShortcutAction enter = new ShortcutAction("enter",
+ ShortcutAction.KeyCode.ENTER, null);
+ ShortcutAction space = new ShortcutAction("space",
+ ShortcutAction.KeyCode.SPACEBAR, null);
+ return new Action[] { enter, space };
+ }
+ });
+
+ Button button = new Button("Focus me and press enter",
+ new ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ log.log("button click listener fired");
+ }
+ });
+ button.focus();
+
+ addComponent(log);
+ addComponent(button);
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Pressing enter or space with the button focused should trigger the button click listener and not the shortcut action on the window.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(5433);
+ }
+
+}