diff --git a/src/javascript.ts b/src/javascript.ts index ccc9398..111136f 100644 --- a/src/javascript.ts +++ b/src/javascript.ts @@ -42,6 +42,15 @@ export const javascriptLanguage = LRLanguage.define({ }), foldNodeProp.add({ "Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType": foldInside, + JSXElement(node) { + const first = node.firstChild; + const start = first?.firstChild ? first.firstChild.nextSibling : null; + const end = first?.name === 'JSXSelfClosingTag' ? first.lastChild : node.lastChild; + + if (!start || !end) return null; + + return start && start.to < end.from ? { from: start.to, to: end.type.isError ? node.to : end.from } : null; + }, BlockComment(tree) { return {from: tree.from + 2, to: tree.to - 2} } }) ] diff --git a/test/test-folding.ts b/test/test-folding.ts new file mode 100644 index 0000000..ea207ca --- /dev/null +++ b/test/test-folding.ts @@ -0,0 +1,47 @@ +import ist from "ist" +import {EditorState} from "@codemirror/state" +import {javascript} from "@codemirror/lang-javascript" +import {foldable} from "@codemirror/language" + +function jsxState(doc: string) { + return EditorState.create({doc, extensions: [javascript({jsx: true})]}) +} + +function fold(doc: string) { + let state = jsxState(doc) + const firstLine = doc.slice(0, doc.indexOf('\n')) + const folded = foldable(state, 0, firstLine.length) + if (folded) doc = doc.slice(0, folded.from) + ' ... ' + doc.slice(folded.to) + return doc +} + +describe("JSX folding", () => { + it("should fold self-closing tags", () => { + ist(fold(`
`), '
') + }) + + it("should fold self-closing tags with attributes", () => { + ist(fold(`
`), '
') + }) + + it("should fold regular tags", () => { + ist(fold(`
\n foo
`), '
') + }) + + it("should fold regular tags with attributes", () => { + ist(fold(`
\nfoo
`), '
') + }) + + it("should fold regular tags with children", () => { + ist(fold(`
\n
\nbar
`), '
') + }) + + it("should fold fragment tags", () => { + ist(fold(`<> \nsdf `), '<> ... ') + }) + + it("should not fold inline tags", () => { + ist(fold(`
`), '
') + }) +}) +