diff --git a/lib/liveview.js b/lib/liveview.js new file mode 100644 index 0000000..8764ec4 --- /dev/null +++ b/lib/liveview.js @@ -0,0 +1,17 @@ +const liveViewFormForPlaceholder = '
'; + +const encodeFormForExpressions = (text) => { + const liveViewFormExpressions = []; + const textWithPlaceholders = text.replace(/(<%=?[^%>]*=\s+form_for[\s\S]*?%>|)/gm, (match) => { + liveViewFormExpressions.push(match); + + return liveViewFormForPlaceholder; + }); + + return { liveViewFormExpressions, textWithPlaceholders }; +}; + +module.exports = { + encodeFormForExpressions, + liveViewFormForPlaceholder, +}; diff --git a/lib/parser.js b/lib/parser.js index 19915ac..1367fcd 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,8 +1,14 @@ const { tokenizeHTML } = require('prettier-html-templates'); const expressionTypeMatcher = require('./expression_type_matcher'); +const { encodeFormForExpressions } = require('./liveview'); function parse(text, parsers, options) { - return tokenizeHTML(text, /<%[\s\S]*?%>/gm, expressionTypeMatcher); + const { liveViewFormExpressions, textWithPlaceholders } = encodeFormForExpressions(text); + + return { + tokens: tokenizeHTML(textWithPlaceholders, /<%[\s\S]*?%>/gm, expressionTypeMatcher), + liveViewFormExpressions, + }; } module.exports = { diff --git a/lib/printers.js b/lib/printers.js index ea583f3..eb09f70 100644 --- a/lib/printers.js +++ b/lib/printers.js @@ -2,10 +2,11 @@ const prettier = require('prettier'); const { mapDoc } = require('prettier').doc.utils; const { encodeExpressions, decodeExpressions } = require('prettier-html-templates'); const { formatEex } = require('./formatter'); +const { liveViewFormForPlaceholder } = require('./liveview'); // args: path, print, textToDoc, options function embed(path, _print, textToDoc, options) { - const tokens = path.stack[0]; + const { tokens, liveViewFormExpressions } = path.stack[0]; const isTextWithExpressions = tokens.find((token) => token.type !== 'text'); @@ -14,13 +15,19 @@ function embed(path, _print, textToDoc, options) { } const formattedTokens = formatEex(tokens, options); - const [text, expressionMap] = encodeExpressions(formattedTokens); + const [textWithPlaceholders, expressionMap] = encodeExpressions(formattedTokens); - const htmlDoc = textToDoc(text, { parser: 'html' }); + const htmlDoc = textToDoc(textWithPlaceholders, { parser: 'html' }); const callback = decodeExpressions(expressionMap); - - return mapDoc(htmlDoc, callback); + return mapDoc(htmlDoc, (doc) => { + let newDoc = doc; + if (doc === liveViewFormForPlaceholder) { + newDoc = liveViewFormExpressions.shift(); + } + + return callback(newDoc); + }); } module.exports = { diff --git a/tests/expressions/__snapshots__/jsfmt.spec.js.snap b/tests/expressions/__snapshots__/jsfmt.spec.js.snap index 93c4190..5c10a70 100644 --- a/tests/expressions/__snapshots__/jsfmt.spec.js.snap +++ b/tests/expressions/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,53 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`liveview_form_for.html.leex 1`] = ` +====================================options===================================== +parsers: ["eex"] +printWidth: 80 + | printWidth +=====================================input====================================== +
+ <%= f = form_for a %> + <%= text_input f, :name %> + +
+
+
+ <%= f = form_for b %> + <%= text_input f, :name %> + +
+
+ <%= fs = form_for c %> + <%= text_input f, :name %> + +
+
+
+ +=====================================output===================================== +
+ <%= f = form_for a %> + <%= text_input f, :name %> + +
+
+
+ <%= f = form_for b %> + <%= text_input f, :name %> + +
+
+ <%= fs = form_for c %> + <%= text_input f, :name %> + +
+
+
+ +================================================================================ +`; + exports[`multiline.html.eex 1`] = ` ====================================options===================================== parsers: ["eex"] diff --git a/tests/expressions/liveview_form_for.html.leex b/tests/expressions/liveview_form_for.html.leex new file mode 100644 index 0000000..1a9e3a6 --- /dev/null +++ b/tests/expressions/liveview_form_for.html.leex @@ -0,0 +1,18 @@ +
+ <%= f = form_for a %> + <%= text_input f, :name %> + +
+
+
+ <%= f = form_for b %> + <%= text_input f, :name %> + +
+
+ <%= fs = form_for c %> + <%= text_input f, :name %> + +
+
+