From dacfc42c7dbf996f81b6c143e715b4ccb532f68d Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 5 Aug 2021 12:54:03 +0200 Subject: [PATCH] Add DOMParser for HTML --- src/parser/config/config.js | 16 +++++++- src/parser/model/BrowserParserHtml.js | 57 ++++++++++++++++----------- src/parser/model/ParserHtml.js | 8 ++-- 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/parser/config/config.js b/src/parser/config/config.js index d33ad56f8..b6d08fec6 100644 --- a/src/parser/config/config.js +++ b/src/parser/config/config.js @@ -4,6 +4,20 @@ export default { // Custom CSS parser parserCss: null, - // Custom HTML parser + // Default DOMParser mime type + // @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + htmlType: 'text/html', + + // Custom function which tells which root Element to extract + // from the DOMParser.parseFromString result + // @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString + // @example + // // with htmlType as 'text/html' the function will be (default): + // htmlResult: (doc) => doc.body, + // // in case of `application/xml` + // htmlResult: (doc) => doc, + htmlResult: null, + + // TODO: Custom HTML parser parserHtml: null }; diff --git a/src/parser/model/BrowserParserHtml.js b/src/parser/model/BrowserParserHtml.js index 3a338908f..4c2c16871 100644 --- a/src/parser/model/BrowserParserHtml.js +++ b/src/parser/model/BrowserParserHtml.js @@ -1,4 +1,34 @@ -// PoC +export default (str, config = {}) => { + const { htmlResult } = config; + const parser = new DOMParser(); + const doc = parser.parseFromString(str, config.htmlType); + + return htmlResult ? htmlResult(doc, str) : doc.body; +}; + +/** + * POC, custom html parser specs + * Parse an HTML string to an array of nodes + * example + * parse(`
Hello
World example`) + * // result + * [ + * { + * tagName: 'div', + * attributes: { class: 'mycls', 'data-test': '' }, + * childNodes: ['Hello'], + * },{ + * tagName: 'span', + * childNodes: [ + * 'World ', + * { + * tagName: 'b', + * childNodes: ['example'], + * } + * ], + * } + * ] + * export const parseNodes = nodes => { const result = []; @@ -44,29 +74,7 @@ export const parseNode = el => { }; }; -/** - * Parse an HTML string to an array of nodes - * @example - * parse(`
Hello
World example`) - * // result - * [ - * { - * tagName: 'div', - * attributes: { class: 'mycls', 'data-test': '' }, - * childNodes: ['Hello'], - * },{ - * tagName: 'span', - * childNodes: [ - * 'World ', - * { - * tagName: 'b', - * childNodes: ['example'], - * } - * ], - * } - * ] - */ -export default (str, config) => { +export default (str, config = {}) => { const result = []; const el = document.createElement('div'); el.innerHTML = str; @@ -79,3 +87,4 @@ export default (str, config) => { return result; }; + */ diff --git a/src/parser/model/ParserHtml.js b/src/parser/model/ParserHtml.js index 654031e73..036ca8512 100644 --- a/src/parser/model/ParserHtml.js +++ b/src/parser/model/ParserHtml.js @@ -1,4 +1,5 @@ import { each, isString } from 'underscore'; +import BrowserParserHtml from './BrowserParserHtml'; export default config => { var TEXT_NODE = 'span'; @@ -275,15 +276,14 @@ export default config => { */ parse(str, parserCss) { const { em } = c; - const config = (em && em.get('Config')) || {}; + const conf = (em && em.get('Config')) || {}; const res = { html: '', css: '' }; - const el = document.createElement('div'); - el.innerHTML = str; + const el = BrowserParserHtml(str, config); const scripts = el.querySelectorAll('script'); let i = scripts.length; // Remove all scripts - if (!config.allowScripts) { + if (!conf.allowScripts) { while (i--) scripts[i].parentNode.removeChild(scripts[i]); }