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

Add handleCut editor property #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions text/0000-handleCut.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Summary

Add a handleCut editor property to EditorView to allow for custom cut behavior.

# Motivation

The handleCut property would allow others to apply custom behavior to cut events while leveraging prosemirror's built in cross browser support for the clipboard api. One use case is for not deleting the selected content on cut but instead adding a mark to the content. For example: tracking changes made to a document by striking a line through deleted content instead of removing it.
Copy link
Member

Choose a reason for hiding this comment

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

I believe that trying to track changes by overriding every possible way of deletion and replacing it with adding marks is not a good idea. And even if you wanted to do that, it'd be much better done at the filterTransaction level than at the UI level. (Not that that invalidates this whole RFC, just that this particular use case is probably a bad example.)

The recommended way to track changes is to store steps, use prosemirror-changeset to condense them to a set of insertions and deletions, and then use decorations to show those in the document.


A handleCut property would allow a custom handler to apply any transactions to the document instead of the default transaction done by prosemirror.

It is currently possible to use a handleDOMEvents.cut handler to override the default prosemirror behavior but it requires the user to write their own cross-browser clipboard support.

# Guide-level explanation

A new property would be added to EditorProps named handleCut. It would behave similarly to other handle properties (handlePaste, handleDrop, etc). If the handleCut function returns true then prosemirror's default behavior is prevented. The handleCut function can carry out its own transaction instead of prosemirror's default behavior of deleting the current selection.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it also call Event#preventDefault() (I believe this is the standard behaviour for returning true from the other handleXXX methods)?


An example of using the handleCut property:
```
new EditorView(dom, {
handleCut: function (view, event) {
Copy link
Member

Choose a reason for hiding this comment

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

The (view, event) signature doesn't provide access to the cut slice, or a way to modify it. I can imagine user code needing a way to influence the thing that'll be put on the clipboard. Which, I suppose, means we'd also need a handleCopy prop.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, I guess we already sort of have clipboardSerializer for that, though that may not always be flexible enough.

// Dispatch custom transaction
...

// Prevent default behavior
return true;
}
})
```

# Reference-level explanation

The handleCut property would use the same code pattern as other handle properties (handlePaste, handleDrop, etc). Because it would leverage common EditorProp functions it should only require one code change in prosemirror-view's input.js file.

```
handlers.copy = editHandlers.cut = (view, e) => {
...
if (cut && !view.someProp("handleCut", f => f(view, e))) view.dispatch(view.state.tr.deleteSelection().scrollIntoView())
}
```

# Drawbacks

There are little to no drawbacks. The code change would be a minor addition that makes use of a common pattern in the library. Prosemirror would still behave the same for users who do not make use of handleCut. Documentation would need to be written for the new property.

# Rationale and alternatives

Adding a handleCut property is the best way to solve custom cut behavior. The alternative requires the user to implement their own cross browser clipboard support or to duplicate the code already in the prosemirror library. Copying code in the library would then require the user to keep an eye on future updates so that they could update their copied code. This is prone to error and is a case of reinventing the wheel.

# Unresolved questions

The handleCut function would have at least two parameters. The EditorView and the event object. Beyond that it is not clear what would be useful to pass to the handleCut function. Perhaps the clipboard data.