Closed Bug 1744524 Opened 3 years ago Closed 2 years ago

Expose `clipboard.readText()` with a user prompt ("Paste" button) to the web, gated behind a pref

Categories

(Core :: DOM: Copy & Paste and Drag & Drop, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
103 Branch
Tracking Status
firefox103 --- fixed

People

(Reporter: mbrodesser-Igalia, Assigned: mbrodesser-Igalia)

References

(Blocks 3 open bugs)

Details

Attachments

(6 files, 8 obsolete files)

(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
No description provided.
Blocks: 1619251

To enable navigator.clipoard.readText().

Depends on D132943

The uploaded patches are WIP towards a working prototype.

Notes for when dev-doc-needed is added (when the patches land):
The BCD table currently has a note that states that the feature is only supported in extensions: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText

The source for that table is at https://github.com/mdn/browser-compat-data/blob/ecf4f6ced00d883e235a4889c40ca26aadd1cd8e/api/Clipboard.json#L213-L234

Once this feature becomes available to web content by default, another note should be added to point out the new support for this feature on the web.

Depends on: 1746870
Depends on: 1748437
Attachment #9253873 - Attachment is obsolete: true
Attachment #9253874 - Attachment is obsolete: true
Attachment #9253875 - Attachment is obsolete: true
Attachment #9253876 - Attachment is obsolete: true
Attachment #9253877 - Attachment is obsolete: true
Attachment #9258009 - Attachment description: WIP: Bug 1744524: part 3) Add "ClipboardReadTextPaste" actor pair → WIP: Bug 1744524: part 3) Start adding JS code for the "Paste" menupopup to react on receiving `ClipboardReadTextPaste` events from the C++ side
Attachment #9258011 - Attachment description: WIP: Bug 1744524: part 5) Start creating custom event for `ClipboardReadTextPaste` on the C++ side → WIP: Bug 1744524: part 4) Start creating and dispatching custom event for `ClipboardReadTextPaste` on the C++ side
Attachment #9258010 - Attachment is obsolete: true
Attachment #9258009 - Attachment description: WIP: Bug 1744524: part 3) Start adding JS code for the "Paste" menupopup to react on receiving `ClipboardReadTextPaste` events from the C++ side → WIP: Bug 1744524: part 3) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events from the C++ side
Attachment #9258011 - Attachment description: WIP: Bug 1744524: part 4) Start creating and dispatching custom event for `ClipboardReadTextPaste` on the C++ side → WIP: Bug 1744524: part 4) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button
Depends on: 1760553
Depends on: 1760807
Depends on: 1766803
Attachment #9253872 - Attachment description: WIP: Bug 1744524: part 2) Add example with user-initiable call of `clipboard.readText()` and non-user initiated call of it → WIP: Bug 1744524: part 1) Add example with user-initiable call of `clipboard.readText()` and non-user initiated call of it
Attachment #9258009 - Attachment description: WIP: Bug 1744524: part 3) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events from the C++ side → WIP: Bug 1744524: part 2) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events created from the C++ side
Attachment #9258011 - Attachment description: WIP: Bug 1744524: part 4) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button → WIP: Bug 1744524: part 3) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button
Attachment #9260157 - Attachment description: WIP: Bug 1744524: part 5) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button → WIP: Bug 1744524: part 4) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button

The web platform test (WPT) framework doesn't support such user agent
specific buttons. The corresponding WPTs continue to use the pref
"dom.events.testing.asyncClipboard", which skips showing the button.

Depends on D136617

Attachment #9253871 - Attachment is obsolete: true
Blocks: 1767941

This is some comments from the needinfo in bug 1766803 that would be better here in this bug.

Looking at this code, is this menu meant to act as a security check so that the user can confirm that the cliboard can be accessed by a web site? I would suggest that you first determine whether that UI makes sense as it seems like an odd UI to me. Instead of a small unexpected menu that is hard to see I would expect something more visible or clearer as to what is being asked of the user. Most notably, if a user hasn't used the mouse to trigger the paste, the menu appears at a seemingly random location. (I think the code is just using the last mouse event over the window?)

Also, is it a concern that the menu can be easily spoofed by a site? Usually, security related asks of the user would appear fully or partially over the chrome area of the browser.

If it is determined that a menu (or a panel) is suitable here, some comments:

I haven't looked in detail, but I assume the code that calculates the screen for the window isn't calculating what you want. This is done by nsIWidget::ScreenForRect. Is the right coordinates being sent to this method or is it returning the wrong value? That would narrow down if there is a bug here and where it is.

However, you're using openPopup to open the popup anchored at something, but not specifying the anchor, so the entire document/window will be used, part of which can be on another screen. So the anchor is technically potentially on many different screens, so the popup alignment code could place it anywhere around the anchor -- it can get flipped around to the opposite side if there isn't room. I suspect that isn't what you want. I think you actually just want the popup to appear at a specific screen position. You should just use openPopupAtScreen for this which opens the popup at a point rather than an anchor rectangle.

(In reply to Neil Deakin from comment #16)

This is some comments from the needinfo in bug 1766803 that would be better here in this bug.

Looking at this code, is this menu meant to act as a security check so that the user can confirm that the cliboard can be accessed by a web site?

Yes.

I would suggest that you first determine whether that UI makes sense as it seems like an odd UI to me. Instead of a small unexpected menu that is hard to see I would expect something more visible or clearer as to what is being asked of the user.

This happened already in https://bugzilla.mozilla.org/show_bug.cgi?id=1578321. Note that Safari already shipped the same UI.

Most notably, if a user hasn't used the mouse to trigger the paste, the menu appears at a seemingly random location. (I think the code is just using the last mouse event over the window?)

Yes. Well, not a random location. It should always be clearly determined.

Also, is it a concern that the menu can be easily spoofed by a site? Usually, security related asks of the user would appear fully or partially over the chrome area of the browser.

Please check https://bugzilla.mozilla.org/show_bug.cgi?id=1578321.

If it is determined that a menu (or a panel) is suitable here, some comments:

Thanks. Appreciated. Will have a closer look at them tomorrow.

I haven't looked in detail, but I assume the code that calculates the screen for the window isn't calculating what you want. This is done by nsIWidget::ScreenForRect. Is the right coordinates being sent to this method or is it returning the wrong value? That would narrow down if there is a bug here and where it is.

However, you're using openPopup to open the popup anchored at something, but not specifying the anchor, so the entire document/window will be used, part of which can be on another screen. So the anchor is technically potentially on many different screens, so the popup alignment code could place it anywhere around the anchor -- it can get flipped around to the opposite side if there isn't room. I suspect that isn't what you want. I think you actually just want the popup to appear at a specific screen position. You should just use openPopupAtScreen for this which opens the popup at a point rather than an anchor rectangle.

I'll follow up on #c17 in bug 1766803.

Yes. Well, not a random location. It should always be clearly determined.

Sure, but if the user, for example, triggered the paste from the edit menu, the menu will appear to them what appears to be an arbitrary point at the edge of the window rather than near the mouse or the field being pasted into.

This happened already in https://bugzilla.mozilla.org/show_bug.cgi?id=1578321. Note that Safari already shipped the same UI.

OK, that's interesting. I tried it out (I needed to update to os12) and Safari opens the menu at the absolute mouse pointer location on screen. That's much better than what this patch does which opens the menu at the last mouse pointer position over the invoking window. We don't have an api to get the screen coordinate of the mouse pointer though, so one would have to be added.

Interestingly, Safari doesn't seem to handle my multiple screen setup either -- the menu never appears for a window in the second screen.

(In reply to Neil Deakin from comment #19)

Yes. Well, not a random location. It should always be clearly determined.

Sure, but if the user, for example, triggered the paste from the edit menu,

Which edit menu? The one at the top of the UI? I'm not sure that would permit calling navigator.clipboard.readText(), because the latter requires user activation. If permitted, that specific case should not show an additional "Paste" button, since the user already indicated he's permitting access to the clipboard.
Be aware that this bug-ticket will gate navigator.clipboard.readText() behind a pref. It won't be enabled by default. Before enabling it by default, we'll test such cases (also on Android and touch events, perhaps more).

Moreover we intend to later implement not showing the "Paste" button to the user, when her privacy isn't affected (see https://webkit.org/blog/10855/, section "Security and Privacy"). The consequence will be, that the "Paste" button is shown less often.

the menu will appear to them what appears to be an arbitrary point at the edge of the window rather than near the mouse or the field being pasted into.

The user can't know where on the page the clipboard content is used. He just knows it will be used somewhere. For instance when clicking a <button> that could call const t = await clipboard.readText() and store t in an arbitrary element on the page.

This happened already in https://bugzilla.mozilla.org/show_bug.cgi?id=1578321. Note that Safari already shipped the same UI.

OK, that's interesting. I tried it out (I needed to update to os12) and Safari opens the menu at the absolute mouse pointer location on screen.

Thanks for the checking. Feedback here is much appreciated.

That's much better than what this patch does which opens the menu at the last mouse pointer position over the invoking window.

One requirement (brought up by Anne van Kesteren) was that the "Paste" button should always appear inside the browser window, indicating the target application of the paste action. Which does make sense.

We don't have an api to get the screen coordinate of the mouse pointer though, so one would have to be added.

Interestingly, Safari doesn't seem to handle my multiple screen setup either -- the menu never appears for a window in the second screen.

That's a bug :-).

Summary: Expose `clipboard.readText` to the web → Expose `clipboard.readText()` with a user prompt ("Paste" button) to the web, gated behind a pref
Blocks: 1770358
Attachment #9258009 - Attachment description: WIP: Bug 1744524: part 2) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events created from the C++ side → Bug 1744524: part 1) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events created from the C++ side. r=edgar
Attachment #9258011 - Attachment description: WIP: Bug 1744524: part 3) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button → Bug 1744524: part 2) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button. r=edgar
Attachment #9260157 - Attachment description: WIP: Bug 1744524: part 4) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button → Bug 1744524: part 3) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button. r=edgar
Attachment #9274387 - Attachment description: WIP: Bug 1744524: part 5) Add pref for enabling `clipboard.readText()` gated by a "Paste" button → Bug 1744524: part 4) Add pref for enabling `clipboard.readText()` gated by a "Paste" button. r=edgar
Attachment #9276215 - Attachment description: WIP: Bug 1744524: part 6) Add mochitest-browser for `navigator.clipboard.readText()` → WIP: Bug 1744524: part 5) Add mochitest-browser for `navigator.clipboard.readText()`
Attachment #9253872 - Attachment is obsolete: true
No longer depends on: 1766803
Depends on: 1772291
Depends on: 1772490
Attachment #9276215 - Attachment description: WIP: Bug 1744524: part 5) Add mochitest-browser for `navigator.clipboard.readText()` → Bug 1744524: part 5) Add mochitest-browser for `navigator.clipboard.readText()`. r=edgar

Preparation for part 3).

The return type of GetUserGestureStart is a class, the return type of
LastUserGestureTimeStamp a double. Hence using the former is safer.

Depends on D135333

Attachment #9258011 - Attachment description: Bug 1744524: part 2) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button. r=edgar → Bug 1744524: part 3) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button. r=edgar
Attachment #9260157 - Attachment description: Bug 1744524: part 3) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button. r=edgar → Bug 1744524: part 4) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button. r=edgar
Attachment #9274387 - Attachment description: Bug 1744524: part 4) Add pref for enabling `clipboard.readText()` gated by a "Paste" button. r=edgar → Bug 1744524: part 5) Add pref for enabling `clipboard.readText()` gated by a "Paste" button. r=edgar
Attachment #9276215 - Attachment description: Bug 1744524: part 5) Add mochitest-browser for `navigator.clipboard.readText()`. r=edgar → Bug 1744524: part 6) Add mochitest-browser for `navigator.clipboard.readText()`. r=edgar
No longer depends on: 1772490
Pushed by mbrodesser@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/866af380a4e9 part 1) Add JS code for the "Paste" menupopup to handle `ClipboardReadTextPaste` events created from the C++ side. r=edgar,Gijs https://hg.mozilla.org/integration/autoland/rev/9e1ab7cfcb09 part 2) Add `WindowContext::GetUserGestureStart` and remove `WindowContext::LastUserGestureTimeStamp`. r=edgar https://hg.mozilla.org/integration/autoland/rev/15610acc0c7a part 3) On the C++ side: dispatch a custom event when `clipboard.readText()` is called and allow the JS side to propagate whether the user clicked or dismissed the "Paste" button. r=edgar https://hg.mozilla.org/integration/autoland/rev/3560ad927c44 part 4) Propagate from the JS side to the C++ side whether the user clicked or dismissed the "Paste" button. r=edgar https://hg.mozilla.org/integration/autoland/rev/326b008de5b5 part 5) Add pref for enabling `clipboard.readText()` gated by a "Paste" button. r=edgar https://hg.mozilla.org/integration/autoland/rev/b7ecf53f7976 part 6) Add mochitest-browser for `navigator.clipboard.readText()`. r=edgar
Regressions: 1774630
No longer depends on: 1760553
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: