Skip to content

Commit

Permalink
Fix formatting of form_for expressions in .leex files
Browse files Browse the repository at this point in the history
  • Loading branch information
adamzapasnik committed Feb 11, 2021
1 parent 3348054 commit e768c96
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
17 changes: 17 additions & 0 deletions lib/liveview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const liveViewFormForPlaceholder = '<form>';

const encodeFormForExpressions = (text) => {
const liveViewFormExpressions = [];
const textWithPlaceholders = text.replace(/(<%=?[^%>]*=\s+form_for[\s\S]*?%>|<form>)/gm, (match) => {
liveViewFormExpressions.push(match);

return liveViewFormForPlaceholder;
});

return { liveViewFormExpressions, textWithPlaceholders };
};

module.exports = {
encodeFormForExpressions,
liveViewFormForPlaceholder,
};
8 changes: 7 additions & 1 deletion lib/parser.js
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down
17 changes: 12 additions & 5 deletions lib/printers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand All @@ -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 = {
Expand Down
48 changes: 48 additions & 0 deletions tests/expressions/__snapshots__/jsfmt.spec.js.snap
Original file line number Diff line number Diff line change
@@ -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======================================
<div>
<%= f = form_for a %>
<%= text_input f, :name %>
</form>
<div>
<form></form>
</div>
<%= f = form_for b %>
<%= text_input f, :name %>
</form>
<div>
<div>
<%= fs = form_for c %>
<%= text_input f, :name %>
</form>
</div>
</div>
</div>
=====================================output=====================================
<div>
<%= f = form_for a %>
<%= text_input f, :name %>
</form>
<div>
<form></form>
</div>
<%= f = form_for b %>
<%= text_input f, :name %>
</form>
<div>
<div>
<%= fs = form_for c %>
<%= text_input f, :name %>
</form>
</div>
</div>
</div>
================================================================================
`;

exports[`multiline.html.eex 1`] = `
====================================options=====================================
parsers: ["eex"]
Expand Down
18 changes: 18 additions & 0 deletions tests/expressions/liveview_form_for.html.leex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div>
<%= f = form_for a %>
<%= text_input f, :name %>
</form>
<div>
<form></form>
</div>
<%= f = form_for b %>
<%= text_input f, :name %>
</form>
<div>
<div>
<%= fs = form_for c %>
<%= text_input f, :name %>
</form>
</div>
</div>
</div>

0 comments on commit e768c96

Please sign in to comment.