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

Support Hyperapp textNode handling #51

Open
johnkazer opened this issue Apr 9, 2021 · 1 comment
Open

Support Hyperapp textNode handling #51

johnkazer opened this issue Apr 9, 2021 · 1 comment

Comments

@johnkazer
Copy link
Contributor

I use pug-vdom to enable Pug templates to be used with the Hyperapp framework. This worked great, until the framework added a new function text() in parallel with h() to separately process virtual text nodes. As per this snippet h("h1", {}, text("To do list")). I generated a work-around in this repo with a local copy of pug-vdom.

So now the following simple template fails

div
    // receives the <greet> variable from the supplied state object
    - var greeting = "Hello " + greet
    p(style={color: "red"}) #{greeting}
    input(size="60" placeholder=placeholder onchange=handler.updateMe)
    button(id='clickMe' onclick=handler.clickMe) Click Me
    p #{userText}

Because the greeting in n2Child is represented by a string in the following rather than what's returned from h().

  var n0Child = []
  var n1Child = []
  var greeting = "Hello " + greet
  var n2Child = []
  n2Child = n2Child.concat(greeting)
  var props = {attributes: runtime.compileAttrs([{name:'style', val: {color: "red"}}], [])};
  if (props.attributes.id) props.key = props.attributes.id;
  var n2 = h('p', props, n2Child)

For Hyperapp, I need to call text(greeting), making it a virtual textNode as follows:

  var n0Child = []
  var n1Child = []
  var greeting = "Hello " + greet
  var n2Child = []
  n2Child = n2Child.concat(text(greeting))
  var props = {attributes: runtime.compileAttrs([{name:'style', val: {color: "red"}}], [])};
  if (props.attributes.id) props.key = props.attributes.id;
  var n2 = h('p', props, n2Child)

So I would like to change pug-vdom.js to optionally support a text() function as follows, where the generated render(context, h) has a new optional function arg that is used by visitText and visitCode:

Compiler.prototype.bootstrap = function () {
  this.addI(`function render(context, h, text = (string) => string) {\r\n`)
  ...

Compiler.prototype.visitText = function (node, parent) {
  var val = node.val;
  var s = JSON.stringify(val)
  if (val[0] === '<') {
    this.addI(`n${this.parentTagId}Child = n${this.parentTagId}Child.concat(runtime.makeHtmlNode(${s}))\r\n`)
  } else {
    this.addI(`n${this.parentTagId}Child.push(text(${s}))\r\n`)
  }  
}

Compiler.prototype.visitCode = function (node, parent) {
  if (node.buffer) {
    this.addI(`n${this.parentTagId}Child = n${this.parentTagId}Child.concat(${node.mustEscape ? `text(${node.val})` : `runtime.makeHtmlNode(${node.val})`})\r\n`)
  } else {
    this.addI(node.val + '\r\n')
  }

  if(node.block){
    this.addI('{\r\n')
    this.indent++
    this.visitBlock(node.block, node)
    this.indent--
    this.addI('}\r\n')
  }
}
@gryphonmyers
Copy link
Collaborator

Sounds reasonable to me. If you make a PR I'll review

johnkazer added a commit to johnkazer/pug-vdom that referenced this issue Apr 11, 2021
batiste pushed a commit that referenced this issue Apr 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants