markmark206

markmark206

HEEX formatter adds a line break in generated html?

HEEX formatter (Phoenix.LiveView.HTMLFormatter / mix format) seems to introduce an unexpected line break in the generated html. User error? A bug? ; )

This looks super-related to Formatter adds space/newline to inline elements · Issue #2237 · phoenixframework/phoenix_live_view · GitHub, but, AFAICT, the fix got merged in LiveView 0.18.2, and I am seeing the problem in 0.18.3.

Details:

Here is my repro (happy to provide a more streamline repro gist, if useful):

I want to add a comma after some text

        <%= link to: ... do %>
          <%= @item.content %><% end %>,

and this works great. Here is the web page (loaded in Safari, on a Mac):
image

Running mix format, moves the <% end %> element (and, therefore, the comma that follows) to its own line:

        <%= link to: ... do %>
          <%= @item.content %>
        <% end %>,

which introduces a space before the comma:
image

I am not expecting a code formatter to change what the code does, only what the code looks like. Am I doing something obviously silly here, or does this look like a bug? ; )

Thank you!

PS A bit more data:

$ cat .formatter.exs
[
  line_length: 120,
  import_deps: [:ecto, :phoenix],
  plugins: [Phoenix.LiveView.HTMLFormatter],
  inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"],
  subdirectories: ["priv/*/migrations"]
]
$ cat mix.exs | grep phoenix
      {:phoenix, "~> 1.6"},
      {:phoenix_ecto, "~> 4.4"},
      {:phoenix_html, "~> 3.2"},
      {:phoenix_live_dashboard, "~> 0.7"},
      {:phoenix_live_reload, "~> 1.4", only: :dev},
      {:phoenix_live_view, "~> 0.18.3"},
$ elixir --version
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit] [dtrace]

Elixir 1.14.1 (compiled with Erlang/OTP 25)

First 9 of 9 Posts Switch mode

BartOtten

BartOtten

I guess this has to do with how how HTML is specced. Browsers condense multiple whitespace characters (including newlines) to a single space for most scripts (Latin for example).

Can you show us the generated HTML source? Won’t be surprised when it looks like

<a href=“http://foo.com”>content</a>
,

or

<a href=“http://foo.com”>
   content
</a>
,

W3C about whitespace

However…as this is code and not HTML I guess the formatter should recognize such and this is a bug.

zachallaun

zachallaun

In the meantime, you could do:

<%= link to: ... do %>
  <%= "#{@item.content}," %>
<% end %>
markmark206

markmark206 OP

Sure, here is what the html looks like in both cases:

$ elixir heexformat.exs
next_line: "<a href=\"/i\">\n  next line\n</a>,\n" <<<<< notice \n just before the closing </a> and ","
same_line: "<a href=\"/i\">\n  same line</a>,\n"

, where heexformat.exs is

Mix.install(
  [
    {:jason, "~> 1.4"},
    {:phoenix, "~> 1.6"},
    {:phoenix_live_view, "~> 0.18.3"}
  ],
  config: [
    phoenix: [json_library: Jason]
  ]
)

defmodule HeexFormatTest do
  use Phoenix.HTML
  import Phoenix.Component, only: [sigil_H: 2]

  def to_text(h) do
    h
    |> Phoenix.HTML.Safe.to_iodata()
    |> List.to_string()
  end

  def generate_html_next_line() do
    assigns = %{}

    ~H"""
    <%= link to: "/i", method: :get do %>
      <%= "next line" %>
    <% end %>,
    """
  end

  def generate_html_same_line() do
    assigns = %{}

    ~H"""
    <%= link to: "/i", method: :get do %>
      <%= "same line" %><% end %>,
    """
  end
end

HeexFormatTest.generate_html_next_line() |> HeexFormatTest.to_text() |> IO.inspect(label: :next_line)
HeexFormatTest.generate_html_same_line() |> HeexFormatTest.to_text() |> IO.inspect(label: :same_line)
adamu

adamu

Does anyone know how to deal with this?

For example, if I write

<a href="/foo">Foo</a>

Formatting it can result in

<a href="/foo">Foo </a>

Adding a space and changing the appearance.

This happens whether I use <a> or <.link>.

LostKobrakai

LostKobrakai

Your example formats just fine for me. But you can also use this: Phoenix.LiveView.HTMLFormatter — Phoenix LiveView v1.0.9

adamu

adamu

Sorry, I simplied it. I’ll check out the LiveView formatter, thanks.

Here’s a reproducible example:

<div>
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <a
                class="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                href="/foo"
              >Foo</a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

frankdugan3

frankdugan3

Did you look at the link he posted? The documentation describes a phx-no-format attribute you can add to any element to disable formatting for that element. So in your case:

<a
  phx-no-format
  class="..."
adamu

adamu

Yes I did, and that avoids the problem. But I agree with @markmark206 - it’s surprising that the formatter adds whitespace to visible text where there was previously none. So it’s really a workaround, rather than a solution.

Out of curiosity, I checked what Prettier does, and it formats it as the following, which preserves the visible whitespace.

<a
  class="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  href="/foo"
  >Foo</a
>
— All posts loaded —

Where Next?

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 91561 914
New
byu
@chrismccord : I just saw the Extract AGENTS.md from Phoenix.new into phx.new generator commit to the phoenix project. My initial shotgu...
New
arcanemachine
I was working on an Ecto migration and I needed a timestamp. So, for the nth time, I looked up the different data types for timestamps, a...
New
AstonJ
Just a general thread to post chat/news/info relating to AI/ML stuff that may be relevant for Nx now or in the future. Got anything to sh...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement