Bug 59409 - Improve drag start logic
Summary: Improve drag start logic
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Daniel Cheng
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-25 18:55 PDT by Daniel Cheng
Modified: 2011-05-13 17:51 PDT (History)
6 users (show)

See Also:


Attachments
Patch (1.85 KB, patch)
2011-04-25 21:47 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (1.88 KB, patch)
2011-04-25 23:03 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Test case (462 bytes, text/html)
2011-04-28 22:54 PDT, Daniel Cheng
no flags Details
Patch (32.59 KB, patch)
2011-05-08 19:35 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (38.17 KB, patch)
2011-05-09 00:13 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (32.54 KB, patch)
2011-05-10 23:36 PDT, Daniel Cheng
dbates: commit-queue-
Details | Formatted Diff | Diff
Patch (32.53 KB, patch)
2011-05-10 23:54 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (34.12 KB, patch)
2011-05-11 12:13 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (34.15 KB, patch)
2011-05-11 14:04 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (119.38 KB, patch)
2011-05-12 19:15 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (119.49 KB, patch)
2011-05-12 19:40 PDT, Daniel Cheng
no flags Details | Formatted Diff | Diff
Patch (41.56 KB, patch)
2011-05-13 15:18 PDT, Daniel Cheng
webkit.review.bot: commit-queue-
Details | Formatted Diff | Diff
Patch (41.90 KB, patch)
2011-05-13 16:06 PDT, Daniel Cheng
tony: review+
webkit.review.bot: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Cheng 2011-04-25 18:55:01 PDT
Per crbug.com/55019, the node is not used as the drag image if you start a drag by clicking on the anchor link text and trying to drag it.

The root cause is here:
http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/rendering/RenderObject.cpp&l=1496
When you try to drag a link without highlighting anything, WebKit treats it as if you were dragging just the inner unnamed text node. I can modify the loop to check for DRAG_ELEMENT on text nodes, but that results in only the text being set as the drag image.

Maybe in http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/page/EventHandler.cpp&q=draggableNode&l=602 we should iterate up the node hierarchy while the current node is draggable until we find a node who's parent is not draggable; that way, we coalesce all children of a draggable node together as a web author might expect. Thoughts?
Comment 1 Nico Weber 2011-04-25 18:58:31 PDT
What does Firefox do?
Comment 2 Daniel Cheng 2011-04-25 19:10:32 PDT
(In reply to comment #1)
> What does Firefox do?

It renders the entire anchor as the drag image as one might expect.

Also, upon further inspection, RenderObject::draggableNode is actually called from EventHandler::handleDrag. It appears eventMayStartDrag is actually a Mac specific method...
Comment 3 Daniel Cheng 2011-04-25 21:47:13 PDT
Created attachment 91053 [details]
Patch
Comment 4 Nico Weber 2011-04-25 22:02:07 PDT
I'm not a reviewer. +dglazkov, who is (and who can cc someone else if he feels not up to this)
Comment 5 Daniel Cheng 2011-04-25 23:03:36 PDT
Created attachment 91060 [details]
Patch

Add missing check that curr->parent() is not NULL
Comment 6 Alexey Proskuryakov 2011-04-26 09:42:47 PDT
This looks confusing to me. What if there are actually several nested draggable elements, and the user is dragging an innermost one?
Comment 7 Daniel Cheng 2011-04-26 14:40:30 PDT
Comment on attachment 91060 [details]
Patch

(In reply to comment #6)
> This looks confusing to me. What if there are actually several nested draggable elements, and the user is dragging an innermost one?


(Note I'm assuming that draggable is implemented in these examples, while it currently isn't)

Case 1:
<a href="foo.html">Link</a>

Anchors default to draggable="true". However, right now, a drag started by a click on "Link" is treated as if only the anonymous text node were dragged. You have to start the drag on the padding area (I think) to get a drag image to be rendered for the anchor element.

Case 2:
<div draggable>Draggable text with a <a href="foo.html">link</a><div>Div inside a div</div></div>

Dragging the anchor will result in just the anchor getting dragged (on Firefox and Chrome). But starting a drag on any other element inside the div will result in the entire div getting dragged.

I think case 1 is something that we should fix. Case 2 is weird but will probably require a more authoritative statement from the spec. The attached patch doesn't really address case 1 correctly though, so I'm marking it as R- while I debate a better fix...
Comment 8 Daniel Cheng 2011-04-28 22:54:29 PDT
Created attachment 91641 [details]
Test case

I've been investigating this more, and this logic seems to be a lot more complicated than necessary:

Today, the code does something like this...

EventHandler::handleMouseMoveEvent(...)
  Does a hit test, I think? This gives us a MouseEventWIthHitTestResults. Dispatch the mouse event. If the event isn't canceled (I think?), treat it as a potential drag event.
EventHandler::handleMouseDraggedEvent(...)
  chains into...
EventHandler::handleDrag(...)
  Hit test the document. If we hit a node, call node->renderer()->draggableNode()
RenderObject::draggableNode(...)
  Using the node we hit, iterate upwards through the tree repeating the following steps:
    Element node and drag mode = element?
      Great, we're done. Return this node and set m_dragSrcIsDHTML to true.
    Text node or element node with drag mode = auto?
      Call EventHandler::shouldDragAutoNode(...)
EventHandler::shouldDragAutoNode(...)
  chains into...
DragController::mayStartDragAtEventLocation(...)
  which does *another* hit test using EventHandler::hitTestResultAtPoint (which does all sorts of stuff I don't really undestand).
  If this one hits an image, link, or selection, then it returns true, other wise false. This extra hit test / short-circuiting is the cause (I believe) of some of the complications.

I believe the logic should be simplified into something more like this:
In selection? Draggable, return the node that was hit.
Otherwise, iterate up the tree.
If the node has drag mode == element or is a node that is draggable by default (anchor or image) and the drag mode is not none, return that node.

Also, what exactly is HitTestResult::innerNonSharedNode()? I see it used several times throughout the dragging code but I'm not really sure what it means...
Comment 9 Daniel Cheng 2011-05-08 19:35:58 PDT
Created attachment 92755 [details]
Patch
Comment 10 Daniel Cheng 2011-05-08 19:37:14 PDT
I'd like to see what people think of this change before I add the new file to all the build systems. If people are generally positive, I'll go ahead and fix the build for all the other platforms.
Comment 11 WebKit Review Bot 2011-05-08 21:13:20 PDT
Comment on attachment 92755 [details]
Patch

Attachment 92755 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8655413
Comment 12 WebKit Review Bot 2011-05-08 21:15:42 PDT
Comment on attachment 92755 [details]
Patch

Attachment 92755 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8640399
Comment 13 WebKit Review Bot 2011-05-08 22:34:18 PDT
Comment on attachment 92755 [details]
Patch

Attachment 92755 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8648419
Comment 14 Daniel Bates 2011-05-08 22:52:14 PDT
Comment on attachment 92755 [details]
Patch

Attachment 92755 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8655435
Comment 15 Ryosuke Niwa 2011-05-08 22:57:28 PDT
Comment on attachment 92755 [details]
Patch

You need to add DragState.h to XCode & Visual Studio project files
Comment 16 Daniel Cheng 2011-05-09 00:13:51 PDT
Created attachment 92763 [details]
Patch
Comment 17 WebKit Review Bot 2011-05-09 01:43:30 PDT
Comment on attachment 92763 [details]
Patch

Attachment 92763 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8652486
Comment 18 WebKit Review Bot 2011-05-09 01:45:33 PDT
Comment on attachment 92763 [details]
Patch

Attachment 92763 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8660475
Comment 19 Daniel Bates 2011-05-09 02:52:59 PDT
Comment on attachment 92763 [details]
Patch

Attachment 92763 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8660494
Comment 20 WebKit Review Bot 2011-05-09 03:07:45 PDT
Comment on attachment 92763 [details]
Patch

Attachment 92763 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8653540
Comment 21 Tony Chang 2011-05-09 10:20:48 PDT
Comment on attachment 92763 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=92763&action=review

Can we split this into 2 patches?  The first patch would just be a refactoring patch and not change any behavior.  It would introduce the DragState class and probably move draggableNode into DragController.  The second patch would be the behavioral change.

> LayoutTests/ChangeLog:11
> +        * fast/css/user-drag-none.html:

Can you add a sentence or two explaining why these changed?

> LayoutTests/editing/pasteboard/drag-selected-image-to-contenteditable.html:47
> +    eventSender.leapForward(500);

Hmm, how was this passing on Mac before?

> Source/WebCore/page/DragController.cpp:580
> +// Determine which node the user wants to drag. In order of priority:
> +// 1. The user is dragging a selection.
> +// 2. The user is dragging an element where draggable=true.
> +// 3. The user is dragging an element where draggable is the default auto value (e.g. unset) and
> +// the element is either an anchor element with an href attribute or an image element.

WebKit normally avoids comments that describe what the code is doing.  I think the preferred style is to make each of these a function, e.g., isDraggingSelection, isDraggableElement, and isElementDraggableByDefault.

> Source/WebCore/page/DragController.cpp:609
> +                    && (m_dragSourceAction& DragSourceActionImage)) {

Nit: missing space before &

> Source/WebCore/page/DragController.cpp:746
> +            m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));

Nit: static_cast instead of (int)

> Source/WebCore/page/DragState.h:31
> +#include <wtf/FastAllocBase.h>
> +#include <wtf/Noncopyable.h>
> +#include <wtf/RefPtr.h>

Can we use wtf/Forward.h for some of these?

> Source/WebCore/page/EventHandler.cpp:2640
> +    default:
> +        break;

Can we enumerate the other cases here rather than using default:?  That will give us a compile break if someone adds a new value to the enum rather than silently falling through.
Comment 22 Daniel Cheng 2011-05-10 23:36:43 PDT
Created attachment 93078 [details]
Patch
Comment 23 Daniel Cheng 2011-05-10 23:54:09 PDT
Created attachment 93080 [details]
Patch
Comment 24 Daniel Cheng 2011-05-10 23:54:19 PDT
(In reply to comment #21)
> (From update of attachment 92763 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=92763&action=review
> 
> Can we split this into 2 patches?  The first patch would just be a refactoring patch and not change any behavior.  It would introduce the DragState class and probably move draggableNode into DragController.  The second patch would be the behavioral change.

Done.

> 
> > LayoutTests/ChangeLog:11
> > +        * fast/css/user-drag-none.html:
> 
> Can you add a sentence or two explaining why these changed?
> 

Done.

> > LayoutTests/editing/pasteboard/drag-selected-image-to-contenteditable.html:47
> > +    eventSender.leapForward(500);
> 
> Hmm, how was this passing on Mac before?
> 

This was required because of a behavior change which I documented in the ChangeLog.

> > Source/WebCore/page/DragController.cpp:580
> > +// Determine which node the user wants to drag. In order of priority:
> > +// 1. The user is dragging a selection.
> > +// 2. The user is dragging an element where draggable=true.
> > +// 3. The user is dragging an element where draggable is the default auto value (e.g. unset) and
> > +// the element is either an anchor element with an href attribute or an image element.
> 
> WebKit normally avoids comments that describe what the code is doing.  I think the preferred style is to make each of these a function, e.g., isDraggingSelection, isDraggableElement, and isElementDraggableByDefault.
> 

I think the code is self-explanatory enough now to avoid pulling those out into separate blocks. Let me know what you think.

> > Source/WebCore/page/DragController.cpp:609
> > +                    && (m_dragSourceAction& DragSourceActionImage)) {
> 
> Nit: missing space before &
> 

Fixed.

> > Source/WebCore/page/DragController.cpp:746
> > +            m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));
> 
> Nit: static_cast instead of (int)
> 

Done.

> > Source/WebCore/page/DragState.h:31
> > +#include <wtf/FastAllocBase.h>
> > +#include <wtf/Noncopyable.h>
> > +#include <wtf/RefPtr.h>
> 
> Can we use wtf/Forward.h for some of these?
> 

We would have to split the definition for the constructor into a .cpp file. I kept the original style where the constructor was inline.

> > Source/WebCore/page/EventHandler.cpp:2640
> > +    default:
> > +        break;
> 
> Can we enumerate the other cases here rather than using default:?  That will give us a compile break if someone adds a new value to the enum rather than silently falling through.

Done.
Comment 25 Daniel Bates 2011-05-11 01:06:01 PDT
Comment on attachment 93078 [details]
Patch

Attachment 93078 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8688224
Comment 26 WebKit Review Bot 2011-05-11 01:22:01 PDT
Comment on attachment 93080 [details]
Patch

Attachment 93080 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8690178
Comment 27 WebKit Review Bot 2011-05-11 01:44:11 PDT
Comment on attachment 93080 [details]
Patch

Attachment 93080 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/8685302
Comment 28 Daniel Cheng 2011-05-11 12:13:10 PDT
Created attachment 93155 [details]
Patch

Fix Mac build (hopefully)
Comment 29 Tony Chang 2011-05-11 12:35:33 PDT
View in context: https://bugs.webkit.org/attachment.cgi?id=93080&action=review

This looks like a move in the right direction.  I just have a mix of style nits and some questions so I can understand the change better.

> LayoutTests/ChangeLog:13
> +        mouse down and the mouse move. The change in dragging priority matches IE and Firefox
> +        behavior.

AFAICT, this matches OSX's behavior as well.  For example, if I put an image in a Stickies note, select text + the image, and try to drag by clicking on the image, I get the whole selection (text + image).

However, if I don't click and hold on the image before the drag, I only get the image in my drag.  Is it possible to make sure both behaviors are retained on Mac (i.e., include tests for the no delay case as well)?  On Win/Linux, I wouldn't expect the delay to be necessary (EventHandler::TextDragDelay is 0).

> Source/WebCore/page/DragController.cpp:698
> +    if (state.m_dragType == DragSourceActionSelection || !imageURL.isEmpty() || !linkURL.isEmpty())

Nit: Can this be an 'else if'?

> Source/WebCore/page/DragController.cpp:702
> +        m_sourceDragOperation = static_cast<DragOperation>(m_sourceDragOperation | DragOperationGeneric | DragOperationCopy);

Why did the previous code replace m_sourceDragOperation and we now add?

> Source/WebCore/page/DragController.cpp:785
> +        // image or link had no URL. Oh well.

Nit: I would replace "Oh well." with "so there's nothing to drag."

> Source/WebCore/page/EventHandler.cpp:891
> +void EventHandler::updateDragSourceActionsAllowed(DragState::EventDispatchPolicy& policy) const

Nit: Maybe this method can just return a DragState::EventDispatchPolicy value?

> Source/WebCore/page/EventHandler.cpp:-913
> -    flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));

Where did this check go?  Is it no longer needed?  It's not clear to me what flagUA was for.

> Source/WebCore/page/EventHandler.cpp:908
> +    if (mask & DragSourceActionDHTML)
> +        policy = DragState::DISPATCH_EVENTS;
> +    else
> +        policy = DragState::DO_NOT_DISPATCH_EVENTS;

Nit: Maybe use a ternary operator?

> Source/WebCore/page/EventHandler.cpp:2640
> +    default:
> +        ASSERT_NOT_REACHED();

I think if you enumerate all the cases, you don't need the default: case at all which makes new DragSourceActions give a compile error rather than a runtime error.  I.e., I would change default: to DragSourceActionNone: DragSourceActionAny:.
Comment 30 Daniel Cheng 2011-05-11 14:03:54 PDT
(In reply to comment #29)
> View in context: https://bugs.webkit.org/attachment.cgi?id=93080&action=review
> 
> This looks like a move in the right direction.  I just have a mix of style nits and some questions so I can understand the change better.
> 
> > LayoutTests/ChangeLog:13
> > +        mouse down and the mouse move. The change in dragging priority matches IE and Firefox
> > +        behavior.
> 
> AFAICT, this matches OSX's behavior as well.  For example, if I put an image in a Stickies note, select text + the image, and try to drag by clicking on the image, I get the whole selection (text + image).
> 
> However, if I don't click and hold on the image before the drag, I only get the image in my drag.  Is it possible to make sure both behaviors are retained on Mac (i.e., include tests for the no delay case as well)?  On Win/Linux, I wouldn't expect the delay to be necessary (EventHandler::TextDragDelay is 0).
> 

I'm currently working on seeing if it's possible to implement the behavior you've described. I'll have to figure out how to write a OS-specific layout test too though. Any tips?

> > Source/WebCore/page/DragController.cpp:698
> > +    if (state.m_dragType == DragSourceActionSelection || !imageURL.isEmpty() || !linkURL.isEmpty())
> 
> Nit: Can this be an 'else if'?
> 

It is intentionally an if to make sure that <anchors> and <images> that were explicitly marked draggable still get the additional behavior for links/images. I'm not sure if that's a desirable thing or not though.

> > Source/WebCore/page/DragController.cpp:702
> > +        m_sourceDragOperation = static_cast<DragOperation>(m_sourceDragOperation | DragOperationGeneric | DragOperationCopy);
> 
> Why did the previous code replace m_sourceDragOperation and we now add?
> 

If the dragged node only set move as an operation, we'd unset it.

> > Source/WebCore/page/DragController.cpp:785
> > +        // image or link had no URL. Oh well.
> 
> Nit: I would replace "Oh well." with "so there's nothing to drag."
> 

Done.

> > Source/WebCore/page/EventHandler.cpp:891
> > +void EventHandler::updateDragSourceActionsAllowed(DragState::EventDispatchPolicy& policy) const
> 
> Nit: Maybe this method can just return a DragState::EventDispatchPolicy value?
> 

I didn't do that since it doesn't seem clear to me what the return value from a function like this would mean. Maybe the function needs a better name? (I can't think of one at the moment though...)

> > Source/WebCore/page/EventHandler.cpp:-913
> > -    flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));
> 
> Where did this check go?  Is it no longer needed?  It's not clear to me what flagUA was for.
> 
> > Source/WebCore/page/EventHandler.cpp:908
> > +    if (mask & DragSourceActionDHTML)
> > +        policy = DragState::DISPATCH_EVENTS;
> > +    else
> > +        policy = DragState::DO_NOT_DISPATCH_EVENTS;
> 
> Nit: Maybe use a ternary operator?
> 

