UNPKG

@shopify/prettier-plugin-liquid

Version:
271 lines 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLastDescendant = exports.hasMeaningfulLackOfDanglingWhitespace = exports.hasMeaningfulLackOfTrailingWhitespace = exports.hasMeaningfulLackOfLeadingWhitespace = exports.preferHardlineAsTrailingSpaces = exports.preferHardlineAsLeadingSpaces = exports.preferHardlineAsSurroundingSpaces = exports.forceBreakChildren = exports.forceBreakContent = exports.forceNextEmptyLine = exports.isPrettierIgnoreAttributeNode = exports.hasPrettierIgnore = exports.isPrettierIgnoreNode = exports.isPrettierIgnoreLiquidNode = exports.isPrettierIgnoreHtmlNode = exports.shouldPreserveContent = exports.hasNonTextChild = exports.isAttributeNode = exports.isHtmlNode = exports.isMultilineLiquidTag = exports.isLiquidNode = exports.isTextLikeNode = exports.isHtmlElement = exports.isVoidElement = exports.isSelfClosing = exports.isHtmlComment = exports.isHtmlDanglingMarkerClose = exports.isHtmlDanglingMarkerOpen = exports.hasNoChildren = exports.hasNoCloseMarker = exports.isPreLikeNode = exports.isScriptLikeTag = void 0; const liquid_html_parser_1 = require("@shopify/liquid-html-parser"); const array_1 = require("./array"); function isScriptLikeTag(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlRawNode; } exports.isScriptLikeTag = isScriptLikeTag; function isPreLikeNode(node) { return node.cssWhitespace.startsWith('pre'); } exports.isPreLikeNode = isPreLikeNode; // A bit like self-closing except we distinguish between them. // Comments are also considered self-closing. function hasNoCloseMarker(node) { return hasNoChildren(node) || isHtmlDanglingMarkerOpen(node); } exports.hasNoCloseMarker = hasNoCloseMarker; function hasNoChildren(node) { return (isSelfClosing(node) || isVoidElement(node) || isHtmlComment(node) || isHtmlDanglingMarkerClose(node)); } exports.hasNoChildren = hasNoChildren; function isHtmlDanglingMarkerOpen(node) { return (node.type === liquid_html_parser_1.NodeTypes.HtmlElement && node.blockEndPosition.start === node.blockEndPosition.end); } exports.isHtmlDanglingMarkerOpen = isHtmlDanglingMarkerOpen; function isHtmlDanglingMarkerClose(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlDanglingMarkerClose; } exports.isHtmlDanglingMarkerClose = isHtmlDanglingMarkerClose; function isHtmlComment(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlComment; } exports.isHtmlComment = isHtmlComment; function isSelfClosing(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlSelfClosingElement; } exports.isSelfClosing = isSelfClosing; function isVoidElement(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlVoidElement; } exports.isVoidElement = isVoidElement; function isHtmlElement(node) { return node.type === liquid_html_parser_1.NodeTypes.HtmlElement; } exports.isHtmlElement = isHtmlElement; function isTextLikeNode(node) { return !!node && node.type === liquid_html_parser_1.NodeTypes.TextNode; } exports.isTextLikeNode = isTextLikeNode; function isLiquidNode(node) { return !!node && liquid_html_parser_1.LiquidNodeTypes.includes(node.type); } exports.isLiquidNode = isLiquidNode; function isMultilineLiquidTag(node) { return !!node && node.type === liquid_html_parser_1.NodeTypes.LiquidTag && !!node.children && !(0, array_1.isEmpty)(node.children); } exports.isMultilineLiquidTag = isMultilineLiquidTag; function isHtmlNode(node) { return !!node && liquid_html_parser_1.HtmlNodeTypes.includes(node.type); } exports.isHtmlNode = isHtmlNode; function isAttributeNode(node) { return (isHtmlNode(node.parentNode) && 'attributes' in node.parentNode && node.parentNode.attributes.indexOf(node) !== -1); } exports.isAttributeNode = isAttributeNode; function hasNonTextChild(node) { return (node.children && node.children.some((child) => child.type !== liquid_html_parser_1.NodeTypes.TextNode)); } exports.hasNonTextChild = hasNonTextChild; function shouldPreserveContent(node) { // // unterminated node in ie conditional comment // // e.g. <!--[if lt IE 9]><html><![endif]--> // if ( // node.type === "ieConditionalComment" && // node.lastChild && // !node.lastChild.isSelfClosing && // !node.lastChild.endSourceSpan // ) { // return true; // } // // incomplete html in ie conditional comment // // e.g. <!--[if lt IE 9]></div><![endif]--> // if (node.type === "ieConditionalComment" && !node.complete) { // return true; // } // TODO: Handle pre correctly? if (isPreLikeNode(node)) { return true; } return false; } exports.shouldPreserveContent = shouldPreserveContent; function isPrettierIgnoreHtmlNode(node) { return (!!node && node.type === liquid_html_parser_1.NodeTypes.HtmlComment && /^\s*prettier-ignore(?=\s|$)/m.test(node.body)); } exports.isPrettierIgnoreHtmlNode = isPrettierIgnoreHtmlNode; function isPrettierIgnoreLiquidNode(node) { return (!!node && node.type === liquid_html_parser_1.NodeTypes.LiquidTag && node.name === '#' && /^\s*prettier-ignore(?=\s|$)/m.test(node.markup)); } exports.isPrettierIgnoreLiquidNode = isPrettierIgnoreLiquidNode; function isPrettierIgnoreNode(node) { return isPrettierIgnoreLiquidNode(node) || isPrettierIgnoreHtmlNode(node); } exports.isPrettierIgnoreNode = isPrettierIgnoreNode; function hasPrettierIgnore(node) { return isPrettierIgnoreNode(node) || isPrettierIgnoreNode(node.prev); } exports.hasPrettierIgnore = hasPrettierIgnore; function getPrettierIgnoreAttributeCommentData(value) { const match = value.trim().match(/prettier-ignore-attribute(?:s?)(?:\s+(.+))?$/s); if (!match) { return false; } if (!match[1]) { return true; } // TODO We should support 'prettier-ignore-attribute a,b,c' and allow users to not // format the insides of some attributes. // // But since we don't reformat the insides of attributes yet (because of // issue #4), that feature doesn't really make sense. // // For now, we'll only support `prettier-ignore-attribute` // // https://github.com/Shopify/prettier-plugin-liquid/issues/4 // // return match[1].split(/\s+/); return true; } function isPrettierIgnoreAttributeNode(node) { if (!node) return false; if (node.type === liquid_html_parser_1.NodeTypes.HtmlComment) { return getPrettierIgnoreAttributeCommentData(node.body); } if (node.type === liquid_html_parser_1.NodeTypes.LiquidTag && node.name === '#') { return getPrettierIgnoreAttributeCommentData(node.markup); } return false; } exports.isPrettierIgnoreAttributeNode = isPrettierIgnoreAttributeNode; function forceNextEmptyLine(node) { if (!node) return false; if (!node.next) return false; const source = node.source; // Current implementation: force next empty line when two consecutive // lines exist between nodes. let tmp; tmp = source.indexOf('\n', node.position.end); if (tmp === -1) return false; tmp = source.indexOf('\n', tmp + 1); if (tmp === -1) return false; return tmp < node.next.position.start; } exports.forceNextEmptyLine = forceNextEmptyLine; /** firstChild leadingSpaces and lastChild trailingSpaces */ function forceBreakContent(node) { return (forceBreakChildren(node) || (node.type === liquid_html_parser_1.NodeTypes.HtmlElement && node.children.length > 0 && (isTagNameIncluded(['body', 'script', 'style'], node.name) || node.children.some((child) => hasNonTextChild(child)))) || (node.firstChild && node.firstChild === node.lastChild && node.firstChild.type !== liquid_html_parser_1.NodeTypes.TextNode && hasLeadingLineBreak(node.firstChild) && (!node.lastChild.isTrailingWhitespaceSensitive || hasTrailingLineBreak(node.lastChild)))); } exports.forceBreakContent = forceBreakContent; /** spaces between children */ function forceBreakChildren(node) { return (node.type === liquid_html_parser_1.NodeTypes.HtmlElement && node.children.length > 0 && (isTagNameIncluded(['html', 'head', 'ul', 'ol', 'select'], node.name) || (node.cssDisplay.startsWith('table') && node.cssDisplay !== 'table-cell'))); } exports.forceBreakChildren = forceBreakChildren; function preferHardlineAsSurroundingSpaces(node) { switch (node.type) { // case 'ieConditionalComment': case liquid_html_parser_1.NodeTypes.HtmlComment: return true; case liquid_html_parser_1.NodeTypes.HtmlElement: return isTagNameIncluded(['script', 'select'], node.name); case liquid_html_parser_1.NodeTypes.LiquidTag: if ((node.prev && isTextLikeNode(node.prev)) || (node.next && isTextLikeNode(node.next))) { return false; } return node.children && node.children.length > 0; } return false; } exports.preferHardlineAsSurroundingSpaces = preferHardlineAsSurroundingSpaces; function preferHardlineAsLeadingSpaces(node) { return (preferHardlineAsSurroundingSpaces(node) || (isLiquidNode(node) && node.prev && isLiquidNode(node.prev)) || (node.prev && preferHardlineAsTrailingSpaces(node.prev)) || hasSurroundingLineBreak(node)); } exports.preferHardlineAsLeadingSpaces = preferHardlineAsLeadingSpaces; function preferHardlineAsTrailingSpaces(node) { return (preferHardlineAsSurroundingSpaces(node) || (isLiquidNode(node) && node.next && (isLiquidNode(node.next) || isHtmlNode(node.next))) || (node.type === liquid_html_parser_1.NodeTypes.HtmlElement && isTagNameIncluded(['br'], node.name)) || hasSurroundingLineBreak(node)); } exports.preferHardlineAsTrailingSpaces = preferHardlineAsTrailingSpaces; function hasMeaningfulLackOfLeadingWhitespace(node) { return node.isLeadingWhitespaceSensitive && !node.hasLeadingWhitespace; } exports.hasMeaningfulLackOfLeadingWhitespace = hasMeaningfulLackOfLeadingWhitespace; function hasMeaningfulLackOfTrailingWhitespace(node) { return node.isTrailingWhitespaceSensitive && !node.hasTrailingWhitespace; } exports.hasMeaningfulLackOfTrailingWhitespace = hasMeaningfulLackOfTrailingWhitespace; function hasMeaningfulLackOfDanglingWhitespace(node) { return node.isDanglingWhitespaceSensitive && !node.hasDanglingWhitespace; } exports.hasMeaningfulLackOfDanglingWhitespace = hasMeaningfulLackOfDanglingWhitespace; function hasSurroundingLineBreak(node) { return hasLeadingLineBreak(node) && hasTrailingLineBreak(node); } function hasLeadingLineBreak(node) { if (node.type === liquid_html_parser_1.NodeTypes.Document) return false; return (node.hasLeadingWhitespace && hasLineBreakInRange(node.source, node.prev ? node.prev.position.end : node.parentNode.blockStartPosition ? node.parentNode.blockStartPosition.end : node.parentNode.position.start, node.position.start)); } function hasTrailingLineBreak(node) { if (node.type === liquid_html_parser_1.NodeTypes.Document) return false; return (node.hasTrailingWhitespace && hasLineBreakInRange(node.source, node.position.end, node.next ? node.next.position.start : node.parentNode.blockEndPosition ? node.parentNode.blockEndPosition.start : node.parentNode.position.end)); } function hasLineBreakInRange(source, start, end) { const index = source.indexOf('\n', start); return index !== -1 && index < end; } function getLastDescendant(node) { return node.lastChild ? getLastDescendant(node.lastChild) : node; } exports.getLastDescendant = getLastDescendant; function isTagNameIncluded(collection, name) { if (name.length !== 1 || name[0].type !== liquid_html_parser_1.NodeTypes.TextNode) return false; return collection.includes(name[0].value); } //# sourceMappingURL=node.js.map