Stillat / blade-parser-typescript

A Laravel Blade parser, compiler, and static analyzer written in TypeScript.
https://stillat.com
MIT License
82 stars 2 forks source link

[Prettier plugin] Error on switch statement inside html tag #85

Closed Roardom closed 10 months ago

Roardom commented 10 months ago

A file containing a switch statement inside an html tag

<div
    @switch(true)
        @case($condition)
            title="thing"
            @break
    @endswitch
></div>

throws an error:

[error] resources/views/test.blade.php: SyntaxError: Unexpected closing tag "Bn1kN8r2wSB". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (12:1)
[error]   10 |
[error]   11 | <B7FPZ9e8uLB></B7FPZ9e8uLB>    </BoB4Xhft3oPFP3mFcB>
[error] > 12 | </Bn1kN8r2wSB>
[error]      | ^^^^^^^^^^^^^^
[error]   13 | ></div>

prettier-plugin-blade: 1.6.14 prettier: 2.8.8

JohnathonKoster commented 10 months ago

Improved in v1.6.15, with additional test coverage

Roardom commented 10 months ago

Hi, thanks so much for the quick fixes! To give perspective, I'm adding formatting to a fairly large (200 KLoC) foss laravel app https://github.com/HDInnovations/UNIT3D-Community-Edition/pull/3234 which had amassed quite some exceptional blade syntax over time. I explored formatting last year, but only just recently found out about your project and decided to try it out and was amazed at how perfect it was compared to previous attempts.

Of all the kinks, I believe this is the last one (Although I still have to read the 23k line diff a second time). I notice that although switch statements no longer error when inside html tags, they aren't actually formatted. Is there any possibility of the switch statement being formatted as well? As a more specific example, I have the following code:

<figure class="torrent-card__figure">
    <img
        class="torrent-card__image"
        @switch (true)
            @case ($torrent->category->movie_meta || $torrent->category->tv_meta)
                src="{{ isset($meta->poster) ? tmdb_image('poster_mid', $meta->poster) : 'https://via.placeholder.com/160x240' }}"
                @break
            @case ($torrent->category->game_meta && isset($torrent->meta) && $meta->cover->image_id && $meta->name)
                src="https://images.igdb.com/igdb/image/upload/t_cover_big/{{ $torrent->meta->cover->image_id }}.jpg"
                @break
            @case ($torrent->category->music_meta)
                src="https://via.placeholder.com/160x240"
                @break
            @case ($torrent->category->no_meta && file_exists(public_path().'/files/img/torrent-cover_'.$torrent->id.'.jpg'))
                src="{{ url('files/img/torrent-cover_'.$torrent->id.'.jpg') }}"
                @break
        @endswitch
        alt="{{ __('torrent.poster') }}"
    />
</figure>

After formatting with version 1.6.15, it becomes

<figure class="torrent-card__figure">
    <img
        class="torrent-card__image"
                @switch (true)
            @case ($torrent->category->movie_meta || $torrent->category->tv_meta)
                src="{{ isset($meta->poster) ? tmdb_image('poster_mid', $meta->poster) : 'https://via.placeholder.com/160x240' }}"
                @break
            @case ($torrent->category->game_meta && isset($torrent->meta) && $meta->cover->image_id && $meta->name)
                src="https://images.igdb.com/igdb/image/upload/t_cover_big/{{ $torrent->meta->cover->image_id }}.jpg"
                @break
            @case ($torrent->category->music_meta)
                src="https://via.placeholder.com/160x240"
                @break
            @case ($torrent->category->no_meta && file_exists(public_path().'/files/img/torrent-cover_'.$torrent->id.'.jpg'))
                src="{{ url('files/img/torrent-cover_'.$torrent->id.'.jpg') }}"
                @break
        @endswitch

        alt="{{ __('torrent.poster') }}"
    />
</figure>

In contrast, the same structure outside of the tag

@switch (true)
    @case ($torrent->category->movie_meta || $torrent->category->tv_meta)
        src="{{ isset($meta->poster) ? tmdb_image('poster_mid', $meta->poster) : 'https://via.placeholder.com/160x240' }}"
        @break
    @case ($torrent->category->game_meta && isset($torrent->meta) && $meta->cover->image_id && $meta->name)
        src="https://images.igdb.com/igdb/image/upload/t_cover_big/{{ $torrent->meta->cover->image_id }}.jpg"
        @break
    @case ($torrent->category->music_meta)
        src="https://via.placeholder.com/160x240"
        @break
    @case ($torrent->category->no_meta && file_exists(public_path().'/files/img/torrent-cover_'.$torrent->id.'.jpg'))
        src="{{ url('files/img/torrent-cover_'.$torrent->id.'.jpg') }}"
        @break
@endswitch

gets formatted to

@switch(true)
    @case($torrent->category->movie_meta || $torrent->category->tv_meta)
        src="{{ isset($meta->poster) ? tmdb_image('poster_mid', $meta->poster) : 'https://via.placeholder.com/160x240' }}"

        @break
    @case($torrent->category->game_meta && isset($torrent->meta) && $meta->cover->image_id && $meta->name)
        src="https://images.igdb.com/igdb/image/upload/t_cover_big/{{ $torrent->meta->cover->image_id }}.jpg"

        @break
    @case($torrent->category->music_meta)
        src="https://via.placeholder.com/160x240"

        @break
    @case($torrent->category->no_meta && file_exists(public_path() . '/files/img/torrent-cover_' . $torrent->id . '.jpg'))
        src="{{ url('files/img/torrent-cover_' . $torrent->id . '.jpg') }}"

        @break
@endswitch
JohnathonKoster commented 10 months ago

Ah, that is a strange one! I'll take a look at this one later this week, as this looks like something I can definitely improve on. Some of these scenarios get complicated when formatting these more complicated structures as attributes 🙂

Update: Took a quick look before heading out for the day, and that has now been improved in 1.6.16, with additional test coverage. It will add a "safety" blank line between the @endswitch and the next attribute for now (prevents issues in some other scenarios), but will format the structure normally now 👍