Done.

> > Source/WebCore/page/EventHandler.cpp:2640
> > +    default:
> > +        ASSERT_NOT_REACHED();
> 
> I think if you enumerate all the cases, you don't need the default: case at all which makes new DragSourceActions give a compile error rather than a runtime error.  I.e., I would change default: to DragSourceActionNone: DragSourceActionAny:.

Done.
Comment 31 Daniel Cheng 2011-05-11 14:04:36 PDT
Created attachment 93181 [details]
Patch
Comment 32 Daniel Cheng 2011-05-11 14:49:04 PDT
> > Source/WebCore/page/EventHandler.cpp:-913
> > -    flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));
> 
> Where did this check go?  Is it no longer needed?  It's not clear to me what flagUA was for.
> 

It was used for two things;
- Potential short-circuiting of logic in eventMayStartDrag(), a Mac-specific method. By removing it, eventMayStartDrag() can no longer return early if DragController::delegateDragSourceAction() returns DragSourceActionNone. I think this is fairly minor, since we'll still get the same return value in the end (draggableNode() won't return anything and we'll return false). If people feel strongly about it, I can certainly add a check to early return if DragController::dragSourceAction() == DragSourceActionNone.
- Double-checked permissions in draggableNode. This is redundant, since we have to check the drag source actions allowed anyway in draggableNode when determining the node to drag.
Comment 33 Daniel Cheng 2011-05-11 14:58:34 PDT
Comment on attachment 93181 [details]
Patch

