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

fix (sync plugin)[Issue #43]: Restore relativeSelection using a NodeSelection if appropriate #118

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jamesopti
Copy link

Changes

  • Update getRelativeSelection to capture whether or not the current selection is a NodeSelection
  • Update restoreRelativeSelection to use a node selection if restoring one

Context

Attempts to fix #43

@jamesopti jamesopti mentioned this pull request May 29, 2022
2 tasks
Copy link
Member

@dmonad dmonad left a comment

Choose a reason for hiding this comment

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

Could you please add a test-case for this?

}
}
}

export const getRelativeSelection = (pmbinding, state) => ({
anchor: absolutePositionToRelativePosition(state.selection.anchor, pmbinding.type, pmbinding.mapping),
head: absolutePositionToRelativePosition(state.selection.head, pmbinding.type, pmbinding.mapping)
head: absolutePositionToRelativePosition(state.selection.head, pmbinding.type, pmbinding.mapping),
isNodeSelection: state.selection instanceof NodeSelection,
Copy link
Member

Choose a reason for hiding this comment

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

Can you please change this to type: 'NodeSelection' | 'TextSelection'? This would make it possible to potentially add more types of selections.

@@ -194,14 +194,18 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
const anchor = relativePositionToAbsolutePosition(binding.doc, binding.type, relSel.anchor, binding.mapping)
const head = relativePositionToAbsolutePosition(binding.doc, binding.type, relSel.head, binding.mapping)
if (anchor !== null && head !== null) {
tr = tr.setSelection(TextSelection.create(tr.doc, anchor, head))
const selection = relSel.isNodeSelection
? NodeSelection.create(tr.doc, Math.min(anchor, head))
Copy link
Member

Choose a reason for hiding this comment

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

How does this behave when multiple nodes are selected?

Copy link
Author

Choose a reason for hiding this comment

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

How does this behave when multiple nodes are selected?

Hmmm good question! I'm actually not sure how to test this.

Copy link
Author

@jamesopti jamesopti May 29, 2022

Choose a reason for hiding this comment

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

According to the Prosemirror docs, a Node Selection is a selection that points at a single node.

I believe a range that points to mulitple nodes or ranges is still considered a Text Selection, however, I don't know how or if it is possible to select multiple specific nodes at once, so I cant say for sure.

@jamesopti jamesopti requested a review from dmonad May 29, 2022 17:06
@jamesopti
Copy link
Author

jamesopti commented May 29, 2022

@dmonad I think the complete solution here to handle custom selections (like Cell Selection for tables) is to accept an optional function parameter restoreSelection(tr, relSel) that a consumer could implement to handle their own selection restoration.

If you think that makes sense to do now, I'm happy to do it as part of this PR or as a follow up.

E.g.

const defaultRestoreSelection = (tr, anchor, head) => {
  const selection = relSel.type === 'node'
    ? NodeSelection.create(tr.doc, Math.min(anchor, head))
    : TextSelection.create(tr.doc, anchor, head)
  tr = tr.setSelection(selection)
}


export const ySyncPlugin = (yXmlFragment, {
  colors = defaultColors,
  colorMapping = new Map(),
  permanentUserData = null,
  onFirstRender = () => {},
  restoreSelection = defaultRestoreSelection
} = {}) => {

  ...

})

const restoreRelativeSelection = (tr, relSel, binding, restoreSelection) => {
  if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {
    const anchor = relativePositionToAbsolutePosition(binding.doc, binding.type, relSel.anchor, binding.mapping)
    const head = relativePositionToAbsolutePosition(binding.doc, binding.type, relSel.head, binding.mapping)
    if (anchor !== null && head !== null) {
      restoreSelection(tr, anchor, head)
    }
  }
}

@jamesopti
Copy link
Author

@dmonad Any chance we could get this merged soon?

@dmonad
Copy link
Member

dmonad commented Jun 19, 2022

FYI this is pretty low on my priority list. I just took some time off. Now I need to catch up on quite a lot of stuff. The good thing is that it is on some kind of priority list I guess 😅

@amilich
Copy link

amilich commented Aug 2, 2022

FYI this is pretty low on my priority list. I just took some time off. Now I need to catch up on quite a lot of stuff. The good thing is that it is on some kind of priority list I guess 😅

Hey all! Just noting that we could use this fix as well. Would help us out fixing some other selection types.

@amilich
Copy link

amilich commented Aug 11, 2022

FYI this is pretty low on my priority list. I just took some time off. Now I need to catch up on quite a lot of stuff. The good thing is that it is on some kind of priority list I guess 😅

Hey all! Just noting that we could use this fix as well. Would help us out fixing some other selection types.

Checking in briefly on this

@rebolyte
Copy link

rebolyte commented Nov 9, 2022

Just bumped into this as well. @jamesopti anything left before it can be merged?

@Alecyrus
Copy link

Alecyrus commented Dec 1, 2022

I have the same issue #43. I try this commit and it does not work, but #43 (comment) works.

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.

Prosemirror SelectedNode Issue
5 participants