From c5c60790c7c2cc291df21eef5a4760605dc94ece Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Sat, 9 May 2020 14:00:10 +0300 Subject: [PATCH 1/8] test: use .is instead of .truthy for comparison shows diffs when a test fails --- test/test-conditionals.js | 6 +++--- test/test-core.js | 2 +- test/test-scopes.js | 2 +- test/test-switch.js | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test-conditionals.js b/test/test-conditionals.js index c16b871..ac6c4c4 100644 --- a/test/test-conditionals.js +++ b/test/test-conditionals.js @@ -23,7 +23,7 @@ function process (t, name, options, log = false) { return clean(result.html) }) .then((html) => { - t.truthy(html === expect(name).trim()) + t.is(html, expect(name).trim()) }) } @@ -51,13 +51,13 @@ test('Conditionals - no render', (t) => { test('Conditionals - "if" tag missing condition', (t) => { return error('conditional_if_error', (err) => { - t.truthy(err.toString() === 'Error: the "if" tag must have a "condition" attribute') + t.is(err.toString(), 'Error: the "if" tag must have a "condition" attribute') }) }) test('Conditionals - "elseif" tag missing condition', (t) => { return error('conditional_elseif_error', (err) => { - t.truthy(err.toString() === 'Error: the "elseif" tag must have a "condition" attribute') + t.is(err.toString(), 'Error: the "elseif" tag must have a "condition" attribute') }) }) diff --git a/test/test-core.js b/test/test-core.js index 09bba9e..57dd597 100644 --- a/test/test-core.js +++ b/test/test-core.js @@ -23,7 +23,7 @@ function process (t, name, options, log = false) { return clean(result.html) }) .then((html) => { - t.truthy(html === expect(name).trim()) + t.is(html, expect(name).trim()) }) } diff --git a/test/test-scopes.js b/test/test-scopes.js index 1e14364..6923386 100644 --- a/test/test-scopes.js +++ b/test/test-scopes.js @@ -23,7 +23,7 @@ function process (t, name, options, log = false) { return clean(result.html) }) .then((html) => { - t.truthy(html === expect(name).trim()) + t.is(html, expect(name).trim()) }) } diff --git a/test/test-switch.js b/test/test-switch.js index 1b63abe..9d83c0a 100644 --- a/test/test-switch.js +++ b/test/test-switch.js @@ -23,7 +23,7 @@ function process (t, name, options, log = false) { return clean(result.html) }) .then((html) => { - t.truthy(html === expect(name).trim()) + t.is(html, expect(name).trim()) }) } @@ -75,7 +75,7 @@ test('Switch - dynamic expression', (t) => { test('Switch - no switch attribute', (t) => { return error('switch_no_attr', (err) => { - t.truthy(err.toString() === 'Error: the "switch" tag must have a "expression" attribute') + t.is(err.toString(), 'Error: the "switch" tag must have a "expression" attribute') }) }) From ae902d1c8a6922ab7b8f9cec1ddca9c2e5e9ba23 Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Sat, 9 May 2020 14:05:29 +0300 Subject: [PATCH 2/8] test: fails to ignore subsequent expressions in text node --- test/expect/expression_ignored.html | 2 +- test/fixtures/expression_ignored.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/expect/expression_ignored.html b/test/expect/expression_ignored.html index 1a8b74e..fe8abcc 100644 --- a/test/expect/expression_ignored.html +++ b/test/expect/expression_ignored.html @@ -1,4 +1,4 @@ {{ foo }}

- And here's a {{ variable }} that would be undefined. + Here's one {{ variable }} and here's {{ another }}.

diff --git a/test/fixtures/expression_ignored.html b/test/fixtures/expression_ignored.html index 5ce0b1d..de18f1e 100644 --- a/test/fixtures/expression_ignored.html +++ b/test/fixtures/expression_ignored.html @@ -1,4 +1,4 @@ @{{ foo }}

- And here's a @{{ variable }} that would be undefined. + Here's one @{{ variable }} and here's @{{ another }}.

From def95f515f18f387ce59a187ec689a438fd00765 Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Sat, 9 May 2020 14:10:08 +0300 Subject: [PATCH 3/8] fix: ignore subsequent expressions in a text node --- lib/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 6074742..df98c9f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -182,7 +182,8 @@ function walk (opts, nodes) { const ignoredDelimiter = new RegExp(`@${before}(.+?)${after}`, 'g') if (ignoredDelimiter.test(node)) { - node = node.replace(`@${before}`, before) + const toReplace = new RegExp(`@${before}`, 'g') + node = node.replace(toReplace, before) m.push(node) From 5b39d5071059c5b01e56405c8f52e34df5fc2068 Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Sat, 9 May 2020 14:12:34 +0300 Subject: [PATCH 4/8] test: fails to ignore expression inside attribute --- test/expect/expression_ignored.html | 2 +- test/fixtures/expression_ignored.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/expect/expression_ignored.html b/test/expect/expression_ignored.html index fe8abcc..13d4a0e 100644 --- a/test/expect/expression_ignored.html +++ b/test/expect/expression_ignored.html @@ -1,4 +1,4 @@ {{ foo }} -

+

Here's one {{ variable }} and here's {{ another }}.

diff --git a/test/fixtures/expression_ignored.html b/test/fixtures/expression_ignored.html index de18f1e..6e25b21 100644 --- a/test/fixtures/expression_ignored.html +++ b/test/fixtures/expression_ignored.html @@ -1,4 +1,4 @@ @{{ foo }} -

+

Here's one @{{ variable }} and here's @{{ another }}.

From 8febd75d6433f41f029e10ea14085630af3b0503 Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Sat, 9 May 2020 15:07:25 +0300 Subject: [PATCH 5/8] fix: ignore expressions inside node attributes --- lib/index.js | 22 ++++++++++++++-------- test/expect/expression_ignored.html | 2 +- test/fixtures/expression_ignored.html | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/index.js b/lib/index.js index df98c9f..3775346 100644 --- a/lib/index.js +++ b/lib/index.js @@ -174,16 +174,16 @@ function walk (opts, nodes) { return m } + const ignoredBefore = delimitersSettings[1].text[0] + const ignoredAfter = delimitersSettings[1].text[1] + const toReplace = new RegExp(`@${ignoredBefore}`, 'g') + let ignoredExpression = new RegExp(`@${ignoredBefore}(.+?)${ignoredAfter}`, 'g') + // if we have a string, match and replace it if (typeof node === 'string') { // if node contains ignored expression delimiter, output as-is - const before = delimitersSettings[1].text[0] - const after = delimitersSettings[1].text[1] - const ignoredDelimiter = new RegExp(`@${before}(.+?)${after}`, 'g') - - if (ignoredDelimiter.test(node)) { - const toReplace = new RegExp(`@${before}`, 'g') - node = node.replace(toReplace, before) + if (ignoredExpression.test(node)) { + node = node.replace(toReplace, ignoredBefore) m.push(node) @@ -199,8 +199,14 @@ function walk (opts, nodes) { // if not, we have an object, so we need to run the attributes and contents if (node.attrs) { + // adapt regex to work with attribute values + ignoredExpression = new RegExp(`.*@${ignoredBefore}(.+?)${ignoredAfter}`) for (const key in node.attrs) { - node.attrs[key] = placeholders(node.attrs[key], ctx, delimitersSettings) + if (ignoredExpression.test(node.attrs[key])) { + node.attrs[key] = node.attrs[key].replace(toReplace, ignoredBefore) + } else { + node.attrs[key] = placeholders(node.attrs[key], ctx, delimitersSettings) + } } } diff --git a/test/expect/expression_ignored.html b/test/expect/expression_ignored.html index 13d4a0e..9741ae1 100644 --- a/test/expect/expression_ignored.html +++ b/test/expect/expression_ignored.html @@ -1,4 +1,4 @@ {{ foo }} -

+

Here's one {{ variable }} and here's {{ another }}.

diff --git a/test/fixtures/expression_ignored.html b/test/fixtures/expression_ignored.html index 6e25b21..56aa868 100644 --- a/test/fixtures/expression_ignored.html +++ b/test/fixtures/expression_ignored.html @@ -1,4 +1,4 @@ @{{ foo }} -

+

Here's one @{{ variable }} and here's @{{ another }}.

From 994e196a04a15da5faa919e5ff447efec25dd1d7 Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Fri, 15 May 2020 15:31:58 +0300 Subject: [PATCH 6/8] refactor: ignored expression regex vars --- lib/index.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/index.js b/lib/index.js index 3775346..fc47819 100644 --- a/lib/index.js +++ b/lib/index.js @@ -177,12 +177,13 @@ function walk (opts, nodes) { const ignoredBefore = delimitersSettings[1].text[0] const ignoredAfter = delimitersSettings[1].text[1] const toReplace = new RegExp(`@${ignoredBefore}`, 'g') - let ignoredExpression = new RegExp(`@${ignoredBefore}(.+?)${ignoredAfter}`, 'g') + const ignoredNodeExpression = new RegExp(`@${ignoredBefore}(.+?)${ignoredAfter}`, 'g') + const ignoredAttrsExpression = new RegExp(`.*@${ignoredBefore}(.+?)${ignoredAfter}`) // if we have a string, match and replace it if (typeof node === 'string') { // if node contains ignored expression delimiter, output as-is - if (ignoredExpression.test(node)) { + if (ignoredNodeExpression.test(node)) { node = node.replace(toReplace, ignoredBefore) m.push(node) @@ -199,10 +200,8 @@ function walk (opts, nodes) { // if not, we have an object, so we need to run the attributes and contents if (node.attrs) { - // adapt regex to work with attribute values - ignoredExpression = new RegExp(`.*@${ignoredBefore}(.+?)${ignoredAfter}`) for (const key in node.attrs) { - if (ignoredExpression.test(node.attrs[key])) { + if (ignoredAttrsExpression.test(node.attrs[key])) { node.attrs[key] = node.attrs[key].replace(toReplace, ignoredBefore) } else { node.attrs[key] = placeholders(node.attrs[key], ctx, delimitersSettings) From 77118303f73d9bf2103c5acc7ce2fa4949fa878b Mon Sep 17 00:00:00 2001 From: Ivan Demidov Date: Fri, 15 May 2020 17:02:20 +0300 Subject: [PATCH 7/8] perf: pulled definitions of ignore from iteration --- lib/index.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/index.js b/lib/index.js index fc47819..af8a1be 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,7 +10,7 @@ const revertBackupedLocals = require('./backup').revert const placeholders = require('./placeholders') const delimitersSettings = [] -let conditionals, switches, loops, scopes, ignored +let conditionals, switches, loops, scopes, ignored, ignoredBefore, ignoredAfter, toReplace, ignoredNodeExpression, ignoredAttrsExpression /** * @description Creates a set of local variables within the loop, and evaluates all nodes within the loop, returning their contents @@ -147,6 +147,13 @@ module.exports = function postHTMLExpressions (options) { delimitersSettings[0] = delimiters[1] delimitersSettings[1] = delimiters[0] } + + + ignoredBefore = delimitersSettings[1].text[0] + ignoredAfter = delimitersSettings[1].text[1] + toReplace = new RegExp(`@${ignoredBefore}`, 'g') + ignoredNodeExpression = new RegExp(`@${ignoredBefore}(.+?)${ignoredAfter}`, 'g') + ignoredAttrsExpression = new RegExp(`.*@${ignoredBefore}(.+?)${ignoredAfter}`) // kick off the parsing return walk.bind(null, { locals: options.locals }) @@ -174,12 +181,6 @@ function walk (opts, nodes) { return m } - const ignoredBefore = delimitersSettings[1].text[0] - const ignoredAfter = delimitersSettings[1].text[1] - const toReplace = new RegExp(`@${ignoredBefore}`, 'g') - const ignoredNodeExpression = new RegExp(`@${ignoredBefore}(.+?)${ignoredAfter}`, 'g') - const ignoredAttrsExpression = new RegExp(`.*@${ignoredBefore}(.+?)${ignoredAfter}`) - // if we have a string, match and replace it if (typeof node === 'string') { // if node contains ignored expression delimiter, output as-is From 28ad6ac89bb4ebb6e136ecbb26cf9538404fc35a Mon Sep 17 00:00:00 2001 From: Cosmin Popovici Date: Fri, 15 May 2020 19:26:33 +0300 Subject: [PATCH 8/8] refactor: inline expression ignoring use negative lookbehind so we only evaluate non-ignored expressions --- lib/index.js | 37 ++++++++++----------------- test/expect/expression_ignored.html | 4 +-- test/fixtures/expression_ignored.html | 4 +-- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/lib/index.js b/lib/index.js index af8a1be..03f5c5d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,7 +10,7 @@ const revertBackupedLocals = require('./backup').revert const placeholders = require('./placeholders') const delimitersSettings = [] -let conditionals, switches, loops, scopes, ignored, ignoredBefore, ignoredAfter, toReplace, ignoredNodeExpression, ignoredAttrsExpression +let conditionals, switches, loops, scopes, ignored, delimitersReplace, unescapeDelimitersReplace /** * @description Creates a set of local variables within the loop, and evaluates all nodes within the loop, returning their contents @@ -124,12 +124,12 @@ module.exports = function postHTMLExpressions (options) { let before = escapeRegexpString(options.delimiters[0]) let after = escapeRegexpString(options.delimiters[1]) - const delimitersRegexp = new RegExp(`${before}(.+?)${after}`, 'g') + const delimitersRegexp = new RegExp(`(? - Here's one {{ variable }} and here's {{ another }}. +

+ Here's one {{ variable }} and here's {{ another }}. And some bar.

diff --git a/test/fixtures/expression_ignored.html b/test/fixtures/expression_ignored.html index 56aa868..e2795a8 100644 --- a/test/fixtures/expression_ignored.html +++ b/test/fixtures/expression_ignored.html @@ -1,4 +1,4 @@ @{{ foo }} -

- Here's one @{{ variable }} and here's @{{ another }}. +

+ Here's one @{{ variable }} and here's @{{ another }}. And some {{ foo }}.