aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorPekka Hyvönen <pekka@vaadin.com>2017-05-10 14:42:31 +0300
committerIlia Motornyi <elmot@vaadin.com>2017-05-10 14:42:31 +0300
commitcbb4393847f02fdbdcd64528918aeacbdc5565e3 (patch)
treeb6003782b956f5f1f9aed2f1d4707d383515a810 /client
parent624a9594b55f0b35e75b9aefd80a97049bc51eed (diff)
downloadvaadin-framework-cbb4393847f02fdbdcd64528918aeacbdc5565e3.tar.gz
vaadin-framework-cbb4393847f02fdbdcd64528918aeacbdc5565e3.zip
Fix partly missing drag image regression on Safari
Doesn't fix #9261, drag image missing on Safari when dragging grid row because that has position: absolute and offset.
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java82
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java54
2 files changed, 103 insertions, 33 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
index 3f673bac01..134e76e7e5 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
@@ -27,6 +27,7 @@ import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Image;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.WidgetUtil;
@@ -37,6 +38,7 @@ import com.vaadin.client.widgets.Escalator;
import com.vaadin.client.widgets.Grid;
import com.vaadin.shared.Range;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.dnd.DragSourceState;
import com.vaadin.shared.ui.dnd.DropEffect;
import com.vaadin.shared.ui.grid.GridDragSourceRpc;
import com.vaadin.shared.ui.grid.GridDragSourceState;
@@ -98,33 +100,53 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
return;
}
+ super.onDragStart(event);
+ }
+
+ @Override
+ protected void setDragImage(NativeEvent dragStartEvent) {
+ // do not call super since need to handle specifically
+ // 1. use resource if set (never needs safari hack)
+ // 2. add number badge if necessary (with safari hack if needed)
+ // 3. just use normal (with safari hack if needed)
+
// Add badge showing the number of dragged columns
- if (draggedItemKeys.size() > 1) {
- Element draggedRowElement = (Element) event.getTarget();
-
- Element badge = DOM.createSpan();
- badge.setClassName(gridConnector.getWidget().getStylePrimaryName()
- + "-row" + STYLE_SUFFIX_DRAG_BADGE);
- badge.setInnerHTML(draggedItemKeys.size() + "");
-
- badge.getStyle().setMarginLeft(
- getRelativeX(draggedRowElement, (NativeEvent) event) + 10,
- Style.Unit.PX);
- badge.getStyle().setMarginTop(
- getRelativeY(draggedRowElement, (NativeEvent) event)
- - draggedRowElement.getOffsetHeight() + 10,
- Style.Unit.PX);
-
- draggedRowElement.appendChild(badge);
-
- // Remove badge on the next animation frame. Drag image will still
- // contain the badge.
- AnimationScheduler.get().requestAnimationFrame(timestamp -> {
- badge.removeFromParent();
- }, (Element) event.getTarget());
+ String imageUrl = getResourceUrl(DragSourceState.RESOURCE_DRAG_IMAGE);
+ if (imageUrl != null && !imageUrl.isEmpty()) {
+ Image dragImage = new Image(
+ getConnection().translateVaadinUri(imageUrl));
+ dragStartEvent.getDataTransfer()
+ .setDragImage(dragImage.getElement(), 0, 0);
+ } else {
+ Element draggedRowElement = (Element) dragStartEvent
+ .getEventTarget().cast();
+ if (draggedItemKeys.size() > 1) {
+
+ Element badge = DOM.createSpan();
+ badge.setClassName(
+ gridConnector.getWidget().getStylePrimaryName() + "-row"
+ + STYLE_SUFFIX_DRAG_BADGE);
+ badge.setInnerHTML(draggedItemKeys.size() + "");
+
+ badge.getStyle().setMarginLeft(
+ getRelativeX(draggedRowElement, dragStartEvent) + 10,
+ Style.Unit.PX);
+ badge.getStyle().setMarginTop(
+ getRelativeY(draggedRowElement, dragStartEvent)
+ - draggedRowElement.getOffsetHeight() + 10,
+ Style.Unit.PX);
+
+ draggedRowElement.appendChild(badge);
+
+ // Remove badge on the next animation frame. Drag image will
+ // still contain the badge.
+ AnimationScheduler.get().requestAnimationFrame(timestamp -> {
+ badge.removeFromParent();
+ }, (Element) dragStartEvent.getEventTarget().cast());
+ setDraggable(draggedRowElement);
+ }
+ fixDragImageForSafari(draggedRowElement);
}
-
- super.onDragStart(event);
}
private int getRelativeY(Element element, NativeEvent event) {
@@ -196,9 +218,9 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* allowed and a selected row is dragged.
*
* @param draggedRow
- * Data of dragged row.
+ * Data of dragged row.
* @return {@code true} if multiple rows are dragged, {@code false}
- * otherwise.
+ * otherwise.
*/
private boolean dragMultipleRows(JsonObject draggedRow) {
SelectionModel<JsonObject> selectionModel = getGrid()
@@ -221,7 +243,7 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* Get all selected rows from a subset of rows defined by {@code range}.
*
* @param range
- * Range of indexes.
+ * Range of indexes.
* @return List of data of all selected rows in the given range.
*/
private List<JsonObject> getSelectedRowsInRange(Range range) {
@@ -241,7 +263,7 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* Converts a list of {@link JsonObject}s to a {@link JsonArray}.
*
* @param objects
- * List of json objects.
+ * List of json objects.
* @return Json array containing all json objects.
*/
private JsonArray toJsonArray(List<JsonObject> objects) {
@@ -257,7 +279,7 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* otherwise.
*
* @param row
- * Row data.
+ * Row data.
* @return Drag data if present or row data otherwise.
*/
private JsonObject getDragData(JsonObject row) {
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
index 932128a8b3..e718fb90d7 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -15,9 +15,12 @@
*/
package com.vaadin.client.extensions;
+import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.dom.client.DataTransfer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
@@ -163,7 +166,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
}
// Set drag image
- setDragImage(event);
+ setDragImage(nativeEvent);
// Set text data parameter
String dataTransferText = createDataTransferText(event);
@@ -185,6 +188,48 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
}
/**
+ * Fixes missing drag image for Safari by making the dragged element
+ * position to relative if needed. Safari won't show drag image unless the
+ * dragged element position is relative or absolute / fixed, but not with
+ * display block for the latter.
+ * <p>
+ * This method is a NOOP for non-safari browser.
+ * <p>
+ * This fix is not needed if a custom drag image is used on Safari.
+ *
+ * @param draggedElement
+ * the element that forms the drag image
+ */
+ protected void fixDragImageForSafari(Element draggedElement) {
+ if (!BrowserInfo.get().isSafari()) {
+ return;
+ }
+ final Style style = draggedElement.getStyle();
+ final String position = style.getPosition();
+
+ // relative works always
+ if ("relative".equalsIgnoreCase(position)) {
+ return;
+ }
+
+ // absolute & fixed don't work when there is offset used
+ if ("absolute".equalsIgnoreCase(position)
+ || "fixed".equalsIgnoreCase(position)) {
+ // FIXME #9261 need to figure out how to get absolute and fixed to
+ // position work when there is offset involved, like in Grid.
+ // The following hack with setting position to relative did not
+ // work, nor did clearing top/right/bottom/left.
+ }
+
+ // for all other positions, set the position to relative and revert it
+ // in an animation frame
+ draggedElement.getStyle().setPosition(Position.RELATIVE);
+ AnimationScheduler.get().requestAnimationFrame(timestamp -> {
+ draggedElement.getStyle().setProperty("position", position);
+ }, draggedElement);
+ }
+
+ /**
* Creates data of type {@code "text"} for the {@code DataTransfer} object
* of the given event.
*
@@ -215,13 +260,16 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
* @param dragStartEvent
* The drag start event.
*/
- protected void setDragImage(Event dragStartEvent) {
+ protected void setDragImage(NativeEvent dragStartEvent) {
String imageUrl = getResourceUrl(DragSourceState.RESOURCE_DRAG_IMAGE);
if (imageUrl != null && !imageUrl.isEmpty()) {
Image dragImage = new Image(
getConnection().translateVaadinUri(imageUrl));
- ((NativeEvent) dragStartEvent).getDataTransfer()
+ dragStartEvent.getDataTransfer()
.setDragImage(dragImage.getElement(), 0, 0);
+ } else {
+ fixDragImageForSafari(
+ (Element) dragStartEvent.getCurrentEventTarget().cast());
}
}