Thinking more about how to resolve selection vs image drag issue on Mac.
Comment 34 Daniel Cheng 2011-05-12 19:15:58 PDT
Created attachment 93389 [details]
Patch
Comment 35 Daniel Cheng 2011-05-12 19:40:29 PDT
Created attachment 93391 [details]
Patch
Comment 36 Hajime Morrita 2011-05-13 00:28:36 PDT
Comment on attachment 93391 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=93391&action=review

Just for curious, do we need the pixel test? typical editing tests are covered by text test with Markup.dump().
(I'm not an expert in this area and this might be a stupid question....)

> Source/WebCore/page/DragController.cpp:577
> +        state.m_dragType = DragSourceActionSelection;

If/else or ternary op? usually assigning-only-once is good idea.

> Source/WebCore/page/DragState.h:46
> +    };

We usually use CamelCase for defining enum. (there are some old code that don't follow this though.)
Comment 37 Tony Chang 2011-05-13 10:22:24 PDT
Comment on attachment 93391 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=93391&action=review

This is looking really good.  One more round and I think we'll be done.

> LayoutTests/platform/mac/editing/pasteboard/drag-selections-to-contenteditable.html:1
> +<html>

Morita is right, this could be a dump as markup test.  You can include LayoutTest/resources/dump-as-markup.js to use Markup.dump.  It would make the pixel result unnecessary (seems like dumping the DOM tree of the contentEditable region is sufficient).

> Source/WebCore/page/DragController.cpp:686
> +    if (!state.m_dragSrc->contains(hitTestResult.innerNode()))
> +        // The original node being dragged isn't under the mouse for some reason... bail out.
> +        return false;

Is this check new?  Can the comment describe why this might happen rather than just describing what the code is doing?

> Source/WebCore/page/EventHandler.cpp:2732
> +            // 4. We enter this block again, and since it's now marked as a selection drag, we
> +            //    cancel the drag.
> +            m_mouseDownTimestamp = event.event().timestamp() - 2 * TextDragDelay;

This seems hacky-- is there other code that depends on m_mouseDownTimestamp?  Maybe we can put an extra bool in dragState() to keep track of this case?

> Source/WebCore/page/EventHandler.cpp:2745
> +    if (!ExactlyOneBitSet(dragState().m_dragType)) {
> +        ASSERT((dragState().m_dragType & DragSourceActionSelection));
> +        ASSERT((dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionDHTML
> +                || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionImage
> +                || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionLink);
> +        dragState().m_dragType = DragSourceActionSelection;
> +    }

Why is this needed?
Comment 38 Daniel Cheng 2011-05-13 15:18:06 PDT
Created attachment 93521 [details]
Patch
Comment 39 Daniel Cheng 2011-05-13 15:19:56 PDT
(In reply to comment #36)
> (From update of attachment 93391 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=93391&action=review
> 
> Just for curious, do we need the pixel test? typical editing tests are covered by text test with Markup.dump().
> (I'm not an expert in this area and this might be a stupid question....)
> 

I've changed the layout test.

> > Source/WebCore/page/DragController.cpp:577
> > +        state.m_dragType = DragSourceActionSelection;
> 
> If/else or ternary op? usually assigning-only-once is good idea.
> 

Done.

> > Source/WebCore/page/DragState.h:46
> > +    };
> 
> We usually use CamelCase for defining enum. (there are some old code that don't follow this though.)

Done.

(In reply to comment #37)
> (From update of attachment 93391 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=93391&action=review
> 
> This is looking really good.  One more round and I think we'll be done.
> 
> > LayoutTests/platform/mac/editing/pasteboard/drag-selections-to-contenteditable.html:1
> > +<html>
> 
> Morita is right, this could be a dump as markup test.  You can include LayoutTest/resources/dump-as-markup.js to use Markup.dump.  It would make the pixel result unnecessary (seems like dumping the DOM tree of the contentEditable region is sufficient).
> 

Done.

> > Source/WebCore/page/DragController.cpp:686
> > +    if (!state.m_dragSrc->contains(hitTestResult.innerNode()))
> > +        // The original node being dragged isn't under the mouse for some reason... bail out.
> > +        return false;
> 
> Is this check new?  Can the comment describe why this might happen rather than just describing what the code is doing?
> 

Done.

> > Source/WebCore/page/EventHandler.cpp:2732
> > +            // 4. We enter this block again, and since it's now marked as a selection drag, we
> > +            //    cancel the drag.
> > +            m_mouseDownTimestamp = event.event().timestamp() - 2 * TextDragDelay;
> 
> This seems hacky-- is there other code that depends on m_mouseDownTimestamp?  Maybe we can put an extra bool in dragState() to keep track of this case?
> 

Done.

> > Source/WebCore/page/EventHandler.cpp:2745
> > +    if (!ExactlyOneBitSet(dragState().m_dragType)) {
> > +        ASSERT((dragState().m_dragType & DragSourceActionSelection));
> > +        ASSERT((dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionDHTML
> > +                || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionImage
> > +                || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionLink);
> > +        dragState().m_dragType = DragSourceActionSelection;
> > +    }
> 
> Why is this needed?

It's just an assertion to make sure that the code is updated if we ever add new edge cases. Right now, I want to make sure only one other bit other than selection is ever set and that bit has to be for either an image/link/HTML drag.
Comment 40 Daniel Cheng 2011-05-13 16:06:26 PDT
Created attachment 93525 [details]
Patch
Comment 41 Tony Chang 2011-05-13 16:11:03 PDT
Comment on attachment 93525 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=93525&action=review

> LayoutTests/platform/mac/editing/pasteboard/drag-selections-to-contenteditable.html:33
> +    log(document.getElementById('target').children[0].tagName);
> +    log(document.getElementById('target').children[1].tagName);
> +    log(document.getElementById('target').children[2].tagName);
> +    log(document.getElementById('target').children[3].tagName);

Nit: It might be good to verify that there are exactly 4 children, although I guess we'd see the extra output in the text dump.
Comment 42 Daniel Cheng 2011-05-13 16:32:01 PDT
Committed r86472: <http://trac.webkit.org/changeset/86472>
Comment 43 Jon Honeycutt 2011-05-13 16:57:15 PDT
It looks like this broke the Windows build:

http://build.webkit.org/builders/Windows%20Release%20%28Build%29/builds/16362/steps/compile-webkit/logs/stdio
Comment 44 WebKit Review Bot 2011-05-13 16:59:43 PDT
Comment on attachment 93521 [details]
Patch

Attachment 93521 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8693345
Comment 45 Daniel Cheng 2011-05-13 17:16:35 PDT
(In reply to comment #43)
> It looks like this broke the Windows build:
> 
> http://build.webkit.org/builders/Windows%20Release%20%28Build%29/builds/16362/steps/compile-webkit/logs/stdio

Working on fixing this at the moment. It should be a simple fix, I'm just testing that it works before committing.
Comment 46 WebKit Review Bot 2011-05-13 17:30:21 PDT
Comment on attachment 93525 [details]
Patch

Attachment 93525 [details] did not pass cr-mac-ews (chromium):
Output: http://queues.webkit.org/results/8698221
Comment 47 Daniel Cheng 2011-05-13 17:51:05 PDT
Unfortunately I can't figure out how to fix this the right way, nor can I figure out why EWS started hating the last two patches. I tried pulling the ctor/dtor out into its own .cpp file but that didn't make the build any happier. For now I'm adding extra #includes to DragState.h.