dy / xhtm

XHTM − eXtended Hyperscript Tagged Markup
MIT License
25 stars 2 forks source link

xhtm 1.5.7 aggresively pruning spaces between tags (xhtml + vhtml) #13

Closed aral closed 1 year ago

aral commented 1 year ago

Some HTML tags should maintain spaces between them (e.g., <span>s)

When used with vhtml, xhtm 1.5.7 removes those spaces entirely.

Failing test:

t('#13: whitespace handling should match HTML specification', t => {
    const html = htm.bind(vhtml)

    const result = 
    t.equal(
        html`<p>These <span>words</span> <span>should</span>      <strong>be</strong> separated with just one space. <span>But</span><span>These</span><span>Should</span><span>Not</span>.</p>`,
        '<p>These <span>words</span> <span>should</span> <strong>be</strong> separated with just one space. <span>But</span><span>These</span><span>Should</span><span>Not</span>.</p>'
    )
})

Result:

►#13: whitespace handling should match HTML specification
× 144 — should equal
actual: "<p>These <span>words</span><span>should</span><strong>be</strong> separated with just one space. <span>But</span><span>These</span><span>Should</span><span>Not</span>.</p>"
expected: "<p>These <span>words</span> <span>should</span> <strong>be</strong> separated with just one space. <span>But</span><span>These</span><span>Should</span><span>Not</span>.</p>"
Error
    at Object.log (file:///var/home/aral/Projects/other/xhtm/node_modules/tst/index.js:89:29)
    at Object.equal (file:///var/home/aral/Projects/other/xhtm/node_modules/tst/assert.js:26:8)
    at Object.fn (file:///var/home/aral/Projects/other/xhtm/test/index.js:145:4)
    at file:///var/home/aral/Projects/other/xhtm/node_modules/tst/index.js:111:29
    at async file:///var/home/aral/Projects/other/xhtm/node_modules/tst/index.js:136:3
dy commented 1 year ago

Is that not the case for htm? Let me check

https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace

aral commented 1 year ago

@dy I only just noticed the issue in the latest xhtm (htm + vhtml keep at least one space) and I believe xhtm was doing the right thing prior to 1.5.7 (although I may be mistaken on the exact version number that the regression occured at).

It seems xhtm is collapsing single and multiple spaces into no spaces.

So, as a simple example:

const htmResult = htmBoundToVhtml`<p><strong>Hello,</strong> <em>world!</em></p>`
const xhtmResult = xhtmBoundToVhtml`<p><strong>Hello,</strong> <em>world!</em></p>`

Results in:

htm:

<p><strong>Hello,</strong> <em>world!</em></p

xhtm:

<p><strong>Hello,</strong><em>world!</em></p>

Which displays in the browser as:

htm:

Hello, world!

xhtm:

Hello,world!

dy commented 1 year ago

Ok v1.5.8 has better spacing handling, please check, it should be htm-complacent. Not html-complacent though, since html has different spacing rules for block/inline elements, not going to fully implement it.

aral commented 1 year ago

@dy Thanks as always, Dmitry. Going to have a play with it now :)

aral commented 1 year ago

@dy That seems to have broken something in one of my more complex examples. I’m trying to create a simple reproduction. It seems to be related to newlines being in tags (e.g., when you write attributes out on different lines) but I can’t reproduce it outside of Kitten yet. Will open a new issue when I can.

For the following code in Kitten:

html`
    <p>Status: <span
      id='status'
      x-data='{ status: "Initialising…" }'
      @htmx:ws-connecting.window='status = "Connecting…"'
      @htmx:ws-open.window='status = "Online"'
      @htmx:ws-close.window='status = "Offline"'
      x-text='status'
      :class='
        status === "Online" ? "online" : status === "Offline" ? "offline" : ""
      '>
      Initialising…
    </span></p>

    <style>
      .online {color: green}
      .offline {color: red}
    </style>
  `

In 1.5.8 I’m seeing:

<p>Status: <spanid='status'x-data=',{ status:="" "initialising…"="" },'@htmx:ws-connecting.window=",status = &quot;Connecting…&quot;," @htmx:ws-open.window=",status = &quot;Online&quot;," @htmx:ws-close.window=",status = &quot;Offline&quot;," x-text="status" :class=",
        status === &quot;Online&quot; ? &quot;online&quot; : status === &quot;Offline&quot; ? &quot;offline&quot; : &quot;&quot;
      ,">Initialising…</spanid='status'x-data=',{></p>

Whereas previously, it was correctly outputting:

<p>Status: <span id="status" x-data="{ status: &quot;Initialising…&quot; }" @htmx:ws-connecting.window="status = &quot;Connecting…&quot;" @htmx:ws-open.window="status = &quot;Online&quot;" @htmx:ws-close.window="status = &quot;Offline&quot;" x-text="status" :class="
        status === &quot;Online&quot; ? &quot;online&quot; : status === &quot;Offline&quot; ? &quot;offline&quot; : &quot;&quot;
      " class="online">Online</span></p>

(I don’t expect you to be able to debug from that. Just documenting it.)

aral commented 1 year ago

OK, I was able to replicate it (I missed that you’d refactored the tests and so i was testing with htm instead of xhtm and wondering why I couldn’t reproduce it.) :)

Here it is: https://github.com/dy/xhtm/issues/14

dy commented 1 year ago

Ok, 1.5.9+ should fix it

dy commented 1 year ago

1.5.10 should too, but it's also faster