Skip to content

Commit

Permalink
fix(docz-utils): fix closing tag detection in removeTags (#1696)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Feb 7, 2022
1 parent f836dcd commit bfcd923
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 15 deletions.
14 changes: 14 additions & 0 deletions core/docz-utils/.babelrc
@@ -0,0 +1,14 @@
{
"plugins": ["lodash"],
"presets": [
"@babel/preset-typescript",
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
35 changes: 35 additions & 0 deletions core/docz-utils/__tests__/jsx.test.ts
@@ -0,0 +1,35 @@
import { removeTags } from '../src/jsx'

describe('removeTags', () => {
test('removes outer JSX tag', () => {
expect(
removeTags(`
<Playground>
<div>Some text</div>
<p>Other text</p>
</Playground>
`)
).toMatchInlineSnapshot(`
"
<div>Some text</div>
<p>Other text</p>
"
`)
})

test('works when the closing tag is repeated in a comment', () => {
expect(
removeTags(`
<Playground>
{/* </Playground> */}
<div>Some text</div>
</Playground>
`)
).toMatchInlineSnapshot(`
"
{/* </Playground> */}
<div>Some text</div>
"
`)
})
})
9 changes: 5 additions & 4 deletions core/docz-utils/package.json
Expand Up @@ -21,12 +21,13 @@
"build": "trash lib && cross-env NODE_ENV=production rollup -c",
"fix": "yarn lint --fix",
"lint": "eslint . --ext mdx,ts,tsx",
"precommit": "lint-staged"
"precommit": "lint-staged",
"test": "yarn jest"
},
"dependencies": {
"@babel/generator": "^7.5.5",
"@babel/parser": "^7.5.5",
"@babel/traverse": "^7.5.5",
"@babel/generator": "^7.16.8",
"@babel/parser": "^7.16.12",
"@babel/traverse": "^7.16.10",
"art-template": "^4.13.2",
"fs-extra": "^8.1.0",
"humanize-string": "^2.1.0",
Expand Down
10 changes: 5 additions & 5 deletions core/docz-utils/src/ast.ts
Expand Up @@ -2,13 +2,13 @@ import * as parser from '@babel/parser'
import traverse from '@babel/traverse'

type Condition = (path: any) => boolean
type Predicate = (path: any) => any
type Predicate<Value> = (path: any) => Value

export const valueFromTraverse = (
export const valueFromTraverse = <Value = any>(
condition: Condition,
predicate: Predicate = p => p
) => (code: string) => {
let value = ''
predicate: Predicate<Value> = p => p
) => (code: string): Value | '' => {
let value: Value | '' = ''
const ast = parser.parse(code, { plugins: ['jsx'] })

traverse(ast, {
Expand Down
20 changes: 15 additions & 5 deletions core/docz-utils/src/jsx.ts
Expand Up @@ -2,19 +2,29 @@ import * as jsxUtils from 'jsx-ast-utils'
import strip from 'strip-indent'
import escapeJS from 'js-string-escape'

import { valueFromTraverse, codeFromNode } from './ast'
import { valueFromTraverse } from './ast'

export const propFromElement = (prop: string) =>
valueFromTraverse(
p => p.isJSXOpeningElement(),
p => jsxUtils.getPropValue(jsxUtils.getProp(p.node.attributes, prop))
)

export const removeTags = (code: string) => {
const open = codeFromNode(p => p.isJSXOpeningElement())
const close = codeFromNode(p => p.isJSXClosingElement())
const getTagContentsRange = valueFromTraverse<[number, number] | null>(
p => p.isJSXElement(),
({ node }) => {
if (!node.closingElement) {
// if the JSX element doesn't have a closingElement, it's because it's self-closed
// and thus does not have any content: <Playground />
return null
}
return [node.openingElement.end, node.closingElement.start]
}
)

return code.replace(open(code), '').replace(close(code), '')
export const removeTags = (code: string) => {
const [start, end] = getTagContentsRange(code) || [0, 0]
return code.slice(start, end)
}

export const sanitizeCode = (code: string) => {
Expand Down

0 comments on commit bfcd923

Please sign in to comment.