Refactor handling or whitespace-only template literals in JS embed (#13517)

* Refactor handling or whitespace-only template literals in JS embed

* Rename "format" to "embed"
This commit is contained in:
Georgii Dolzhykov authored and GitHub committed 2022-09-25 15:26:14 +03:00
1 parent 81a4d455f3
commit 04faada98b
6 files changed
+46 -65

No files matched your search

+35 -34
View File
@@ -3,10 +3,10 @@ import {
CommentCheckFlags,
isObjectProperty,
} from "./utils/index.js";
import formatMarkdown from "./embed/markdown.js";
import formatCss from "./embed/css.js";
import formatGraphql from "./embed/graphql.js";
import { formatHtml, formatAngular } from "./embed/html.js";
import embedMarkdown from "./embed/markdown.js";
import embedCss from "./embed/css.js";
import embedGraphQL from "./embed/graphql.js";
import { embedHtml, embedAngular } from "./embed/html.js";
function embed(path) {
const { node } = path;
@@ -20,29 +20,42 @@ function embed(path) {
return;
}
const embedder = getEmbedder(path);
if (embedder) {
// Special case: whitespace-only template literals
if (node.quasis.length === 1 && node.quasis[0].value.raw.trim() === "") {
return "``";
}
return embedder;
}
}
function getEmbedder(path) {
if (
isStyledJsx(path) ||
isStyledComponents(path) ||
isCssProp(path) ||
isAngularComponentStyles(path)
) {
return formatCss;
return embedCss;
}
if (isGraphQL(path)) {
return formatGraphql;
return embedGraphQL;
}
if (isHtml(path)) {
return formatHtml;
return embedHtml;
}
if (isAngularComponentTemplate(path)) {
return formatAngular;
return embedAngular;
}
if (isMarkdown(path)) {
return formatMarkdown;
return embedMarkdown;
}
}
@@ -50,9 +63,7 @@ function embed(path) {
* md`...`
* markdown`...`
*/
function isMarkdown(path) {
const { node } = path;
const parent = path.getParentNode();
function isMarkdown({ node, parent }) {
return (
parent &&
parent.type === "TaggedTemplateExpression" &&
@@ -69,17 +80,14 @@ function isMarkdown(path) {
* css.global``
* css.resolve``
*/
function isStyledJsx(path) {
const { node } = path;
const parent = path.getParentNode();
const parentParent = path.getParentNode(1);
function isStyledJsx({ node, parent, grandparent }) {
return (
(parentParent &&
(grandparent &&
node.quasis &&
parent.type === "JSXExpressionContainer" &&
parentParent.type === "JSXElement" &&
parentParent.openingElement.name.name === "style" &&
parentParent.openingElement.attributes.some(
grandparent.type === "JSXElement" &&
grandparent.openingElement.name.name === "style" &&
grandparent.openingElement.attributes.some(
(attribute) => attribute.name.name === "jsx"
)) ||
(parent &&
@@ -145,9 +153,7 @@ const angularComponentObjectExpressionPredicates = [
/**
* styled-components template literals
*/
function isStyledComponents(path) {
const parent = path.getParentNode();
function isStyledComponents({ parent }) {
if (!parent || parent.type !== "TaggedTemplateExpression") {
return false;
}
@@ -193,15 +199,13 @@ function isStyledComponents(path) {
/**
* JSX element with CSS prop
*/
function isCssProp(path) {
const parent = path.getParentNode();
const parentParent = path.getParentNode(1);
function isCssProp({ parent, grandparent }) {
return (
parentParent &&
grandparent &&
parent.type === "JSXExpressionContainer" &&
parentParent.type === "JSXAttribute" &&
parentParent.name.type === "JSXIdentifier" &&
parentParent.name.name === "css"
grandparent.type === "JSXAttribute" &&
grandparent.name.type === "JSXIdentifier" &&
grandparent.name.name === "css"
);
}
@@ -223,10 +227,7 @@ function isStyledExtend(node) {
* This intentionally excludes Relay Classic tags, as Prettier does not
* support Relay Classic formatting.
*/
function isGraphQL(path) {
const { node } = path;
const parent = path.getParentNode();
function isGraphQL({ node, parent }) {
return (
hasLanguageComment(node, "GraphQL") ||
(parent &&
+3 -13
View File
@@ -3,7 +3,7 @@ import { indent, hardline, softline } from "../../document/builders.js";
import { mapDoc, replaceEndOfLine, cleanDoc } from "../../document/utils.js";
import { printTemplateExpressions } from "../print/template-literal.js";
async function format(textToDoc, print, path /*, options*/) {
async function embedCss(textToDoc, print, path /*, options*/) {
const { node } = path;
// Get full template literal with expressions replaced by placeholders
@@ -20,18 +20,8 @@ async function format(textToDoc, print, path /*, options*/) {
currVal,
""
);
const doc = await textToDoc(text, { parser: "scss" });
const quasisDoc = await textToDoc(text, { parser: "scss" });
const expressionDocs = printTemplateExpressions(path, print);
return transformCssDoc(doc, node, expressionDocs);
}
function transformCssDoc(quasisDoc, parentNode, expressionDocs) {
const isEmpty =
parentNode.quasis.length === 1 && !parentNode.quasis[0].value.raw.trim();
if (isEmpty) {
return "``";
}
const newDoc = replacePlaceholders(quasisDoc, expressionDocs);
/* istanbul ignore if */
if (!newDoc) {
@@ -69,4 +59,4 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
return expressionDocs.length === replaceCounter ? newDoc : null;
}
export default format;
export default embedCss;
+2 -5
View File
@@ -4,13 +4,10 @@ import {
printTemplateExpressions,
} from "../print/template-literal.js";
async function format(textToDoc, print, path /*, options*/) {
async function embedGraphQL(textToDoc, print, path /*, options*/) {
const { node } = path;
const numQuasis = node.quasis.length;
if (numQuasis === 1 && node.quasis[0].value.raw.trim() === "") {
return "``";
}
const expressionDocs = printTemplateExpressions(path, print);
const parts = [];
@@ -97,4 +94,4 @@ function printGraphqlComments(lines) {
return parts.length === 0 ? null : join(hardline, parts);
}
export default format;
export default embedGraphQL;
+3 -8
View File
@@ -7,7 +7,7 @@ import {
// The counter is needed to distinguish nested embeds.
let htmlTemplateLiteralCounter = 0;
async function format(textToDoc, print, path, options, parser) {
async function embedHtmlLike(parser, textToDoc, print, path, options) {
const { node } = path;
const counter = htmlTemplateLiteralCounter;
htmlTemplateLiteralCounter = (htmlTemplateLiteralCounter + 1) >>> 0;
@@ -24,9 +24,6 @@ async function format(textToDoc, print, path, options, parser) {
.join("");
const expressionDocs = printTemplateExpressions(path, print);
if (expressionDocs.length === 0 && text.trim().length === 0) {
return "``";
}
const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g");
let topLevelCount = 0;
@@ -89,7 +86,5 @@ async function format(textToDoc, print, path, options, parser) {
]);
}
export const formatHtml = (textToDoc, print, path, options) =>
format(textToDoc, print, path, options, "html");
export const formatAngular = (textToDoc, print, path, options) =>
format(textToDoc, print, path, options, "angular");
export const embedHtml = embedHtmlLike.bind(undefined, "html");
export const embedAngular = embedHtmlLike.bind(undefined, "angular");
+2 -2
View File
@@ -6,7 +6,7 @@ import {
} from "../../document/builders.js";
import { escapeTemplateCharacters } from "../print/template-literal.js";
async function format(textToDoc, print, path /*, options*/) {
async function embedMarkdown(textToDoc, print, path /*, options*/) {
const { node } = path;
let text = node.quasis[0].value.raw.replace(
/((?:\\\\)*)\\`/g,
@@ -34,4 +34,4 @@ function getIndentation(str) {
return firstMatchedIndent === null ? "" : firstMatchedIndent[1];
}
export default format;
export default embedMarkdown;
@@ -65,9 +65,7 @@ css\`
}
\`;
md\`
\`;
md\`\`;
graphql(
\`