choojs / nanomorph

🚅 - Hyper fast diffing algorithm for real DOM nodes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

selected attribute is not updated properly

cideM opened this issue · comments

The repo where this bug happens is https://github.com/cideM/tinyfinancial on the details branch (https://github.com/cideM/tinyfinancial/blob/details/src/client/views/Details/index.js). But it requires MongoDB and one would have to remove the facebook authentication. But maybe I'll be able to explain my issue through code examples as well.

I have a controlled <select> and onchange a choo state variable is updated, the view function is rerendered and the newly selected <option> should now be selected. The actual behavior is very confusing though:

When the function renders the first time the DOM looks like this

<select value="2017">
   <option value="2017" selected="selected">2017</option>
   <option value="2016">2016</option>
</select>

If the user select 2016, the DOM looks like this

<select value="2016">
  <option value="2017" selected="">2017</option>
  <option value="2016" selected="selected">2016</option>
</select>

Note the leftover selected="".

Now here are a few console.log statements that I put in updateAttribute of morphdom

function updateAttribute (newNode, oldNode, name) {
  console.log(newNode)
  console.log(newNode.selected)
  console.log(oldNode)
  console.log(oldNode.selected)

When the user chooses 2016, the log statements evaluate to this:
<option value="2017">2017</option>
true why? :[
<option value="2017" selected="">2017</option>
false Seems okay I guess

and
<option value="2016" selected="selected">2016</option>
false O_o
<option value="2016" selected="selected">2016</option>
false Ó_ò

It's late and it's been confusing, so maybe this is totally expected, but I don't it. The booleans seem off though. My intuition says something is mutating the nodes in between other actions but that doesn't sound right. And that getAttribute and properties are not always the same is known but that it would cause such a bug also sounds odd. Lastly, maybe I am just making a grave mistake here somewhere?

I was actually able to fix this by changing updateAttributes to

function updateAttribute (newNode, oldNode, name) {
  if (newNode.getAttribute(name) !== oldNode.getAttribute(name)) {
    oldNode.setAttribute(name, newNode.getAttribute(name))
    if (newNode.getAttribute(name)) {
      oldNode.setAttribute(name, '')
    } else {
      oldNode.removeAttribute(name, '')
    }
  }
}

Note that I replaced the calls to node.selected with node.getAttribute('selected'). I didn't fork and run tests and I didn't manually check anything else because I really need to sleep now. But please let me know
a) if my bug is known and there's a workaround I couldn't find
b) my "discoveries" are expected behavior and I just don't it

Should have been fixed by #60

Memo to myself: check pull requests not just issues. Sorry for the redundant post! It did indeed fix my problem.