Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Diff between two HTML chunks: structural instead of lines/chars?

I'm looking for a JavaScript diff engine that will return the difference in the structure of two chunks of HTML. That is, instead of, "at this line, at such and such character, something happened", it'd be, "this element was inserted after this element", or "this element was removed", or "this text node was altered", etc.

Cursory research suggests this is hard.

The specific scenario is that I have a live preview of Markdown text editor. It works well with just text, but as soon as a user posts in, say, a YouTube <iframe> embed, then it renders/reloads on every keystroke, which is absurdly expensive. Large images are difficult, too, because they cause a nauseous jittering effect as they load from the cache (at least in WebKit).

What would be beautiful is a replacement for jQuery.html() that instead of just replacing the HTML contents actually compared the old with the new, and selectively updated/inserted/appended so that unchanged elements are left alone.

like image 741
JKS Avatar asked Aug 12 '11 19:08

JKS


1 Answers

  1. Deep clone (via node.cloneNode(true)) both nodes if they're currently in use (i.e. if any child nodes are referenced in your JavaScript).
  2. Normalize both nodes via node.normalize().
  3. Iterate over every child node of both nodes and compare with node.isEqualNode(other_node).
  4. For every non-equal node, iterate deeper to see if you can find any equal child nodes.

To be honest, you're much better off using a text diff lib instead of making your own DOM-based diff lib.

like image 195
Eli Grey Avatar answered Oct 31 '22 15:10

Eli Grey