rittenhop-dev/versions/5.94.2/node_modules/@tryghost/kg-clean-basic-html/cjs/clean-basic-html.js
2024-09-23 19:40:12 -04:00

97 lines
3.3 KiB
JavaScript

'use strict';
/**
* Removes any <code> wrappers around replacement strings {foo}
* Example input: <code><span>{foo}</span></code>
* Example output: <span>{foo}</span>
* @param {string} html
* @returns {string}
*/
function removeCodeWrappers(html) {
return html.replace(/<code\b[^>]*>((.*?){.*?}(.*?))<\/code>/gi, '$1');
}
/**
* Parses an html string and returns a cleaned version
* @param {string} html
* @param {Object} _options
* @param {boolean} [_options.allowBr] - if true, <br> tags will be kept
* @param {boolean} [_options.firstChildInnerContent] - if true, only the innerHTML of the first element will be returned
* @param {boolean} [_options.removeCodeWrappers] - if true, <code> wrappers around replacement strings {foo} will be removed
* @returns {string}
*/
function cleanBasicHtml(html = '', _options = {}) {
const defaults = {};
const options = Object.assign({}, defaults, _options);
if (!options.createDocument) {
const Parser = (typeof DOMParser !== 'undefined' && DOMParser) || (typeof window !== 'undefined' && window.DOMParser);
if (!Parser) {
// eslint-disable-next-line ghost/ghost-custom/no-native-error
throw new Error('cleanBasicHtml() must be passed a `createDocument` function as an option when used in a non-browser environment');
}
options.createDocument = function (docHtml) {
const parser = new Parser();
return parser.parseFromString(docHtml, 'text/html');
};
}
let cleanHtml = html;
if (!options.allowBr || cleanHtml === '<br>') {
cleanHtml = cleanHtml
.replace(/<br\s?\/?>/g, ' ');
}
if (options.removeCodeWrappers) {
cleanHtml = removeCodeWrappers(cleanHtml);
}
cleanHtml = cleanHtml
.replace(/(\s|&nbsp;){2,}/g, ' ')
.trim()
.replace(/^&nbsp;|&nbsp$/g, '')
.trim();
// remove any elements that have a blank textContent
if (cleanHtml) {
let doc = options.createDocument(cleanHtml);
// don't analyze the document if it's empty (can result in storing <br> tags if allowed)
if (doc.body.textContent === '') {
return null;
}
doc.body.querySelectorAll('*').forEach((element) => {
// Treat Zero Width Non-Joiner characters as spaces
if (!element.textContent.trim().replace(/\u200c+/g, '')) {
if (options.allowBr && element.tagName === 'BR') {
// keep it
return;
}
if (options.allowBr && element.querySelector('br')) {
return element.replaceWith(doc.createElement('br'));
}
if (element.textContent.length > 0) {
// keep a single space to avoid collapsing spaces
let space = doc.createTextNode(' ');
return element.replaceWith(space);
}
return element.remove();
}
});
if (options.firstChildInnerContent && doc.body.firstElementChild) {
cleanHtml = doc.body.firstElementChild.innerHTML.trim();
} else {
cleanHtml = doc.body.innerHTML.trim();
}
}
return cleanHtml;
}
module.exports = cleanBasicHtml;