Skip to Content
SimulatorsWordinsertOoxml Replace across paragraphs

Simulators

insertOoxml Replace across paragraphs

insertOoxml(…, 'Replace') over a range across paragraph marks joins what the range spans or, under tracking, marks it deleted. Under TrackAll, replacing a paragraph’s Whole range with a package marks the old text deleted and keeps the paragraph’s mark:

await Word.run(async context => {
  const body = context.document.body;
  body.insertParagraph('Payment is due in 30 days.', 'End');
  body.insertParagraph('Payment is due in 45 days.', 'End');
  await context.sync();
});
await Word.run(async context => {
  const paragraphs = context.document.body.paragraphs;
  paragraphs.load('items');
  await context.sync();
  const [, old, revised] = paragraphs.items;
  const pkg = revised.getOoxml();
  await context.sync();
  context.document.changeTrackingMode = Word.ChangeTrackingMode.trackAll;
  old.getRange('Whole').insertOoxml(pkg.value, 'Replace');
  const changes = context.document.body.getTrackedChanges();
  changes.load('items/type,items/text');
  old.load('text');
  await context.sync();
  // changes.items.map(c => [c.type, c.text]) -> [["Added", "Payment is due in 45 days."], ["Deleted", "Payment is due in 30 days."]]
  // old.text -> "Payment is due in 45 days.Payment is due in 30 days."
});

An insertOoxml Replace joins what its range spans

With tracking off, insertOoxml(…, 'Replace') over a range across paragraph marks takes everything between, a block content control included. It joins the text before the range and the text after it around the package. Under TrackMineOnly, where insertOoxml tracks nothing, it joins the same way. A range that ends at a paragraph’s start joins nothing. A package that would land inside a plain-text content control throws NotAllowed.

The joined paragraph is the one whose mark ends the range. Its Paragraph object reads the joined text. Every range in it keeps its offsets there, whether a search hit from a sync that only read or one that wrote. So a hit on gggg at 5 to 9 reads bbbb once aaaa bbbb cccc sits before it.

The paragraphs the range starts in and crosses are gone. These throw ItemNotFound:

  • their Paragraph objects and every range in them;
  • every range running into them from a paragraph before;
  • every tracked change listed in them;
  • the body’s own getRange(), when the range starts in the body’s first paragraph.

A package of several paragraphs then splits the joined paragraph, which keeps the part holding its mark.

Across table cells

With tracking off, or under TrackMineOnly, a Replace goes through across table cells too, where delete() and insertText throw GeneralException. The first cell the range reaches holds the join, in the paragraph the range ends in. That cell follows the cells before it in its row, and the cells after the range in the row it ends in follow it. The cells and rows between go. A row left shorter than the others skips the rest of the grid with gridAfter.

RangeResult
from before a table into itthe paragraph’s text joins the table’s first cell
from a cell out of the tablethe cell’s text joins the paragraph after
over exactly one table, from its first cell’s start through its last cell’s endthe table goes, and the package’s last paragraph joins the paragraph after, which keeps its object

Into or out of a block content control

With tracking off, or under TrackMineOnly, a Replace into or out of a block content control’s paragraph joins the same way. The control is left inline around what is left of its text, empty when nothing is. It’s gone when the range held its only paragraph from its start.

The package lands inside the control the range began in, past any spaces that ended the control’s text. Those spaces leave the control, as they do for an inline control.

A control that keeps other paragraphs stays a block. The text after the range sits apart in the paragraph after it, and the controls around that paragraph stay blocks too. The range the call returns ends at that paragraph’s start.

A tracked Replace from a paragraph’s start

Under TrackAll, a Replace across a mark goes through as a tracked edit when its range:

  • starts at a paragraph’s start, a table cell’s included;
  • holds less than the body’s or the table’s whole text;
  • crosses no block content control’s edge.

It also goes through when every mark it crosses is one an insertOoxml put in. Such a tracked edit does this:

  • The package lands at the range’s start.
  • The text up to the range’s last paragraph’s start is marked deleted, and so are the marks between. A mark an insertOoxml put in goes instead.
  • The paragraph whose mark ends the range keeps its object.
  • The range the call returns, and the one it was called on, run from the package to that paragraph’s start while it stands apart.

A tracked Replace whose range ends just past a paragraph mark deletes short of that mark, which stays. A paragraph’s Whole range is such a range, as in the example above.

A tracked Replace that changes nothing

Under TrackAll, these throw no error and change nothing:

  • a Replace from inside a paragraph’s text across a mark the document had;
  • a Replace over the body’s whole text, from its first paragraph’s start to its last paragraph’s text end or past its mark;
  • a Replace over a whole table.

paragraphs, the body’s text and getTrackedChanges read the document as it was. The range the call returns, and the one it was called on, run from the range’s start to the start of its last paragraph. Over exactly one table, they run to its end. The one it was called on keeps its offsets. getOoxml writes the document as it was.

Differs from Word for the web: Word’s reads stay as they were, in later runs too, but its getOoxml writes a half-applied edit. That edit holds the package’s text untracked at the range’s start, the range’s first paragraph mark deleted and some of its text deleted, which differs from run to run. A later edit lands in that half-applied document without the reads showing it. Once the body’s getOoxml is read, the paragraphs and the tracked changes show it too, as a document holding that package reads it. Word’s reads and its package disagree, so the simulator follows the reads.

Last updated on