diff --git a/packages/expression-parser/package-lock.json b/packages/expression-parser/package-lock.json
index a0bf0f1..4df2da9 100644
--- a/packages/expression-parser/package-lock.json
+++ b/packages/expression-parser/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@starptech/expression-parser",
- "version": "0.8.4",
+ "version": "0.8.12",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1778,12 +1778,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -1798,17 +1800,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -1925,7 +1930,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -1937,6 +1943,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -1951,6 +1958,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -1958,12 +1966,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -1982,6 +1992,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -2062,7 +2073,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -2074,6 +2086,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -2195,6 +2208,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
diff --git a/packages/prettyhtml-formatter/index.js b/packages/prettyhtml-formatter/index.js
index 1e92b3b..61745f0 100644
--- a/packages/prettyhtml-formatter/index.js
+++ b/packages/prettyhtml-formatter/index.js
@@ -114,25 +114,7 @@ function format(options) {
}
if (is('comment', node)) {
- /**
- * indent last line of comment
- * e.g
- *
- * to
- *
- */
-
- let commentLines = node.value.split(single)
- if (commentLines.length > 1) {
- commentLines[commentLines.length - 1] =
- repeat(indent, level - 1) +
- commentLines[commentLines.length - 1].trim()
- node.value = commentLines.join(single)
- }
+ indentComment(node, indent, level)
}
/**
@@ -144,7 +126,7 @@ function format(options) {
// clear empty script, textarea, pre, style tags
if (length) {
- const empty = containsOnlyEmptyTextNodes(node)
+ const empty = hasOnlyEmptyTextChildren(node)
const isEmbeddedContent =
isElement(node, 'style') || isElement(node, 'script')
if (empty) {
@@ -158,6 +140,9 @@ function format(options) {
return visit.SKIP
}
+ let newline = false
+ const willBreak = collapsed(node, children)
+
/**
* Indent children
*/
@@ -166,12 +151,16 @@ function format(options) {
let child = children[index]
// only indent text in nodes
- // root text nodes should't influence other root nodes
+ // root text nodes should't influence other root nodes^^
if (node.type === 'root') {
break
}
if (is('text', child)) {
+ if (containsNewline(child) || willBreak) {
+ newline = true
+ }
+
child.value = child.value
// reduce newlines to one newline
// $& contains the lastMatch
@@ -182,12 +171,9 @@ function format(options) {
// reset
result = []
index = -1
-
node.children = result
- let prevChild
- let hasLeadingNewline = false
-
+ let prevChild = null
if (length) {
// walk through children
// hint: a child has no children informations we already walking through
@@ -215,25 +201,14 @@ function format(options) {
value: double + repeat(indent, indentLevel)
})
} else if (
- !endsWithNewline(prevChild) &&
- beforeChildNodeAddedHook(node, children, child, index, prevChild)
+ beforeChildNodeAddedHook(node, children, child, index, prevChild) ||
+ (newline && index === 0)
) {
- // all template expression are indented on a ewline thats why need to check
- // so that we don't add another one
- if (index === 0 && checkForTemplateExpression(child.value)) {
- hasLeadingNewline = true
- }
// only necessary because we are trying to indent tags on newlines
// even when in inline context when possible
if (is('text', prevChild)) {
// remove trailing whitespaces and tabs because a newline is inserted before
prevChild.value = prevChild.value.replace(/[ \t]+$/, '')
-
- // adds a leading newline because the sibling node is indented on a newline
- if (index === 1 && hasLeadingNewline === false) {
- prevChild.value =
- single + repeat(indent, indentLevel) + prevChild.value
- }
}
// remove leading whitespaces and tabs because a newline is inserted before
if (is('text', child)) {
@@ -245,15 +220,6 @@ function format(options) {
value: single + repeat(indent, indentLevel)
})
}
- // adds a leading newline when he sibling element was inteded on a newline and when no newlines was added
- else if (
- is('text', child) &&
- hasLeadingNewline === false &&
- endsWithNewline(child) &&
- !startsWithNewline(child)
- ) {
- child.value = single + repeat(indent, indentLevel) + child.value
- }
prevChild = child
@@ -261,7 +227,7 @@ function format(options) {
}
}
- if (afterChildNodesAddedHook(node, prevChild)) {
+ if (afterChildNodesAddedHook(node, prevChild) || newline) {
result.push({
type: 'text',
value: single + repeat(indent, level - 1)
@@ -279,12 +245,36 @@ function startsWithNewline(node) {
return is('text', node) && node.value && /^\s*\n/.test(node.value)
}
+function containsNewline(node) {
+ return node.value.indexOf(single) !== -1
+}
+
+/**
+ * indent last line of comment
+ * e.g
+ *
+ * to
+ *
+ */
+function indentComment(node, indent, level) {
+ let commentLines = node.value.split(single)
+ if (commentLines.length > 1) {
+ commentLines[commentLines.length - 1] =
+ repeat(indent, level - 1) + commentLines[commentLines.length - 1].trim()
+ node.value = commentLines.join(single)
+ }
+}
+
function handleTemplateExpression(child, children) {
const brackets = checkForTemplateExpression(child.value)
if (brackets) {
// dont touch nodes with single text element
if (
- containsOnlyTextNodes({
+ hasOnlyTextChildren({
children
})
) {
@@ -300,7 +290,30 @@ function handleTemplateExpression(child, children) {
}
}
+/**
+ * Check if any children will be wrapped on a newline
+ * @param {*} node
+ * @param {*} children
+ */
+function collapsed(node, children) {
+ let index = -1
+ let prevChild = false
+ while (++index < children.length) {
+ let child = children[index]
+ if (beforeChildNodeAddedHook(node, children, child, index, prevChild)) {
+ return true
+ }
+ prevChild = child
+ }
+}
+
function beforeChildNodeAddedHook(node, children, child, index, prev) {
+ // don't add newline when prev child already has one
+ if (endsWithNewline(prev)) {
+ return false
+ }
+
+ // every template expression is indented on a newline
if (is('text', child) && handleTemplateExpression(child, children)) {
return true
}
@@ -310,11 +323,12 @@ function beforeChildNodeAddedHook(node, children, child, index, prev) {
return true
}
+ // embedded content is indented on newlines
if (isElement(child, ['script', 'style']) && index !== 0) {
return true
}
- // don't add newline on the first element
+ // don't add newline on the first element of the page
const isRootElement = node.type === 'root' && index === 0
if (isRootElement) {
return false
@@ -336,15 +350,15 @@ function afterChildNodesAddedHook(node, prev) {
/**
* e.g
*/
- if (hasChilds && !containsOnlyTextNodes(node) && !isVoid(node)) {
+ if (hasChilds && !hasOnlyTextChildren(node) && !isVoid(node)) {
return true
}
/**
* e.g
*/
- const isPrevRawText = is('text', prev)
- return hasChilds && !isVoid(node) && !isPrevRawText
+ const isPrevTextNode = is('text', prev)
+ return hasChilds && !isVoid(node) && !isPrevTextNode
}
function checkForTemplateExpression(value) {
@@ -363,7 +377,7 @@ function checkForTemplateExpression(value) {
return null
}
-function containsOnlyTextNodes(node) {
+function hasOnlyTextChildren(node) {
const children = node.children || []
if (children.length === 0) {
@@ -373,7 +387,7 @@ function containsOnlyTextNodes(node) {
return children.every(n => is('text', n))
}
-function containsOnlyEmptyTextNodes(node) {
+function hasOnlyEmptyTextChildren(node) {
const children = node.children || []
if (children.length === 0) {
diff --git a/packages/prettyhtml-formatter/test/fixtures/indent-multiline-text/output.html b/packages/prettyhtml-formatter/test/fixtures/indent-multiline-text/output.html
index 2c30d0f..f09db94 100644
--- a/packages/prettyhtml-formatter/test/fixtures/indent-multiline-text/output.html
+++ b/packages/prettyhtml-formatter/test/fixtures/indent-multiline-text/output.html
@@ -1,6 +1,8 @@
-
I am writing to tell you that I am
+ extremely excited about this new
+ HTML formatter. It promises to be
+ as far as I can tell both
+ flexible and
+ resilient in the face of many new ways of writing
+ HTML
+
+ I am writing to tell you that I am
+ extremely excited about this new
+ HTML formatter. It promises to be
+ as far as I can tell both
+ flexible and
+ resilient in the face of many new ways of writing
+ HTML
+Cats of YouTube
{/each}
-
diff --git a/packages/prettyhtml-formatter/test/fixtures/whitespace-leading-text/output.html b/packages/prettyhtml-formatter/test/fixtures/whitespace-leading-text/output.html index 1fb75dd..3032b6e 100644 --- a/packages/prettyhtml-formatter/test/fixtures/whitespace-leading-text/output.html +++ b/packages/prettyhtml-formatter/test/fixtures/whitespace-leading-text/output.html @@ -10,8 +10,7 @@Some -
code
- , +code
, emphasis, and
importance @@ -20,8 +19,7 @@Some -
code
- , +code
, emphasis, and
importance diff --git a/packages/prettyhtml/package-lock.json b/packages/prettyhtml/package-lock.json index 8c844c4..027a5c6 100644 --- a/packages/prettyhtml/package-lock.json +++ b/packages/prettyhtml/package-lock.json @@ -1761,12 +1761,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1781,17 +1783,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1908,7 +1913,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1920,6 +1926,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1934,6 +1941,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1941,12 +1949,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -1965,6 +1975,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2045,7 +2056,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2057,6 +2069,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2178,6 +2191,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",