Closed Bug 953389 Opened 6 years ago Closed 7 months ago

CodeMirror doesn't paste with middle mouse click in Firefox

Categories

(DevTools :: Source Editor, defect, P4, minor)

29 Branch
x86_64
Linux
defect

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 1482875

People

(Reporter: ahmadsamir3891, Unassigned)

References

Details

Attachments

(1 file)

Using Firefox 29.0a1, pasting the X11 selection with middle click doesn't work. Also selecting text from Scratchpad doesn't copy the selection to the X11 buffer.
Component: Developer Tools: Scratchpad → Developer Tools: Source Editor
Summary: Scratchpad with CodeMirror doesn't paste with middle mouse click → CodeMirror doesn't paste with middle mouse click
Priority: -- → P4
It does get annoying after a while, in every app in Linux I can select text then paste it with the middle-click; except in the CodeMirror in Firefox, where I usually forget this irregular behaviour and then have to go back again and select then copy then paste .... any ETA on this one?
Summary: CodeMirror doesn't paste with middle mouse click → CodeMirror doesn't paste with middle mouse click in Firefox
This seems to be a general non-textarea widgets-on-Linux problem. Going to http://codemirror.net/ for example on Ubuntu, I can paste via middle-click in Chrome but not Firefox.

(for those watching, setting middlemouse.paste to true in about:config gives users on non-Linux platforms the same powers).

Ehsan - I know that Editor does middle-mouse click paste[1]... do you know if we try to fire paste events on any DOM element that gets middle-clicked? Is that a thing we should be doing?

