trivago / melody

Melody is a library for building JavaScript web applications.
https://melody.js.org
Apache License 2.0
215 stars 39 forks source link

packages/melody-parser: Unclosed and several closing element tag cause `ERROR: Unknown tag` #159

Closed lidqqq closed 4 years ago

lidqqq commented 4 years ago

Hi.

Explain the problem

I found an Error when if and for statements have several close tags.

{% if product.stock > 10 %}
   <p>start P tag
{% elseif product.stock > 0 %}
   else if close P tag</p>
{% else %}
   else close P tag</p>
{% endif %}

⬇️

Error: ERROR: Unknown tag "elseif"
  3 | {% if product.stock > 10 %}
  4 |    <p>start P tag
> 5 | {% elseif product.stock > 0 %}
    |    ^^^^^^
  6 |    else if close P tag</p>
  7 | {% else %}
  8 |    else close P tag</p>

This sample is so simple, so it may not need to separate, but there are many complicated structure of DOM in production code like creating <li> element with parameters state.

Expected Behaviour

work correctly

Actual Behaviour

cause a ERROR: Unknown tag

Steps to reproduce

REPL is here. https://repl.it/repls/SpectacularHarmlessOffices

Provide a repository that reproduces issue if possible

REPL is here. https://repl.it/repls/SpectacularHarmlessOffices

Provide your Environment details

"dependencies": {
    "melody-extension-core": "^1.7.1",
    "melody-idom": "^1.7.1",
    "melody-parser": "^1.7.1",
    "melody-runtime": "^1.7.1",
    "melody-traverse": "^1.7.1",
    "melody-types": "^1.7.1"
  }
ayusharma commented 4 years ago

Hi @lidqqq, Thanks for opening the issue. Please format your markup as follows:

const code = `\n
{% if product.stock > 10 %}
   <p>start P tag </p>
{% elseif product.stock > 0 %}
   <p>else if close P tag</p>
{% else %}
   <p>else close P tag</p>
{% endif %}
`;

Currently, you are not closing the <p> tags in the same if blocks. I hope it helps.

ayusharma commented 4 years ago

updated REPL https://repl.it/repls/PunyReadyPrinters

lidqqq commented 4 years ago

@ayusharma Thanks for quick reply!

you are not closing the <p> tags in the same if blocks.

Sorry, I had understood that, and the case which I showed is not good. 😢 Actually, I mean that this happen when it not been closed element tag.

In real world HTML, there are many complicated structure of DOM. For example:

{% if users.size > 10 %}
   {% set lastGroupId = "" %}
    <ul>
        {% for user in users %}
            {# create <li> element by user.gruopId #}
            {% if lastGroupId is empty %}
                <li>
                <p>first id: start!</p>
            {% elseif user.groupId == lastGroupId %}
                {# same id: continue! #}
                <p>same id: continue!</p>
            {% else %}
                {# not same id: close! #}
                </li>
                <li>
                <p>not same id: start!</p>
            {% endif %}
            {# last idx #}
            {% if users.size == {{ loop.index }} - 1 %}
                </li>
            {% endif %}
            {# set last groupId #}
            {% set lastGroupId = user.groupId %}
        {% endfor %}
    </ul>
{% endif %}

repl https://repl.it/repls/DistantLeanApi

What do you think about it ? 😄