From b2b0ab34dd185b9d57364bbed30b015a1d9ca481 Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Wed, 1 Jun 2016 15:43:42 -0400 Subject: [PATCH] parse pattern attribute correctly --- render/hyperscript.js | 7 ++++--- render/tests/test-hyperscript.js | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/render/hyperscript.js b/render/hyperscript.js index 2a75de61..f328a03a 100644 --- a/render/hyperscript.js +++ b/render/hyperscript.js @@ -2,7 +2,7 @@ var Node = require("../render/node") -var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[.+?\])/g, attrParser = /\[(.+?)(?:\s*=\s*("|'|)(.*?)\2)?\]/ +var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g var selectorCache = {} function hyperscript(selector) { if (typeof selector === "string") { @@ -14,8 +14,9 @@ function hyperscript(selector) { else if (type === "#") attributes.id = value else if (type === ".") classes.push(value) else if (match[3][0] === "[") { - var pair = attrParser.exec(match[3]) - attributes[pair[1]] = pair[3] || true + var attrValue = match[6] + if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\") + attributes[match[4]] = attrValue || true } } if (classes.length > 0) attributes.className = classes.join(" ") diff --git a/render/tests/test-hyperscript.js b/render/tests/test-hyperscript.js index b9789daa..91bd6f3d 100644 --- a/render/tests/test-hyperscript.js +++ b/render/tests/test-hyperscript.js @@ -51,6 +51,41 @@ o.spec("hyperscript", function() { o(vnode.tag).equals("div") o(vnode.attrs.a).equals("b") }) + o("handles attr w/ quoted square bracket", function() { + var vnode = m("[a='[b]'].c") + + o(vnode.tag).equals("div") + o(vnode.attrs.a).equals("[b]") + o(vnode.attrs.className).equals("c") + }) + o("handles attr w/ unmatched square bracket", function() { + var vnode = m("[a=']'].c") + + o(vnode.tag).equals("div") + o(vnode.attrs.a).equals("]") + o(vnode.attrs.className).equals("c") + }) + o("handles attr w/ quoted square bracket and quote", function() { + var vnode = m("[a='[b\"\\']'].c") // `[a='[b"\']']` + + o(vnode.tag).equals("div") + o(vnode.attrs.a).equals("[b\"']") // `[b"']` + o(vnode.attrs.className).equals("c") + }) + o("handles attr w/ quoted square containing escaped square bracket", function() { + var vnode = m("[a='[\\]]'].c") // `[a='[\]]']` + + o(vnode.tag).equals("div") + o(vnode.attrs.a).equals("[\\]]") // `[\]]` + o(vnode.attrs.className).equals("c") + }) + o("handles attr w/ backslashes", function() { + var vnode = m("[a='\\\\'].c") // `[a='\\']` + + o(vnode.tag).equals("div") + o(vnode.attrs.a).equals("\\") + o(vnode.attrs.className).equals("c") + }) o("handles attr w/ quotes and spaces in selector", function() { var vnode = m("[a = 'b']")