Handling unintuitive AllSelection behavior when mapping across docs

Mapping an AllSelection from one document to another produces a new AllSelection that encompasses the entirety of the destination document:

This results in some pretty unintuitive behavior when viewing and acting on sub-trees – if a user selects all while viewing a subtree configured to map transactions back to the primary document, they end up selecting the entirety of the primary document.

You can see the behavior in the official footnote example (ProseMirror footnote example):

  1. Click a footnote
  2. Place the cursor inside the footnote
  3. Use the select all shortcut (ctr+a/cmd+a)

I would expect this to select the full contents of the footnote, but instead it selects the full contents of the document the footnote is embedded in. This behavior presumably stems from the semantic ambiguity of what it means to “Select everything” when you’re in a view that isn’t showing everything, but I’m curious if there are cases where this is actually the desired behavior.

That said, I understand that AllSelection is necessary for selecting the entirety of documents that might end in leaf block nodes, and I can’t think of a more reasonable way of mapping it that accounts for this case. If anyone else runs into this issue in a text document scenario, the simplest solution I found was to overwrite the behavior in my keymap.

const selectSubDoc: Command = ({tr}, dispatch) => {
  const start = tr.doc.resolve(0);
  const end = tr.doc.resolve(tr.doc.content.size);
  if (dispatch) dispatch(tr.setSelection(TextSelection.between(start, end)));
  return true;
};

const keyHandlers = keymap({
  ...baseKeymap,
  "Mod-a": selectSubDoc
})
1 Like