Skip to content

Commit 25bdb49

Browse files
TSX: Temporary fix for the collisions of JSX tags and TS generics (#2596)
1 parent 129faf5 commit 25bdb49

File tree

5 files changed

+267
-6
lines changed

5 files changed

+267
-6
lines changed

components/prism-jsx.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
var javascript = Prism.util.clone(Prism.languages.javascript);
44

55
Prism.languages.jsx = Prism.languages.extend('markup', javascript);
6-
Prism.languages.jsx.tag.pattern= /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:$-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}))?|\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}))*\s*\/?)?>/i;
6+
Prism.languages.jsx.tag.pattern = /<\/?(?:[\w.:-]+\s*(?:\s+(?:[\w.:$-]+(?:=(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s{'">=]+|\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}))?|\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}))*\s*\/?)?>/i;
77

88
Prism.languages.jsx.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i;
9-
Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i;
9+
Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i;
1010
Prism.languages.jsx.tag.inside['tag'].inside['class-name'] = /^[A-Z]\w*(?:\.[A-Z]\w*)*$/;
1111

1212
Prism.languages.insertBefore('inside', 'attr-name', {

components/prism-jsx.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/prism-tsx.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
var typescript = Prism.util.clone(Prism.languages.typescript);
2-
Prism.languages.tsx = Prism.languages.extend('jsx', typescript);
1+
(function (Prism) {
2+
var typescript = Prism.util.clone(Prism.languages.typescript);
3+
Prism.languages.tsx = Prism.languages.extend('jsx', typescript);
4+
5+
// This will prevent collisions between TSX tags and TS generic types.
6+
// Idea by https://github.com/karlhorky
7+
// Discussion: https://github.com/PrismJS/prism/issues/2594#issuecomment-710666928
8+
var tag = Prism.languages.tsx.tag;
9+
tag.pattern = RegExp(/(^|[^\w$]|(?=<\/))/.source + '(?:' + tag.pattern.source + ')', tag.pattern.flags);
10+
tag.lookbehind = true;
11+
}(Prism));

components/prism-tsx.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/languages/tsx/issue2594.test

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
function Add1(a, b) { return <div>a + b</div> }
2+
3+
type Bar = Foo<string>;
4+
5+
function Add2(a, b) { return <div>a + b</div> }
6+
7+
function handleSubmit(event: FormEvent<HTMLFormElement>) {
8+
event.preventDefault();
9+
}
10+
11+
function handleChange(event: ChangeEvent<HTMLInputElement>) {
12+
console.log(event.target.value);
13+
}
14+
15+
function handleClick(event: MouseEvent) {
16+
console.log(event.button);
17+
}
18+
19+
export default function Form() {
20+
return (
21+
<form onSubmit={handleSubmit}>
22+
<input onChange={handleChange} placeholder="Name" />
23+
<button onClick={handleClick}></button>
24+
</form>
25+
);
26+
}
27+
28+
----------------------------------------------------
29+
30+
[
31+
["keyword", "function"],
32+
["function", "Add1"],
33+
["punctuation", "("],
34+
["parameter", [
35+
"a",
36+
["punctuation", ","],
37+
" b"
38+
]],
39+
["punctuation", ")"],
40+
["punctuation", "{"],
41+
["keyword", "return"],
42+
["tag", [
43+
["tag", [
44+
["punctuation", "<"],
45+
"div"
46+
]],
47+
["punctuation", ">"]
48+
]],
49+
["plain-text", "a + b"],
50+
["tag", [
51+
["tag", [
52+
["punctuation", "</"],
53+
"div"
54+
]],
55+
["punctuation", ">"]
56+
]],
57+
["punctuation", "}"],
58+
59+
["keyword", "type"],
60+
["class-name", [
61+
"Bar"
62+
]],
63+
["operator", "="],
64+
" Foo",
65+
["operator", "<"],
66+
["builtin", "string"],
67+
["operator", ">"],
68+
["punctuation", ";"],
69+
70+
["keyword", "function"],
71+
["function", "Add2"],
72+
["punctuation", "("],
73+
["parameter", [
74+
"a",
75+
["punctuation", ","],
76+
" b"
77+
]],
78+
["punctuation", ")"],
79+
["punctuation", "{"],
80+
["keyword", "return"],
81+
["tag", [
82+
["tag", [
83+
["punctuation", "<"],
84+
"div"
85+
]],
86+
["punctuation", ">"]
87+
]],
88+
["plain-text", "a + b"],
89+
["tag", [
90+
["tag", [
91+
["punctuation", "</"],
92+
"div"
93+
]],
94+
["punctuation", ">"]
95+
]],
96+
["punctuation", "}"],
97+
98+
["keyword", "function"],
99+
["function", "handleSubmit"],
100+
["punctuation", "("],
101+
["parameter", [
102+
"event",
103+
["operator", ":"],
104+
" FormEvent",
105+
["operator", "<"],
106+
"HTMLFormElement",
107+
["operator", ">"]
108+
]],
109+
["punctuation", ")"],
110+
["punctuation", "{"],
111+
"\r\n event",
112+
["punctuation", "."],
113+
["function", "preventDefault"],
114+
["punctuation", "("],
115+
["punctuation", ")"],
116+
["punctuation", ";"],
117+
["punctuation", "}"],
118+
119+
["keyword", "function"],
120+
["function", "handleChange"],
121+
["punctuation", "("],
122+
["parameter", [
123+
"event",
124+
["operator", ":"],
125+
" ChangeEvent",
126+
["operator", "<"],
127+
"HTMLInputElement",
128+
["operator", ">"]
129+
]],
130+
["punctuation", ")"],
131+
["punctuation", "{"],
132+
["builtin", "console"],
133+
["punctuation", "."],
134+
["function", "log"],
135+
["punctuation", "("],
136+
"event",
137+
["punctuation", "."],
138+
"target",
139+
["punctuation", "."],
140+
"value",
141+
["punctuation", ")"],
142+
["punctuation", ";"],
143+
["punctuation", "}"],
144+
145+
["keyword", "function"],
146+
["function", "handleClick"],
147+
["punctuation", "("],
148+
["parameter", [
149+
"event",
150+
["operator", ":"],
151+
" MouseEvent"
152+
]],
153+
["punctuation", ")"],
154+
["punctuation", "{"],
155+
["builtin", "console"],
156+
["punctuation", "."],
157+
["function", "log"],
158+
["punctuation", "("],
159+
"event",
160+
["punctuation", "."],
161+
"button",
162+
["punctuation", ")"],
163+
["punctuation", ";"],
164+
["punctuation", "}"],
165+
166+
["keyword", "export"],
167+
["keyword", "default"],
168+
["keyword", "function"],
169+
["function", "Form"],
170+
["punctuation", "("],
171+
["punctuation", ")"],
172+
["punctuation", "{"],
173+
["keyword", "return"],
174+
["punctuation", "("],
175+
["tag", [
176+
["tag", [
177+
["punctuation", "<"],
178+
"form"
179+
]],
180+
["attr-name", [
181+
"onSubmit"
182+
]],
183+
["script", [
184+
["script-punctuation", "="],
185+
["punctuation", "{"],
186+
"handleSubmit",
187+
["punctuation", "}"]
188+
]],
189+
["punctuation", ">"]
190+
]],
191+
["plain-text", "\r\n "],
192+
["tag", [
193+
["tag", [
194+
["punctuation", "<"],
195+
"input"
196+
]],
197+
["attr-name", [
198+
"onChange"
199+
]],
200+
["script", [
201+
["script-punctuation", "="],
202+
["punctuation", "{"],
203+
"handleChange",
204+
["punctuation", "}"]
205+
]],
206+
["attr-name", [
207+
"placeholder"
208+
]],
209+
["attr-value", [
210+
["punctuation", "="],
211+
["punctuation", "\""],
212+
"Name",
213+
["punctuation", "\""]
214+
]],
215+
["punctuation", "/>"]
216+
]],
217+
["plain-text", "\r\n "],
218+
["tag", [
219+
["tag", [
220+
["punctuation", "<"],
221+
"button"
222+
]],
223+
["attr-name", [
224+
"onClick"
225+
]],
226+
["script", [
227+
["script-punctuation", "="],
228+
["punctuation", "{"],
229+
"handleClick",
230+
["punctuation", "}"]
231+
]],
232+
["punctuation", ">"]
233+
]],
234+
["tag", [
235+
["tag", [
236+
["punctuation", "</"],
237+
"button"
238+
]],
239+
["punctuation", ">"]
240+
]],
241+
["plain-text", "\r\n "],
242+
["tag", [
243+
["tag", [
244+
["punctuation", "</"],
245+
"form"
246+
]],
247+
["punctuation", ">"]
248+
]],
249+
["punctuation", ")"],
250+
["punctuation", ";"],
251+
["punctuation", "}"]
252+
]

0 commit comments

Comments
 (0)