shallow-equal icon indicating copy to clipboard operation
shallow-equal copied to clipboard

add .isSameNode equality checks for Elements

Open juliangruber opened this issue 8 years ago • 7 comments

When used in the browser, this addition makes it useful for objects and arrays containing DOM nodes as well.

It is not uncommon to override an element's .isSameNode(element) -> Boolean to implement custom caching mechanisms with libraries such as https://github.com/yoshuawuyts/nanomorph.

I had to add one istanbul comment as some code would only run in the browser. If you're interested I can also refactor this test suite to use some tooling that makes it run in node and the browser.

juliangruber avatar May 01 '17 15:05 juliangruber

Thanks for the PR!

Can I ask what's the difference between isSameNode and === for Elements? (they look the same to me)

Also, what tooling do you have in mind for running the tests in a browser?

moroshko avatar May 01 '17 17:05 moroshko

Sure! With .isSameNode you can do stuff like

component.render = () => {
  if (!this.shouldUpdate()) {
    const el = document.createElement('div')
    el.isSameNode = (e) => e === el
    return el
  } else {
    return this.actualRender()
  }
}

so you can create shallow DOM nodes that to diffing algorithms appear to be the same as what's already in the DOM - as they check .isSameNode() - instead of having to return the full rendered element and letting the diffing algorithm compare the fully nested DOM structure.

Does that make sense to you?

For browser tests, I'd refactor the suite to use https://github.com/substack/tape, then you can run them like this:

"devDependencies": {
  "browserify": "..."
  "tape": "...",
  "tape-run": "..."
},
"scripts": {
  "test-node": "tape src/*.test.js",
  "test-browser": "browserify src/*.test.js | tape-run",
  "test": "test-node && test-browser"
}

We can also hook coverage reporting into this, which will work on both environments too. Also, we could integrate mocha-like output formatting.

juliangruber avatar May 01 '17 18:05 juliangruber

Looks like isSameNode() was deprecated in DOM v4. Any idea why do these diffing algorithms use isSameNode() rather than ===?

What do you think about adding another argument to shallowEqualObjects which will be a custom comparator? (I assume you don't need this functionality in shallowEqualArrays)

moroshko avatar May 01 '17 21:05 moroshko

great point actually, i'll investigate this

juliangruber avatar May 02 '17 06:05 juliangruber

Looks like isSameNode() was deprecated in DOM v4.

Looks like it's back in the living standard tho.


Any idea why do these diffing algorithms use isSameNode() rather than ===?

https://github.com/yoshuawuyts/nanocomponent/pull/31#issuecomment-300141760


See Also

  • https://dom.spec.whatwg.org/#interface-node
  • https://developer.mozilla.org/en/docs/Web/API/Node/isSameNode

yoshuawuyts avatar May 09 '17 12:05 yoshuawuyts

@moroshko is this patch good to merge tho?

yoshuawuyts avatar May 22 '17 12:05 yoshuawuyts

I would be happy to be able to pass a custom comparator function too

juliangruber avatar May 22 '17 13:05 juliangruber