mediawiki-extensions-Popups/src/formatter.js
Ed Sanders 9b8b402cb1 Update jsdoc to 4 and use jsdoc-wmf-theme
Change-Id: Idb33efa5b714826550917397d4de1f2e5087f1bd
2024-04-29 19:17:17 +01:00

75 lines
2.1 KiB
JavaScript

/**
* @module formatter
*/
/**
* Improves the plain text extracts
*
* @param {string} plainTextExtract
* @param {string} title
* @return {Array}
*/
export function formatPlainTextExtract( plainTextExtract, title ) {
let extract = plainTextExtract;
if ( plainTextExtract === undefined ) {
return [];
}
// After cleaning the extract it may have been blanked
if ( extract.length === 0 ) {
return [];
}
extract = makeTitleInExtractBold( extract, title );
return extract;
}
/**
* Converts the extract into a list of elements, which correspond to fragments
* of the extract. Fragments that match the title verbatim are wrapped in a
* `<b>` element.
*
* Using the bolded elements of the extract of the page directly is covered by
* [T141651](https://phabricator.wikimedia.org/T141651).
*
* Extracted from `mw.popups.renderer.article.getProcessedElements`.
*
* @param {string} extract
* @param {string} title
* @return {Array} A set of HTML Elements
*/
function makeTitleInExtractBold( extract, title ) {
const elements = [],
boldIdentifier = `<bi-${ Math.random() }>`,
snip = `<snip-${ Math.random() }>`;
title = title.replace( /\s+/g, ' ' ).trim(); // Remove extra white spaces
const escapedTitle = mw.util.escapeRegExp( title );
// eslint-disable-next-line security/detect-non-literal-regexp
const regExp = new RegExp( `(^|\\s)(${ escapedTitle })(|$)`, 'i' );
// Remove text in parentheses along with the parentheses
extract = extract.replace( /\s+/, ' ' ); // Remove extra white spaces
// Make title bold in the extract text
// As the extract is html escaped there can be no such string in it
// Also, the title is escaped of RegExp elements thus can't have "*"
extract = extract.replace(
regExp,
`$1${ snip }${ boldIdentifier }$2${ snip }$3`
);
extract = extract.split( snip );
extract.forEach( ( part ) => {
if ( part.indexOf( boldIdentifier ) === 0 ) {
const highlightNode = document.createElement( 'b' );
highlightNode.textContent = part.slice( boldIdentifier.length );
elements.push( highlightNode );
} else {
elements.push( document.createTextNode( part ) );
}
} );
return elements;
}