|
|
Chromium Code Reviews
Description[InputEvent] Support |deleteByDrag| and |insertFromDrop|
CLOSED for new CL: https://codereview.chromium.org/2374743002/
* Event order: (See [1] [2])
1. 'drop'
2. 'beforeinput' InputType=|deleteByDrag|
3. 'beforeinput' InputType=|insertFromDrop|
4. (DOM update)
5. 'input' InputType=|deleteByDrag|
6. 'input' InputType=|insertFromDrop|
7. 'dragend'
* Canceling 'beforeinput' will only prevent DOM update, and won't
affect other operations.
e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop'
* |dataTransfer| field:
1. NULL for |deleteByDrag| (JS could always get from selection)
2. Readonly |dataTransfer| for |insertFromDrop|
For more detailed behavior please refer to LayoutTest.
[1] GitHub discussion for event order:
https://github.com/w3c/input-events/issues/24
[2] |deleteByDrag| and |insertFromDrop| naming SPEC:
https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes
Intent to Implement:
https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEvent/blink-dev/RrnitB0OElc/rirueVekCwAJ
BUG=639139
Patch Set 1 #
Total comments: 16
Patch Set 2 : yosin's review, handle removed elements and add tests #
Total comments: 4
Patch Set 3 : Yosin's review 2, check |!isConnected()| #
Total comments: 5
Patch Set 4 : yosin's review 3, check |ownerDocument()| #Messages
Total messages: 43 (29 generated)
The CQ bit was checked by chongz@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: linux_chromium_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...) win_chromium_rel_ng on master.tryserver.chromium.win (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.win/builders/win_chromium_rel_...)
The CQ bit was checked by chongz@chromium.org to run a CQ dry run
Patchset #1 (id:1) has been deleted
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Description was changed from ========== Support |deleteByDrag| and |insertFromDrop| BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more details please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ==========
Description was changed from ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more details please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed bahavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ==========
Description was changed from ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed bahavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ==========
chongz@chromium.org changed reviewers: + yosin@chromium.org
yosin@ PTAL at this InputEvent CL for Drag&Drop, thanks! https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:113: if (inputType == InputEvent::InputType::MoveByDragDrop) { Do we have any other solution that does not require an internal InputType? https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:125: dispatchInputEvent(endRoot, inputType, data, isComposing); Do we have other commands that will affect two editing hosts? (Other than Drap&Drop and it's Undo&Redo)
https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:118: dispatchInputEvent(endRoot, InputEvent::InputType::InsertFromDrop, data, isComposing); Q: Do we dispatch "insertFromDrop" even if "deleteByDrag" is canceled? Q: Do we dispatch "insertFromDrop" even if |!endRoot.isConnected()|? https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:124: if (endRoot && endRoot != startRoot) Do we need to check |endRoot.isConnected()|? https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/page/DragController.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:118: shouldDelete = (dragBeforeInputResult == DispatchEventResult::NotCanceled); nit: We don't need to have parenthesis. Edit https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:122: if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->document().frame()) What is happened when |dropTarget| is removed? https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:129: bool shouldInsert = (dropBeforeInputResult == DispatchEventResult::NotCanceled); nit: We don't need to have parenthesis.
The CQ bit was checked by chongz@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
yosin@ sorry for the delay. I've added check for removed elements and updated layout tests, PTAL again, thanks! https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:118: dispatchInputEvent(endRoot, InputEvent::InputType::InsertFromDrop, data, isComposing); On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > Q: Do we dispatch "insertFromDrop" even if "deleteByDrag" is canceled? Yes. Canceling 'deleteByDrag' only means cancelling the DOM update part of it, but the Drag&Drop process is still going, so we will do |DragDropBeforeInputResult::InsertOnly|. e.g. Similar to 'deleteByCut' & 'insertFromPaste', where canceling 'deleteByCut' won't prevent clipboard update. > Q: Do we dispatch "insertFromDrop" even if |!endRoot.isConnected()|? From my testing |endRoot| is always connected. If drop target was removed |endRoot| will point to drag target, so I have to handle it in |DragController|. https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:124: if (endRoot && endRoot != startRoot) On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > Do we need to check |endRoot.isConnected()|? It seems to me that if the element was changed, we should dispatch 'input' event not matter it's connected or not. But I'm not sure but will it cause any issue by dispatching events to removed elements? https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/page/DragController.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:118: shouldDelete = (dragBeforeInputResult == DispatchEventResult::NotCanceled); On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > nit: We don't need to have parenthesis. > Edit Done. https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:122: if (dragFrame != dragTarget->document().frame() || dropFrame != dropTarget->document().frame()) On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > What is happened when |dropTarget| is removed? Added check for removed element. So if |dropTarget| is removed: 1. We still dispatch 'beforeinput' to |dragTarget| and |dropTarget| 2. Only apply |DeleteSelectionCommand| to |dragTarget| 3. Only fire 'input' for |dragTarget| I think it's OK to dispatch 'beforeinput' to detached elements, but since editing commands won't modify removed elements we shouldn't dispatch 'input' for them. Which means removing |dropTarget| behaves similar to cancelling |insertFromDrop|, and this won't affect existing behavior for 'drop' and 'dragend' events. https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:129: bool shouldInsert = (dropBeforeInputResult == DispatchEventResult::NotCanceled); On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > nit: We don't need to have parenthesis. Done.
https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:118: dispatchInputEvent(endRoot, InputEvent::InputType::InsertFromDrop, data, isComposing); On 2016/09/02 at 18:02:10, chongz wrote: > On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > > Q: Do we dispatch "insertFromDrop" even if "deleteByDrag" is canceled? > > Yes. Canceling 'deleteByDrag' only means cancelling the DOM update part of it, but the Drag&Drop process is still going, so we will do |DragDropBeforeInputResult::InsertOnly|. > e.g. Similar to 'deleteByCut' & 'insertFromPaste', where canceling 'deleteByCut' won't prevent clipboard update. > > > Q: Do we dispatch "insertFromDrop" even if |!endRoot.isConnected()|? > > From my testing |endRoot| is always connected. If drop target was removed |endRoot| will point to drag target, so I have to handle it in |DragController|. Your testing doesn't covered to make the case |endRoot| becomes not to connected. ;-) Attackers can do anything by using JavaScript. ClusterFuzz will find such case. L123's |startRoot| also can be not connected by both "beforeInput" event from |startRoot| and |endRoot|. https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:124: if (endRoot && endRoot != startRoot) On 2016/09/02 at 18:02:10, chongz wrote: > On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > > Do we need to check |endRoot.isConnected()|? > > It seems to me that if the element was changed, we should dispatch 'input' event not matter it's connected or not. > But I'm not sure but will it cause any issue by dispatching events to removed elements? According DOM spec, https://www.w3.org/TR/dom/#dispatching-events, 3.7 Dispatching events If event's target attribute value is participating in a tree, let event path be a static ordered list of all its ancestors in tree order, and let event path be the empty list otherwise. Event target should be connected before computing event path. Since |dispatchInputEvent()| checks null target element, let's check whether target is connected or not in |dispatchInputEvent()| and remove if-statement from call sites to make code simpler. https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/page/DragController.cpp (right): https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:567: innerFrame->editor().deleteSelectionWithSmartDelete(innerFrame->editor().smartInsertDeleteEnabled(), InputEvent::InputType::DeleteByDrag); |innerFrame| can be destroyed due by "beforeInput" event at L559. https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:578: m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(fragment, dragData->canSmartReplace(), chosePlainText); |m_documentUnderMouse->frame()| can be null due by "beforeInput" event at L559
The CQ bit was checked by chongz@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
yosin@ I've added check for |!isConnected()|, PTAL again, thanks! https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:118: dispatchInputEvent(endRoot, InputEvent::InputType::InsertFromDrop, data, isComposing); On 2016/09/05 01:37:50, Yosi_UTC9 wrote: > On 2016/09/02 at 18:02:10, chongz wrote: > > On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > > > Q: Do we dispatch "insertFromDrop" even if "deleteByDrag" is canceled? > > > > Yes. Canceling 'deleteByDrag' only means cancelling the DOM update part of it, > but the Drag&Drop process is still going, so we will do > |DragDropBeforeInputResult::InsertOnly|. > > e.g. Similar to 'deleteByCut' & 'insertFromPaste', where canceling > 'deleteByCut' won't prevent clipboard update. > > > > > Q: Do we dispatch "insertFromDrop" even if |!endRoot.isConnected()|? > > > > From my testing |endRoot| is always connected. If drop target was removed > |endRoot| will point to drag target, so I have to handle it in |DragController|. > > Your testing doesn't covered to make the case |endRoot| becomes not to > connected. ;-) > Attackers can do anything by using JavaScript. ClusterFuzz will find such case. > > L123's |startRoot| also can be not connected by both "beforeInput" event from > |startRoot| and |endRoot|. Added check in |dispatchInputEvent()|. https://codereview.chromium.org/2288913002/diff/20001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:124: if (endRoot && endRoot != startRoot) On 2016/09/05 01:37:50, Yosi_UTC9 wrote: > On 2016/09/02 at 18:02:10, chongz wrote: > > On 2016/08/31 01:20:34, Yosi_UTC9 wrote: > > > Do we need to check |endRoot.isConnected()|? > > > > It seems to me that if the element was changed, we should dispatch 'input' > event not matter it's connected or not. > > But I'm not sure but will it cause any issue by dispatching events to removed > elements? > According DOM spec, https://www.w3.org/TR/dom/#dispatching-events, 3.7 > Dispatching events > > If event's target attribute value is participating in a tree, let event path be > a static ordered list of all its ancestors in tree order, and let event path be > the empty list otherwise. > > Event target should be connected before computing event path. OK, thanks for the reference! > > Since |dispatchInputEvent()| checks null target element, let's check whether > target is connected or not > in |dispatchInputEvent()| and remove if-statement from call sites to make code > simpler. > > > Added check in |dispatchInputEvent()|. https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/page/DragController.cpp (right): https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:567: innerFrame->editor().deleteSelectionWithSmartDelete(innerFrame->editor().smartInsertDeleteEnabled(), InputEvent::InputType::DeleteByDrag); On 2016/09/05 01:37:50, Yosi_UTC9 wrote: > |innerFrame| can be destroyed due by "beforeInput" event at L559. Added check for |innerFrame| and |m_documentUnderMouse->frame()|. https://codereview.chromium.org/2288913002/diff/40001/third_party/WebKit/Sour... third_party/WebKit/Source/core/page/DragController.cpp:578: m_documentUnderMouse->frame()->editor().replaceSelectionAfterDragging(fragment, dragData->canSmartReplace(), chosePlainText); On 2016/09/05 01:37:50, Yosi_UTC9 wrote: > |m_documentUnderMouse->frame()| can be null due by "beforeInput" event at L559 See above.
lgtm Thanks!
Oops, one more thing. https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || !target->isConnected()) One more. Could you make |disaptchInputEvent()| to take |const Document& originateDocument| and check or DCEHCK |target->ownerDocument() == originateDocument| to catch source and destination still in document starting drag-and-drop.
The CQ bit was checked by chongz@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
yosin@ I've updated CL but don't really understand why, PTAL again, thanks! https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || !target->isConnected()) On 2016/09/08 04:34:40, Yosi_UTC9 wrote: > One more. > Could you make |disaptchInputEvent()| to take |const Document& > originateDocument| and check or DCEHCK |target->ownerDocument() == > originateDocument| > to catch source and destination still in document starting drag-and-drop. I've added check for |ownerDocument()| but I don't really understand why... 1. Drag&drop could happen from one iframe to another, so I assume their document are not necessarily to be the same. 2. If we want to make sure |ownerDocument()| for one target doesn't change during the drag&drop, we should record |originalDocument| before 'beforeinput' and check here, but |Editor::appliedEditing()| doesn't seem to have that information? 3. If we just want to make sure 'input' handler for |startRoot| doesn't do anything bad, we already have |dispatchScopedEvent()| which only dispatch events when safe, or did I misunderstood something? Thanks!
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
On 2016/09/08 22:37:50, chongz wrote: > yosin@ I've updated CL but don't really understand why, PTAL again, thanks! > > https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... > File third_party/WebKit/Source/core/editing/Editor.cpp (right): > > https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... > third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || > !target->isConnected()) > On 2016/09/08 04:34:40, Yosi_UTC9 wrote: > > One more. > > Could you make |disaptchInputEvent()| to take |const Document& > > originateDocument| and check or DCEHCK |target->ownerDocument() == > > originateDocument| > > to catch source and destination still in document starting drag-and-drop. > > I've added check for |ownerDocument()| but I don't really understand why... > 1. Drag&drop could happen from one iframe to another, so I assume their > document are not necessarily to be the same. > 2. If we want to make sure |ownerDocument()| for one target doesn't change > during the drag&drop, we should record |originalDocument| before 'beforeinput' > and check here, but |Editor::appliedEditing()| doesn't seem to have that > information? > 3. If we just want to make sure 'input' handler for |startRoot| doesn't do > anything bad, we already have |dispatchScopedEvent()| which only dispatch events > when safe, or did I misunderstood something? > > Thanks! yosin@ I'm not sure if you missed the previous email, but can you take a look again please? Thanks!
Description was changed from ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update. * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update, and won't affect other operations. e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop' * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ==========
chongz@chromium.org changed reviewers: + dtapuska@chromium.org
dtapuska@ can you take a look at the "|target->ownerDocument() == originateDocument|" issue please? Thanks! (Seems yosin@ is not available) https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || !target->isConnected()) On 2016/09/08 22:37:50, chongz wrote: > On 2016/09/08 04:34:40, Yosi_UTC9 wrote: > > One more. > > Could you make |disaptchInputEvent()| to take |const Document& > > originateDocument| and check or DCEHCK |target->ownerDocument() == > > originateDocument| > > to catch source and destination still in document starting drag-and-drop. > > I've added check for |ownerDocument()| but I don't really understand why... > 1. Drag&drop could happen from one iframe to another, so I assume their > document are not necessarily to be the same. > 2. If we want to make sure |ownerDocument()| for one target doesn't change > during the drag&drop, we should record |originalDocument| before 'beforeinput' > and check here, but |Editor::appliedEditing()| doesn't seem to have that > information? > 3. If we just want to make sure 'input' handler for |startRoot| doesn't do > anything bad, we already have |dispatchScopedEvent()| which only dispatch events > when safe, or did I misunderstood something? > > Thanks! dtapuska@ I'm not sure if I understood the issue correctly, can you take a look please? thanks!
https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || !target->isConnected()) On 2016/09/13 17:17:12, chongz wrote: > On 2016/09/08 22:37:50, chongz wrote: > > On 2016/09/08 04:34:40, Yosi_UTC9 wrote: > > > One more. > > > Could you make |disaptchInputEvent()| to take |const Document& > > > originateDocument| and check or DCEHCK |target->ownerDocument() == > > > originateDocument| > > > to catch source and destination still in document starting drag-and-drop. > > > > I've added check for |ownerDocument()| but I don't really understand why... > > 1. Drag&drop could happen from one iframe to another, so I assume their > > document are not necessarily to be the same. > > 2. If we want to make sure |ownerDocument()| for one target doesn't change > > during the drag&drop, we should record |originalDocument| before 'beforeinput' > > and check here, but |Editor::appliedEditing()| doesn't seem to have that > > information? > > 3. If we just want to make sure 'input' handler for |startRoot| doesn't do > > anything bad, we already have |dispatchScopedEvent()| which only dispatch > events > > when safe, or did I misunderstood something? > > > > Thanks! > > dtapuska@ I'm not sure if I understood the issue correctly, can you take a look > please? thanks! Ya this change seems odd to me. The old code use to ensure that only one inputEvent was dispatched. That is why it was checking the endRoot didn't matched the startRoot. But with the type of the event changing both events need to be dispatched. And I find passing the originateDocument into the dispatchInputEvent confusing. If you wanted to assert that the endRoot's document matched the startRoot's document then you should do it on line 116.
https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... File third_party/WebKit/Source/core/editing/Editor.cpp (right): https://codereview.chromium.org/2288913002/diff/60001/third_party/WebKit/Sour... third_party/WebKit/Source/core/editing/Editor.cpp:105: if (!target || !target->isConnected()) On 2016/09/13 at 17:27:50, dtapuska wrote: > On 2016/09/13 17:17:12, chongz wrote: > > On 2016/09/08 22:37:50, chongz wrote: > > > On 2016/09/08 04:34:40, Yosi_UTC9 wrote: > > > > One more. > > > > Could you make |disaptchInputEvent()| to take |const Document& > > > > originateDocument| and check or DCEHCK |target->ownerDocument() == > > > > originateDocument| > > > > to catch source and destination still in document starting drag-and-drop. > > > > > > I've added check for |ownerDocument()| but I don't really understand why... > > > 1. Drag&drop could happen from one iframe to another, so I assume their > > > document are not necessarily to be the same. > > > 2. If we want to make sure |ownerDocument()| for one target doesn't change > > > during the drag&drop, we should record |originalDocument| before 'beforeinput' > > > and check here, but |Editor::appliedEditing()| doesn't seem to have that > > > information? > > > 3. If we just want to make sure 'input' handler for |startRoot| doesn't do > > > anything bad, we already have |dispatchScopedEvent()| which only dispatch > > events > > > when safe, or did I misunderstood something? > > > > > > Thanks! > > > > dtapuska@ I'm not sure if I understood the issue correctly, can you take a look > > please? thanks! > > Ya this change seems odd to me. The old code use to ensure that only one inputEvent was dispatched. That is why it was checking the endRoot didn't matched the startRoot. But with the type of the event changing both events need to be dispatched. And I find passing the originateDocument into the dispatchInputEvent confusing. If you wanted to assert that the endRoot's document matched the startRoot's document then you should do it on line 116. I changed mind, we should verify source and target aren't removed from originate document. * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| Verify source and target aren't removed. 3. 'beforeinput' InputType=|insertFromDrop| Verify source and target arent' removed. 4. (DOM update) Both source and target are modified, we don't care source and target anymore. But, we don't dispatch events for source and target if they aren't connected. 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' Given that, |Editor| should observe nodeWillBeRemoved and nodeChildrenRemoved() to stop drag-and-drop process when either source or target removed. Is it better to introduce DragAndDropEventDispatcher class and make |Editor| to hold it during drag-and-drop?
I could not find the resolution of event order of beforeinput/input for drag-and-drop in [1] and [2]. Could you point out? It seems proposed event order makes our life harder: 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) UA may choose one of following to update DOM: - Delete source then replace target by source - Replace target by source then delete source. 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' IMO, beforeinput and input are pair and should not be nested. I prefer following order: 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. Remove source 4. 'input' InputType=|deleteByDrag| 5. 'beforeinput' InputType=|insertFromDrop| 6. Replace target by source 7. 'input' InputType=|insertFromDrop| 8. 'dragend'
On 2016/09/14 02:06:23, Yosi_UTC9 wrote: > I could not find the resolution of event order of beforeinput/input for > drag-and-drop in [1] and [2]. Could you point out? > > It seems proposed event order makes our life harder: > 1. 'drop' > 2. 'beforeinput' InputType=|deleteByDrag| > 3. 'beforeinput' InputType=|insertFromDrop| > 4. (DOM update) > UA may choose one of following to update DOM: > - Delete source then replace target by source > - Replace target by source then delete source. > 5. 'input' InputType=|deleteByDrag| > 6. 'input' InputType=|insertFromDrop| > 7. 'dragend' > > IMO, beforeinput and input are pair and should not be nested. > > I prefer following order: > 1. 'drop' > 2. 'beforeinput' InputType=|deleteByDrag| > 3. Remove source > 4. 'input' InputType=|deleteByDrag| > 5. 'beforeinput' InputType=|insertFromDrop| > 6. Replace target by source > 7. 'input' InputType=|insertFromDrop| > 8. 'dragend' Sorry for the confusion. We only have resolution for the order between InputEvent and Drag&Drop events, but no resolution for the order between 'deleteByDrag' and 'insertFromDrop'. (Just filed https://github.com/w3c/input-events/issues/24) I agree that un-nested events are better, but I'm not sure what's the best way to implement it. I can come up with 2 possible solutions: 1. Removed |MoveSelectionCommand| and split it into |DeleteSelectionCommand| and |ReplaceSelectionCommand| Pros: * Cleaner code, 'input' event handling goes into "Editor.cpp" Cons: * Requires 2 undo to undo drag-and-drop * Or should we do something similar to |TypingCommand| to merge these 2 undo? 2. Still use |MoveSelectionCommand|, but inject 'beforeinput'/'input' inside |MoveSelectionCommand::doApply()| Pros: * Requires 1 undo (existing behavior) Cons: * Confusing code, we don't usually dispatch events in |doApply()|
Description was changed from ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update, and won't affect other operations. e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop' * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| CLODED for new CL: https://codereview.chromium.org/2374743002/ * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update, and won't affect other operations. e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop' * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ==========
Message was sent while issue was closed.
Description was changed from ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| CLODED for new CL: https://codereview.chromium.org/2374743002/ * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update, and won't affect other operations. e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop' * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== to ========== [InputEvent] Support |deleteByDrag| and |insertFromDrop| CLOSED for new CL: https://codereview.chromium.org/2374743002/ * Event order: (See [1] [2]) 1. 'drop' 2. 'beforeinput' InputType=|deleteByDrag| 3. 'beforeinput' InputType=|insertFromDrop| 4. (DOM update) 5. 'input' InputType=|deleteByDrag| 6. 'input' InputType=|insertFromDrop| 7. 'dragend' * Canceling 'beforeinput' will only prevent DOM update, and won't affect other operations. e.g. Cancelling 'deleteByDrag' won't affect 'insertFromDrop' * |dataTransfer| field: 1. NULL for |deleteByDrag| (JS could always get from selection) 2. Readonly |dataTransfer| for |insertFromDrop| For more detailed behavior please refer to LayoutTest. [1] GitHub discussion for event order: https://github.com/w3c/input-events/issues/24 [2] |deleteByDrag| and |insertFromDrop| naming SPEC: https://w3c.github.io/input-events/index.html#h-interface-inputevent-attributes Intent to Implement: https://groups.google.com/a/chromium.org/forum/#!searchin/blink-dev/InputEven... BUG=639139 ========== |
