326 lines
9.4 KiB
HTML
326 lines
9.4 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<script src="../../../resources/js-test-pre.js"></script>
|
|
</head>
|
|
<body>
|
|
<p id=description></p>
|
|
<div id="console"></div>
|
|
<script>
|
|
|
|
window.jsTestIsAsync = true;
|
|
var mutations;
|
|
var mutations2;
|
|
var mutationsWithOldValue;
|
|
var calls;
|
|
var charDataNode;
|
|
|
|
function testBasic() {
|
|
var div;
|
|
var observer;
|
|
|
|
function start() {
|
|
debug('Testing basic aspects of characterData observation.');
|
|
|
|
mutations = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'foo';
|
|
charDataNode = div.firstChild;
|
|
observer = new MutationObserver(function(m) {
|
|
mutations = m;
|
|
});
|
|
|
|
observer.observe(charDataNode, {characterData: true});
|
|
charDataNode.textContent = 'bar';
|
|
setTimeout(checkDisconnectAndMutate, 0);
|
|
}
|
|
|
|
function checkDisconnectAndMutate() {
|
|
debug('...can characterData changes be observed at all');
|
|
|
|
shouldBe('mutations.length', '1');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].target', 'charDataNode');
|
|
|
|
mutations = null;
|
|
observer.disconnect();
|
|
charDataNode.textContent = 'baz';
|
|
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
|
|
}
|
|
|
|
function checkNotDeliveredAndMutateMultiple() {
|
|
debug('...observer.disconnect() should prevent further delivery of mutations.');
|
|
|
|
shouldBe('mutations', 'null');
|
|
charDataNode = document.createComment("test");
|
|
observer.observe(charDataNode, { characterData: true });
|
|
charDataNode.textContent = 'foo';
|
|
charDataNode.textContent = 'bar';
|
|
setTimeout(finish);
|
|
}
|
|
|
|
function finish() {
|
|
debug('...re-observing after disconnect works with the same observer.');
|
|
|
|
shouldBe('mutations.length', '2');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].target', 'charDataNode');
|
|
shouldBe('mutations[1].type', '"characterData"');
|
|
shouldBe('mutations[1].target', 'charDataNode');
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testWrongType() {
|
|
var div;
|
|
var observer;
|
|
|
|
function start() {
|
|
debug('Testing that observing without specifying "characterData" does not result in hearing about characterData changes.');
|
|
|
|
mutations = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'hello';
|
|
charDataNode = div.firstChild;
|
|
observer = new MutationObserver(function(m) {
|
|
mutations = m;
|
|
});
|
|
|
|
observer.observe(charDataNode, {childList: true, attributes: true});
|
|
charDataNode = 'goodbye';
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutations', 'null');
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testMultipleObservers() {
|
|
var div;
|
|
var observer;
|
|
var observer2;
|
|
|
|
function start() {
|
|
debug('Testing that multiple observers can be registered to a given node and both receive mutations.');
|
|
mutations = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'foo';
|
|
charDataNode = div.firstChild;
|
|
observer = new MutationObserver(function(m) {
|
|
mutations = m;
|
|
});
|
|
observer2 = new MutationObserver(function(m) {
|
|
mutations2 = m;
|
|
});
|
|
observer.observe(charDataNode, {characterData: true});
|
|
observer2.observe(charDataNode, {characterData: true});
|
|
charDataNode.textContent = 'bar';
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutations.length', '1');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].target', 'charDataNode');
|
|
shouldBe('mutations2.length', '1');
|
|
shouldBe('mutations2[0].type', '"characterData"');
|
|
shouldBe('mutations2[0].target', 'charDataNode');
|
|
observer.disconnect();
|
|
observer2.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testOrderingWrtDOMSubtreeModified() {
|
|
var div, div2, subDiv;
|
|
var observer;
|
|
var listener;
|
|
|
|
function start() {
|
|
debug('Testing mutation records are enqueued for characterData before DOMSubtreeModified is dispatched.');
|
|
|
|
mutations = null;
|
|
div = document.body.appendChild(document.createElement('div'));
|
|
div2 = document.body.appendChild(document.createElement('div'));
|
|
|
|
subDiv = div.appendChild(document.createElement('div'));
|
|
subDiv.textContent = 'foo';
|
|
charDataNode = subDiv.firstChild;
|
|
|
|
observer = new MutationObserver(function(m) {
|
|
mutations = m;
|
|
});
|
|
|
|
listener = function(e) {
|
|
div2.setAttribute('baz', 'bat');
|
|
}
|
|
|
|
div.addEventListener('DOMSubtreeModified', listener);
|
|
observer.observe(charDataNode, {characterData: true});
|
|
observer.observe(div2, {attributes: true});
|
|
|
|
charDataNode.textContent = 'bar';
|
|
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutations.length', '2');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[1].type', '"attributes"');
|
|
div.removeEventListener('DOMSubtreeModified', listener);
|
|
document.body.removeChild(div);
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testOldValue() {
|
|
var div;
|
|
var observer;
|
|
|
|
function start() {
|
|
debug('Testing that oldValue is returned when requested.');
|
|
mutations = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'foo';
|
|
charDataNode = div.firstChild;
|
|
observer = new MutationObserver(function(mutations) {
|
|
window.mutations = mutations;
|
|
});
|
|
observer.observe(charDataNode, {characterData: true, characterDataOldValue: true});
|
|
charDataNode.textContent = 'bar';
|
|
charDataNode.textContent = 'baz';
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutations.length', '2');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].target', 'charDataNode');
|
|
shouldBe('mutations[0].oldValue', '"foo"');
|
|
shouldBe('mutations[1].type', '"characterData"');
|
|
shouldBe('mutations[1].target', 'charDataNode');
|
|
shouldBe('mutations[1].oldValue', '"bar"');
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testOldValueAsRequested() {
|
|
var div;
|
|
var observerWithOldValue;
|
|
var observer;
|
|
|
|
function start() {
|
|
debug('Testing that oldValue is delivered as requested (or not).');
|
|
mutations = null;
|
|
mutationsWithOldValue = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'foo';
|
|
charDataNode = div.firstChild;
|
|
observerWithOldValue = new MutationObserver(function(mutations) {
|
|
window.mutationsWithOldValue = mutations;
|
|
});
|
|
observer = new MutationObserver(function(mutations) {
|
|
window.mutations = mutations;
|
|
});
|
|
observerWithOldValue.observe(charDataNode, {characterData: true, characterDataOldValue: true});
|
|
observer.observe(charDataNode, {characterData: true});
|
|
charDataNode.textContent = 'bar';
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutationsWithOldValue.length', '1');
|
|
shouldBe('mutationsWithOldValue[0].type', '"characterData"');
|
|
shouldBe('mutationsWithOldValue[0].oldValue', '"foo"');
|
|
shouldBe('mutations.length', '1');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].oldValue', 'null');
|
|
observerWithOldValue.disconnect();
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
function testOldValueUnionMultipleObservations() {
|
|
var div;
|
|
var observer;
|
|
|
|
function start() {
|
|
debug('An observer with multiple observations will get characterDataOldValue if any entries request it.');
|
|
mutations = null;
|
|
div = document.createElement('div');
|
|
div.textContent = 'foo';
|
|
charDataNode = div.firstChild;
|
|
observer = new MutationObserver(function(mutations) {
|
|
window.mutations = mutations;
|
|
});
|
|
observer.observe(div, {characterData: true, characterDataOldValue: true, subtree: true});
|
|
observer.observe(charDataNode, {characterData: true});
|
|
charDataNode.textContent = 'bar';
|
|
setTimeout(finish, 0);
|
|
}
|
|
|
|
function finish() {
|
|
shouldBe('mutations.length', '1');
|
|
shouldBe('mutations[0].type', '"characterData"');
|
|
shouldBe('mutations[0].oldValue', '"foo"');
|
|
observer.disconnect();
|
|
debug('');
|
|
runNextTest();
|
|
}
|
|
|
|
start();
|
|
}
|
|
|
|
var tests = [
|
|
testBasic,
|
|
testWrongType,
|
|
testMultipleObservers,
|
|
testOrderingWrtDOMSubtreeModified,
|
|
testOldValue,
|
|
testOldValueAsRequested,
|
|
testOldValueUnionMultipleObservations
|
|
];
|
|
var testIndex = 0;
|
|
|
|
function runNextTest() {
|
|
if (testIndex < tests.length)
|
|
tests[testIndex++]();
|
|
else
|
|
finishJSTest();
|
|
}
|
|
|
|
description('Test WebKitMutationObserver.observe on CharacterData nodes');
|
|
|
|
runNextTest();
|
|
</script>
|
|
<script src="../../../resources/js-test-post.js"></script>
|
|
</body>
|
|
</html>
|