Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions javascript/packages/formatter/src/format-printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ export class FormatPrinter extends Printer {

if (adjacentInlineCount >= 2) {
const { processedIndices } = this.renderAdjacentInlineElements(children, adjacentInlineCount)
this.visitRemainingChildren(children, processedIndices)
this.visitRemainingChildrenAsTextFlow(children, processedIndices)

return
}
Expand Down Expand Up @@ -1975,7 +1975,7 @@ export class FormatPrinter extends Printer {
}
}

if (lastProcessedIndex >= 0) {
if (inlineContent && lastProcessedIndex >= 0) {
for (let index = lastProcessedIndex + 1; index < children.length; index++) {
const child = children[index]

Expand Down Expand Up @@ -2101,6 +2101,55 @@ export class FormatPrinter extends Printer {
}
}

/**
* Visit remaining children as text flow after processing adjacent inline elements.
* Detects subsequent groups of adjacent inline elements and renders them as a group,
* while passing non-group children through text flow wrapping.
*/
private visitRemainingChildrenAsTextFlow(children: Node[], processedIndices: Set<number>): void {
let index = 0
let textFlowBuffer: Node[] = []

const flushTextFlow = () => {
if (textFlowBuffer.length > 0) {
this.buildAndWrapTextFlow(textFlowBuffer)
textFlowBuffer = []
}
}

while (index < children.length) {
const child = children[index]

if (processedIndices.has(index)) {
index++
continue
}

if (isPureWhitespaceNode(child) || isNode(child, WhitespaceNode)) {
textFlowBuffer.push(child)
index++
continue
}

const adjacentCount = countAdjacentInlineElements(children, index, processedIndices)

if (adjacentCount >= 2) {
flushTextFlow()

const { processedIndices: newProcessedIndices, lastIndex } =
this.renderAdjacentInlineElements(children, adjacentCount, index, processedIndices)

newProcessedIndices.forEach(i => processedIndices.add(i))
index = lastIndex + 1
} else {
textFlowBuffer.push(child)
index++
}
}

flushTextFlow()
}

/**
* Build words array from text/inline/ERB and wrap them
*/
Expand Down Expand Up @@ -2152,6 +2201,13 @@ export class FormatPrinter extends Printer {
}
}

// Trim trailing space from last word before final flush - trailing spaces are
// informational for spacing with subsequent words but shouldn't inflate
// effective length when it's the final word (it gets trimmed from output anyway)
if (words.length > 0) {
words[words.length - 1].word = words[words.length - 1].word.trimEnd()
}

this.flushWords(words)
}

Expand Down Expand Up @@ -2462,7 +2518,7 @@ export class FormatPrinter extends Printer {
nextEffectiveLength = effectiveLength + spaceBefore + word.length
}

if (currentLine && !isClosingPunctuation(word) && nextEffectiveLength >= wrapWidth) {
if (currentLine && !isClosingPunctuation(word) && nextEffectiveLength > wrapWidth) {
lines.push(this.indent + currentLine.trimEnd())

currentLine = word
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,7 @@ describe("Document-level formatting", () => {
</h1>

<h2 class="text-inherit opacity-60 text-sm line-clamp-1">
<%= event.static_metadata.location %> •
<%= event.formatted_dates %>
<%= event.static_metadata.location %> • <%= event.formatted_dates %>
</h2>

<h2 class="text-inherit font-medium text-sm line-clamp-3 hidden lg:block">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ describe("ERB Formatter Additional Tests", () => {
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. 🍰🍰🍰🍰🍰🍰🍰🍰🍰🍰Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo <span>co<strong>nse</strong>quat.</span> Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
aliquip ex ea commodo <span>co<strong>nse</strong>quat.</span> Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
`)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@ describe("ERB Formatter Compatibility Tests", () => {
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. 🍰🍰🍰🍰🍰🍰🍰🍰🍰🍰Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo <span>co<strong>nse</strong>quat.</span> Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
aliquip ex ea commodo <span>co<strong>nse</strong>quat.</span> Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
`)
})
Expand Down
38 changes: 18 additions & 20 deletions javascript/packages/formatter/test/erb/erb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,7 @@ describe("@herb-tools/formatter", () => {
<p>
This will be the all-in-one home for everything to do with
<a href="https://hanamirb.org">Hanami</a>,
<a href="https://dry-rb.org">Dry</a> and
<a href="https://rom-rb.org">Rom</a>.
<a href="https://dry-rb.org">Dry</a> and <a href="https://rom-rb.org">Rom</a>.
</p>
`)

Expand Down Expand Up @@ -384,13 +383,13 @@ describe("@herb-tools/formatter", () => {
const result = formatter.format(input)

expect(result).toBe(dedent`
<p>
Visit
<a href="/products">our amazing product catalog with hundreds of items</a>
or <a href="/support">contact our customer support team</a> for assistance
with your order.
</p>
`)
<p>
Visit
<a href="/products">our amazing product catalog with hundreds of items</a> or
<a href="/support">contact our customer support team</a> for assistance with
your order.
</p>
`)
})

test("handles multiple inline elements with adjacent text", () => {
Expand Down Expand Up @@ -676,8 +675,8 @@ describe("@herb-tools/formatter", () => {
<%= hosted_image_tag('mailer/footer-logo.png', class: 'h-[48px] mb-1') %>

<p class="text-muted-foreground text-sm leading-5">
&copy;<%= Time.current.year %> - Company Inc, All
rights reserved.
&copy;<%= Time.current.year %> - Company Inc, All rights
reserved.
<br />
Main Street, San Francisco, CAs, USA 12345
<br />
Expand Down Expand Up @@ -1387,16 +1386,15 @@ describe("@herb-tools/formatter", () => {
<span>
<strong>Cover Image</strong><br>
Dimensions
<strong>
<%= "#{cover.metadata['width']}x#{cover.metadata['height']}" %>
</strong>
<strong><%= "#{cover.metadata['width']}x#{cover.metadata['height']}" %></strong>
&mdash;
<%= link_to "View original", rails_blob_path(cover), target: "_blank", rel: "noopener" %>
</span>
</figcaption>
</figure>
<% end %>
`)

})

test("adjecent ERB text within elements", () => {
Expand Down Expand Up @@ -1461,8 +1459,8 @@ describe("@herb-tools/formatter", () => {

const expected = dedent`
<div>
<%= icon("icon") %>some text some text some text some text some text some
text some text
<%= icon("icon") %>some text some text some text some text some text some text
some text
</div>
`

Expand All @@ -1472,12 +1470,12 @@ describe("@herb-tools/formatter", () => {

test("ERB output after adjecent text within HTML element causing line-break", () => {
const input = dedent`
<div>some text some text some text some text some text some text<%= icon("icon") %></div>
<div>some text some text some text some text some text somes text<%= icon("icon") %></div>
`

const expected = dedent`
<div>
some text some text some text some text some text some
some text some text some text some text some text somes
text<%= icon("icon") %>
</div>
`
Expand Down Expand Up @@ -1554,8 +1552,8 @@ describe("@herb-tools/formatter", () => {

const expected = dedent`
<%= link_to "/" do %>
<%= icon("icon") %>some text some text some text some text some text some
text some text
<%= icon("icon") %>some text some text some text some text some text some text
some text
<% end %>
`

Expand Down
Loading
Loading