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:
1 parent
81a4d455f3
commit
04faada98b
6 files changed
+46
-65
No files matched your search
+35
-34
@@ -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,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;
|
||||
@@ -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;
|
||||
@@ -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");
|
||||
@@ -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;
|
||||
+1
-3
@@ -65,9 +65,7 @@ css\`
|
||||
}
|
||||
\`;
|
||||
|
||||
md\`
|
||||
|
||||
\`;
|
||||
md\`\`;
|
||||
|
||||
graphql(
|
||||
\`
|
||||
|
||||
Reference in new issue
Block a user