Reverse Traversal Descendants

If i try to traverse on doc using doc.descendants method, and try to delete some ranges inside parents (Yes must be inside any parent on my use case),

with tr.delete(pos, pos + node.nodeSize) the first deletion works fine (because no removal before it), but after the first delete other nodes not deleting successfully, because may be they effected by the prev deletion, May be there a shifting on positions after it!

So my temporary solution is:

Store all ranges i want to delete on a list while i’m traversal inside the descendants

And after it, i iterate over this list in backward to delete the ranges from the end to begging to prevent the issues happens with nodes shifting.

Q1: So how i can prevent this shifting while i’m doing multiple transactions

Q2: Is there any method to traverse backward?

// Remove nodes placeholders if they contain text
// The placeholder are represented here as a atom node

// placeholder: {
//   group: 'inline',
//   inline: true,
//   atom: true,
//   parseDOM: [{ tag: 'span.placeholder' }],
//   toDOM() {
//     return ['span', { class: 'placeholder', 'data-placeholder': 'Placeholder' }];
//   },
// },

appendTransaction(trs, oldState, newState) {
  const isChanged = trs.some(tr => tr.docChanged);
  const tr = newState.tr;

  if (isChanged) {
    const placeholdersToDelete: { from: number; to: number }[] = [];

    // Delete all placeholders if there parents nodes are contain a text
    newState.doc.descendants((node, pos, parent) => {
      if (node.type.name === 'placeholder') {
        if (parent && parent.textContent.trim().length > 0) {
          placeholdersToDelete.push({ from: pos, to: pos + node.nodeSize });
        }
      }
    });

    // Deletions from the end to the beginning
    for (let i = placeholdersToDelete.length - 1; i >= 0; i--) {
      const { from, to } = placeholdersToDelete[i];
      tr.delete(from, to);
    }

    if (tr.docChanged) {
      return tr;
    }
  }

  return null;
},

You cannot. Positions in subsequent steps in a transaction refer to the document as it is after any steps that come before them.

No, but storing changes and applying them in reverse order, like you describe, works. Alternatively, you can map positions through tr.mapping to go from start-doc positions to current-doc positions.

You the best @marijn :+1: