yoastseo
Version:
Yoast client-side content analysis
131 lines (123 loc) • 4.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.filterShortcodesFromHTML = exports.default = exports.createShortcodeTagsRegex = void 0;
/**
* Creates a regex to filter shortcodes from HTML.
* @param {string[]} shortcodeTags The tags of the shortcodes to filter.
* @returns {RegExp} The regex to recognize the shortcodes.
*/
const createShortcodeTagsRegex = shortcodeTags => {
const shortcodeTagsRegexString = `\\[\\/?(${shortcodeTags.join("|")})[^\\]]*\\]`;
return new RegExp(shortcodeTagsRegexString, "g");
};
/**
* Filters shortcodes from HTML string.
* @param {string} html The HTML to filter.
* @param {string[]} shortcodeTags The tags of the shortcodes to filter.
* @returns {string} The filtered HTML.
*/
exports.createShortcodeTagsRegex = createShortcodeTagsRegex;
const filterShortcodesFromHTML = (html, shortcodeTags) => {
if (!shortcodeTags || shortcodeTags.length === 0) {
return html;
}
const shortcodeTagsRegex = createShortcodeTagsRegex(shortcodeTags);
return html.replace(shortcodeTagsRegex, "");
};
/**
* Checks if a token is part of an opening shortcode.
* @param {Token[]} tokens The tokens to check.
* @param {number} index The index of the current token.
* @returns {boolean} Whether the token is part of an opening shortcode.
*/
exports.filterShortcodesFromHTML = filterShortcodesFromHTML;
const tokenIsPartOfOpeningShortcode = (tokens, index) => {
return tokens[index - 1] && tokens[index - 1].text === "[";
};
/**
* Checks if a token is part of a closing shortcode.
* @param {Token[]} tokens The tokens to check.
* @param {number} index The index of the current token.
* @returns {boolean} Whether the token is part of a closing shortcode.
*/
const tokenIsPartOfClosingShortcode = (tokens, index) => {
return tokens[index - 1] && tokens[index - 1].text === "/" && tokens[index - 2] && tokens[index - 2].text === "[";
};
/**
* Checks if a token is part of a shortcode.
* @param {Token[]} tokens The tokens to check.
* @param {number} index The index of the current token.
* @param {string[]} shortcodeTags An array of active shortcode tags.
* @param {boolean} encounteredClosingBracket Whether a closing bracket has been encountered (while looping backwards through the tokens).
* @returns {boolean} Whether the token is part of a shortcode.
*/
const tokenIsShortcode = (tokens, index, shortcodeTags, encounteredClosingBracket) => {
return encounteredClosingBracket && shortcodeTags.includes(tokens[index].text) && (tokenIsPartOfOpeningShortcode(tokens, index) || tokenIsPartOfClosingShortcode(tokens, index));
};
/**
* Filters shortcodes from a sentence.
* @param {Sentence} sentence The sentence to filter.
* @param {string[]} shortcodeTags The tags of the shortcodes to filter.
* @param {RegExp} shortcodeTagsRegex The regex to filter the shortcodes.
* @returns {void}
*
*/
const filterShortcodesFromSentence = (sentence, shortcodeTags, shortcodeTagsRegex) => {
const tokens = sentence.tokens;
let encounteredClosingBracket = false;
// traverse through tokens backwards
for (let i = tokens.length - 1; i >= 0; i--) {
if (tokens[i].text === "]") {
encounteredClosingBracket = true;
}
if (tokenIsShortcode(tokens, i, shortcodeTags, encounteredClosingBracket)) {
while (tokens[i].text !== "]") {
tokens.splice(i, 1);
}
tokens.splice(i, 1);
encounteredClosingBracket = false;
while (tokens[i - 1] && "[/".includes(tokens[i - 1].text)) {
tokens.splice(i - 1, 1);
i--;
}
}
}
sentence.tokens = tokens;
sentence.text = sentence.text.replace(shortcodeTagsRegex, "");
};
/**
* A recursive function that filters shortcodes from sentences.
* @param {Node} tree The tree to filter.
* @param {string[]} shortcodeTags The tags of the shortcodes to filter.
* @param {RegExp} shortcodeTagsRegex The regex to filter the shortcodes.
* @returns {void}
*/
const filterShortcodesFromSentences = (tree, shortcodeTags, shortcodeTagsRegex) => {
if (tree.sentences) {
tree.sentences.forEach(sentence => {
filterShortcodesFromSentence(sentence, shortcodeTags, shortcodeTagsRegex);
});
}
if (tree.childNodes) {
tree.childNodes.forEach(childNode => {
filterShortcodesFromSentences(childNode, shortcodeTags, shortcodeTagsRegex);
});
}
};
/**
* Filters shortcodes from the tree.
* @param {Node} tree The tree to filter.
* @param {string[]} shortcodeTags The tags of the shortcodes to filter.
* @returns {void}
*/
const filterShortcodesFromTree = (tree, shortcodeTags) => {
if (!shortcodeTags || shortcodeTags.length === 0) {
return;
}
const shortcodeTagsRegex = createShortcodeTagsRegex(shortcodeTags);
filterShortcodesFromSentences(tree, shortcodeTags, shortcodeTagsRegex);
};
var _default = exports.default = filterShortcodesFromTree;
//# sourceMappingURL=filterShortcodesFromTree.js.map