Simulators
Deleting and replacing text
insertText takes the locations Word takes for its receiver, Replace included, and delete and clear remove text and paragraphs by Word for the web’s rules. Deleting the document’s last paragraph, for one, empties it and leaves it in the list:
await Word.run(async context => {
context.document.body.insertParagraph('first', 'End');
context.document.body.insertParagraph('last', 'End');
await context.sync();
});
await Word.run(async context => {
const paragraphs = context.document.body.paragraphs;
paragraphs.load('items/text');
await context.sync();
paragraphs.items[paragraphs.items.length - 1].delete();
await context.sync();
const after = context.document.body.getRange('Whole').paragraphs;
after.load('items/text');
await context.sync();
// after.items.map(p => p.text) -> ["", "first", ""]
});
Replace writes unformatted text
Inserted text takes its formatting by where it goes:
| Insertion | Its text’s formatting |
|---|---|
insertText(…, 'Replace'), tracked or not | none of its own, whatever the text it replaces had |
at Start, End, Before or After | the formatting of the text beside it |
untracked, through a paragraph’s or the body’s End, at a paragraph mark with formatting of its own | the mark’s |
So replacing a bold phrase writes the new phrase plain. Text typed at the end of a paragraph whose mark is bold comes out bold.
An edit at the end of a paragraph’s text gives its mark the formatting of the paragraph’s last run. That includes a delete or Replace that runs from there into the next paragraph, and the last run may be the one a delete took. With tracking on, only a mark with no formatting of its own takes it.
Differs from Word for the web: through a span from a search hit made in a sync that only read, Word’s delete or Replace across a mark leaves the mark’s run properties as they were. The simulator gives the mark the last run’s formatting, as above.
insertParagraph on the body gives the new paragraph:
- the alignment, style and numbering of the paragraph beside it;
- that paragraph’s run formatting, on its text;
- no formatting of its own, on its mark.
At Start, the first paragraph’s mark stays as it was. At End, the last paragraph’s mark is left with none either.
Deleting the last paragraph empties it
delete() on the document’s last paragraph, or on a table cell’s, takes only its text. body.paragraphs still lists the paragraph, empty, and the document still ends in it.
| Paragraph | After delete() |
|---|---|
| the document’s last | gives way to a new empty one; the one you deleted throws ItemNotFound for the rest of the run, as any deleted paragraph does |
| a table cell’s last | stays and reads empty |
| any other | is removed, with any comment anchored in it |
Tracked, the text is marked deleted and the paragraph mark is not. The mark that stays takes the formatting of the last run deleted, so text typed there afterwards takes it too. That holds for the document’s last paragraph, tracked or not, and for a cell’s, untracked.
Deleting a paragraph’s whole range removes it
With tracking off, delete() on a range that holds a paragraph whole, its text and its mark, removes the paragraph as the paragraph’s own delete() does. paragraph.getRange('Whole') is such a range. So:
- the document’s last paragraph and a table cell’s last only empty;
- a block content control’s only paragraph takes the control with it;
- a range a
searchorgetRangemade inside the paragraph, in an earliercontext.sync()that only read, throwsItemNotFound.
A range over several paragraphs removes each one it holds whole. It leaves those it holds only part of, unjoined, even when it takes the block content controls between them. body.getRange('Whole').delete() leaves one empty paragraph, as body.clear() does. The range you deleted reads empty where it started, or at the start of the next cell after emptying a cell’s last paragraph.
Tracked, every paragraph stays, its text and mark marked deleted, except the mark that ends the document or a cell. A range that ran through the document’s last mark throws ItemNotFound afterwards.
body.clear() and the body’s Replace keep the last paragraph
With tracking off, body.clear() and body.insertText(…, 'Replace') remove every paragraph but the document’s last. That one stays, emptied, and a Replace writes its new text there. body.paragraphs reached before lists the others, empty, and reading one of them throws ItemNotFound.
A range made before the edit then reads as follows:
- Made by
searchorgetRangein an earliercontext.sync()that only read, in a paragraph that went: throwsItemNotFound. The body’sgetRange('Start'),ContentandWholecount as such ranges. - Made the same way, in the last paragraph: keeps its offsets and reads what sits there. That is empty after
clear(), and the new text at its offsets after aReplace. - Any other range: collapses to the start of the paragraph that stays. After
clear(), it reads empty, and text inserted at it lands there. After aReplace, one from the last paragraph reads empty after the new text. - Any other range, from a paragraph that went, after a
Replace: reads the new text, with its start past the new text and its end before it.
So for that last range:
- text inserted at its
Startlands after the new text, and at itsEndbefore it; - a
Replacethrough it writes after the new text; - its
searchfinds nothing, and itsdeletetakes nothing; - its
getOoxmlthrowsGeneralException.
The body’s getRange('Whole') keeps the final mark and reads \r.
An insertText Replace across paragraphs deletes first
With tracking off, insertText(…, 'Replace') over a range across a paragraph mark first deletes as delete() does. Block content controls between, of any kind, go whole, and the paragraphs either side stay apart. It then writes its text where the range collapsed. Take a range from fore. in Before. to Aft in After., around a control or a paragraph. Replacing it with X leaves BeX and er..
Differs from Word for the web: through a span from a search hit made in a sync that only read, Word’s delete or Replace across a mark keeps a block control. The simulator handles such a span as one from a sync that wrote.
A paragraph mark the range ends just past stays. A range through a paragraph’s Whole, or to the next paragraph’s start, ends that way, and it leaves that paragraph empty. When the range holds the block content control that mark ends, from the control’s start, the control goes and the paragraph stays. Over one paragraph, such as a control’s only paragraph’s Whole, the text goes in its place.
With tracking on, the range’s text is marked deleted, and the new text goes by what the deletion crosses:
| The deletion | The new text goes |
|---|---|
| crosses a paragraph mark | after the deleted text, in the paragraph the range ends in, a table cell’s too |
| crosses a mark, but the range starts inside a paragraph’s text and ends just past an empty paragraph’s mark | before the deleted text |
crosses no mark, as for a range from fore. to the next paragraph’s start | before the deleted text, as within one paragraph |