Skip to content

Commit

Permalink
feat(slatetodom): add encodeBreakingEntities option (thompsonsj#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
thompsonsj authored and steven-pribilinskiy committed May 3, 2023
1 parent d0090ca commit e9040fa
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
65 changes: 64 additions & 1 deletion __tests__/serializers/slateToHtml/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChildNode, Element } from 'domhandler'
import { Element } from 'domhandler'
import { slateToHtml, slateToDomConfig } from '../../../src'

describe('slateToHtml expected behaviour', () => {
Expand All @@ -17,6 +17,69 @@ describe('slateToHtml expected behaviour', () => {
expect(slateToHtml(slate)).toEqual(html)
})

/**
* @see https://www.w3.org/International/questions/qa-escapes#use
*/
it('encodes `breaking` HTML entities', () => {
const html = `<p>2 &gt; 1 but is &lt; 3 &amp; it can break HTML</p>`
const slate = [
{
children: [
{
text: "2 > 1 but is < 3 & it can break HTML",
},
],
type: 'p',
},
]
expect(slateToHtml(slate)).toEqual(html)
})

it('encodes `non breaking` HTML entities', () => {
const html = `<p>The company&#x2019;s priority is &apos;inside sales&apos; and changing the spelling of cafe to caf&#xe9;.</p>`
const slate = [
{
children: [
{
text: "The company’s priority is 'inside sales' and changing the spelling of cafe to café.",
},
],
type: 'p',
},
]
expect(slateToHtml(slate)).toEqual(html)
})

it('encodes `breaking` HTML entities only if option is active', () => {
const html = `<p>2 &gt; 1 but is &lt; 3 &amp; it can break HTML</p><p>The company’s priority is 'inside sales' and changing the spelling of cafe to café.</p>`
const slate = [
{
children: [
{
text: "2 > 1 but is < 3 & it can break HTML",
},
],
type: 'p',
},
{
children: [
{
text: "The company’s priority is 'inside sales' and changing the spelling of cafe to café.",
},
],
type: 'p',
},
]
expect(slateToHtml(
slate,
{
...slateToDomConfig,
encodeEntities: false,
alwaysEncodeBreakingEntities: true,
}
)).toEqual(html)
})

it('does not encode HTML entities with the appropriate option', () => {
const html = `<h1>What's Heading 1</h1>`
const slate = [
Expand Down
1 change: 1 addition & 0 deletions src/config/slateToDom/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const config: Config = {
},
},
encodeEntities: true,
alwaysEncodeBreakingEntities: false,
alwaysEncodeCodeEntities: false,
convertLineBreakToBr: false,
}
1 change: 1 addition & 0 deletions src/config/slateToDom/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface Config {
elementTransforms: ElementTagTransform
defaultTag?: string
encodeEntities?: boolean
alwaysEncodeBreakingEntities?: boolean
alwaysEncodeCodeEntities?: boolean
convertLineBreakToBr?: boolean
}
4 changes: 2 additions & 2 deletions src/serializers/slateToHtml/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Text as SlateText } from 'slate'

import { config as defaultConfig } from '../../config/slateToDom/default'
import { nestedMarkElements } from '../../utilities/domhandler'
import { getNested, isEmptyObject, styleToString } from '../../utilities'
import { getNested, isEmptyObject, styleToString, encodeBreakingEntities } from '../../utilities'
import { SlateToDomConfig } from '../..'
import { isBlock } from '../blocks'

Expand All @@ -30,7 +30,7 @@ export const slateToDom: SlateToDom = (node: any[], config = defaultConfig) => {

const slateNodeToHtml = (node: any, config = defaultConfig, isLastNodeInDocument = false) => {
if (SlateText.isText(node)) {
const str = node.text
const str = (config.alwaysEncodeBreakingEntities && config.encodeEntities === false) ? encodeBreakingEntities(node.text) : node.text

// convert line breaks to br tags
const strLines = config.convertLineBreakToBr ? str.split('\n') : [str]
Expand Down
20 changes: 20 additions & 0 deletions src/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,23 @@ export const removeEmpty = (obj: {}): {} => {
export const getNested = (obj: any, ...args: string[]) => {
return args.reduce((o, level) => o && o[level], obj)
}

export const encodeBreakingEntities = (str: string) => {
const swapChar = (charToSwap: string) => { // that swaps characters to HTML entities
switch(charToSwap){
case "&":
return "&amp;"
case "<":
return "&lt;"
case ">":
return "&gt;"
default:
return charToSwap
}
}
str = str.replace(/[&<>]/g, function(match){
return swapChar(match)
})

return str
}

0 comments on commit e9040fa

Please sign in to comment.