diff options
Diffstat (limited to 'client')
3 files changed, 115 insertions, 76 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java index 09142e222b..8126f85c1e 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java @@ -82,7 +82,7 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { @Override protected void sendDropEventToServer(String dataTransferText, - Event dropEvent) { + String dropEffect, Event dropEvent) { String rowKey = null; DropLocation dropLocation = null; @@ -96,8 +96,8 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { (NativeEvent) dropEvent); } - getRpcProxy(GridDropTargetRpc.class).drop(dataTransferText, rowKey, - dropLocation); + getRpcProxy(GridDropTargetRpc.class).drop(dataTransferText, dropEffect, + rowKey, dropLocation); } private JsonObject getRowData(TableRowElement row) { @@ -147,7 +147,7 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { } @Override - protected void setTargetIndicator(Event event) { + protected void setTargetClassIndicator(Event event) { getTargetRow(((Element) event.getTarget())).ifPresent(target -> { // Get required class name @@ -184,7 +184,7 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { } @Override - protected void removeTargetIndicator(Event event) { + protected void removeTargetClassIndicator(Event event) { // Remove all possible style names getTargetRow((Element) event.getTarget()).ifPresent(e -> { 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 165e0ca9df..932128a8b3 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java @@ -77,7 +77,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Sets the given element draggable and adds class name. * * @param element - * Element to be set draggable. + * Element to be set draggable. */ protected void setDraggable(Element element) { element.setDraggable(Element.DRAGGABLE_TRUE); @@ -91,7 +91,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Removes draggable and class name from the given element. * * @param element - * Element to remove draggable from. + * Element to remove draggable from. */ protected void removeDraggable(Element element) { element.setDraggable(Element.DRAGGABLE_FALSE); @@ -104,7 +104,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Adds dragstart and dragend event listeners to the given DOM element. * * @param element - * DOM element to attach event listeners to. + * DOM element to attach event listeners to. */ protected void addDragListeners(Element element) { EventTarget target = element.cast(); @@ -117,7 +117,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Removes dragstart and dragend event listeners from the given DOM element. * * @param element - * DOM element to remove event listeners from. + * DOM element to remove event listeners from. */ protected void removeDragListeners(Element element) { EventTarget target = element.cast(); @@ -150,7 +150,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * dragstart} event occurs. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDragStart(Event event) { // Convert elemental event to have access to dataTransfer @@ -167,10 +167,12 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { // Set text data parameter String dataTransferText = createDataTransferText(event); - if (dataTransferText != null && !dataTransferText.isEmpty()) { - nativeEvent.getDataTransfer() - .setData(DragSourceState.DATA_TYPE_TEXT, dataTransferText); + // Always set something as the text data, or DnD won't work in FF ! + if (dataTransferText == null) { + dataTransferText = ""; } + nativeEvent.getDataTransfer().setData(DragSourceState.DATA_TYPE_TEXT, + dataTransferText); // Initiate firing server side dragstart event when there is a // DragStartListener attached on the server side @@ -187,7 +189,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * of the given event. * * @param dragStartEvent - * Event to set the data for. + * Event to set the data for. * @return Textual data to be set for the event or {@literal null}. */ protected String createDataTransferText(Event dragStartEvent) { @@ -201,7 +203,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * handler attached. * * @param dragStartEvent - * Client side dragstart event. + * Client side dragstart event. */ protected void sendDragStartEventToServer(Event dragStartEvent) { getRpcProxy(DragSourceRpc.class).dragStart(); @@ -211,7 +213,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Sets the drag image to be displayed. * * @param dragStartEvent - * The drag start event. + * The drag start event. */ protected void setDragImage(Event dragStartEvent) { String imageUrl = getResourceUrl(DragSourceState.RESOURCE_DRAG_IMAGE); @@ -228,7 +230,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * event occurs. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDragEnd(Event event) { // Initiate server start dragend event when there is a DragEndListener @@ -248,9 +250,9 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { * Initiates a server RPC for the drag end event. * * @param dragEndEvent - * Client side dragend event. + * Client side dragend event. * @param dropEffect - * Drop effect of the dragend event, extracted from {@code + * Drop effect of the dragend event, extracted from {@code * DataTransfer.dropEffect} parameter. */ protected void sendDragEndEventToServer(Event dragEndEvent, @@ -269,11 +271,13 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { } private native void setEffectAllowed(DataTransfer dataTransfer, - String effectAllowed)/*-{ + String effectAllowed) + /*-{ dataTransfer.effectAllowed = effectAllowed; }-*/; - private native String getDropEffect(DataTransfer dataTransfer)/*-{ + static native String getDropEffect(DataTransfer dataTransfer) + /*-{ return dataTransfer.dropEffect; }-*/; @@ -282,7 +286,8 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { return (DragSourceState) super.getState(); } - private native boolean getStylePrimaryName(Element element)/*-{ + private native boolean getStylePrimaryName(Element element) + /*-{ return @com.google.gwt.user.client.ui.UIObject::getStylePrimaryName(Lcom/google/gwt/dom/client/Element;)(element); }-*/; } diff --git a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java index e3fbeabab4..7c9e9755b8 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java @@ -25,6 +25,7 @@ import com.vaadin.client.ServerConnector; import com.vaadin.event.dnd.DropTargetExtension; 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.dnd.DropTargetRpc; import com.vaadin.shared.ui.dnd.DropTargetState; @@ -92,7 +93,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { * DOM element. * * @param element - * DOM element to attach event listeners to. + * DOM element to attach event listeners to. */ protected void addDropListeners(Element element) { EventTarget target = element.cast(); @@ -108,7 +109,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { * given DOM element. * * @param element - * DOM element to remove event listeners from. + * DOM element to remove event listeners from. */ protected void removeDropListeners(Element element) { EventTarget target = element.cast(); @@ -140,34 +141,68 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { * Event handler for the {@code dragenter} event. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDragEnter(Event event) { - // Generate style name for drop target - styleDragCenter = dropTargetWidget.getStylePrimaryName() - + STYLE_SUFFIX_DRAG_CENTER; + NativeEvent nativeEvent = (NativeEvent) event; + if (isDropAllowed(nativeEvent)) { + // Generate style name for drop target + styleDragCenter = dropTargetWidget.getStylePrimaryName() + + STYLE_SUFFIX_DRAG_CENTER; + + setTargetClassIndicator(event); - setTargetIndicator(event); + setDropEffect(nativeEvent); + + // According to spec, need to call this for allowing dropping, the + // default action would be to reject as target + event.preventDefault(); + } else { + // Remove drop effect + nativeEvent.getDataTransfer() + .setDropEffect(DataTransfer.DropEffect.NONE); + } + } + + /** + * Set the drop effect for the dragenter / dragover event, if one has been + * set from server side. + * <p> + * From Moz Foundation: "You can modify the dropEffect property during the + * dragenter or dragover events, if for example, a particular drop target + * only supports certain operations. You can modify the dropEffect property + * to override the user effect, and enforce a specific drop operation to + * occur. Note that this effect must be one listed within the effectAllowed + * property. Otherwise, it will be set to an alternate value that is + * allowed." + * + * @param event + * the dragenter or dragover event. + */ + protected void setDropEffect(NativeEvent event) { + if (getState().dropEffect != null) { + + DataTransfer.DropEffect dropEffect = DataTransfer.DropEffect + // the valueOf() needs to have equal string and name() + // doesn't return in all upper case + .valueOf(getState().dropEffect.name().toUpperCase()); + event.getDataTransfer().setDropEffect(dropEffect); + } } /** * Event handler for the {@code dragover} event. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDragOver(Event event) { NativeEvent nativeEvent = (NativeEvent) event; - if (isDragOverAllowed(nativeEvent)) { - // Set dropEffect parameter - if (getState().dropEffect != null) { - nativeEvent.getDataTransfer().setDropEffect( - DataTransfer.DropEffect - .valueOf(getState().dropEffect.name())); - } + if (isDropAllowed(nativeEvent)) { + setDropEffect(nativeEvent); // Add drop target indicator in case the element doesn't have one - setTargetIndicator(event); + setTargetClassIndicator(event); // Prevent default to allow drop nativeEvent.preventDefault(); @@ -178,60 +213,55 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { .setDropEffect(DataTransfer.DropEffect.NONE); // Remove drop target indicator - removeTargetIndicator(event); - } - } - - /** - * Determines if dragover event is allowed on this drop target according to - * the dragover criteria. - * - * @param event - * Native dragover event. - * @return {@code true} if dragover is allowed, {@code false} otherwise. - * @see DropTargetExtension#setDragOverCriteria(String) - */ - protected boolean isDragOverAllowed(NativeEvent event) { - if (getState().dragOverCriteria != null) { - return executeScript(event, getState().dragOverCriteria); + removeTargetClassIndicator(event); } - - // Allow when criteria not set - return true; } /** * Event handler for the {@code dragleave} event. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDragLeave(Event event) { - removeTargetIndicator(event); + removeTargetClassIndicator(event); } /** * Event handler for the {@code drop} event. * * @param event - * browser event to be handled + * browser event to be handled */ protected void onDrop(Event event) { NativeEvent nativeEvent = (NativeEvent) event; - if (dropAllowed(nativeEvent)) { + if (isDropAllowed(nativeEvent)) { nativeEvent.preventDefault(); nativeEvent.stopPropagation(); - String dataTransferText = nativeEvent.getDataTransfer().getData( - DragSourceState.DATA_TYPE_TEXT); + String dataTransferText = nativeEvent.getDataTransfer() + .getData(DragSourceState.DATA_TYPE_TEXT); - sendDropEventToServer(dataTransferText, event); + String dropEffect = DragSourceExtensionConnector + .getDropEffect(nativeEvent.getDataTransfer()); + + sendDropEventToServer(dataTransferText, dropEffect, event); } - removeTargetIndicator(event); + removeTargetClassIndicator(event); } - private boolean dropAllowed(NativeEvent event) { + private boolean isDropAllowed(NativeEvent event) { + // there never should be a drop when effect has been set to none + if (getState().dropEffect != null + && getState().dropEffect == DropEffect.NONE) { + return false; + } + // TODO #9246: Should add verification for checking effectAllowed and + // dropEffect from event and comparing that to target's dropEffect. + // Currently Safari, Edge and IE don't follow the spec by allowing drop + // if those don't match + if (getState().dropCriteria != null) { return executeScript(event, getState().dropCriteria); } @@ -244,23 +274,26 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { * Initiates a server RPC for the drop event. * * @param dataTransferText - * Client side textual data that can be set for the drag source and - * is transferred to the drop target. + * Client side textual data that can be set for the drag source + * and is transferred to the drop target. + * @param dropEffect + * the desired drop effect * @param dropEvent - * Client side drop event. + * Client side drop event. */ protected void sendDropEventToServer(String dataTransferText, - Event dropEvent) { - getRpcProxy(DropTargetRpc.class).drop(dataTransferText); + String dropEffect, Event dropEvent) { + getRpcProxy(DropTargetRpc.class).drop(dataTransferText, dropEffect); } /** * Add class that indicates that the component is a target. * * @param event - * The drag enter or dragover event that triggered the indication. + * The drag enter or dragover event that triggered the + * indication. */ - protected void setTargetIndicator(Event event) { + protected void setTargetClassIndicator(Event event) { getDropTargetElement().addClassName(styleDragCenter); } @@ -270,13 +303,14 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { * This is triggered on dragleave, drop and dragover events. * * @param event - * the event that triggered the removal of the indicator + * the event that triggered the removal of the indicator */ - protected void removeTargetIndicator(Event event) { + protected void removeTargetClassIndicator(Event event) { getDropTargetElement().removeClassName(styleDragCenter); } - private native boolean executeScript(NativeEvent event, String script)/*-{ + private native boolean executeScript(NativeEvent event, String script) + /*-{ return new Function('event', script)(event); }-*/; |