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

Should liftListItem handle a selection over multiple lists? #766

Open
adrianheine opened this issue Mar 9, 2018 · 2 comments
Open

Should liftListItem handle a selection over multiple lists? #766

adrianheine opened this issue Mar 9, 2018 · 2 comments

Comments

@adrianheine
Copy link
Member

Given the following doc:

  • doc
    • ul
      • li
    • ul
      • li

With both lists selected, liftListItem doesn't work, since it uses blockRange to find a single NodeRange over a list covering the whole current selection. Since liftListItem is the primitive operation exported by prosemirror-schema-list, this limitation means the behavior has to be re-implemented by client-code if it should cover the case I described.

@marijnh
Copy link
Member

marijnh commented Mar 9, 2018

I believe this was hard to get right, the last time I tried, or raised some hard-to-answer questions, so I omitted it. Unfortunately, I don't remember the precise issue. If you want to make the default implementation handle this, and can do so without introducing anything problematic, I'd be okay with that.

@steveccable
Copy link

For anyone who comes across this, I put together a hack-around for flattening the entire list that seems to do the job (at the very least, it handles the case in the description). It could certainly be modified to just lift one level at a time, but figured I would share it here in case others come across a need to do this before it gets fully integrated into this library.

// Some error checking/handling has been omitted
// Assume selection here either is or has been expanded to cover the whole list you want to flatten
const selectedContents = selection.content();
const selectedNodes = selectedContents.content.content;

// Not always necessarily paragraphs, but always necessarily NOT lists
const generateNewParagraphNode = node => {
  const type = node.type;
  // Assume these point to the actual schema NodeTypes that they correspond with
  if (type === ol || type === ul || type === li) {
    const childContents = node.content.content || [];
    const wrappedChildren = childContents.map(generateNewParagraphNode);
    return wrappedChildren;
  } else {
    return node;
  }
};
const liftedContents = selectedNodes.map(generateNewParagraphNode);

// Not sure how well Slice handles nested arrays, so I flatten here with a simple JS function
const flatContents = flattenArray(liftedContents);
const newSlice = new Slice(Fragment.fromArray(flatContents), selectedContents.openStart, selectedContents.openEnd);
transaction = editorView.state.tr.replaceSelection(newSlice);
editorView.dispatch(transaction);

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

No branches or pull requests

3 participants