Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit bfcd923

Browse files
fix(docz-utils): fix closing tag detection in removeTags (#1696)
1 parent f836dcd commit bfcd923

File tree

6 files changed

+238
-15
lines changed

6 files changed

+238
-15
lines changed

core/docz-utils/.babelrc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"plugins": ["lodash"],
3+
"presets": [
4+
"@babel/preset-typescript",
5+
[
6+
"@babel/preset-env",
7+
{
8+
"targets": {
9+
"node": "current"
10+
}
11+
}
12+
]
13+
]
14+
}

core/docz-utils/__tests__/jsx.test.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { removeTags } from '../src/jsx'
2+
3+
describe('removeTags', () => {
4+
test('removes outer JSX tag', () => {
5+
expect(
6+
removeTags(`
7+
<Playground>
8+
<div>Some text</div>
9+
<p>Other text</p>
10+
</Playground>
11+
`)
12+
).toMatchInlineSnapshot(`
13+
"
14+
<div>Some text</div>
15+
<p>Other text</p>
16+
"
17+
`)
18+
})
19+
20+
test('works when the closing tag is repeated in a comment', () => {
21+
expect(
22+
removeTags(`
23+
<Playground>
24+
{/* </Playground> */}
25+
<div>Some text</div>
26+
</Playground>
27+
`)
28+
).toMatchInlineSnapshot(`
29+
"
30+
{/* </Playground> */}
31+
<div>Some text</div>
32+
"
33+
`)
34+
})
35+
})

core/docz-utils/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
"build": "trash lib && cross-env NODE_ENV=production rollup -c",
2222
"fix": "yarn lint --fix",
2323
"lint": "eslint . --ext mdx,ts,tsx",
24-
"precommit": "lint-staged"
24+
"precommit": "lint-staged",
25+
"test": "yarn jest"
2526
},
2627
"dependencies": {
27-
"@babel/generator": "^7.5.5",
28-
"@babel/parser": "^7.5.5",
29-
"@babel/traverse": "^7.5.5",
28+
"@babel/generator": "^7.16.8",
29+
"@babel/parser": "^7.16.12",
30+
"@babel/traverse": "^7.16.10",
3031
"art-template": "^4.13.2",
3132
"fs-extra": "^8.1.0",
3233
"humanize-string": "^2.1.0",

core/docz-utils/src/ast.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import * as parser from '@babel/parser'
22
import traverse from '@babel/traverse'
33

44
type Condition = (path: any) => boolean
5-
type Predicate = (path: any) => any
5+
type Predicate<Value> = (path: any) => Value
66

7-
export const valueFromTraverse = (
7+
export const valueFromTraverse = <Value = any>(
88
condition: Condition,
9-
predicate: Predicate = p => p
10-
) => (code: string) => {
11-
let value = ''
9+
predicate: Predicate<Value> = p => p
10+
) => (code: string): Value | '' => {
11+
let value: Value | '' = ''
1212
const ast = parser.parse(code, { plugins: ['jsx'] })
1313

1414
traverse(ast, {

core/docz-utils/src/jsx.ts

+15-5
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,29 @@ import * as jsxUtils from 'jsx-ast-utils'
22
import strip from 'strip-indent'
33
import escapeJS from 'js-string-escape'
44

5-
import { valueFromTraverse, codeFromNode } from './ast'
5+
import { valueFromTraverse } from './ast'
66

77
export const propFromElement = (prop: string) =>
88
valueFromTraverse(
99
p => p.isJSXOpeningElement(),
1010
p => jsxUtils.getPropValue(jsxUtils.getProp(p.node.attributes, prop))
1111
)
1212

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

17-
return code.replace(open(code), '').replace(close(code), '')
25+
export const removeTags = (code: string) => {
26+
const [start, end] = getTagContentsRange(code) || [0, 0]
27+
return code.slice(start, end)
1828
}
1929

2030
export const sanitizeCode = (code: string) => {

0 commit comments

Comments
 (0)