Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In-browser compilation with spaces after opening { bracket #2988

Open
mrmattson opened this issue Dec 6, 2023 · 2 comments
Open

In-browser compilation with spaces after opening { bracket #2988

mrmattson opened this issue Dec 6, 2023 · 2 comments

Comments

@mrmattson
Copy link

I found an issue during in-browser compilation where a space after the opening bracket of onclick={ breaks the compiler.

This doesn't compile:

<template id="my-tag-example">
  <my-tag-example>
    <p>{ state.message }</p>
    <button onclick={ helloAgain }>Click Me!</button>
    <script>
      export default {
        onMounted() {
          this.update({
            message: this.props.message
          })
        },
        helloAgain() {
          this.update({
            message: this.state.message + ' again'
          })
        }
      }
    </script>
  </my-tag-example>
</template>

In the browser console, if I do this:

const tagString = document.getElementById('my-tag-example').innerHTML
const {code} = riot.compileFromString(tagString)
code

code contains this:

export default {
  css: null,

  exports: {
    onMounted() {
      this.update({
        message: this.props.message
      })
    },

    helloAgain() {
      this.update({
        message: this.state.message + ' again'
      })
    }
  },

  template: (
    template,
    expressionTypes,
    bindingTypes,
    getComponent
  ) => template(
    '<p expr0="expr0"> </p><button onclick="{" helloagain }>Click Me!</button>',
    [
      {
        redundantAttribute: 'expr0',
        selector: '[expr0]',

        expressions: [
          {
            type: expressionTypes.TEXT,
            childNodeIndex: 0,
            evaluate: _scope => _scope.state.message
          }
        ]
      }
    ]
  ),

  name: 'my-tag-example'
};

This compiles:

<template id="my-tag-example">
  <my-tag-example>
    <p>{ state.message }</p>
    <button onclick={helloAgain}>Click Me!</button>
    <script>
      export default {
        onMounted() {
          this.update({
            message: this.props.message
          })
        },
        helloAgain() {
          this.update({
            message: this.state.message + ' again'
          })
        }
      }
    </script>
  </my-tag-example>
</template>

And this compiles:

<template id="my-tag-example">
  <my-tag-example>
    <p>{ state.message }</p>
    <button onclick="{ helloAgain }">Click Me!</button>
    <script>
      export default {
        onMounted() {
          this.update({
            message: this.props.message
          })
        },
        helloAgain() {
          this.update({
            message: this.state.message + ' again'
          })
        }
      }
    </script>
  </my-tag-example>
</template>
@GianlucaGuarini
Copy link
Member

The native browser template inner html is something we can't control with our compiler. However the Riot attribute expressions support also single and double quotes to circumvent this issue.
Other users experienced similar issues so it could be worth to mention it in our documentation. Would you mind opening a PR adding this information? Thanks

@exside
Copy link

exside commented Apr 18, 2024

To clarify what @GianlucaGuarini said above about innerHTML on template tag within a browser.

If you run document.querySelector('#my-tag-example').innerHTML on the page where you added your component for in-browser compilation, you'll get:

\n  <my-tag-example>\n    <p>{ state.message }</p>\n    <button onclick="{" helloagain="" }="">Click Me!</button>\n    \x3Cscript>\n      export default {\n        onMounted() {\n          this.update({\n            message: this.props.message\n          })\n        },\n        helloAgain() {\n          this.update({\n            message: this.state.message + ' again'\n          })\n        }\n      }\n    \x3C/script>\n  </my-tag-example>\n

you can easily see that the missing quotes around the onclick value mess up the dom parsing in the browser => <button onclick="{" helloagain="" }="">Click Me!</button> so it's not really an issue with a compiler, just write consistent HTMl and use quotes 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants