diff options
author | snej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 17:29:25 +0000 |
---|---|---|
committer | snej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 17:29:25 +0000 |
commit | 1d9f4137eff50f1305e288767bb770151526552d (patch) | |
tree | 4ae1750d34778e7b0ae23dfe315118cf124c3715 /webkit/glue | |
parent | c7f475ed4a9fd8f198468df696c55e1c75d65526 (diff) | |
download | chromium_src-1d9f4137eff50f1305e288767bb770151526552d.zip chromium_src-1d9f4137eff50f1305e288767bb770151526552d.tar.gz chromium_src-1d9f4137eff50f1305e288767bb770151526552d.tar.bz2 |
Plumb the DragOperation through all the layers between the platform Drag-n-drop code and WebCore.
This allows the HTML5 DataTransfer effectAllowed and dropEffect properties to be set correctly in JS handlers, as per the HTML5 spec.
(The drag-dropeffect test isn't in WebKit yet -- it's part of a separate WebKit patch that's been in review for weeks.)
R=darin,pink
BUG=http://code.google.com/p/chromium/issues/detail?id=14654, http://code.google.com/p/chromium/issues/detail?id=20985
TEST=LayoutTests/fast/events/drag-dropeffect.html, LayoutTests/editing/pasteboard/files-during-page-drags.html
Review URL: http://codereview.chromium.org/174364
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25629 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/dragclient_impl.cc | 10 | ||||
-rw-r--r-- | webkit/glue/webview.h | 21 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 7 | ||||
-rw-r--r-- | webkit/glue/webview_impl.cc | 96 | ||||
-rw-r--r-- | webkit/glue/webview_impl.h | 30 |
5 files changed, 104 insertions, 60 deletions
diff --git a/webkit/glue/dragclient_impl.cc b/webkit/glue/dragclient_impl.cc index 661a7a0..75a8ba9 100644 --- a/webkit/glue/dragclient_impl.cc +++ b/webkit/glue/dragclient_impl.cc @@ -16,6 +16,7 @@ #include "webkit/glue/webview_impl.h" using WebKit::WebDragData; +using WebKit::WebPoint; void DragClientImpl::willPerformDragDestinationAction( WebCore::DragDestinationAction, @@ -59,7 +60,14 @@ void DragClientImpl::startDrag(WebCore::DragImageRef drag_image, WebDragData drag_data = webkit_glue::ChromiumDataObjectToWebDragData( static_cast<WebCore::ClipboardChromium*>(clipboard)->dataObject()); - webview_->StartDragging(drag_data); + WebCore::DragOperation drag_operation_mask; + if (!clipboard->sourceOperation(drag_operation_mask)) { + drag_operation_mask = WebCore::DragOperationEvery; + } + + webview_->StartDragging(webkit_glue::IntPointToWebPoint(event_pos), + drag_data, + static_cast<WebKit::WebDragOperationsMask>(drag_operation_mask)); } WebCore::DragImageRef DragClientImpl::createDragImageForLink( diff --git a/webkit/glue/webview.h b/webkit/glue/webview.h index 0b55232..0cd33fc 100644 --- a/webkit/glue/webview.h +++ b/webkit/glue/webview.h @@ -9,6 +9,7 @@ #include <vector> #include "base/basictypes.h" +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebWidget.h" namespace WebKit { @@ -185,15 +186,11 @@ class WebView : public WebKit::WebWidget { // Show the JavaScript console. virtual void ShowJavaScriptConsole() = 0; - // Notifies the webview that a drag has been cancelled. - virtual void DragSourceCancelledAt( - const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; - - // Notifies the webview that a drag has terminated. + // Notifies the webview that a drag has ended (with a drop or a cancel). virtual void DragSourceEndedAt( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperation operation) = 0; // Notifies the webview that a drag and drop operation is in progress, with // dropable items over the view. @@ -206,13 +203,15 @@ class WebView : public WebKit::WebWidget { // Callback methods when a drag and drop operation is trying to drop data // on this webview. - virtual bool DragTargetDragEnter( + virtual WebKit::WebDragOperation DragTargetDragEnter( const WebKit::WebDragData& drag_data, int identity, const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; - virtual bool DragTargetDragOver( + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed) = 0; + virtual WebKit::WebDragOperation DragTargetDragOver( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point) = 0; + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed) = 0; virtual void DragTargetDragLeave() = 0; virtual void DragTargetDrop( const WebKit::WebPoint& client_point, diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 804049d..7a8e313 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -28,6 +28,7 @@ #include <vector> +#include "webkit/api/public/WebDragOperation.h" #include "webkit/api/public/WebFrame.h" #include "webkit/api/public/WebNavigationPolicy.h" #include "webkit/api/public/WebNavigationType.h" @@ -639,10 +640,14 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { // Starts a drag session with the supplied contextual information. // webview: The WebView sending the delegate method. + // mouseCoords: Current mouse coordinates // drop_data: a WebDropData struct which should contain all the necessary // information for dragging data out of the webview. + // drag_source_operation_mask: indicates what drag operations are allowed virtual void StartDragging(WebView* webview, - const WebKit::WebDragData& drag_data) { + const WebKit::WebPoint &mouseCoords, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask operations_mask) { } // Returns the focus to the client. diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index f38c390..cc9ebbd 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -96,6 +96,10 @@ using WebKit::WebCompositionCommand; using WebKit::WebCompositionCommandConfirm; using WebKit::WebCompositionCommandDiscard; using WebKit::WebDragData; +using WebKit::WebDragOperation; +using WebKit::WebDragOperationCopy; +using WebKit::WebDragOperationNone; +using WebKit::WebDragOperationsMask; using WebKit::WebEditingClient; using WebKit::WebFrame; using WebKit::WebInputEvent; @@ -129,10 +133,19 @@ static const double kMaxTextSizeMultiplier = 3.0; // one page group. static const char* kPageGroupName = "default"; -// The webcore drag operation type when something is trying to be dropped on -// the webview. These values are taken from Apple's windows port. -static const WebCore::DragOperation kDropTargetOperation = - static_cast<WebCore::DragOperation>(DragOperationCopy | DragOperationLink); +// Ensure that the WebKit::WebDragOperation enum values stay in sync with +// the original WebCore::DragOperation constants. +#define COMPILE_ASSERT_MATCHING_ENUM(webcore_name) \ + COMPILE_ASSERT(int(WebCore::webcore_name) == int(WebKit::Web##webcore_name),\ + dummy##webcore_name) +COMPILE_ASSERT_MATCHING_ENUM(DragOperationNone); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationLink); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete); +COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); // AutocompletePopupMenuClient class AutocompletePopupMenuClient : public WebCore::PopupMenuClient { @@ -380,7 +393,8 @@ WebViewImpl::WebViewImpl(WebViewDelegate* delegate, drag_target_dispatch_(false), drag_identity_(0), drop_effect_(DROP_EFFECT_DEFAULT), - drop_accept_(false), + operations_allowed_(WebKit::WebDragOperationNone), + drag_operation_(WebKit::WebDragOperationNone), autocomplete_popup_showing_(false), is_transparent_(false) { // WebKit/win/WebView.cpp does the same thing, except they call the @@ -1495,24 +1509,16 @@ void WebViewImpl::ShowJavaScriptConsole() { page_->inspectorController()->showPanel(InspectorController::ConsolePanel); } -void WebViewImpl::DragSourceCancelledAt( - const WebPoint& client_point, - const WebPoint& screen_point) { - PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point), - webkit_glue::WebPointToIntPoint(screen_point), - NoButton, MouseEventMoved, 0, false, false, false, - false, 0); - page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, DragOperationNone); -} - void WebViewImpl::DragSourceEndedAt( const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operation) { PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), LeftButton, MouseEventMoved, 0, false, false, false, false, 0); - page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, DragOperationCopy); + page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme, + static_cast<WebCore::DragOperation>(operation)); } void WebViewImpl::DragSourceMovedTo( @@ -1534,52 +1540,70 @@ void WebViewImpl::DragSourceSystemDragEnded() { } } -bool WebViewImpl::DragTargetDragEnter( +WebDragOperation WebViewImpl::DragTargetDragEnter( const WebDragData& web_drag_data, int identity, const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operations_allowed) { DCHECK(!current_drag_data_.get()); current_drag_data_ = webkit_glue::WebDragDataToChromiumDataObject(web_drag_data); drag_identity_ = identity; + operations_allowed_ = operations_allowed; DragData drag_data( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed)); drop_effect_ = DROP_EFFECT_DEFAULT; drag_target_dispatch_ = true; DragOperation effect = page_->dragController()->dragEntered(&drag_data); + // Mask the operation against the drag source's allowed operations. + if ((effect & drag_data.draggingSourceOperationMask()) != effect) { + effect = DragOperationNone; + } drag_target_dispatch_ = false; if (drop_effect_ != DROP_EFFECT_DEFAULT) - return drop_accept_ = (drop_effect_ != DROP_EFFECT_NONE); - return drop_accept_ = (effect != DragOperationNone); + drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ? + WebDragOperationCopy : WebDragOperationNone; + else + drag_operation_ = static_cast<WebDragOperation>(effect); + return drag_operation_; } -bool WebViewImpl::DragTargetDragOver( +WebDragOperation WebViewImpl::DragTargetDragOver( const WebPoint& client_point, - const WebPoint& screen_point) { + const WebPoint& screen_point, + WebDragOperation operations_allowed) { DCHECK(current_drag_data_.get()); + operations_allowed_ = operations_allowed; DragData drag_data( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed)); drop_effect_ = DROP_EFFECT_DEFAULT; drag_target_dispatch_ = true; DragOperation effect = page_->dragController()->dragUpdated(&drag_data); + // Mask the operation against the drag source's allowed operations. + if ((effect & drag_data.draggingSourceOperationMask()) != effect) { + effect = DragOperationNone; + } drag_target_dispatch_ = false; if (drop_effect_ != DROP_EFFECT_DEFAULT) - return drop_accept_ = (drop_effect_ != DROP_EFFECT_NONE); - return drop_accept_ = (effect != DragOperationNone); + drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ? + WebDragOperationCopy : WebDragOperationNone; + else + drag_operation_ = static_cast<WebDragOperation>(effect); + return drag_operation_; } void WebViewImpl::DragTargetDragLeave() { @@ -1589,7 +1613,7 @@ void WebViewImpl::DragTargetDragLeave() { current_drag_data_.get(), IntPoint(), IntPoint(), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed_)); drag_target_dispatch_ = true; page_->dragController()->dragExited(&drag_data); @@ -1597,7 +1621,7 @@ void WebViewImpl::DragTargetDragLeave() { current_drag_data_ = NULL; drop_effect_ = DROP_EFFECT_DEFAULT; - drop_accept_ = false; + drag_operation_ = WebDragOperationNone; drag_identity_ = 0; } @@ -1611,9 +1635,9 @@ void WebViewImpl::DragTargetDrop( // flight, or else delayed by javascript processing in this webview. If a // drop happens before our IPC reply has reached the browser process, then // the browser forwards the drop to this webview. So only allow a drop to - // proceed if our webview drop_accept_ state is true. + // proceed if our webview drag_operation_ state is not DragOperationNone. - if (!drop_accept_) { // IPC RACE CONDITION: do not allow this drop. + if (drag_operation_ == WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. DragTargetDragLeave(); return; } @@ -1622,7 +1646,7 @@ void WebViewImpl::DragTargetDrop( current_drag_data_.get(), webkit_glue::WebPointToIntPoint(client_point), webkit_glue::WebPointToIntPoint(screen_point), - kDropTargetOperation); + static_cast<WebCore::DragOperation>(operations_allowed_)); drag_target_dispatch_ = true; page_->dragController()->performDrag(&drag_data); @@ -1630,7 +1654,7 @@ void WebViewImpl::DragTargetDrop( current_drag_data_ = NULL; drop_effect_ = DROP_EFFECT_DEFAULT; - drop_accept_ = false; + drag_operation_ = WebDragOperationNone; drag_identity_ = 0; } @@ -1795,11 +1819,13 @@ void WebViewImpl::DidCommitLoad(bool* is_new_navigation) { observed_new_navigation_ = false; } -void WebViewImpl::StartDragging(const WebDragData& drag_data) { +void WebViewImpl::StartDragging(WebPoint event_pos, + const WebDragData& drag_data, + WebDragOperationsMask mask) { if (delegate_) { DCHECK(!doing_drag_and_drop_); doing_drag_and_drop_ = true; - delegate_->StartDragging(this, drag_data); + delegate_->StartDragging(this, event_pos, drag_data, mask); } } diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index 2504c1e..3c753ac 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -111,23 +111,23 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { virtual void CopyImageAt(int x, int y); virtual void InspectElement(int x, int y); virtual void ShowJavaScriptConsole(); - virtual void DragSourceCancelledAt( - const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); virtual void DragSourceEndedAt( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperation operation); virtual void DragSourceMovedTo( const WebKit::WebPoint& client_point, const WebKit::WebPoint& screen_point); virtual void DragSourceSystemDragEnded(); - virtual bool DragTargetDragEnter( + virtual WebKit::WebDragOperation DragTargetDragEnter( const WebKit::WebDragData& drag_data, int identity, const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); - virtual bool DragTargetDragOver( + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed); + virtual WebKit::WebDragOperation DragTargetDragOver( const WebKit::WebPoint& client_point, - const WebKit::WebPoint& screen_point); + const WebKit::WebPoint& screen_point, + WebKit::WebDragOperationsMask operations_allowed); virtual void DragTargetDragLeave(); virtual void DragTargetDrop( const WebKit::WebPoint& client_point, @@ -231,7 +231,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { } // Start a system drag and drop operation. - void StartDragging(const WebKit::WebDragData& drag_data); + void StartDragging(WebKit::WebPoint event_pos, + const WebKit::WebDragData& drag_data, + WebKit::WebDragOperationsMask drag_source_operation_mask); // Hides the autocomplete popup if it is showing. void HideAutoCompletePopup(); @@ -369,9 +371,13 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { DROP_EFFECT_COPY } drop_effect_; - // When true, the drag data can be dropped onto the current drop target in - // this WebView (the drop target can accept the drop). - bool drop_accept_; + // The available drag operations (copy, move link...) allowed by the source. + WebKit::WebDragOperation operations_allowed_; + + // The current drag operation as negotiated by the source and destination. + // When not equal to DragOperationNone, the drag data can be dropped onto the + // current drop target in this WebView (the drop target can accept the drop). + WebKit::WebDragOperation drag_operation_; // The autocomplete popup. Kept around and reused every-time new suggestions // should be shown. |