Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native HTML5 Drag'n'Drop for text. #1599

Merged
merged 13 commits into from Sep 20, 2013

Conversation

danyaPostfactum
Copy link
Contributor

Sorry, I donno how to rebase branch, so this is the new version of #1431 .
All issues I wanted are fixed.

This needs test and review.

Issues I would like to fix but need help:

  • Wrong selection on undo of drag operation.
  • Autoscroll while dragging should not scroll if there is no line (scrolled past last row) or char (scrolled past last char) at cursor.
  • Editor should not scroll selection into view if we leave (through negligence) editor rect while autoscrolling.

Issues we can not resolve:

  • Wrong ui feedback (drag cursor) in IE9+
  • Safari 5 does not support dnd

Issues I do not know reason of:

  • Opera blinks drag cursor (cursor icon) while dragging.

Issues I don't like or not sure:

  • Sequence click interval is handled by browsers differently.

Also, in Firefox, dragenter event fires twice, so dragleave event does not get caret back. Can anybody reproduce?

Great news! All bugs I (or someone else) found in IE and reported to MS are marked as Won't Fix )))
They say those are "by design", "not reproducible" etc :)

  1. https://connect.microsoft.com/IE/feedback/details/789773/ie-increments-event-detail-on-clicks-over-different-locations
  2. https://connect.microsoft.com/IE/feedback/details/790344/ie-ignores-draggable-attribute-if-set-after-mousedown-event
  3. https://connect.microsoft.com/IE/feedback/details/782906/setting-dropeffect-has-no-effect-in-ie9-and-ie10-standards-mode
  4. https://connect.microsoft.com/IE/feedback/details/780585/dropeffect-not-working-properly-in-ie-standard-mode-ie9-ie10

@danyaPostfactum
Copy link
Contributor Author

Fixed IE issues (reverted captureMouse logic).
Improved autoscroll behavior.

@danyaPostfactum
Copy link
Contributor Author

Selection is correct after undo if text was moved below (or right). It's wrong if you move text to the left or to the top.
It's ok if I remove this line: https://github.com/ajaxorg/ace/blob/master/lib/ace/edit_session.js#L1248

@nightwing
Copy link
Member

This is absolutely awesome!
Only issue i noticed is that on old Opera setting drag image doesn't work anymore.

For 'wrong selection on undo' issues, i am going to change it to keep and restore actual selection instead of reconstructing from change ranges.
Will do that and more detailed review this weekend.

@danyaPostfactum
Copy link
Contributor Author

What is your version of Opera? 12.14 (win7) works fine. Can you check CodeMirror? It uses similar workaround (in fact, I stole it :) )
Can you reproduce mentioned Firefox issue?

@nightwing
Copy link
Member

I was testing on 12.14 too. Seems like it happens only when splitview is active.
I couldn't reproduce firefox issue on ff 26

@danyaPostfactum
Copy link
Contributor Author

It seems image must be rendered on screen. Is it ok if image always present (in Opera) at screen with such styles?

element.style { 
    position: fixed;
    height: 1px;
    width: 1px;
    top: 0px;
    left: 0px;
    opacity: 0;
    visibility: hidden;
    z-index: 2147483647;
}

visibility is toggled right on dragstart event for a while. display:none can't be used...

@nightwing
Copy link
Member

I think it's ok.

@danyaPostfactum
Copy link
Contributor Author

Opera drag image is fixed.
Bth, I found why cursor flashes. It is caused by element dimension access. This includes getBoundingClientRect() and offset*** properties. As an option, we could disable font size change polling, and cache scroller client rect (updating on page resizing (zoom) and scrolling (browser autoscroll) ) while dragging. But I think this is not necessary. May be later.

