diff --git a/package.json b/package.json index 7c334c5..9fee0d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "epitelete-html", - "version": "0.2.18", + "version": "0.2.19-beta.1", "description": "", "main": "dist/index.js", "directories": { @@ -27,7 +27,7 @@ "homepage": "https://github.com/unfoldingWord/epitelete-html#readme", "dependencies": { "@babel/core": "^7.17.10", - "epitelete": "^0.2.18", + "epitelete": "^0.2.19", "node-html-parser": "^5.3.3" }, "devDependencies": { diff --git a/src/helpers.js b/src/helpers.js index 3aa9fb2..9b8676d 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -1,7 +1,7 @@ const getAttributesHtml = (props) => Object.keys(props).reduce( (html, propKey) => - props[propKey] ? (html += `${propKey}="${props[propKey]}" `) : html, + props[propKey] ? (html += ` ${propKey}="${props[propKey]}"`) : html, "" ); @@ -13,26 +13,25 @@ const getDatasetHtml = (data) => ); const setClassList = classList => classList && Array.isArray(classList) - ? ` class="${classList.join(" ")}" ` - : ` class="${classList}" `; + ? ` class="${classList.join(" ")}"` + : ` class="${classList}"`; const setElementAttributes = ({ classList, id, - props, + attributes, dataset -}) => `${setClassList(classList)}${id && `id="${id}" `}${getAttributesHtml(props)}${getDatasetHtml(dataset)}`; - +}) => `${setClassList(classList)}${id && ` id="${id}"`}${getDatasetHtml(dataset)}${getAttributesHtml(attributes)}`; export const createElement = ( { tagName = "div", - classList = "", id = "", - props = {}, + classList = "", dataset = {}, - children = "" + children = "", + attributes = {}, } -) => `<${tagName || "div"}${setElementAttributes({classList,id,props,dataset})}>${children}`; +) => `<${tagName || "div"}${setElementAttributes({classList,id,attributes,dataset})}>${children}`; export const mapHtml = ({ props, htmlMap }) => { const { type, subtype } = props; @@ -50,18 +49,18 @@ export const mapHtml = ({ props, htmlMap }) => { const getClassList = (classList) => classList && (Array.isArray(classList) ? classList : [classList]); const result = maps.reduce((_result, map) => { const _map = map || {}; - const { classList, tagName, id } = (typeof _map === 'function') ? _map(props) : _map; - + const { classList, tagName, id, attributes } = (typeof _map === 'function') ? _map(props) : _map; _result.classList = _result.classList.concat(getClassList(classList) || []); + _result.attributes = {..._result.attributes, ...attributes}; if (!_result.tagName && tagName) _result.tagName = tagName; if (!_result.id && id) _result.id = id; return _result; - }, { classList: [], tagName: ""}); - + }, { classList: [], tagName: "", attributes:{}}); return { classList: result.classList.length ? [...new Set(result.classList)] : setDefaultClassList(type, subtype), tagName: result.tagName, - id: result.id + id: result.id, + attributes :result.attributes } } diff --git a/src/index.js b/src/index.js index 19bdbc3..2134905 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,7 @@ class EpiteleteHtml extends Epitelete { * @param {string} options.readPipeline - the name of the read pipeline */ async readHtml(bookCode, options = {}) { - return this._outputHtml(await this.readPerf(bookCode, options)); + return this._outputHtml(await this.readPerf(bookCode, {...options, cloning: false})); } /** @@ -40,7 +40,7 @@ class EpiteleteHtml extends Epitelete { * @param {string} options.readPipeline - the name of the read pipeline */ async undoHtml(bookCode, options = {}) { - return this._outputHtml(await this.undoPerf(bookCode, options)); + return this._outputHtml(await this.undoPerf(bookCode, {...options, cloning: false})); } /** @@ -50,7 +50,7 @@ class EpiteleteHtml extends Epitelete { * @param {string} options.readPipeline - the name of the read pipeline */ async redoHtml(bookCode, options = {}) { - return this._outputHtml(await this.redoPerf(bookCode, options)); + return this._outputHtml(await this.redoPerf(bookCode, {...options, cloning: false})); } /** @@ -65,7 +65,7 @@ class EpiteleteHtml extends Epitelete { async writeHtml(bookCode, sequenceId, perfHtml, options = {}) { const { writePipeline, readPipeline } = options; const perf = html2perf(perfHtml, sequenceId); - await this.writePerf(bookCode,sequenceId,perf, {writePipeline}); + await this.writePerf(bookCode,sequenceId,perf, {writePipeline, cloning: false}); return await this.readHtml(bookCode, {readPipeline}); } diff --git a/src/perf2html.js b/src/perf2html.js index f4d3f3e..5687643 100644 --- a/src/perf2html.js +++ b/src/perf2html.js @@ -41,7 +41,7 @@ function perf2html(perfDocument, sequenceId, htmlMap = defaultHtmlMap) { } = element; const attsProps = handleAtts(atts); const subtypes = handleSubtypeNS(subtype); - const { classList, tagName, id } = mapHtml({ props:{ type, subtype, atts, ...props }, htmlMap }); + const { classList, tagName, id, attributes } = mapHtml({ props:{ type, subtype, atts, ...props }, htmlMap }); const innerHtml = (content) => { const getters = { markHtml: () => ["chapter", "verses"].includes(subtype) ? atts.number : "", @@ -55,6 +55,7 @@ function perf2html(perfDocument, sequenceId, htmlMap = defaultHtmlMap) { tagName, id, classList, + attributes, dataset: { type, ...subtypes, ...attsProps, ...props}, children: innerHtml(content) }); @@ -64,11 +65,12 @@ function perf2html(perfDocument, sequenceId, htmlMap = defaultHtmlMap) { const { type, subtype, atts, content, ...props } = block; const attsProps = handleAtts(atts); const subtypes = handleSubtypeNS(subtype); - const { classList, tagName, id } = mapHtml({ props:{ type, subtype, atts, ...props }, htmlMap }); + const { classList, tagName, id, attributes } = mapHtml({ props:{ type, subtype, atts, ...props }, htmlMap }); return createElement({ tagName, id, classList, + attributes, dataset: { type, ...subtypes, ...attsProps, ...props }, children: contentChildren(content) }); @@ -76,12 +78,13 @@ function perf2html(perfDocument, sequenceId, htmlMap = defaultHtmlMap) { const sequenceHtml = (perfSequence, sequenceId) => { const { blocks, ...props } = perfSequence; - const { classList, tagName } = mapHtml({ props: {...props, subtype: "sequence"}, htmlMap }); + const { classList, tagName, attributes } = mapHtml({ props: {...props, subtype: "sequence"}, htmlMap }); return createElement({ tagName, id: `${sequenceId}`, classList: classList, dataset: props, + attributes, children: blocks?.reduce( (blocksHtml, block) => (blocksHtml += blockHtml(block)), "" diff --git a/test/code/htmlMap.cjs b/test/code/htmlMap.cjs index e8b1d81..9c0d15b 100644 --- a/test/code/htmlMap.cjs +++ b/test/code/htmlMap.cjs @@ -29,10 +29,13 @@ test(`Maps correctly with htmlMap (${testGroup})`, async function (t) { }, main: { "*": { - tagName: "custom2", + tagName: "custom2" }, }, paragraph: { + "*": { + attributes: {contenteditable: true} + }, "usfm:p": { tagName: "custom3" } diff --git a/yarn.lock b/yarn.lock index 9bda1ac..4c50969 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1775,10 +1775,10 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -epitelete@^0.2.18: - version "0.2.18" - resolved "https://registry.yarnpkg.com/epitelete/-/epitelete-0.2.18.tgz#76d0d08e79c7c33f19177254b85fc31c4ddffa29" - integrity sha512-xoJ5+X4M9zlq26D64pT1P7LGlritbdPPlS1SyC9AUacwocrhRmX25VeKLnDkW6GUG/+IJSsx/uik51cq5TB/MA== +epitelete@^0.2.19: + version "0.2.19" + resolved "https://registry.yarnpkg.com/epitelete/-/epitelete-0.2.19.tgz#a2cd4156cea874c9491f827a13303f498f0480a4" + integrity sha512-AcFE189Yda5aTC88wuRb4cceqQUYxvX/IH+ji1RwFvQ4C0OKc6c4i2Vkk0v+ET9hqEzvRa5HFPPAQiZCcYW6nQ== dependencies: "@babel/core" "^7.19.0" proskomma-json-tools "^0.6.6"