/*
* Copyright 2012 The Polymer Authors. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
suite('JsMutationObserver childList', function() {
var testDiv;
teardown(function() {
document.body.removeChild(testDiv);
});
var addedNodes, removedNodes;
setup(function() {
testDiv = document.body.appendChild(document.createElement('div'));
addedNodes = [];
removedNodes = [];
});
function mergeRecords(records) {
records.forEach(function(record) {
if (record.addedNodes)
addedNodes.push.apply(addedNodes, record.addedNodes);
if (record.removedNodes)
removedNodes.push.apply(removedNodes, record.removedNodes);
});
}
function assertAll(records, expectedProperties) {
records.forEach(function(record) {
for (var propertyName in expectedProperties) {
assert.strictEqual(record[propertyName], expectedProperties[propertyName]);
}
});
}
test('appendChild', function() {
var div = document.createElement('div');
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
var a = document.createElement('a');
var b = document.createElement('b');
div.appendChild(a);
div.appendChild(b);
var records = observer.takeRecords();
assert.strictEqual(records.length, 2);
expectRecord(records[0], {
type: 'childList',
target: div,
addedNodes: [a]
});
expectRecord(records[1], {
type: 'childList',
target: div,
addedNodes: [b],
previousSibling: a
});
});
test('insertBefore', function() {
var div = document.createElement('div');
var a = document.createElement('a');
var b = document.createElement('b');
var c = document.createElement('c');
div.appendChild(a);
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
div.insertBefore(b, a);
div.insertBefore(c, a);
var records = observer.takeRecords();
assert.strictEqual(records.length, 2);
expectRecord(records[0], {
type: 'childList',
target: div,
addedNodes: [b],
nextSibling: a
});
expectRecord(records[1], {
type: 'childList',
target: div,
addedNodes: [c],
nextSibling: a,
previousSibling: b
});
});
test('removeChild', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createElement('a'));
var b = div.appendChild(document.createElement('b'));
var c = div.appendChild(document.createElement('c'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
div.removeChild(b);
div.removeChild(a);
var records = observer.takeRecords();
assert.strictEqual(records.length, 2);
expectRecord(records[0], {
type: 'childList',
target: div,
removedNodes: [b],
nextSibling: c,
previousSibling: a
});
expectRecord(records[1], {
type: 'childList',
target: div,
removedNodes: [a],
nextSibling: c
});
});
test('Direct children', function() {
var div = testDiv.appendChild(document.createElement('div'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
var a = document.createElement('a');
var b = document.createElement('b');
div.appendChild(a);
div.insertBefore(b, a);
div.removeChild(b);
var records = observer.takeRecords();
assert.strictEqual(records.length, 3);
expectRecord(records[0], {
type: 'childList',
target: div,
addedNodes: [a]
});
expectRecord(records[1], {
type: 'childList',
target: div,
nextSibling: a,
addedNodes: [b]
});
expectRecord(records[2], {
type: 'childList',
target: div,
nextSibling: a,
removedNodes: [b]
});
});
test('subtree', function() {
var div = document.createElement('div');
var child = div.appendChild(document.createElement('div'));
var observer = new JsMutationObserver(function() {});
observer.observe(child, {
childList: true
});
var a = document.createTextNode('a');
var b = document.createTextNode('b');
child.appendChild(a);
child.insertBefore(b, a);
child.removeChild(b);
var records = observer.takeRecords();
assert.strictEqual(records.length, 3);
expectRecord(records[0], {
type: 'childList',
target: child,
addedNodes: [a]
});
expectRecord(records[1], {
type: 'childList',
target: child,
nextSibling: a,
addedNodes: [b]
});
expectRecord(records[2], {
type: 'childList',
target: child,
nextSibling: a,
removedNodes: [b]
});
});
test('both direct and subtree', function() {
var div = document.createElement('div');
var child = div.appendChild(document.createElement('div'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true,
subtree: true
});
observer.observe(child, {
childList: true
});
var a = document.createTextNode('a');
var b = document.createTextNode('b');
child.appendChild(a);
div.appendChild(b);
var records = observer.takeRecords();
assert.strictEqual(records.length, 2);
expectRecord(records[0], {
type: 'childList',
target: child,
addedNodes: [a]
});
expectRecord(records[1], {
type: 'childList',
target: div,
addedNodes: [b],
previousSibling: child
});
});
test('Append multiple at once at the end', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createTextNode('a'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
var df = document.createDocumentFragment();
var b = df.appendChild(document.createTextNode('b'));
var c = df.appendChild(document.createTextNode('c'));
var d = df.appendChild(document.createTextNode('d'));
div.appendChild(df);
var records = observer.takeRecords();
mergeRecords(records);
assertArrayEqual(addedNodes, [b, c, d]);
assertArrayEqual(removedNodes, []);
assertAll(records, {
type: 'childList',
target: div
});
});
test('Append multiple at once at the front', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createTextNode('a'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
var df = document.createDocumentFragment();
var b = df.appendChild(document.createTextNode('b'));
var c = df.appendChild(document.createTextNode('c'));
var d = df.appendChild(document.createTextNode('d'));
div.insertBefore(df, a);
var records = observer.takeRecords();
mergeRecords(records);
assertArrayEqual(addedNodes, [b, c, d]);
assertArrayEqual(removedNodes, []);
assertAll(records, {
type: 'childList',
target: div
});
});
test('Append multiple at once in the middle', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createTextNode('a'));
var b = div.appendChild(document.createTextNode('b'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
var df = document.createDocumentFragment();
var c = df.appendChild(document.createTextNode('c'));
var d = df.appendChild(document.createTextNode('d'));
div.insertBefore(df, b);
var records = observer.takeRecords();
mergeRecords(records);
assertArrayEqual(addedNodes, [c, d]);
assertArrayEqual(removedNodes, []);
assertAll(records, {
type: 'childList',
target: div
});
});
test('Remove all children', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createTextNode('a'));
var b = div.appendChild(document.createTextNode('b'));
var c = div.appendChild(document.createTextNode('c'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
div.innerHTML = '';
var records = observer.takeRecords();
mergeRecords(records);
assertArrayEqual(addedNodes, []);
assertArrayEqual(removedNodes, [a, b, c]);
assertAll(records, {
type: 'childList',
target: div
});
});
test('Replace all children using innerHTML', function() {
var div = testDiv.appendChild(document.createElement('div'));
var a = div.appendChild(document.createTextNode('a'));
var b = div.appendChild(document.createTextNode('b'));
var observer = new JsMutationObserver(function() {});
observer.observe(div, {
childList: true
});
div.innerHTML = '';
var c = div.firstChild;
var d = div.lastChild;
var records = observer.takeRecords();
mergeRecords(records);
assertArrayEqual(addedNodes, [c, d]);
assertArrayEqual(removedNodes, [a, b]);
assertAll(records, {
type: 'childList',
target: div
});
});
});