| <html> | 
 | <import src="../resources/chai.sky" /> | 
 | <import src="../resources/mocha.sky" /> | 
 | <script> | 
 | describe('MutationObserver.observe on childList', function() { | 
 |   it('should handle basic observation', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var mutations; | 
 |     var removedDiv1, removedDiv2; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { childList: true }); | 
 |       removedDiv1 = div.appendChild(document.createElement('div')); | 
 |       setTimeout(checkDisconnectAndMutate, 0); | 
 |     } | 
 |  | 
 |     function checkDisconnectAndMutate() { | 
 |       // ...can childList changes be observed at all. | 
 |  | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].addedNodes.length, 1); | 
 |       assert.equal(mutations[0].addedNodes[0], removedDiv1); | 
 |  | 
 |       mutations = null; | 
 |       observer.disconnect(); | 
 |       removedDiv1 = div.appendChild(document.createElement('div')); | 
 |       setTimeout(checkNotDeliveredAndMutateMultiple, 0); | 
 |     } | 
 |  | 
 |     function checkNotDeliveredAndMutateMultiple() { | 
 |       // ...observer.disconnect() should prevent further delivery of mutations. | 
 |  | 
 |       assert.equal(mutations, null); | 
 |       observer.observe(div, { childList: true }); | 
 |       removedDiv1 = div.removeChild(div.firstChild); | 
 |       removedDiv2 = div.removeChild(div.firstChild); | 
 |       setTimeout(finish); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       // ...re-observing after disconnect works with the same observer. | 
 |  | 
 |       assert.equal(mutations.length, 2); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].removedNodes.length, 1); | 
 |       assert.equal(mutations[0].removedNodes[0], removedDiv1); | 
 |       assert.equal(mutations[1].type, "childList"); | 
 |       assert.equal(mutations[1].removedNodes.length, 1); | 
 |       assert.equal(mutations[1].removedNodes[0], removedDiv2); | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should handle observing without specifying "childList" does not result in hearing about childList changes', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var mutations; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { attributes: true, characterData: true }); | 
 |       div.appendChild(document.createElement('div')); | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       assert.equal(mutations, null); | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should handle re-observing the same node with the same observer has the effect of resetting the options', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var mutations; | 
 |     var calls = 0; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |         calls++; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { childList: true, characterData: true }); | 
 |       observer.observe(div, { childList: true }); | 
 |       div.appendChild(document.createElement('div')); | 
 |       setTimeout(checkDisconnectAndMutate, 0); | 
 |     } | 
 |  | 
 |     function checkDisconnectAndMutate() { | 
 |       assert.equal(calls, 1); | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       mutations = null; | 
 |       observer.observe(div, { childList: true, characterData: true }); | 
 |       observer.observe(div, { attributes: true }); | 
 |       div.appendChild(document.createElement('div')); | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       assert.equal(mutations, null); | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should handle multiple observers can be registered to a given node and both receive mutations', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var observer2; | 
 |     var mutations; | 
 |     var mutations2; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |       observer2 = new MutationObserver(function(m) { | 
 |         mutations2 = m; | 
 |       }); | 
 |       observer.observe(div, { childList: true }); | 
 |       observer2.observe(div, { childList: true }); | 
 |       div.appendChild(document.createElement('div')); | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations2.length, 1); | 
 |       assert.equal(mutations2[0].type, "childList"); | 
 |       observer.disconnect(); | 
 |       observer2.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should create minimal mutations for replaceChild', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var fragment; | 
 |     var mutations; | 
 |     var addedDiv1; | 
 |     var addedDiv2; | 
 |     var removedDiv1; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |  | 
 |       var first = document.createElement('span'); | 
 |       first.textContent = 'Foo'; | 
 |       div.appendChild(first); | 
 |  | 
 |       var second = document.createElement('div'); | 
 |       second.textContent = 'Bar'; | 
 |       div.appendChild(second); | 
 |  | 
 |       removedDiv1 = div.firstChild; | 
 |  | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { childList: true }); | 
 |       addedDiv1 = document.createElement('div'); | 
 |       div.replaceChild(addedDiv1, div.firstChild); | 
 |       setTimeout(checkReplaceWithNode, 0); | 
 |     } | 
 |  | 
 |     function checkReplaceWithNode() { | 
 |       // ...simple replace child | 
 |  | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].addedNodes.length, 1); | 
 |       assert.equal(mutations[0].addedNodes[0], addedDiv1); | 
 |       assert.equal(mutations[0].removedNodes.length, 1); | 
 |       assert.equal(mutations[0].removedNodes[0], removedDiv1); | 
 |  | 
 |       mutations = null; | 
 |       fragment = document.createDocumentFragment(); | 
 |       addedDiv1 = fragment.appendChild(document.createElement('div')); | 
 |       addedDiv2 = fragment.appendChild(document.createElement('div')); | 
 |       removedDiv1 = div.firstChild; | 
 |  | 
 |       div.replaceChild(fragment, removedDiv1); | 
 |  | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       // ...replace with DocumentFragment. | 
 |  | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].addedNodes.length, 2); | 
 |       assert.equal(mutations[0].addedNodes[0], addedDiv1); | 
 |       assert.equal(mutations[0].addedNodes[1], addedDiv2); | 
 |       assert.equal(mutations[0].removedNodes.length, 1); | 
 |       assert.equal(mutations[0].removedNodes[0], removedDiv1); | 
 |  | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should create minimal mutations for insertBefore', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var fragment; | 
 |     var mutations; | 
 |     var addedDiv1; | 
 |     var addedDiv2; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |  | 
 |       var first = document.createElement('span'); | 
 |       first.textContent = 'Foo'; | 
 |       div.appendChild(first); | 
 |  | 
 |       fragment = document.createDocumentFragment(); | 
 |       addedDiv1 = fragment.appendChild(document.createElement('div')); | 
 |       addedDiv2 = fragment.appendChild(document.createElement('div')); | 
 |  | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { childList: true }); | 
 |       div.insertBefore(fragment, div.firstChild); | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |  | 
 |     function finish() { | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].addedNodes.length, 2); | 
 |       assert.equal(mutations[0].addedNodes[0], addedDiv1); | 
 |       assert.equal(mutations[0].addedNodes[1], addedDiv2); | 
 |       assert.equal(mutations[0].removedNodes.length, 0); | 
 |  | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 |  | 
 |   it('should create minimal mutations for appendChild', function(done) { | 
 |     var div; | 
 |     var observer; | 
 |     var fragment; | 
 |     var mutations; | 
 |     var addedDiv1; | 
 |     var addedDiv2; | 
 |  | 
 |     function start() { | 
 |       div = document.createElement('div'); | 
 |  | 
 |       var first = document.createElement('span'); | 
 |       first.textContent = 'Foo'; | 
 |       div.appendChild(first); | 
 |  | 
 |       fragment = document.createDocumentFragment(); | 
 |       addedDiv1 = fragment.appendChild(document.createElement('div')); | 
 |       addedDiv2 = fragment.appendChild(document.createElement('div')); | 
 |  | 
 |       observer = new MutationObserver(function(m) { | 
 |         mutations = m; | 
 |       }); | 
 |  | 
 |       observer.observe(div, { childList: true }); | 
 |       div.appendChild(fragment); | 
 |       setTimeout(finish, 0); | 
 |     } | 
 |  | 
 |     function finish() { | 
 |       assert.equal(mutations.length, 1); | 
 |       assert.equal(mutations[0].type, "childList"); | 
 |       assert.equal(mutations[0].addedNodes.length, 2); | 
 |       assert.equal(mutations[0].addedNodes[0], addedDiv1); | 
 |       assert.equal(mutations[0].addedNodes[1], addedDiv2); | 
 |       assert.equal(mutations[0].removedNodes.length, 0); | 
 |  | 
 |       observer.disconnect(); | 
 |       done(); | 
 |     } | 
 |  | 
 |     start(); | 
 |   }); | 
 | }); | 
 | </script> | 
 | </body> | 
 | </html> |