@@ -13,6 +16,7 @@
top: 0;
bottom: 0;
background-color: inherit;
z-index: 8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scrollbar elements are a bit wider, than their visible part. This is needed to overlap invisible part of scrollbar, so autoscroll triggers at very edge of scroller.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work on mac since scroller will completely cover scrollbar elements. Can we add drag listeners to the container instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm..Changing event target seems working, but I don't like that scrollbars turned into drop zones..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why, in textarea scrollbars are drop zones, in notepad++ both gutter and scrollbars are drop zones, i think it's much better.

}
this.setState("dragWait");
} else {
this.startDrag();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must not be called on double/triple/quad click. How can we pass click count here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe set clickCount on event in multimousedown listener and add getClickCount to mouseEvent?

@nightwing
Copy link
Member

Good to know what causes flickering on opera, i agree that fixing it is better left for the future.

@nightwing
Copy link
Member

In old version dragging was disabled for multiselect, but here it only drags text from the last selection.
Should we disable it or set drag text to the value of getSelectedText() ?

Also on IE when ctrl+clicking on selected text there is a quick flash of native selection.

@nightwing
Copy link
Member

Editor should not scroll selection into view if we leave (through negligence) editor rect while autoscrolling.

also it shouldn't loose it's scroll position if text is dragged over it to another editor

@danyaPostfactum
Copy link
Contributor Author

Phhhhhh...Many bad words to webkit developers... Chrome dispatches fake mousemove events sometimes.. This breaks drag ability. I will try to use the same workaround: https://github.com/ajaxorg/ace/pull/1599/files#L7R340

@danyaPostfactum
Copy link
Contributor Author

also it shouldn't loose it's scroll position if text is dragged over it to another editor

Ok. if we just pass by, editor should stay still. If we stop moving and delay for 250ms over inactive editor - editor come to live.
If we leave editor area - editor restores it's scroll position after some delay.

Do you like this, @nightwing ?

@danyaPostfactum
Copy link
Contributor Author

It could be done differently: set delay for autoscrolling and do not restore previous scroll position on dragleave. I like this more.

@nightwing
Copy link
Member

Was going to make the same comment:) Yes delay for autoscrolling is better.

Add overlay (css ::before generated content) while dragging to prevent IE to trigger `drop` event while autoscrolling
@danyaPostfactum
Copy link
Contributor Author

Ok, now all issues are fixed (I would like to separate multiselect issue from this).

@nightwing
Copy link
Member

Ok, looks good to me.
@lennartcl can you test this on mac?

var dragOperation;
var autoScrollStartTime;
var cursorMovedTime;
var cursorPointOnCaretMoved;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for bad variables naming, I have no idea how to name them better.

@danyaPostfactum
Copy link
Contributor Author

Unfortunately, new bug. On dblclick (quadclick, and every even click), Firefox does not capture mouse outside window. So, when you doubleclick an editor to select by words and move your mouse outside a window and release mouse there - editor will not receive mouseup event.
I am not sure, but I guess this bug hardly depends on clickcount, so there is no workaround.
I think this bug is ugly, but not significant, and can be fixed in future versions of FF.

@nightwing
Copy link
Member

FF bug isn't caused by this pull request it is present on master too.
We can check for event.buttons !== 0 in mousemove https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent, but let's not do it in this pull request.

@danyaPostfactum
Copy link
Contributor Author

Is associated Firefox bug filed on bugzilla? Can't find. If no, I'll file it.

@lennartcl
Copy link
Contributor

Alright, I tested this on OSX with Chrome, Firefox, Safari. Seems to work! One thing that is different compared to master is that it now shows an arrow cursor instead of a "move" cursor. Combined with #1609 that doesn't make it very intuitive to use, as you get no feedback that you're dragging text: http://screencast.com/t/Aqx8fXhC.

(Note that #1609 is something that also existed in master, it's not necessary to address that as part of this PR.)

@@ -23,6 +27,25 @@
cursor: text;
}

.ace_dragging, .ace_dragging * {
cursor: default !important;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to be the "move" cursor, would it be okay to put it back? (seems to work as desired if it's "move")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, "move" cursor looks wrong and does not match OS system Drag'n'Drop behavior (as far as I know).
I would like to use "default" cursor...

@nightwing
Copy link
Member

@lennartcl let's merge this since main part of changes are good, and we need to tweak cursor anyway e.g see #303.
Also see #1613

@lennartcl
Copy link
Contributor

@nightwing @danyaPostfactum Alright, merging as is.

Thanks for your contribution @danyaPostfactum!

@danyaPostfactum
Copy link
Contributor Author

Just played with setDragImage: https://rawgithub.com/danyaPostfactum/ace/dragimage/kitchen-sink.html
This demo works in Webkit only, but it is not too hard to implement in all browsers.

@danyaPostfactum
Copy link
Contributor Author

Anybody knows how to disable drag image scaling in Firefox? It scales drag image with height > screen height / 2 (it seems)

@nightwing
Copy link
Member

This is really nice!

It scales drag image with height > screen height / 2 (it seems)

And same for width, but It seems to be impossible to change this behavior.
Maybe it would be better to show small portion of text with ...?

@danyaPostfactum
Copy link
Contributor Author

We could enable dnd in Safari 5 (Windows) by covering editor with blank textarea.
Additionally, this trick would fix IE dropEffect issue.

@nightwing
Copy link
Member

I don't think it is worth the effort, almost no one uses safari for windows, and it is not updated anymore.
IE dropEffect issues might be worth fixing if it is broken on ie11, and can be done with very small amount of additional code.

@mlajtos
Copy link

mlajtos commented May 28, 2015

Why this branch was not merged? It gives much better feeback while dragging the selected text than current solution. Or is dragging broken?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants