diff options
| author | Christophe Matthieu <chm@openerp.com> | 2013-09-06 10:35:00 +0200 |
|---|---|---|
| committer | Christophe Matthieu <chm@openerp.com> | 2013-09-06 10:35:00 +0200 |
| commit | 8a3f1742e0e9c7acaae726e5c7106d2d7df7e970 (patch) | |
| tree | 78ae5d981fcd25677caea5c8b3999b1e77bf4547 /addons/website/static/lib/MutationObservers/test | |
| parent | 6f6c59ec1de1881a70e4bf728ea5d8b56bd609f9 (diff) | |
| parent | c80cf7d0646463b290137c26fbada568a6942b00 (diff) | |
[MERGE] from website-al
bzr revid: chm@openerp.com-20130906083500-4n5knaxiqt4cg2ht
Diffstat (limited to 'addons/website/static/lib/MutationObservers/test')
8 files changed, 1266 insertions, 0 deletions
diff --git a/addons/website/static/lib/MutationObservers/test/attributes.js b/addons/website/static/lib/MutationObservers/test/attributes.js new file mode 100644 index 00000000000..73d697beede --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/attributes.js @@ -0,0 +1,276 @@ +/* + * 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 attributes', function() { + + test('attr', function() { + var div = document.createElement('div'); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true + }); + div.setAttribute('a', 'A'); + div.setAttribute('a', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + expectRecord(records[1], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + }); + + test('attr with oldValue', function() { + var div = document.createElement('div'); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + attributeOldValue: true + }); + div.setAttribute('a', 'A'); + div.setAttribute('a', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null, + oldValue: null + }); + expectRecord(records[1], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null, + oldValue: 'A' + }); + }); + + test('attr change in subtree should not genereate a record', function() { + var div = document.createElement('div'); + var child = div.appendChild(document.createElement('div')); + + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true + }); + child.setAttribute('a', 'A'); + child.setAttribute('a', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + }); + + test('attr change, subtree', function() { + var div = document.createElement('div'); + var child = div.appendChild(document.createElement('div')); + + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + subtree: true + }); + child.setAttribute('a', 'A'); + child.setAttribute('a', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'a' + }); + expectRecord(records[1], { + type: 'attributes', + target: child, + attributeName: 'a' + }); + }); + + + test('multiple observers on same target', function() { + var div = document.createElement('div'); + var observer1 = new JsMutationObserver(function() {}); + observer1.observe(div, { + attributes: true, + attributeOldValue: true + }); + var observer2 = new JsMutationObserver(function() {}); + observer2.observe(div, { + attributes: true, + attributeFilter: ['b'] + }); + + div.setAttribute('a', 'A'); + div.setAttribute('a', 'A2'); + div.setAttribute('b', 'B'); + + var records = observer1.takeRecords(); + assert.strictEqual(records.length, 3); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a' + }); + expectRecord(records[1], { + type: 'attributes', + target: div, + attributeName: 'a', + oldValue: 'A' + }); + expectRecord(records[2], { + type: 'attributes', + target: div, + attributeName: 'b' + }); + + records = observer2.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'b' + }); + }); + + test('observer observes on different target', function() { + var div = document.createElement('div'); + var child = div.appendChild(document.createElement('div')); + + var observer = new JsMutationObserver(function() {}); + observer.observe(child, { + attributes: true + }); + observer.observe(div, { + attributes: true, + subtree: true, + attributeOldValue: true + }); + + child.setAttribute('a', 'A'); + child.setAttribute('a', 'A2'); + child.setAttribute('b', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 3); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'a' + }); + expectRecord(records[1], { + type: 'attributes', + target: child, + attributeName: 'a', + oldValue: 'A' + }); + expectRecord(records[2], { + type: 'attributes', + target: child, + attributeName: 'b' + }); + }); + + test('observing on the same node should update the options', function() { + var div = document.createElement('div'); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + attributeFilter: ['a'] + }); + observer.observe(div, { + attributes: true, + attributeFilter: ['b'] + }); + + div.setAttribute('a', 'A'); + div.setAttribute('b', 'B'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'b' + }); + }); + + test('disconnect should stop all events and empty the records', function() { + var div = document.createElement('div'); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + }); + + div.setAttribute('a', 'A'); + + observer.disconnect(); + var records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + + div.setAttribute('b', 'B'); + + records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + }); + + test('disconnect should not affect other observers', function() { + var div = document.createElement('div'); + var observer1 = new JsMutationObserver(function() {}); + observer1.observe(div, { + attributes: true, + }); + var observer2 = new JsMutationObserver(function() {}); + observer2.observe(div, { + attributes: true, + }); + + div.setAttribute('a', 'A'); + + observer1.disconnect(); + var records1 = observer1.takeRecords(); + assert.strictEqual(records1.length, 0); + + var records2 = observer2.takeRecords(); + assert.strictEqual(records2.length, 1); + expectRecord(records2[0], { + type: 'attributes', + target: div, + attributeName: 'a' + }); + + div.setAttribute('b', 'B'); + + records1 = observer1.takeRecords(); + assert.strictEqual(records1.length, 0); + + records2 = observer2.takeRecords(); + assert.strictEqual(records2.length, 1); + expectRecord(records2[0], { + type: 'attributes', + target: div, + attributeName: 'b' + }); + }); + +});
\ No newline at end of file diff --git a/addons/website/static/lib/MutationObservers/test/callback.js b/addons/website/static/lib/MutationObservers/test/callback.js new file mode 100644 index 00000000000..b3083c7bec3 --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/callback.js @@ -0,0 +1,72 @@ +/* + * 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 callback', function() { + + test('One observer, two attribute changes', function(cont) { + var div = document.createElement('div'); + var observer = new JsMutationObserver(function(records) { + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + expectRecord(records[1], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + + cont(); + }); + + observer.observe(div, { + attributes: true + }); + + div.setAttribute('a', 'A'); + div.setAttribute('a', 'B'); + }); + + test('nested changes', function(cont) { + var div = document.createElement('div'); + var i = 0; + var observer = new JsMutationObserver(function(records) { + assert.strictEqual(records.length, 1); + + if (i === 0) { + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + div.setAttribute('b', 'B'); + i++; + } else { + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'b', + attributeNamespace: null + }); + + cont(); + } + }); + + observer.observe(div, { + attributes: true + }); + + div.setAttribute('a', 'A'); + }); + +});
\ No newline at end of file diff --git a/addons/website/static/lib/MutationObservers/test/characterData.js b/addons/website/static/lib/MutationObservers/test/characterData.js new file mode 100644 index 00000000000..498dc053e6e --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/characterData.js @@ -0,0 +1,106 @@ +/* + * 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 characterData', function() { + + var testDiv; + + setup(function() { + testDiv = document.body.appendChild(document.createElement('div')); + }); + + teardown(function() { + document.body.removeChild(testDiv); + }); + + test('characterData', function() { + var text = document.createTextNode('abc'); + var observer = new JsMutationObserver(function() {}); + observer.observe(text, { + characterData: true + }); + text.data = 'def'; + text.data = 'ghi'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'characterData', + target: text + }); + expectRecord(records[1], { + type: 'characterData', + target: text + }); + }); + + test('characterData with old value', function() { + var text = testDiv.appendChild(document.createTextNode('abc')); + var observer = new JsMutationObserver(function() {}); + observer.observe(text, { + characterData: true, + characterDataOldValue: true + }); + text.data = 'def'; + text.data = 'ghi'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'characterData', + target: text, + oldValue: 'abc' + }); + expectRecord(records[1], { + type: 'characterData', + target: text, + oldValue: 'def' + }); + }); + + test('characterData change in subtree should not generate a record', + function() { + var div = document.createElement('div'); + var text = div.appendChild(document.createTextNode('abc')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + characterData: true + }); + text.data = 'def'; + text.data = 'ghi'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + }); + + test('characterData change in subtree', + function() { + var div = document.createElement('div'); + var text = div.appendChild(document.createTextNode('abc')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + characterData: true, + subtree: true + }); + text.data = 'def'; + text.data = 'ghi'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'characterData', + target: text + }); + expectRecord(records[1], { + type: 'characterData', + target: text + }); + }); + +});
\ No newline at end of file diff --git a/addons/website/static/lib/MutationObservers/test/childList.js b/addons/website/static/lib/MutationObservers/test/childList.js new file mode 100644 index 00000000000..8ff4e4f2718 --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/childList.js @@ -0,0 +1,377 @@ +/* + * 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 = '<c></c><d></d>'; + 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 + }); + }); + +});
\ No newline at end of file diff --git a/addons/website/static/lib/MutationObservers/test/index.html b/addons/website/static/lib/MutationObservers/test/index.html new file mode 100644 index 00000000000..fcedaf4e3fe --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/index.html @@ -0,0 +1,81 @@ +<!DOCTYPE html> +<!-- +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. +--> +<meta charset="utf-8"> +<link rel="stylesheet" href="../node_modules/mocha/mocha.css"> +<script src="../node_modules/chai/chai.js"></script> +<script src="../node_modules/mocha/mocha.js"></script> +<script src="sidetable.js"></script> +<script src="../MutationObserver.js"></script> +<script> + +mocha.setup({ + ui: 'tdd', + ignoreLeaks: true +}); + +var assert = chai.assert; + +function assertArrayEqual(a, b, msg) { + assert.equal(a.length, b.length, msg); + for (var i = 0; i < a.length; i++) { + assert.equal(a[i], b[i], msg); + } +} + +var expectRecord = (function() { + var useNative = /native/.test(location.search); + var isWebKit = /WebKit/.test(navigator.userAgent); + var slice = Array.prototype.slice.call.bind(Array.prototype.slice); + + if (useNative) { + JsMutationObserver = + window.MutationObserver || window.WebKitMutationObserver; + } + + // addedNodes/removedNodes are broken in WebKit. + // https://bugs.webkit.org/show_bug.cgi?id=98921 + function fixWebKitNodes(nodes) { + if (nodes === null && useNative && isWebKit) + return []; + return nodes; + } + + return function expectRecord(record, expected) { + assert.strictEqual(record.type, + expected.type === undefined ? null : expected.type); + assert.strictEqual(record.target, + expected.target === undefined ? null : expected.target); + assertArrayEqual(fixWebKitNodes(record.addedNodes), + expected.addedNodes === undefined ? [] : expected.addedNodes); + assertArrayEqual(fixWebKitNodes(record.removedNodes), + expected.removedNodes === undefined ? [] : expected.removedNodes); + assert.strictEqual(record.previousSibling, + expected.previousSibling === undefined ? + null : expected.previousSibling); + assert.strictEqual(record.nextSibling, + expected.nextSibling === undefined ? null : expected.nextSibling); + assert.strictEqual(record.attributeName, + expected.attributeName === undefined ? null : expected.attributeName); + assert.strictEqual(record.attributeNamespace, + expected.attributeNamespace === undefined ? + null : expected.attributeNamespace); + assert.strictEqual(record.oldValue, + expected.oldValue === undefined ? null : expected.oldValue); + }; +})(); + +</script> +<script src="attributes.js"></script> +<script src="characterData.js"></script> +<script src="childList.js"></script> +<script src="mixed.js"></script> +<script src="callback.js"></script> +<script src="transient.js"></script> +<div id="mocha"></div> +<script> +mocha.run(); +</script> diff --git a/addons/website/static/lib/MutationObservers/test/mixed.js b/addons/website/static/lib/MutationObservers/test/mixed.js new file mode 100644 index 00000000000..eae6a60604c --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/mixed.js @@ -0,0 +1,36 @@ +/* + * 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 mixed types', function() { + + test('attr and characterData', function() { + var div = document.createElement('div'); + var text = div.appendChild(document.createTextNode('text')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + characterData: true, + subtree: true + }); + div.setAttribute('a', 'A'); + div.firstChild.data = 'changed'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'attributes', + target: div, + attributeName: 'a', + attributeNamespace: null + }); + expectRecord(records[1], { + type: 'characterData', + target: div.firstChild + }); + }); + +});
\ No newline at end of file diff --git a/addons/website/static/lib/MutationObservers/test/sidetable.js b/addons/website/static/lib/MutationObservers/test/sidetable.js new file mode 100644 index 00000000000..cae31e6c012 --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/sidetable.js @@ -0,0 +1,35 @@ +/* + * Copyright 2012 The Polymer Authors. All rights reserved. + * Use of this source code is goverened by a BSD-style + * license that can be found in the LICENSE file. + */ + +// SideTable is a weak map where possible. If WeakMap is not available the +// association is stored as an expando property. +var SideTable; +// TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox +if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) { + SideTable = WeakMap; +} else { + (function() { + var defineProperty = Object.defineProperty; + var hasOwnProperty = Object.hasOwnProperty; + var counter = new Date().getTime() % 1e9; + + SideTable = function() { + this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); + }; + + SideTable.prototype = { + set: function(key, value) { + defineProperty(key, this.name, {value: value, writable: true}); + }, + get: function(key) { + return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined; + }, + delete: function(key) { + this.set(key, undefined); + } + } + })(); +} diff --git a/addons/website/static/lib/MutationObservers/test/transient.js b/addons/website/static/lib/MutationObservers/test/transient.js new file mode 100644 index 00000000000..7dda83e27d9 --- /dev/null +++ b/addons/website/static/lib/MutationObservers/test/transient.js @@ -0,0 +1,283 @@ +/* + * 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 transient', function() { + + var testDiv; + + setup(function() { + testDiv = document.body.appendChild(document.createElement('div')); + }); + + teardown(function() { + document.body.removeChild(testDiv); + }); + + test('attr', function() { + var div = testDiv.appendChild(document.createElement('div')); + var child = div.appendChild(document.createElement('div')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + attributes: true, + subtree: true + }); + div.removeChild(child); + child.setAttribute('a', 'A'); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'a', + attributeNamespace: null + }); + + child.setAttribute('b', 'B'); + + records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'b', + attributeNamespace: null + }); + }); + + test('attr callback', function(cont) { + var div = testDiv.appendChild(document.createElement('div')); + var child = div.appendChild(document.createElement('div')); + var i = 0; + var observer = new JsMutationObserver(function(records) { + i++; + if (i > 1) + expect().fail(); + + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'a', + attributeNamespace: null + }); + + // The transient observers are removed before the callback is called. + child.setAttribute('b', 'B'); + records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + + cont(); + }); + + observer.observe(div, { + attributes: true, + subtree: true + }); + + div.removeChild(child); + child.setAttribute('a', 'A'); + }); + + test('attr, make sure transient gets removed', function(cont) { + var div = testDiv.appendChild(document.createElement('div')); + var child = div.appendChild(document.createElement('div')); + var i = 0; + var observer = new JsMutationObserver(function(records) { + i++; + if (i > 1) + expect().fail(); + + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'a', + attributeNamespace: null + }); + + step2(); + }); + + observer.observe(div, { + attributes: true, + subtree: true + }); + + div.removeChild(child); + child.setAttribute('a', 'A'); + + function step2() { + var div2 = document.createElement('div'); + var observer2 = new JsMutationObserver(function(records) { + i++; + if (i > 2) + expect().fail(); + + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'attributes', + target: child, + attributeName: 'b', + attributeNamespace: null + }); + + cont(); + }); + + observer2.observe(div2, { + attributes: true, + subtree: true, + }); + + div2.appendChild(child); + child.setAttribute('b', 'B'); + } + }); + + test('characterData', function() { + var div = document.createElement('div'); + var child = div.appendChild(document.createTextNode('text')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + characterData: true, + subtree: true + }); + div.removeChild(child); + child.data = 'changed'; + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'characterData', + target: child + }); + + child.data += ' again'; + + records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'characterData', + target: child + }); + }); + + test('characterData callback', function(cont) { + var div = document.createElement('div'); + var child = div.appendChild(document.createTextNode('text')); + var i = 0; + var observer = new JsMutationObserver(function(records) { + i++; + if (i > 1) + expect().fail(); + + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'characterData', + target: child + }); + + // The transient observers are removed before the callback is called. + child.data += ' again'; + records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + + cont(); + }); + observer.observe(div, { + characterData: true, + subtree: true + }); + div.removeChild(child); + child.data = 'changed'; + }); + + test('childList', function() { + var div = testDiv.appendChild(document.createElement('div')); + var child = div.appendChild(document.createElement('div')); + var observer = new JsMutationObserver(function() {}); + observer.observe(div, { + childList: true, + subtree: true + }); + div.removeChild(child); + var grandChild = child.appendChild(document.createElement('span')); + + var records = observer.takeRecords(); + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'childList', + target: div, + removedNodes: [child] + }); + + expectRecord(records[1], { + type: 'childList', + target: child, + addedNodes: [grandChild] + }); + + child.removeChild(grandChild); + + records = observer.takeRecords(); + assert.strictEqual(records.length, 1); + + expectRecord(records[0], { + type: 'childList', + target: child, + removedNodes: [grandChild] + }); + }); + + test('childList callback', function(cont) { + var div = testDiv.appendChild(document.createElement('div')); + var child = div.appendChild(document.createElement('div')); + var i = 0; + var observer = new JsMutationObserver(function(records) { + i++; + if (i > 1) + expect().fail(); + + assert.strictEqual(records.length, 2); + + expectRecord(records[0], { + type: 'childList', + target: div, + removedNodes: [child] + }); + + expectRecord(records[1], { + type: 'childList', + target: child, + addedNodes: [grandChild] + }); + + // The transient observers are removed before the callback is called. + child.removeChild(grandChild); + + records = observer.takeRecords(); + assert.strictEqual(records.length, 0); + + cont(); + }); + observer.observe(div, { + childList: true, + subtree: true + }); + div.removeChild(child); + var grandChild = child.appendChild(document.createElement('span')); + }); +}); |
