I have the following scenario Word:
font.color
, font.name
, font.size
etc. which is read from the selection in which the content control is being inserted)The issue is, when content controls are updated, the current document selection can be anywhere but I need to be sure they re-apply the same style as the text adjacent to them.
Is there a way inside Office.js to get the range adjacent to a content control? That way I could read it's style and apply it to the content control.
My assumption is that you want the text immediately preceding the content control. Unfortunately, the object model doesn't provide an equivalent to getNextTextRange
for going "backwards" (getPreviousTextRange
).
It can be done, but it's a bit round-about. Following is my Script Lab sample code:
async function
getAdjacentRange() {
await Word.run(async (context) => {
var ccs = context.document.contentControls;
ccs.load("items");
await context.sync();
console.log("Nr cc: " + ccs.items.length);
let cc = ccs.items[0];
//The starting point of the content control so that
//the range can be extended backwards
let ccRange = cc.getRange("Start");
let ccParas = ccRange.paragraphs; cc.load("text,range,paragraphs");
let ccPara = ccParas.getFirst();
ccParas.load("items")
//The content control must be in a paragraph: get that paragraph's
//starting point so that the range can be extended in that direction
let paraRange = ccPara.getRange("Start");
let rng = paraRange.expandTo(ccRange);
//Get the words in the range of the start of the paragraph to the
//start of the content control in order to get the last one before the content control
let em = [" "];
let words = rng.getTextRanges(em, true);
words.load("items");
await context.sync();
let nrWords = words.items.length;
//minus 2 to get second to last word since last word is directly adjacent to content control (no space)
let lastWord = words.items[nrWords - 2];
//Now get the content from the end of the second to last word to
//the start of the content control, which will be the last word
let word2BeforeCC = lastWord.getRange("End");
let wordBeforeCC = word2BeforeCC.expandTo(ccRange);
wordBeforeCC.load("text");
await context.sync();
console.log(cc.text + "/ Word before the content control: " + wordBeforeCC.text + " / nr Words: " + nrWords);
})
}
Code for the case when there is a space between the last word and the content control:
async function
getAdjacentRange() {
await Word.run(async (context) => {
var ccs = context.document.contentControls;
ccs.load("items");
await context.sync();
let cc = ccs.getFirstOrNullObject();
//The starting point of the content control so that
//the range can be extended backwards
let ccRange = cc.getRange("Start");
//The content control must be in a paragraph, so get that paragraph's
//starting point so that the range can be extended in that direction
let ccParas = ccRange.paragraphs; cc.load("text,range,paragraphs");
let ccPara = ccParas.getFirst();
ccParas.load("items")
let paraRange = ccPara.getRange("Start");
let rng = paraRange.expandTo(ccRange);
//Now it's possible to get the last word in the extended range
let em = [" "];
console.log(em.length.toString());
let words = rng.getTextRanges(em, true);
words.load("items");
await context.sync();
let nrWords = words.items.length;
//returns a Range object, from which you can get the style info
let lastWord = words.items[nrWords - 1];
await context.sync();
console.log(cc.text + "/" + "nr Words: " + nrWords + "last word: " + lastWord.text);
})
}