in source/nodejs/adaptivecards/src/card-elements.ts [1070:1259]
protected internalRender(): HTMLElement | undefined {
this._processedText = undefined;
if (this.text) {
const preProcessedText = this.preProcessPropertyValue(BaseTextBlock.textProperty);
const hostConfig = this.hostConfig;
let element: HTMLElement;
if (this.forElementId) {
const labelElement = document.createElement("label");
labelElement.htmlFor = this.forElementId;
element = labelElement;
} else {
element = document.createElement("div");
}
element.classList.add(hostConfig.makeCssClassName("ac-textBlock"));
element.style.overflow = "hidden";
this.applyStylesTo(element);
if (this.style === "heading") {
element.setAttribute("role", "heading");
const headingLevel = this.hostConfig.textBlock.headingLevel;
if (headingLevel !== undefined && headingLevel > 0) {
element.setAttribute("aria-level", headingLevel.toString());
}
}
if (this.selectAction && hostConfig.supportsInteractivity) {
element.onclick = (e) => {
if (this.selectAction && this.selectAction.isEnabled) {
e.preventDefault();
e.cancelBubble = true;
this.selectAction.execute();
}
};
this.selectAction.setupElementForAccessibility(element);
if (this.selectAction.isEnabled) {
element.classList.add(hostConfig.makeCssClassName("ac-selectable"));
}
}
if (!this._processedText) {
this._treatAsPlainText = true;
let formattedText = TextFormatters.formatText(this.lang, preProcessedText);
if (this.useMarkdown && formattedText) {
if (GlobalSettings.allowMarkForTextHighlighting) {
formattedText = formattedText
.replace(/<mark>/g, "===")
.replace(/<\/mark>/g, "/==/");
}
const markdownProcessingResult = AdaptiveCard.applyMarkdown(formattedText);
if (
markdownProcessingResult.didProcess &&
markdownProcessingResult.outputHtml
) {
this._processedText = markdownProcessingResult.outputHtml;
this._treatAsPlainText = false;
// Only process <mark> tag if markdown processing was applied because
// markdown processing is also responsible for sanitizing the input string
if (GlobalSettings.allowMarkForTextHighlighting && this._processedText) {
let markStyle: string = "";
const effectiveStyle = this.getEffectiveStyleDefinition();
if (effectiveStyle.highlightBackgroundColor) {
markStyle +=
"background-color: " +
effectiveStyle.highlightBackgroundColor +
";";
}
if (effectiveStyle.highlightForegroundColor) {
markStyle +=
"color: " + effectiveStyle.highlightForegroundColor + ";";
}
if (markStyle) {
markStyle = 'style="' + markStyle + '"';
}
this._processedText = this._processedText
.replace(/===/g, "<mark " + markStyle + ">")
.replace(/\/==\//g, "</mark>");
}
} else {
this._processedText = formattedText;
this._treatAsPlainText = true;
}
} else {
this._processedText = formattedText;
this._treatAsPlainText = true;
}
}
if (!this._processedText) {
this._processedText = "";
}
if (this._treatAsPlainText) {
element.innerText = this._processedText;
} else {
element.innerHTML = this._processedText;
}
if (element.firstElementChild instanceof HTMLElement) {
const firstElementChild = element.firstElementChild;
firstElementChild.style.marginTop = "0px";
firstElementChild.style.width = "100%";
if (!this.wrap) {
firstElementChild.style.overflow = "hidden";
firstElementChild.style.textOverflow = "ellipsis";
}
}
if (element.lastElementChild instanceof HTMLElement) {
element.lastElementChild.style.marginBottom = "0px";
}
const anchors = element.getElementsByTagName("a");
for (const anchor of Array.from(anchors)) {
anchor.classList.add(hostConfig.makeCssClassName("ac-anchor"));
anchor.target = "_blank";
anchor.onclick = (e: MouseEvent) => {
if (raiseAnchorClickedEvent(this, anchor, e)) {
e.preventDefault();
e.cancelBubble = true;
}
};
anchor.oncontextmenu = (e: MouseEvent) => {
if (raiseAnchorClickedEvent(this, anchor, e)) {
e.preventDefault();
e.cancelBubble = true;
return false;
}
return true;
};
}
if (this.wrap) {
element.style.wordWrap = "break-word";
if (this.maxLines && this.maxLines > 0) {
element.style.overflow = "hidden";
if (Utils.isInternetExplorer() || !GlobalSettings.useWebkitLineClamp) {
element.style.maxHeight = this._computedLineHeight * this.maxLines + "px";
} else {
// While non standard, --webkit-line-clamp works in every browser (except IE)
// and is a great solution to support the maxLines feature with ellipsis
// truncation. With --webkit-line-clamp there is need to use explicit line heights
element.style.removeProperty("line-height");
element.style.display = "-webkit-box";
element.style.webkitBoxOrient = "vertical";
element.style.webkitLineClamp = this.maxLines.toString();
}
}
} else {
element.style.whiteSpace = "nowrap";
element.style.textOverflow = "ellipsis";
}
if (
GlobalSettings.useAdvancedTextBlockTruncation ||
GlobalSettings.useAdvancedCardBottomTruncation
) {
this._originalInnerHtml = element.innerHTML;
}
return element;
} else {
return undefined;
}
}