From 3d462180da7a2e705b4f9976d6efbdbc06dfc94e Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 11 Oct 2022 19:52:03 +0200 Subject: [PATCH] optimize render of textOnly snippets (#31581) Co-authored-by: Robert Sese <734194+rsese@users.noreply.github.com> --- lib/render-content/renderContent.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/render-content/renderContent.js b/lib/render-content/renderContent.js index a5db3a2ddb..c22ace3d2d 100644 --- a/lib/render-content/renderContent.js +++ b/lib/render-content/renderContent.js @@ -1,6 +1,6 @@ import liquid from './liquid.js' import cheerio from 'cheerio' -import { encode } from 'html-entities' +import { encode, decode } from 'html-entities' import stripHtmlComments from 'strip-html-comments' import createProcessor from './create-processor.js' @@ -52,17 +52,21 @@ async function renderContent(template = '', context = {}, options = {}) { let html = vFile.toString() // Remove unwanted newlines (which appear as spaces) from inline tags inside tables - if (html.includes('')) html = removeNewlinesFromInlineTags(html) + if (html.includes('
')) { + html = removeNewlinesFromInlineTags(html) + } if (options.textOnly) { - html = cheerio.load(html).text().trim() + html = fastTextOnly(html) } if (options.cheerioObject) { return cheerio.load(html, { xmlMode: true }) } - if (options.encodeEntities) html = encode(html) + if (options.encodeEntities) { + html = encode(html) + } return html.trim() } catch (error) { @@ -85,6 +89,21 @@ function removeNewlinesFromInlineTags(html) { return $('body').html() } +// Given a piece of HTML return it without HTML. E.g. +// `

Foo & bar

` becomes `Foo & bar` +// and `A link and code` becomes `A link and code`. +// Take advantage of the subtle fact that a lot of the times, the html value +// we get here is a single line that starts with `

` and ends with `

` +// and contains no longer HTML tags. +function fastTextOnly(html) { + if (!html) return '' + if (html.startsWith('

') && html.endsWith('

')) { + const middle = html.slice(3, -4) + if (!middle.includes('<')) return decode(middle.trim()) + } + return cheerio.load(html, { xmlMode: true }).text().trim() +} + renderContent.liquid = liquid export default renderContent