[1]: http://dxr.mozilla.org/mozilla-central/source/editor/libeditor/base/nsEditorEventListener.cpp#535
Flags: needinfo?(ehsan)
The editor handles middle click pastes in both plaintext and HTML editable fields just fine, but CodeMirror doesn't use a normal contentEditable document (I just tested) and I have no idea how it tries to imitate the editable area, so it's hard for me to suggest what might be broken here.
Flags: needinfo?(ehsan)
Brian and Jan have looked into CodeMirror in the past if I am not mistaken.
(I'll be away for a week. If this is indeed a CodeMirror issue, and it's not resolved before I get back, I'll have a look then.)
Flags: needinfo?(janx)
(In reply to :Ehsan Akhgari (lagging on bugmail, needinfo? me!) from comment #4)
> The editor handles middle click pastes in both plaintext and HTML editable
> fields just fine, but CodeMirror doesn't use a normal contentEditable
> document (I just tested) and I have no idea how it tries to imitate the
> editable area, so it's hard for me to suggest what might be broken here.

When you say plaintext field, are you talking about a textarea?  CM uses a textarea for handling input events - the weird part is that the textarea may not be focused when the paste first occurs.  If this is the case, it catches the paste event on the container element and focuses the input inside of that callback: https://github.com/marijnh/CodeMirror/blob/aba7f0c4f057940b82655fdb469d3613eb627b86/lib/codemirror.js#L2423-L2442.
(In reply to comment #7)
> (In reply to :Ehsan Akhgari (lagging on bugmail, needinfo? me!) from comment
> #4)
> > The editor handles middle click pastes in both plaintext and HTML editable
> > fields just fine, but CodeMirror doesn't use a normal contentEditable
> > document (I just tested) and I have no idea how it tries to imitate the
> > editable area, so it's hard for me to suggest what might be broken here.
> 
> When you say plaintext field, are you talking about a textarea?

Yes.

> CM uses a
> textarea for handling input events - the weird part is that the textarea may
> not be focused when the paste first occurs.  If this is the case, it catches
> the paste event on the container element and focuses the input inside of that
> callback:
> https://github.com/marijnh/CodeMirror/blob/aba7f0c4f057940b82655fdb469d3613eb627b86/lib/codemirror.js#L2423-L2442.

What is the container event in this case?  Is the issue the fact that we don't fire the paste event on all types of elements?
(In reply to :Ehsan Akhgari (lagging on bugmail, needinfo? me!) from comment #8)
 
> What is the container event in this case?  Is the issue the fact that we
> don't fire the paste event on all types of elements?

The container is a div, the .CodeMirror-scroll element that can be seen when inspecting the editor on http://codemirror.net/.  The paste event does work via ctrl+v, just not middle click.

If you load http://codemirror.net/ then run this line the console it may help show what the editor is doing:

$$(".CodeMirror div")[0].style.overflow="visible"; var t = $$(".CodeMirror div > textarea")[0];t.style.width = t.style.height="100px";

Presumably the textarea is not focused on middle click, and a paste event never fires.  I'm not sure if it is focused on ctrl+v, but the presence of the event handler on the container makes me think that it isn't and the paste event still fires in this case.
Wow!!!

I can't middle click on my trackpad, but I double checked the code which handles middle click pasting and it indeed only works if and only if an editable field has focus and we catch the mouse click event on that element.  And based on your test script, the textarea is indeed the thing which receives the Ctrl+V event (I can see the pasted content in the textarea momentarily before it appears in CodeMirror.)

So I'd say CodeMirror needs to make sure the textarea has the focus when the middle mouse button is clicked.  Based on how it seems to move the textarea around on mouse clicks, I'm surprised that it doesn't currently work, but I'm not familiar with how it does things, so it's possible I'm missing something.
I don't know what the proper solution to this is -- if Firefox provides *any* way to make this work, I'll gladly hook CodeMirror up to it. But I can tell you how this works in Chrome. There, middle-clicking on a non-editable element (the visible rendering of the document, as opposed to the hidden textarea that is actually focused) fires a paste event. If the handler for that event moves the focus to an editable element, the middle-click paste will go through on that element.

A similar problem exists for selection. In Chrome, the (programatically) selected test in the hidden textarea will end up pasted when the user middle-clicks on some other control, in Firefox, it seems this only happens when the text was selected manually by the user. Again, give me any way to work around this, no matter how hacky, and I'll gladly use it.
(In reply to Marijn Haverbeke from comment #11)
> I don't know what the proper solution to this is -- if Firefox provides
> *any* way to make this work, I'll gladly hook CodeMirror up to it. But I can
> tell you how this works in Chrome. There, middle-clicking on a non-editable
> element (the visible rendering of the document, as opposed to the hidden
> textarea that is actually focused) fires a paste event. If the handler for
> that event moves the focus to an editable element, the middle-click paste
> will go through on that element.

Hmm, so according to the spec, Chrome is right, and we should fire the paste event no matter what <http://dev.w3.org/2006/webapi/clipops/clipops.html#paste-event>.  What do you think, Neil?

> A similar problem exists for selection. In Chrome, the (programatically)
> selected test in the hidden textarea will end up pasted when the user
> middle-clicks on some other control, in Firefox, it seems this only happens
> when the text was selected manually by the user. Again, give me any way to
> work around this, no matter how hacky, and I'll gladly use it.

Do you mind filing a different bug about this please so that we can talk about that problem separately?  Thanks!
Flags: needinfo?(enndeakin)
> Do you mind filing a different bug about this please so that we can talk about that problem separately?  

Done in https://bugzilla.mozilla.org/show_bug.cgi?id=1015877
This is just the same issue in some other bugs where there's no way to indicate that the cut/copy/paste commands should be enabled/disabled. It 'works' in Chrome because Chrome keeps the commands enabled at all times. Firefox does not, so you cannot 'initiate a paste operation' when nothing is focused.

The spec recently added the before versions of the events, but I don't think those should be implemented. More details are in bug 846674.
Flags: needinfo?(enndeakin)
Oh indeed, this is trickier than it seems.  I read bug 846674 and agree with your concerns there.  This bug seems like an exact dupe of that bug though, do you agree?
Flags: needinfo?(janx)
Flags: needinfo?(enndeakin)
This bug is caused by 846674, yes.
Flags: needinfo?(enndeakin)
Status: UNCONFIRMED → RESOLVED
Closed: 5 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 846674
Bug 846674 has been resolved, but as of 58.0b15 this issue still seems valid to me. Just testing with the example from there:

<!DOCTYPE html>
<html>
    <head>
        <title>Paste!</title>
        <script type="text/javascript">            
            window.onload = function () {
                document.addEventListener(
                    "paste",
                    function (event) {
                        alert(event.clipboardData.getData("text"));
                    },
                    false
                );
            };
        </script>
    </head>
    <body>
        <p>Copy some text elsewhere, then paste it here.</p>
    </body>
</html>

Pasting with Ctrl-V triggers the alert, but middle-clicking does not.
Product: Firefox → DevTools
See Also: → 1482875
I second what's said in Comment 18.
I put up a page to show the differences between input: https://swamp-existence.glitch.me/ .

Only the simple div won't fire a paste event with a middle click, but Ctrl+V does.

This is important for the DevTools team since we plan to switch the console input to a CodeMirror instance (probably shipping in 64), in which middle-click is not working properly right now.

Nika, since you resolved Bug 1208217 (which fixed the Ctrl+V case), could you have a look in the next days to see what's missing for middle-click pasting to work ? Thanks a lot !
Flags: needinfo?(nika)
i think that https://searchfox.org/mozilla-central/rev/e126996d9b0a3d7653de205898517f4f5b632e7f/editor/libeditor/EditorEventListener.cpp#679-732 is the code which handles the middle-click. Currently this callback is only called from the EditorEventListener middle-click event. 

If we don't have an editor set up for the current document, that won't be attached.

I think we'll have to hook up another event listener which listens for the middle-click event on windows, but only run it if no editor is present?

I don't really have time to look into this more deeply, but perhaps masayuki will have more ideas.
Flags: needinfo?(nika) → needinfo?(masayuki)
(In reply to :Nika Layzell from comment #20)
> i think that
> https://searchfox.org/mozilla-central/rev/
> e126996d9b0a3d7653de205898517f4f5b632e7f/editor/libeditor/
> EditorEventListener.cpp#679-732 is the code which handles the middle-click.
> Currently this callback is only called from the EditorEventListener
> middle-click event. 

Exactly.

> If we don't have an editor set up for the current document, that won't be
> attached.
> 
> I think we'll have to hook up another event listener which listens for the
> middle-click event on windows, but only run it if no editor is present?
> 
> I don't really have time to look into this more deeply, but perhaps masayuki
> will have more ideas.

EventStateManager::PostHandleEvent() must be a good point to dispatch paste event if middle click has not been handled yet (i.e., WidgetEvent::DefaultPrevented() is false) since if there is an editor and its listener handles middle click has already been handled as paste, its PreventDefault() was called at that time.

And I found a bug of current our paste event, that is, Event.target is set to a text node. However, it should be its parent element: https://www.w3.org/TR/clipboard-apis/#to-fire-a-clipboard-event
Flags: needinfo?(masayuki)
Great to hear what the fix could look like.
Masayuki, would you have some time to look into this in the coming weeks ? This issue is blocking the DevTools Console team from shipping a new console input using CodeMirror and it would be nice if we could have some help to fix this :)
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: DUPLICATE → ---
Yeah, but perhaps, late next week or later.
Probably related to Bug 1461708
(In reply to Masayuki Nakano [:masayuki] (JST, +0900) (offline: 9/21-9/30) from comment #23)
> Yeah, but perhaps, late next week or later.

Hello Masayuki, sorry to bother you again, but would you have some bandwidth soon to work on this? Thanks!
Flags: needinfo?(masayuki)
Working on bug 1461708, but I'll request review after I'm back from vacation (I've already fixed some blocker bugs).
Flags: needinfo?(masayuki)
that's great, thanks a lot !
Depends on: 1461708
I fixed bug 1461708! As far as I've tested, the fix also fixes this bug too. Let me know if you find some STRs which you cannot paste with middle click in CodeMirror.
(In reply to Masayuki Nakano [:masayuki] (JST, +0900) from comment #28)
> I fixed bug 1461708! As far as I've tested, the fix also fixes this bug too.
> Let me know if you find some STRs which you cannot paste with middle click
> in CodeMirror.

Thanks a lot !
Sadly I still can't paste using the middle click in the Console Input. I'm going to check if there's anything preventing that in the console code.
Sure. Somebody must call preventDefault() of click event or auxclick event before the Console handles it. stop(Immediate)Propagation() isn't related in this case (since it's not Gecko built-in editor).

FYI: middle click paste is one of default actions of mouseup event. After dispatching click, dblclick and auxclick events, and no of them is consumed with preventDefault(), EventStateManager dispatches a paste event for web app.

Hello again Masayuki,

I was looking at this those days, and I put up a demo of how (I think), CodeMirror is supposed to handle that.

In CodeMirror, there's a hidden (0px height) textarea that has a paste event listener [1].
Then a container, which takes the whole visible space of the CodeMirror element, also has a paste event listener which focus the textarea [2] (in order to get the paste event to fire there too I guess).

I'm about to monkeypatch the m-c checked-in version of CodeMirror to use dispatchEvent instead (which makes pasting with middle click work in the console), but I was wondering if there's a Gecko issue here.

Hmm, event target chain is created when browser dispatches an event. So, even if web apps change focused element during propagation of an event, the event won't be fired on the newly focused element.

Actually, the testcase does not work on Chromium on Linux too. So, I think that you missed something of CodeMirror.

Fixed in Bug 1482875

Status: REOPENED → RESOLVED
Closed: 5 years ago7 months ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1482875
You need to log in before you can comment on or make changes to this bug.