Commit 05bf67dc45422d45ee8e4a364a7761ad2d2dddee

Golmote 2018-03-08T09:05:21

JSX: Allow for one level of nested curly braces inside tag attribute value. Fix #1335

diff --git a/components/prism-jsx.js b/components/prism-jsx.js
index 4b59cfb..b4530a2 100644
--- a/components/prism-jsx.js
+++ b/components/prism-jsx.js
@@ -3,7 +3,7 @@
 var javascript = Prism.util.clone(Prism.languages.javascript);
 
 Prism.languages.jsx = Prism.languages.extend('markup', javascript);
-Prism.languages.jsx.tag.pattern= /<\/?[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+|(?:\{\{?[^}]*\}?\})))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?>/i;
+Prism.languages.jsx.tag.pattern= /<\/?[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{[^}]+\}|[^{}])+\}))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?>/i;
 
 Prism.languages.jsx.tag.inside['attr-value'].pattern = /=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i;
 
diff --git a/components/prism-jsx.min.js b/components/prism-jsx.min.js
index 7f696af..0704816 100644
--- a/components/prism-jsx.min.js
+++ b/components/prism-jsx.min.js
@@ -1 +1 @@
-!function(a){var e=a.util.clone(a.languages.javascript);a.languages.jsx=a.languages.extend("markup",e),a.languages.jsx.tag.pattern=/<\/?[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+|(?:\{\{?[^}]*\}?\})))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?>/i,a.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i,a.languages.insertBefore("inside","attr-name",{spread:{pattern:/\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}/,inside:{punctuation:/\.{3}|[{}.]/,"attr-value":/\w+/}}},a.languages.jsx.tag);var s=a.util.clone(a.languages.jsx);delete s.punctuation,s=a.languages.insertBefore("jsx","operator",{punctuation:/=(?={)|[{}[\];(),.:]/},{jsx:s}),a.languages.insertBefore("inside","attr-value",{script:{pattern:/=(\{(?:\{[^}]*\}|[^}])+\})/i,inside:s,alias:"language-javascript"}},a.languages.jsx.tag)}(Prism);
\ No newline at end of file
+!function(a){var e=a.util.clone(a.languages.javascript);a.languages.jsx=a.languages.extend("markup",e),a.languages.jsx.tag.pattern=/<\/?[\w.:-]+\s*(?:\s+(?:[\w.:-]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s{'">=]+|\{(?:\{[^}]+\}|[^{}])+\}))?|\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}))*\s*\/?>/i,a.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">]+)/i,a.languages.insertBefore("inside","attr-name",{spread:{pattern:/\{\.{3}[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\}/,inside:{punctuation:/\.{3}|[{}.]/,"attr-value":/\w+/}}},a.languages.jsx.tag);var s=a.util.clone(a.languages.jsx);delete s.punctuation,s=a.languages.insertBefore("jsx","operator",{punctuation:/=(?={)|[{}[\];(),.:]/},{jsx:s}),a.languages.insertBefore("inside","attr-value",{script:{pattern:/=(\{(?:\{[^}]*\}|[^}])+\})/i,inside:s,alias:"language-javascript"}},a.languages.jsx.tag)}(Prism);
\ No newline at end of file
diff --git a/tests/languages/jsx/issue1335.test b/tests/languages/jsx/issue1335.test
new file mode 100644
index 0000000..9de5749
--- /dev/null
+++ b/tests/languages/jsx/issue1335.test
@@ -0,0 +1,124 @@
+<Button onClick={(e) => this.setState({clicked: true})} />
+<Component
+  data={[
+    {id: 0, name: 'Joe'},
+    {id: 1, name: 'Sue'},
+  ]}
+/>
+<Component title={`${name}`} />
+<Component title={`${name}'s page`} />
+
+----------------------------------------------------
+
+[
+	["tag", [
+		["tag", [
+			["punctuation", "<"],
+			"Button"
+		]],
+		["attr-name", ["onClick"]],
+		["script", [
+			["punctuation", "="],
+			["punctuation", "{"],
+			["punctuation", "("],
+			"e",
+			["punctuation", ")"],
+			["operator", "=>"],
+			["keyword", "this"],
+			["punctuation", "."],
+			["function", "setState"],
+			["punctuation", "("],
+			["punctuation", "{"],
+			"clicked",
+			["punctuation", ":"],
+			["boolean", "true"],
+			["punctuation", "}"],
+			["punctuation", ")"],
+			["punctuation", "}"]
+		]],
+		["punctuation", "/>"]
+	]],
+	["tag", [
+		["tag", [
+			["punctuation", "<"],
+			"Component"
+		]],
+		["attr-name", ["data"]],
+		["script", [
+			["punctuation", "="],
+			["punctuation", "{"],
+			["punctuation", "["],
+			["punctuation", "{"],
+			"id",
+			["punctuation", ":"],
+			["number", "0"],
+			["punctuation", ","],
+			" name",
+			["punctuation", ":"],
+			["string", "'Joe'"],
+			["punctuation", "}"],
+			["punctuation", ","],
+			["punctuation", "{"],
+			"id",
+			["punctuation", ":"],
+			["number", "1"],
+			["punctuation", ","],
+			" name",
+			["punctuation", ":"],
+			["string", "'Sue'"],
+			["punctuation", "}"],
+			["punctuation", ","],
+			["punctuation", "]"],
+			["punctuation", "}"]
+		]],
+		["punctuation", "/>"]
+	]],
+	["tag", [
+		["tag", [
+			["punctuation", "<"],
+			"Component"
+		]],
+		["attr-name", ["title"]],
+		["script", [
+			["punctuation", "="],
+			["punctuation", "{"],
+			["template-string", [
+				["string", "`"],
+				["interpolation", [
+					["interpolation-punctuation", "${"],
+					"name",
+					["interpolation-punctuation", "}"]
+				]],
+				["string", "`"]
+			]],
+			["punctuation", "}"]
+		]],
+		["punctuation", "/>"]
+	]],
+	["tag", [
+		["tag", [
+			["punctuation", "<"],
+			"Component"
+		]],
+		["attr-name", ["title"]],
+		["script", [
+			["punctuation", "="],
+			["punctuation", "{"],
+			["template-string", [
+				["string", "`"],
+				["interpolation", [
+					["interpolation-punctuation", "${"],
+					"name",
+					["interpolation-punctuation", "}"]
+				]],
+				["string", "'s page`"]
+			]],
+			["punctuation", "}"]
+		]],
+		["punctuation", "/>"]
+	]]
+]
+
+----------------------------------------------------
+
+Handles nested pairs of curly braces inside tag attribute. See #1335
\ No newline at end of file