matthewp / corset

Declarative data bindings, bring your own backend.

Home Page:https://corset.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Selector Bug

JaneOri opened this issue · comments

copying over from the twitter DMs and adding more info ~
If I have this Test Corset component (A):

import sheet from "https://cdn.corset.dev/0.8.10/main.js"

export const Template = (t => (t.innerHTML = `
  <h1>Hello World</h1>
  Count is <span class="count"></span>
  
  <button type="button" class="increment">Increment</button>
`, t))(document.createElement("template"))

export const Behavior = class {
  static inputProperties = ["--initial-count"]

  constructor (props) {
    this.count = props.get("--initial-count")
  }

  increment () {
    this.count++
  }

  bind () {
    const { count } = this

    return sheet`
      .count {
        --count: ${count};
        text: var(--count);
      }

      .increment {
        --cb: ${this.increment};
        event: click var(--cb);
      }
    `
  }
}

and this higher level App component that consumes it (B):

import sheet from "https://cdn.corset.dev/0.8.10/main.js"
import * as Test from "./components/test.js"

export const Template = (t => (t.innerHTML = `
  <div></div>
  <div class="shared counter-1"></div>
  <div class="shared counter-2"></div>
`, t))(document.createElement("template"))

export const Behavior = class {
  bind () {
    return sheet`
      .counter-1,
      .counter-2 {
        --initial-count: ${22};
        attach-template: ${Test.Template};
        behavior: mount(${Test.Behavior});
      }
    `
  }
}
And this is index.html (C)
<!doctype html>
<html>
  <head>
  </head>
  <body>
    <div id="app"></div>

    <script type="module">
      import sheet, { mount } from "https://cdn.corset.dev/0.8.10/main.js"
      import * as App from "./src/app.js"
      mount(document.body, class {
        bind () {
          return sheet`
             #app {
              attach-template: ${App.Template};
              behavior: mount(${App.Behavior});
            }
          `
        }
      })
    </script>
  </body>
</html>

I get this output with a single working counter:
image

If I change the selector in my sheet from (B) to either of these variants below, both counters will be populated and working:

.counter-1,
.counter-2,
.FOOBAR { ... }
.shared { ... }

image

I believe it's in part because of the hyphen in the selector because .counter-1 { ... } by itself also does not work even though .shared does

Happy to poke the regex myself and suggest the fix if you can to point me to it!

Thanks, actually there's no regex for selector parsing, that's done here: https://github.com/matthewp/corset/blob/main/src/parser.c#L172

Here's a reproduction: https://codepen.io/matthewp/pen/dyZgdWB

Pretty sure it's because we are not allowing numbers in selectors: https://github.com/matthewp/corset/blob/main/src/parser.c#L172-L190