0))) ||
+ /**
+ *
123
+ */
+ (prevNode.type === "element" &&
+ prevNode.isSelfClosing &&
+ needsToBorrowPrevClosingTagEndMarker(nextNode))
+ ? ""
+ : !nextNode.isLeadingSpaceSensitive ||
+ preferHardlineAsLeadingSpaces(nextNode) ||
+ /**
+ * Want to write us a letter? Use ourmailing address.
+ */
+ (needsToBorrowPrevClosingTagEndMarker(nextNode) &&
+ prevNode.lastChild &&
+ needsToBorrowParentClosingTagStartMarker(prevNode.lastChild) &&
+ prevNode.lastChild.lastChild &&
+ needsToBorrowParentClosingTagStartMarker(prevNode.lastChild.lastChild))
+ ? hardline
+ : nextNode.hasLeadingSpaces
+ ? line
+ : softline;
+}
+
+function printChildren(path, options, print) {
+ const node = path.getValue();
+
+ if (forceBreakChildren(node)) {
+ return [
+ breakParent,
+
+ ...path.map((childPath) => {
+ const childNode = childPath.getValue();
+ const prevBetweenLine = !childNode.prev
+ ? ""
+ : printBetweenLine(childNode.prev, childNode);
+ return [
+ !prevBetweenLine
+ ? ""
+ : [
+ prevBetweenLine,
+ forceNextEmptyLine(childNode.prev) ? hardline : "",
+ ],
+ printChild(childPath, options, print),
+ ];
+ }, "children"),
+ ];
+ }
+
+ const groupIds = node.children.map(() => Symbol(""));
+ return path.map((childPath, childIndex) => {
+ const childNode = childPath.getValue();
+
+ if (isTextLikeNode(childNode)) {
+ if (childNode.prev && isTextLikeNode(childNode.prev)) {
+ const prevBetweenLine = printBetweenLine(childNode.prev, childNode);
+ if (prevBetweenLine) {
+ if (forceNextEmptyLine(childNode.prev)) {
+ return [hardline, hardline, printChild(childPath, options, print)];
+ }
+ return [prevBetweenLine, printChild(childPath, options, print)];
+ }
+ }
+ return printChild(childPath, options, print);
+ }
+
+ const prevParts = [];
+ const leadingParts = [];
+ const trailingParts = [];
+ const nextParts = [];
+
+ const prevBetweenLine = childNode.prev
+ ? printBetweenLine(childNode.prev, childNode)
+ : "";
+
+ const nextBetweenLine = childNode.next
+ ? printBetweenLine(childNode, childNode.next)
+ : "";
+
+ if (prevBetweenLine) {
+ if (forceNextEmptyLine(childNode.prev)) {
+ prevParts.push(hardline, hardline);
+ } else if (prevBetweenLine === hardline) {
+ prevParts.push(hardline);
+ } else {
+ if (isTextLikeNode(childNode.prev)) {
+ leadingParts.push(prevBetweenLine);
+ } else {
+ leadingParts.push(
+ ifBreak("", softline, {
+ groupId: groupIds[childIndex - 1],
+ })
+ );
+ }
+ }
+ }
+
+ if (nextBetweenLine) {
+ if (forceNextEmptyLine(childNode)) {
+ if (isTextLikeNode(childNode.next)) {
+ nextParts.push(hardline, hardline);
+ }
+ } else if (nextBetweenLine === hardline) {
+ if (isTextLikeNode(childNode.next)) {
+ nextParts.push(hardline);
+ }
+ } else {
+ trailingParts.push(nextBetweenLine);
+ }
+ }
+
+ return [
+ ...prevParts,
+ group([
+ ...leadingParts,
+ group([printChild(childPath, options, print), ...trailingParts], {
+ id: groupIds[childIndex],
+ }),
+ ]),
+ ...nextParts,
+ ];
+ }, "children");
+}
+
+module.exports = { printChildren };
diff --git a/src/language-html/print/element.js b/src/language-html/print/element.js
new file mode 100644
index 000000000..98f63c05a
--- /dev/null
+++ b/src/language-html/print/element.js
@@ -0,0 +1,176 @@
+"use strict";
+
+const {
+ builders: {
+ breakParent,
+ dedentToRoot,
+ group,
+ ifBreak,
+ indentIfBreak,
+ indent,
+ line,
+ softline,
+ },
+ utils: { replaceTextEndOfLine },
+} = require("../../document/index.js");
+const getNodeContent = require("../get-node-content.js");
+const {
+ shouldPreserveContent,
+ isScriptLikeTag,
+ isVueCustomBlock,
+ countParents,
+ forceBreakContent,
+} = require("../utils.js");
+const {
+ printOpeningTagPrefix,
+ printOpeningTag,
+ printClosingTagSuffix,
+ printClosingTag,
+ needsToBorrowPrevClosingTagEndMarker,
+ needsToBorrowLastChildClosingTagEndMarker,
+} = require("./tag.js");
+const { printChildren } = require("./children.js");
+
+function printElement(path, options, print) {
+ const node = path.getValue();
+
+ if (shouldPreserveContent(node, options)) {
+ return [
+ printOpeningTagPrefix(node, options),
+ group(printOpeningTag(path, options, print)),
+ ...replaceTextEndOfLine(getNodeContent(node, options)),
+ ...printClosingTag(node, options),
+ printClosingTagSuffix(node, options),
+ ];
+ }
+ /**
+ * do not break:
+ *
+ * {{
+ * ~
+ * interpolation
+ * }}
+ * ~
+ *
+ * exception: break if the opening tag breaks
+ *
+ * {{
+ * interpolation
+ * }}
+ */
+ const shouldHugContent =
+ node.children.length === 1 &&
+ node.firstChild.type === "interpolation" &&
+ node.firstChild.isLeadingSpaceSensitive &&
+ !node.firstChild.hasLeadingSpaces &&
+ node.lastChild.isTrailingSpaceSensitive &&
+ !node.lastChild.hasTrailingSpaces;
+
+ const attrGroupId = Symbol("element-attr-group-id");
+
+ const printTag = (doc) =>
+ group([
+ group(printOpeningTag(path, options, print), { id: attrGroupId }),
+ doc,
+ printClosingTag(node, options),
+ ]);
+
+ const printChildrenDoc = (childrenDoc) => {
+ if (shouldHugContent) {
+ return indentIfBreak(childrenDoc, { groupId: attrGroupId });
+ }
+ if (
+ (isScriptLikeTag(node) || isVueCustomBlock(node, options)) &&
+ node.parent.type === "root" &&
+ options.parser === "vue" &&
+ !options.vueIndentScriptAndStyle
+ ) {
+ return childrenDoc;
+ }
+ return indent(childrenDoc);
+ };
+
+ const printLineBeforeChildren = () => {
+ if (shouldHugContent) {
+ return ifBreak(softline, "", { groupId: attrGroupId });
+ }
+ if (
+ node.firstChild.hasLeadingSpaces &&
+ node.firstChild.isLeadingSpaceSensitive
+ ) {
+ return line;
+ }
+ if (
+ node.firstChild.type === "text" &&
+ node.isWhitespaceSensitive &&
+ node.isIndentationSensitive
+ ) {
+ return dedentToRoot(softline);
+ }
+ return softline;
+ };
+
+ const printLineAfterChildren = () => {
+ const needsToBorrow = node.next
+ ? needsToBorrowPrevClosingTagEndMarker(node.next)
+ : needsToBorrowLastChildClosingTagEndMarker(node.parent);
+ if (needsToBorrow) {
+ if (
+ node.lastChild.hasTrailingSpaces &&
+ node.lastChild.isTrailingSpaceSensitive
+ ) {
+ return " ";
+ }
+ return "";
+ }
+ if (shouldHugContent) {
+ return ifBreak(softline, "", { groupId: attrGroupId });
+ }
+ if (
+ node.lastChild.hasTrailingSpaces &&
+ node.lastChild.isTrailingSpaceSensitive
+ ) {
+ return line;
+ }
+ if (
+ (node.lastChild.type === "comment" ||
+ (node.lastChild.type === "text" &&
+ node.isWhitespaceSensitive &&
+ node.isIndentationSensitive)) &&
+ new RegExp(
+ `\\n[\\t ]{${
+ options.tabWidth *
+ countParents(
+ path,
+ (node) => node.parent && node.parent.type !== "root"
+ )
+ }}$`
+ ).test(node.lastChild.value)
+ ) {
+ return "";
+ }
+ return softline;
+ };
+
+ if (node.children.length === 0) {
+ return printTag(
+ node.hasDanglingSpaces && node.isDanglingSpaceSensitive ? line : ""
+ );
+ }
+
+ return printTag([
+ forceBreakContent(node) ? breakParent : "",
+ printChildrenDoc([
+ printLineBeforeChildren(),
+ printChildren(path, options, print),
+ ]),
+ printLineAfterChildren(),
+ ]);
+}
+
+module.exports = { printElement };
diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js
index 86e57437a..101dce2d1 100644
--- a/src/language-html/printer-html.js
+++ b/src/language-html/printer-html.js
@@ -5,34 +5,12 @@
*/
const {
- builders: {
- breakParent,
- dedentToRoot,
- fill,
- group,
- hardline,
- ifBreak,
- indentIfBreak,
- indent,
- line,
- literalline,
- softline,
- },
+ builders: { fill, group, hardline, literalline },
utils: { cleanDoc, getDocParts, isConcat, replaceTextEndOfLine },
} = require("../document/index.js");
const clean = require("./clean.js");
const {
countChars,
- countParents,
- forceBreakChildren,
- forceBreakContent,
- forceNextEmptyLine,
- hasPrettierIgnore,
- isVueCustomBlock,
- isScriptLikeTag,
- isTextLikeNode,
- preferHardlineAsLeadingSpaces,
- shouldPreserveContent,
unescapeQuoteEntities,
getTextValueParts,
} = require("./utils.js");
@@ -41,20 +19,13 @@ const { insertPragma } = require("./pragma.js");
const { locStart, locEnd } = require("./loc.js");
const embed = require("./embed.js");
const {
- printClosingTagEndMarker,
printClosingTagSuffix,
- printClosingTag,
printClosingTagEnd,
- needsToBorrowPrevClosingTagEndMarker,
- needsToBorrowLastChildClosingTagEndMarker,
- needsToBorrowParentClosingTagStartMarker,
printOpeningTagPrefix,
- printOpeningTag,
printOpeningTagStart,
- printOpeningTagStartMarker,
- needsToBorrowNextOpeningTagStartMarker,
} = require("./print/tag.js");
-const getNodeContent = require("./get-node-content.js");
+const { printElement } = require("./print/element.js");
+const { printChildren } = require("./print/children.js");
function genericPrint(path, options, print) {
const node = path.getValue();
@@ -153,335 +124,6 @@ function genericPrint(path, options, print) {
}
}
-function printElement(path, options, print) {
- const node = path.getValue();
-
- if (shouldPreserveContent(node, options)) {
- return [
- printOpeningTagPrefix(node, options),
- group(printOpeningTag(path, options, print)),
- ...replaceTextEndOfLine(getNodeContent(node, options)),
- ...printClosingTag(node, options),
- printClosingTagSuffix(node, options),
- ];
- }
- /**
- * do not break:
- *
- * {{
- * ~
- * interpolation
- * }}
- * ~
- *
- * exception: break if the opening tag breaks
- *
- * {{
- * interpolation
- * }}
- */
- const shouldHugContent =
- node.children.length === 1 &&
- node.firstChild.type === "interpolation" &&
- node.firstChild.isLeadingSpaceSensitive &&
- !node.firstChild.hasLeadingSpaces &&
- node.lastChild.isTrailingSpaceSensitive &&
- !node.lastChild.hasTrailingSpaces;
-
- const attrGroupId = Symbol("element-attr-group-id");
-
- const printTag = (doc) =>
- group([
- group(printOpeningTag(path, options, print), { id: attrGroupId }),
- doc,
- printClosingTag(node, options),
- ]);
-
- const printChildrenDoc = (childrenDoc) => {
- if (shouldHugContent) {
- return indentIfBreak(childrenDoc, { groupId: attrGroupId });
- }
- if (
- (isScriptLikeTag(node) || isVueCustomBlock(node, options)) &&
- node.parent.type === "root" &&
- options.parser === "vue" &&
- !options.vueIndentScriptAndStyle
- ) {
- return childrenDoc;
- }
- return indent(childrenDoc);
- };
-
- const printLineBeforeChildren = () => {
- if (shouldHugContent) {
- return ifBreak(softline, "", { groupId: attrGroupId });
- }
- if (
- node.firstChild.hasLeadingSpaces &&
- node.firstChild.isLeadingSpaceSensitive
- ) {
- return line;
- }
- if (
- node.firstChild.type === "text" &&
- node.isWhitespaceSensitive &&
- node.isIndentationSensitive
- ) {
- return dedentToRoot(softline);
- }
- return softline;
- };
-
- const printLineAfterChildren = () => {
- const needsToBorrow = node.next
- ? needsToBorrowPrevClosingTagEndMarker(node.next)
- : needsToBorrowLastChildClosingTagEndMarker(node.parent);
- if (needsToBorrow) {
- if (
- node.lastChild.hasTrailingSpaces &&
- node.lastChild.isTrailingSpaceSensitive
- ) {
- return " ";
- }
- return "";
- }
- if (shouldHugContent) {
- return ifBreak(softline, "", { groupId: attrGroupId });
- }
- if (
- node.lastChild.hasTrailingSpaces &&
- node.lastChild.isTrailingSpaceSensitive
- ) {
- return line;
- }
- if (
- (node.lastChild.type === "comment" ||
- (node.lastChild.type === "text" &&
- node.isWhitespaceSensitive &&
- node.isIndentationSensitive)) &&
- new RegExp(
- `\\n[\\t ]{${
- options.tabWidth *
- countParents(
- path,
- (node) => node.parent && node.parent.type !== "root"
- )
- }}$`
- ).test(node.lastChild.value)
- ) {
- return "";
- }
- return softline;
- };
-
- if (node.children.length === 0) {
- return printTag(
- node.hasDanglingSpaces && node.isDanglingSpaceSensitive ? line : ""
- );
- }
-
- return printTag([
- forceBreakContent(node) ? breakParent : "",
- printChildrenDoc([
- printLineBeforeChildren(),
- printChildren(path, options, print),
- ]),
- printLineAfterChildren(),
- ]);
-}
-
-function printChildren(path, options, print) {
- const node = path.getValue();
-
- if (forceBreakChildren(node)) {
- return [
- breakParent,
-
- ...path.map((childPath) => {
- const childNode = childPath.getValue();
- const prevBetweenLine = !childNode.prev
- ? ""
- : printBetweenLine(childNode.prev, childNode);
- return [
- !prevBetweenLine
- ? ""
- : [
- prevBetweenLine,
- forceNextEmptyLine(childNode.prev) ? hardline : "",
- ],
- printChild(childPath),
- ];
- }, "children"),
- ];
- }
-
- const groupIds = node.children.map(() => Symbol(""));
- return path.map((childPath, childIndex) => {
- const childNode = childPath.getValue();
-
- if (isTextLikeNode(childNode)) {
- if (childNode.prev && isTextLikeNode(childNode.prev)) {
- const prevBetweenLine = printBetweenLine(childNode.prev, childNode);
- if (prevBetweenLine) {
- if (forceNextEmptyLine(childNode.prev)) {
- return [hardline, hardline, printChild(childPath)];
- }
- return [prevBetweenLine, printChild(childPath)];
- }
- }
- return printChild(childPath);
- }
-
- const prevParts = [];
- const leadingParts = [];
- const trailingParts = [];
- const nextParts = [];
-
- const prevBetweenLine = childNode.prev
- ? printBetweenLine(childNode.prev, childNode)
- : "";
-
- const nextBetweenLine = childNode.next
- ? printBetweenLine(childNode, childNode.next)
- : "";
-
- if (prevBetweenLine) {
- if (forceNextEmptyLine(childNode.prev)) {
- prevParts.push(hardline, hardline);
- } else if (prevBetweenLine === hardline) {
- prevParts.push(hardline);
- } else {
- if (isTextLikeNode(childNode.prev)) {
- leadingParts.push(prevBetweenLine);
- } else {
- leadingParts.push(
- ifBreak("", softline, {
- groupId: groupIds[childIndex - 1],
- })
- );
- }
- }
- }
-
- if (nextBetweenLine) {
- if (forceNextEmptyLine(childNode)) {
- if (isTextLikeNode(childNode.next)) {
- nextParts.push(hardline, hardline);
- }
- } else if (nextBetweenLine === hardline) {
- if (isTextLikeNode(childNode.next)) {
- nextParts.push(hardline);
- }
- } else {
- trailingParts.push(nextBetweenLine);
- }
- }
-
- return [
- ...prevParts,
- group([
- ...leadingParts,
- group([printChild(childPath), ...trailingParts], {
- id: groupIds[childIndex],
- }),
- ]),
- ...nextParts,
- ];
- }, "children");
-
- function printChild(childPath) {
- const child = childPath.getValue();
-
- if (hasPrettierIgnore(child)) {
- return [
- printOpeningTagPrefix(child, options),
- ...replaceTextEndOfLine(
- options.originalText.slice(
- locStart(child) +
- (child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev)
- ? printOpeningTagStartMarker(child).length
- : 0),
- locEnd(child) -
- (child.next && needsToBorrowPrevClosingTagEndMarker(child.next)
- ? printClosingTagEndMarker(child, options).length
- : 0)
- )
- ),
- printClosingTagSuffix(child, options),
- ];
- }
-
- return print();
- }
-
- function printBetweenLine(prevNode, nextNode) {
- return isTextLikeNode(prevNode) && isTextLikeNode(nextNode)
- ? prevNode.isTrailingSpaceSensitive
- ? prevNode.hasTrailingSpaces
- ? preferHardlineAsLeadingSpaces(nextNode)
- ? hardline
- : line
- : ""
- : preferHardlineAsLeadingSpaces(nextNode)
- ? hardline
- : softline
- : (needsToBorrowNextOpeningTagStartMarker(prevNode) &&
- (hasPrettierIgnore(nextNode) ||
- /**
- * 123
- */
- nextNode.firstChild ||
- /**
- * 123
- */
- nextNode.isSelfClosing ||
- /**
- * 123 0))) ||
- /**
- *
123
- */
- (prevNode.type === "element" &&
- prevNode.isSelfClosing &&
- needsToBorrowPrevClosingTagEndMarker(nextNode))
- ? ""
- : !nextNode.isLeadingSpaceSensitive ||
- preferHardlineAsLeadingSpaces(nextNode) ||
- /**
- * Want to write us a letter? Use ourmailing address.
- */
- (needsToBorrowPrevClosingTagEndMarker(nextNode) &&
- prevNode.lastChild &&
- needsToBorrowParentClosingTagStartMarker(prevNode.lastChild) &&
- prevNode.lastChild.lastChild &&
- needsToBorrowParentClosingTagStartMarker(
- prevNode.lastChild.lastChild
- ))
- ? hardline
- : nextNode.hasLeadingSpaces
- ? line
- : softline;
- }
-}
-
module.exports = {
preprocess,
print: genericPrint,