Closed Bug 596764 Opened 14 years ago Closed 8 years ago

support onbeforepaste, onbeforecopy and onbeforecut events (removed previously)

Categories

(Core :: DOM: UI Events & Focus Handling, defect)

x86
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: C5r1a5z0y, Unassigned)

References

Details

(Keywords: dev-doc-needed, Whiteboard: [clipops])

Attachments

(2 files)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 It looks like bug 280959 ended up removing the onbeforepaste/copy/cut events as a resolution to another bug. It was noted that there wasn't much of a use case for these events, though they should be supported if one is found. Well, I just ran into this issue, and my use case is that I want to try to format the data being pasted into a contenteditable element, to ensure that any RTF (rich text format) text is removed/converted to plain text (or what looks like plaintext). Currently there doesn't seem to be any way to do this outside of montioring the text in the element itself and noting when the paste event fires to do some really complex diff'ing logic. In contrast, IE can redirect focus in the onbeforepaste event to a textarea so that the text is converted to plaintext by the browser when the actual paste event is fired. Moving the focus doesn't work in the paste event however, as the text won't be pasted into the newly focused element - this is consistent in FF & IE. A similar method can be used to move the focus in FF if the keydown event is trapped - since the event isn't the paste event itself, refocusing to another element behaves like the onbeforepaste event would. The only issue is that this only will work when pasting via the keyboard. Pasting from the context menu & Edit menu both will obviously bypass the keydown handler. Another posible solution besides adding the onbefore* event handlers back in would be to allow access to what is being pasted as part of the onpaste event object. This would actually be more ideal, in fact, but it would likely be non-standard as well. Reproducible: Always Steps to Reproduce: 1.Copy some RTF text 2.Paste it into the example file's editable div 3.The scripts on the page should convert the text to plain text. Actual Results: In Firefox the text is pasted as-is. Expected Results: Note that in IE the text is converted to non-rtf (or at least it's displayed as if it's plaintext). I'll attach the files momentarily...
Attached file Testing file (deleted) —
This is a test case I first ran into the issue with. The test case works correctly in IE, but not in FF.
Whiteboard: [clipops]
We need these events to make sure web content can tell the browser to enable copy/cut/paste commands. Especially since currently, you can't make the events fire if the commands are not enabled. Quoting a message from Ehsan on https://groups.google.com/d/msg/mozilla.dev.webapi/Bvb-S152azI/i2ArCikbxbsJ : Currently we don't dispatch those events if the corresponding command is disabled. I think the right thing to do would be to dispatch the events always, but bail out early on the default action if the command is disabled. That way, if the command is disabled, content can still receive these events. The issue that makes that a bit hard to fix is that right now the Ctrl+X/C/V are bound to XUL commands, which we disable/enable as the current selection changes. This stuff is triggered on the Gecko side by calling nsGlobalWindow::UpdateCommand("select") in nsDocViewerSelectionListener::NotifySelectionChanged. That ends up calling goUpdateGlobalEditMenuItems in toolkit, which currently updates the cmd_cut/copy/paste commands. I think we'd want to instead update the corresponding menu items and toolbar keys. But these are well known commands in XUL applications, I don't know we can simply change toolkit here. CCing dev-firefox and Neil, hopefully someone can check over my idea here.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Note that per the new spec, the events use a ClipboardEvent-type event object with a DataTransfer clipboardData property. http://dev.w3.org/2006/webapi/clipops/clipops.html#events http://dev.w3.org/2006/webapi/clipops/clipops.html#processing-model-for-before-events
Also note that the use case in the description of this bug is a hack that should not be used. The better way to do that is document.addEventListener('paste', function(e){ var plaintext = e.clipboardData.getData('text/plain'); // or 'text' for old IE compat e.preventDefault(); // don't insert your payload }) since clipboard implementations typically have a plain text alternative to rich text data.
Summary: OnBeforePaste, OnBeforeCopy, & OnBeforeCut events not supported (removed previously) → support onbeforepaste, onbeforecopy and onbeforecut events (removed previously)
As far as I can tell, the only use case for these events is to allow the browser to consult the web page before enabling/disabling its commands. I think this approach has a few issues though: 1. It relies on every web page handling the cut/copy/paste events to be aware of these before events and do the right thing with them. If the page doesn't handle these events, the browser will do something that the web page probably doesn't expect. 2. It is not clear what circumstances the browser should fire the events based on. For example, should it only fire the events when the selection changes? What about when the contents of the clipboard changes? What about when you switch tabs to/away from a page? Most importantly, what if something inside the internal state of the page changes that would affect whether one of these commands needs to be enabled? The page has no way to directly signal this to the UA without waiting around for the UA to dispatch the events at some point later. 3. It is inefficient, since it means that the browser will need to synchronously dispatch an event to the page, wait for the event dispatch to finish before it can update its UI. This is especially bad if the browser's UI runs on a different thread than the page's, such as in Fennec or e10s. Do other UAs implement this? How do they deal with the problems above? For now I'm inclined to do the much simpler thing of enabling the clipboard commands unconditionally in bug 1159490.
Flags: needinfo?(hsteen)
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #6) > 1. It relies on every web page handling the cut/copy/paste events to be > aware of these before events and do the right thing with them. If the page > doesn't handle these events, the browser will do something that the web page > probably doesn't expect. The only pages that really need to worry about this, are pages that use somewhat fancy clipboard logic - say you've implemented a file manager UI and use CSS to fake "selectedness" of files. Now, since there's no actual selection in the page you want to make sure the copy/cut commands are enabled, and you can listen for the events to do so. (Similar for paste, although you may only want to enable it when the data on the clipboard can be inserted into your app..) However, many pages that write to or read from the clipboard will have simple needs - just setting or enhancing a string, or getting some HTML to massage/validate it slightly - and those will likely be working in a context where before* events aren't necessary. > 2. It is not clear what circumstances the browser should fire the events > based on. For example, should it only fire the events when the selection > changes? What about when the contents of the clipboard changes? What about > when you switch tabs to/away from a page? Most importantly, what if > something inside the internal state of the page changes that would affect > whether one of these commands needs to be enabled? The page has no way to > directly signal this to the UA without waiting around for the UA to dispatch > the events at some point later. Indeed - the "original" approach (IE invented this) is to fire the events before any menu with copy/cut/paste actions in opens. That is adequate for menu UI, but not quite for keyboard shortcuts and always-visible UI like toolbar buttons. > 3. It is inefficient, since it means that the browser will need to > synchronously dispatch an event to the page, wait for the event dispatch to > finish before it can update its UI. This is especially bad if the browser's > UI runs on a different thread than the page's, such as in Fennec or e10s. > > Do other UAs implement this? How do they deal with the problems above? I've done limited testing of IE and know what Presto did. IE - although the inventor - has rather limited and buggy support for this at the moment. You can enable pasting into <input disabled> but that's about it - I was surprised by how weird and limited their implementation is. Presto did a different (but IMO clever) thing: it simply enabled the commands if there were corresponding event listeners in the page. > For now I'm inclined to do the much simpler thing of enabling the clipboard > commands unconditionally in bug 1159490. If that's OK with UI and UX and Human Interface Guidelines-type people, fine with me ;) Another option might be to invent the missing document.setCommandEnabledState() method.. WDYT? document.setCommandEnabledState('<command>', 'enabled'|'disabled'|'automatic') or something?
Flags: needinfo?(hsteen)
Flags: needinfo?(ehsan)
(In reply to Hallvord R. M. Steen [:hallvors] from comment #7) > (In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from > comment #6) > > 1. It relies on every web page handling the cut/copy/paste events to be > > aware of these before events and do the right thing with them. If the page > > doesn't handle these events, the browser will do something that the web page > > probably doesn't expect. > > The only pages that really need to worry about this, are pages that use > somewhat fancy clipboard logic - say you've implemented a file manager UI > and use CSS to fake "selectedness" of files. Now, since there's no actual > selection in the page you want to make sure the copy/cut commands are > enabled, and you can listen for the events to do so. (Similar for paste, > although you may only want to enable it when the data on the clipboard can > be inserted into your app..) However, many pages that write to or read from > the clipboard will have simple needs - just setting or enhancing a string, > or getting some HTML to massage/validate it slightly - and those will likely > be working in a context where before* events aren't necessary. Well, the issue is that this requirement is non-obvious. For example, if the said file manager's original UI just selected a bunch of DOM nodes to represent selected files, and if in their v2 they rewrite their UI to fake selections using CSS, their site would suddenly break unless if they handled these events, which is probably unexpected. > > 2. It is not clear what circumstances the browser should fire the events > > based on. For example, should it only fire the events when the selection > > changes? What about when the contents of the clipboard changes? What about > > when you switch tabs to/away from a page? Most importantly, what if > > something inside the internal state of the page changes that would affect > > whether one of these commands needs to be enabled? The page has no way to > > directly signal this to the UA without waiting around for the UA to dispatch > > the events at some point later. > > Indeed - the "original" approach (IE invented this) is to fire the events > before any menu with copy/cut/paste actions in opens. That is adequate for > menu UI, but not quite for keyboard shortcuts and always-visible UI like > toolbar buttons. Yeah, and we do need to handle those cases in Firefox today. > > 3. It is inefficient, since it means that the browser will need to > > synchronously dispatch an event to the page, wait for the event dispatch to > > finish before it can update its UI. This is especially bad if the browser's > > UI runs on a different thread than the page's, such as in Fennec or e10s. > > > > Do other UAs implement this? How do they deal with the problems above? > > I've done limited testing of IE and know what Presto did. > > IE - although the inventor - has rather limited and buggy support for this > at the moment. You can enable pasting into <input disabled> but that's about > it - I was surprised by how weird and limited their implementation is. Ugh. So basically their implementation has always been broken. :/ > Presto did a different (but IMO clever) thing: it simply enabled the > commands if there were corresponding event listeners in the page. I have thought about that, but I think that's a bad approach too, since event handlers can just do nothing, and there is no way for us to know what kind of event handler we're dealing with. > > For now I'm inclined to do the much simpler thing of enabling the clipboard > > commands unconditionally in bug 1159490. > > If that's OK with UI and UX and Human Interface Guidelines-type people, fine > with me ;) > > Another option might be to invent the missing > document.setCommandEnabledState() method.. WDYT? > > document.setCommandEnabledState('<command>', > 'enabled'|'disabled'|'automatic') > > or something? That would be the correct way to solve this, yes. But the first issue still exists. Essentially I don't think this is solvable in a great way...
Flags: needinfo?(ehsan)
I guess we should close this as WONTFIX?
Now, now.. This use case (say you will understand a paste, enable UI) is important - especially if we consider document.execCommand('paste') too dangerous. So let's wait and discuss a little - I want to suggest something else on the public-html or whatwg lists if we don't want to do the before* events.. I quite like something like document.setCommandEnabledState('copy', 'enabled') However, one of the good sides of the event solution (as spec'd - please ignore the borked implementations) is that the event object tells you what data types are on the clipboard, and thus lets you enable "paste" only if you see a data type you think you can handle.. There's no other way to get this unless we add a whole new clipboard API.
Flags: needinfo?(ehsan)
(And the needinfo - sorry to pester you - was to hear any thoughts you might have on "if we don't do the onbefore* thingy, do you have any suggestions for an API that solves this use case?)
(In reply to Hallvord R. M. Steen [:hallvors] from comment #10) > Now, now.. This use case (say you will understand a paste, enable UI) is > important - especially if we consider document.execCommand('paste') too > dangerous. So let's wait and discuss a little - I want to suggest something > else on the public-html or whatwg lists if we don't want to do the before* > events.. > > I quite like something like > document.setCommandEnabledState('copy', 'enabled') Like I said before, this also suffers from issue #1 in comment 6. IOW, an implementation that wants to be helpful to the user must still enable the copy command at all times, at least until the Web page asks the browser to _disable_ it. > However, one of the good sides of the event solution (as spec'd - please > ignore the borked implementations) is that the event object tells you what > data types are on the clipboard, and thus lets you enable "paste" only if > you see a data type you think you can handle.. There's no other way to get > this unless we add a whole new clipboard API. Handling paste is a completely different beast, since whether or not you can paste ultimately depends on the contents of the clipboard, so we need a bidirectional signal, from the page to the UA to signal when it can accept paste commands, and from the UA to the page to signal what kinds of data are available to paste. That being said, I'm not sure if it's worth exposing all of this complicated functionality to web pages. It seems like the default for all three commands needs to be enabled at all times. With that, I'm not sure how much of this complexity is worth it in practice just to be able to disable a bunch of commands in the rare case where an application opts in to whatever we end up deciding on here.
Flags: needinfo?(ehsan)
(In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from comment #12) > IOW, an > implementation that wants to be helpful to the user must still enable the > copy command at all times, at least until the Web page asks the browser to > _disable_ it. The onbefore* approach doesn't actually give the web page a way to _disable_ the commands, only enable them if they would otherwise be disabled by the built-in logic. I think this is considered a feature because it lowers the risk of a site annoying the user by disabling commands by mistake.
(In reply to Hallvord R. M. Steen [:hallvors] from comment #13) > (In reply to :Ehsan Akhgari (not reading bugmail, needinfo? me!) from > comment #12) > > IOW, an > > implementation that wants to be helpful to the user must still enable the > > copy command at all times, at least until the Web page asks the browser to > > _disable_ it. > > The onbefore* approach doesn't actually give the web page a way to _disable_ > the commands, only enable them if they would otherwise be disabled by the > built-in logic. I think this is considered a feature because it lowers the > risk of a site annoying the user by disabling commands by mistake. Yes, and that's my point. Let me rephrase: * I believe that a usable implementation needs to keep copy, cut and paste commands enabled at all times for the reasons mentioned above. * onbefore events are only useful for implementations that do not do that. Based on the above two points, I don't think implementing these events makes sense.
We're removing this feature from the spec because it's poorly implemented so far and there's a general lack of implementor interest in this approach.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → INVALID
Component: Event Handling → User events and focus handling
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: