Delete Sky tests that we're not going to run with Dart
This CL removes a number of tests that we don't plan to port to Dart: 1) custom-elements. We're going to use a different mechanism for custom elements. We'll need to write a new set of tests as we implement it. 2) inspector. These are tests of the JS inspector backend, which we don't plan to use. 3) js. This is a test of a JavaScript feature. 4) mocha. These are tests of the JavaScript testing framework we were using. 5) mutation-observer. We're keeping the C++ code for mutation observers, but it's unclear how we want to expose this in the platform. 6) resources. These are JavaScript-based testing frameworks. R=eseidel@chromium.org, ojan@chromium.org Review URL: https://codereview.chromium.org/920343002
This commit is contained in:
@@ -1,10 +1,4 @@
|
||||
|
||||
# These tests require gc() to be exposed.
|
||||
crbug.com/1 mutation-observer/observer-wrapper-dropoff-transient.sky [ Skip ]
|
||||
crbug.com/1 mutation-observer/observer-wrapper-dropoff.sky [ Skip ]
|
||||
crbug.com/1 mutation-observer/transient-gc-crash.sky [ Skip ]
|
||||
crbug.com/1 mutation-observer/weak-callback-gc-crash.sky [ Skip ]
|
||||
|
||||
# These tests need more basic testing support plumbed right into the
|
||||
# platform, which we don't currently have:
|
||||
https://github.com/domokit/mojo/issues/15 parser/cr.sky [ Skip ]
|
||||
@@ -16,29 +10,12 @@ https://github.com/domokit/mojo/issues/14 parser/normaliser-null.sky [ Skip ]
|
||||
https://github.com/domokit/mojo/issues/14 parser/utf16.sky [ Skip ]
|
||||
https://github.com/domokit/mojo/issues/16 parser/normaliser-crlf.sky [ Skip ]
|
||||
|
||||
# These tests are flaky on the bots
|
||||
https://github.com/domokit/mojo/issues/24 custom-elements/constructor-calls-created-synchronously.sky [ Skip ]
|
||||
https://github.com/domokit/mojo/issues/24 mutation-observer/observe-attributes.sky [ Skip ]
|
||||
|
||||
# We don't implement embed ViewManagerClient yet.
|
||||
crbug.com/2 services/iframe-embed-vmc.sky [ Skip ]
|
||||
|
||||
# This test only fails on the bots:
|
||||
#crbug.com/434822 inspector/page-agent-get-resource-tree.sky [ Pass Failure ]
|
||||
|
||||
# These tests broke during the Dart migration
|
||||
crbug.com/2 animation/basic-imperative.sky [ Skip ]
|
||||
crbug.com/2 animation/basic-transition.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/document-register-basic.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/document-register-reentrant-null-constructor.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/document-register-reentrant-returning-fake.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/document-register-reentrant-throwing-constructor.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/element-upgrade-no-register-and-leak.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/generated-constructor.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/html-element-type-extension-assert.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/lifecycle-created-createElement-recursion.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/lifecycle-created-createElement-reentrancy.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/lifecycle-created-parser-script.sky [ Skip ]
|
||||
crbug.com/2 custom-elements/resources/document-register-fuzz.sky [ Skip ]
|
||||
crbug.com/2 editing/backspace.sky [ Skip ]
|
||||
crbug.com/2 editing/delete_block_contents.sky [ Skip ]
|
||||
crbug.com/2 editing/replace.sky [ Skip ]
|
||||
@@ -58,47 +35,15 @@ crbug.com/2 framework/xmlhttprequest/unicode-post.sky [ Skip ]
|
||||
crbug.com/2 framework/xmlhttprequest/xhr-does-not-exist.sky [ Skip ]
|
||||
crbug.com/2 framework/xmlhttprequest/xhr-relative.sky [ Skip ]
|
||||
crbug.com/2 framework/xmlhttprequest/xhr.sky [ Skip ]
|
||||
crbug.com/2 inspector/css-computed-style.sky [ Skip ]
|
||||
crbug.com/2 inspector/dom-mutation-modify-text-node-and-append.sky [ Skip ]
|
||||
crbug.com/2 inspector/dom-mutation.sky [ Skip ]
|
||||
crbug.com/2 inspector/page-agent-get-resource-tree.sky [ Skip ]
|
||||
crbug.com/2 js/classes.sky [ Skip ]
|
||||
crbug.com/2 layout/margins-absolute.sky [ Skip ]
|
||||
crbug.com/2 layout/margins.sky [ Skip ]
|
||||
crbug.com/2 lowlevel/createElement.sky [ Skip ]
|
||||
crbug.com/2 mocha/describe-only.sky [ Skip ]
|
||||
crbug.com/2 mocha/it-only.sky [ Skip ]
|
||||
crbug.com/2 modules/application.sky [ Skip ]
|
||||
crbug.com/2 modules/instance-of-application.sky [ Skip ]
|
||||
crbug.com/2 modules/instance-of-module.sky [ Skip ]
|
||||
crbug.com/2 modules/load-event.sky [ Skip ]
|
||||
crbug.com/2 modules/modules.sky [ Skip ]
|
||||
crbug.com/2 modules/resources/does-not-export.sky [ Skip ]
|
||||
crbug.com/2 modules/resources/instance-of-module-module.sky [ Skip ]
|
||||
crbug.com/2 modules/resources/intermediate.sky [ Skip ]
|
||||
crbug.com/2 modules/resources/pass.sky [ Skip ]
|
||||
crbug.com/2 modules/script-import.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/callback-arguments.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/clear-transient-without-delivery.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/create-during-delivery.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/cross-document.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/delivery-order.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/disconnect-cancel-pending.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/document-fragment-insertion.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/mutate-during-delivery.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/mutation-callback-non-element-crash.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/mutation-observer-constructor.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/mutation-record-constructor.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/mutation-record-nullity.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-characterdata.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-childList.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-exceptions.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-options-attributes.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-options-character-data.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/observe-subtree.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/script-append.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/shadow-dom.sky [ Skip ]
|
||||
crbug.com/2 mutation-observer/takeRecords.sky [ Skip ]
|
||||
crbug.com/2 parser/script.sky [ Skip ]
|
||||
crbug.com/2 services/buffer.sky [ Skip ]
|
||||
crbug.com/2 services/codec.sky [ Skip ]
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 Custom element constructors should run the createdCallback synchronously
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,21 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
describe('Custom element constructors', function() {
|
||||
it('should run the createdCallback synchronously', function() {
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
var ncallbacks = 0;
|
||||
proto.createdCallback = function () {
|
||||
ncallbacks++;
|
||||
};
|
||||
var A = document.registerElement('x-a', {prototype: proto});
|
||||
var x = new A();
|
||||
assert.equal(ncallbacks, 1);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 document.registerElement() should have basic behaviors
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,101 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
describe('document.registerElement()', function() {
|
||||
it('should have basic behaviors', function() {
|
||||
function createRegisterParameters()
|
||||
{
|
||||
return {
|
||||
prototype: Object.create(HTMLElement.prototype, { thisIsPrototype: { value: true } })
|
||||
};
|
||||
}
|
||||
|
||||
var fooConstructor = document.registerElement('x-foo', createRegisterParameters());
|
||||
assert.equal(typeof fooConstructor, "function");
|
||||
assert.equal(fooConstructor.prototype.__proto__, HTMLElement.prototype);
|
||||
assert.ok(fooConstructor.prototype.thisIsPrototype);
|
||||
|
||||
// Bad prototype: prototype is already a built-in interface prototype object
|
||||
assert.throws(function() {
|
||||
document.registerElement("x-bad-a", HTMLElement)
|
||||
});
|
||||
// Bad prototype: prototype is already a Custom Element interface prototype object
|
||||
assert.throws(function() {
|
||||
document.registerElement("x-bad-b", fooConstructor)
|
||||
});
|
||||
// Bad prototype: 'constructor' is not configurable
|
||||
var proto = Object.create(HTMLElement.prototype, {
|
||||
constructor: {configurable: false, writable: true}
|
||||
});
|
||||
assert.throws(function() {
|
||||
document.registerElement("x-bad-c", { prototype: proto })
|
||||
});
|
||||
// Call as function
|
||||
assert.throws(function() {
|
||||
fooConstructor()
|
||||
})
|
||||
|
||||
// Constructor initiated instantiation
|
||||
var createdFoo = new fooConstructor();
|
||||
|
||||
// JS built-in properties
|
||||
assert.equal(createdFoo.__proto__, fooConstructor.prototype);
|
||||
assert.equal(createdFoo.constructor, fooConstructor);
|
||||
|
||||
// Native getter
|
||||
assert.equal(createdFoo.tagName, "x-foo");
|
||||
|
||||
// Native setter
|
||||
createdFoo.textContent = 'Hello';
|
||||
assert.equal(createdFoo.textContent, "Hello");
|
||||
|
||||
// Native method
|
||||
var childDiv = document.createElement('div');
|
||||
createdFoo.appendChild(childDiv);
|
||||
assert.equal(createdFoo.lastChild, childDiv);
|
||||
|
||||
// Parser initiated instantiation
|
||||
var container = document.getElementById('container');
|
||||
container.appendChild(document.createElement("x-foo"));
|
||||
var parsedFoo = container.firstChild;
|
||||
|
||||
assert.equal(parsedFoo.__proto__, fooConstructor.prototype);
|
||||
assert.equal(parsedFoo.tagName, "x-foo");
|
||||
|
||||
// Ensuring the wrapper is retained
|
||||
parsedFoo.someProperty = 'hello';
|
||||
assert.equal(parsedFoo.someProperty, container.firstChild.someProperty);
|
||||
|
||||
// Having another constructor
|
||||
var barConstructor = document.registerElement('x-bar', createRegisterParameters());
|
||||
assert.ok('barConstructor !== fooConstructor');
|
||||
var createdBar = new barConstructor();
|
||||
assert.equal(createdBar.tagName, "x-bar");
|
||||
|
||||
// Having a subclass
|
||||
var bazConstructor = document.registerElement('x-baz', { prototype: Object.create(fooConstructor.prototype, { thisIsAlsoPrototype: { value: true } }) });
|
||||
var createdBaz = new bazConstructor();
|
||||
assert.equal(createdBaz.tagName, "x-baz");
|
||||
assert.ok(createdBaz.thisIsPrototype);
|
||||
assert.ok(createdBaz.thisIsAlsoPrototype);
|
||||
|
||||
// With irregular cases
|
||||
var createdUpperBar = document.createElement('X-BAR');
|
||||
var createdMixedBar = document.createElement('X-Bar');
|
||||
assert.notEqual(createdUpperBar.constructor, barConstructor);
|
||||
assert.notEqual(createdUpperBar.tagName, "x-bar");
|
||||
assert.notEqual(createdMixedBar.constructor, barConstructor);
|
||||
assert.notEqual(createdMixedBar.tagName, "x-bar");
|
||||
|
||||
// Constructors shouldn't interfere with each other
|
||||
assert.equal((new fooConstructor).tagName, "x-foo");
|
||||
assert.equal((new barConstructor).tagName, "x-bar");
|
||||
assert.equal((new bazConstructor).tagName, "x-baz");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +0,0 @@
|
||||
CONSOLE: LOG: Constructor object isn't created.
|
||||
Fuzzing document.registerElement() through getters. PASS unless crash.
|
||||
@@ -1,18 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
Fuzzing document.registerElement() through getters. PASS unless crash.
|
||||
<script>
|
||||
fuzzer.setupObjectHooks({
|
||||
prototypeGet: function() { },
|
||||
prototypeSet: function(value) { },
|
||||
constructorGet: function() { },
|
||||
constructorSet: function(value) { }
|
||||
});
|
||||
|
||||
fuzzer.exerciseDocumentRegister();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
Fuzzing document.registerElement() through getters. PASS uless crash.
|
||||
@@ -1,21 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
Fuzzing document.registerElement() through getters. PASS uless crash.
|
||||
<script>
|
||||
var badPrototype = Image.prototype;
|
||||
var badConstructor = Image.prototype.constructor;
|
||||
|
||||
fuzzer.setupObjectHooks({
|
||||
prototypeGet: function() { return badPrototype; },
|
||||
prototypeSet: function(value) { },
|
||||
constructorGet: function() { return badConstructor; },
|
||||
constructorSet: function(value) { }
|
||||
});
|
||||
|
||||
fuzzer.exerciseDocumentRegister();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +0,0 @@
|
||||
CONSOLE: LOG: Constructor object isn't created.
|
||||
Fuzzing document.registerElement() through getters. PASS unless crash.
|
||||
@@ -1,18 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<import src="resources/document-register-fuzz.sky" as="fuzzer" />
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
Fuzzing document.registerElement() through getters. PASS unless crash.
|
||||
<script>
|
||||
fuzzer.setupObjectHooks({
|
||||
prototypeGet: function() { throw "Error"; },
|
||||
prototypeSet: function(value) { throw "Error"; },
|
||||
constructorGet: function() { throw "Error"; },
|
||||
constructorSet: function(value) { throw "Error"; }
|
||||
});
|
||||
|
||||
fuzzer.exerciseDocumentRegister();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +0,0 @@
|
||||
Tests unresolved element not leaking if never resolved.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<body>
|
||||
Tests unresolved element not leaking if never resolved.
|
||||
<div id="container"></div>
|
||||
<script>
|
||||
// Verify that a custom tag for which no element is ever registered
|
||||
// doesn't cause a document nor elements to leak.
|
||||
var host = document.createElement('div');
|
||||
host.appendChild(document.createElement('x-a'));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 Custom element constructor should inherit from the passed constructor
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,19 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/mocha.sky" />
|
||||
<import src="../resources/chai.sky" />
|
||||
<script>
|
||||
describe("Custom element constructor", function() {
|
||||
it("should inherit from the passed constructor", function() {
|
||||
class TestElementClass extends HTMLElement {
|
||||
static test() { return 10; }
|
||||
}
|
||||
var TestElement = document.registerElement("test-element-1", {
|
||||
prototype: TestElementClass.prototype,
|
||||
});
|
||||
assert.isFunction(TestElement.test);
|
||||
assert.equal(TestElement.test(), 10);
|
||||
assert.equal(Object.getPrototypeOf(TestElement), TestElementClass);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
Tests that type extension of a element whose DOM interface is HTMLElement does not assert
|
||||
@@ -1,11 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<body>
|
||||
<section id="a" is="x-a"></section>
|
||||
Tests that type extension of a element whose DOM interface is HTMLElement does not assert
|
||||
<script>
|
||||
var u = document.querySelector('#a');
|
||||
var v = document.createElement('section', 'x-a');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +0,0 @@
|
||||
CONSOLE: LOG: PASS unless crash
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<body>
|
||||
<script>
|
||||
document.registerElement("x-foo", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function () { this.innerHTML = "<x-foo>Hello</x-foo>"; } } }) });
|
||||
document.createElement("x-foo");
|
||||
console.log("PASS unless crash");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
This test ensures that is visible in following script block.
|
||||
@@ -1,29 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<import src="../resources/chai.sky" />
|
||||
<body>
|
||||
This test ensures that is visible in following script block.
|
||||
<script>
|
||||
window.callbacksCalled = [];
|
||||
|
||||
function fooCreatedFunction() {
|
||||
assert.deepEqual(window.callbacksCalled, []);
|
||||
window.callbacksCalled.push(this.tagName);
|
||||
this.appendChild(document.createElement("x-bar"));
|
||||
assert.deepEqual(window.callbacksCalled, ['x-foo', 'x-bar']);
|
||||
}
|
||||
|
||||
function barCreatedFunction() {
|
||||
assert.deepEqual(window.callbacksCalled, ['x-foo']);
|
||||
window.callbacksCalled.push(this.tagName);
|
||||
}
|
||||
|
||||
document.registerElement("x-foo", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: fooCreatedFunction } }) });
|
||||
document.registerElement("x-bar", { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: barCreatedFunction } }) });
|
||||
</script>
|
||||
<script>
|
||||
document.createElement("x-foo");
|
||||
assert.deepEqual(window.callbacksCalled, ['x-foo', 'x-bar']);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,2 +0,0 @@
|
||||
This test ensures that the lifecycle callback of a parser-made element is visible in following script block.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<import src="../resources/chai.sky" />
|
||||
<body>
|
||||
This test ensures that the lifecycle callback of a parser-made element is visible in following script block.
|
||||
<script>
|
||||
var proto = Object.create(HTMLElement.prototype, { createdCallback: { value: function() { window.callbacksCalled = true; } } });
|
||||
document.registerElement("x-foo", { prototype: proto });
|
||||
</script>
|
||||
<x-foo></x-foo>
|
||||
<script>
|
||||
assert.ok("window.callbacksCalled");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,60 +0,0 @@
|
||||
<script>
|
||||
function setupObjectHooks(hooks)
|
||||
{
|
||||
// Wrapper for these object should be materialized before setting hooks.
|
||||
console.log;
|
||||
document.register;
|
||||
|
||||
Object.defineProperty(Object.prototype, "prototype", {
|
||||
get: function() { return hooks.prototypeGet(); },
|
||||
set: function(value) { return hooks.prototypeSet(value); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Object.prototype, "constructor", {
|
||||
get: function() { return hooks.constructorGet(); },
|
||||
set: function(value) { return hooks.constructorSet(value); }
|
||||
});
|
||||
|
||||
return hooks;
|
||||
}
|
||||
|
||||
function exerciseDocumentRegister()
|
||||
{
|
||||
register('x-a', {});
|
||||
register('x-b', {prototype: Object.create(HTMLElement.prototype)});
|
||||
}
|
||||
|
||||
function register(name, options)
|
||||
{
|
||||
var myConstructor = null;
|
||||
try {
|
||||
myConstructor = document.registerElement(name, options);
|
||||
} catch (e) { }
|
||||
|
||||
try {
|
||||
if (!myConstructor) {
|
||||
console.log("Constructor object isn't created.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (myConstructor.prototype != options.prototype) {
|
||||
console.log("FAIL: bad prototype");
|
||||
return;
|
||||
}
|
||||
|
||||
var element = new myConstructor();
|
||||
if (!element)
|
||||
return;
|
||||
if (element.constructor != myConstructor) {
|
||||
console.log("FAIL: bad constructor");
|
||||
return;
|
||||
}
|
||||
} catch (e) { console.log(e); }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setupObjectHooks: setupObjectHooks,
|
||||
exerciseDocumentRegister: exerciseDocumentRegister,
|
||||
register: register,
|
||||
}
|
||||
</script>
|
||||
@@ -1 +0,0 @@
|
||||
Done!
|
||||
@@ -1,18 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="/sky/framework/inspector/css-agent.sky" as="CSSAgent" />
|
||||
<script>
|
||||
var fakeDOMAgent = {
|
||||
getNodeForId: function(id) {
|
||||
return document.documentElement;
|
||||
}
|
||||
};
|
||||
|
||||
var cssAgent = new CSSAgent(fakeDOMAgent);
|
||||
cssAgent.enable();
|
||||
var response = cssAgent.getComputedStyleForNode({nodeId: '1'});
|
||||
|
||||
assert.isTrue(response["computedStyle"].length > 0);
|
||||
internals.notifyTestComplete("Done!");
|
||||
</script>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
Done!
|
||||
@@ -1,6 +0,0 @@
|
||||
CONSOLE: LOG: DOM.childNodeInserted
|
||||
CONSOLE: LOG: 2
|
||||
CONSOLE: LOG: 3
|
||||
CONSOLE: LOG: DOM.childNodeInserted
|
||||
CONSOLE: LOG: 3
|
||||
adding
|
||||
@@ -1,34 +0,0 @@
|
||||
<html>
|
||||
<import src="/sky/framework/inspector/dom-agent.sky" as="DOMAgent" />
|
||||
<div></div>
|
||||
<script>
|
||||
// FIXME: This shows a bug in our DOM mutation handling, we should
|
||||
// only get one childNodeInserted record here, but we get two, which
|
||||
// means the inspector shows two nodes where it should only show one.
|
||||
|
||||
// setTimeout to flush pending DOM modifications and measure
|
||||
// only the changes we want to.
|
||||
setTimeout(function() {
|
||||
var delegate = {
|
||||
sendMessage: function(message, params) {
|
||||
console.log(message);
|
||||
if (params.node)
|
||||
console.log(params.node.nodeId);
|
||||
if (params.node && params.node.children)
|
||||
console.log(params.node.children[0].nodeId);
|
||||
}
|
||||
};
|
||||
|
||||
var domAgent = new DOMAgent(delegate);
|
||||
domAgent.enable();
|
||||
|
||||
var adding = document.createElement('adding');
|
||||
document.querySelector('div').appendChild(adding);
|
||||
adding.textContent = 'adding';
|
||||
|
||||
setTimeout(function() {
|
||||
internals.notifyTestComplete(internals.contentAsText());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,36 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="/sky/framework/inspector/dom-agent.sky" as="DOMAgent" />
|
||||
<div><div></div></div>
|
||||
<script>
|
||||
// setTimeout to flush pending DOM modifications and measure
|
||||
// only the changes we want to.
|
||||
var expectedMessages = [
|
||||
'DOM.childNodeRemoved',
|
||||
'DOM.childNodeInserted',
|
||||
];
|
||||
var actualMessages = [];
|
||||
|
||||
setTimeout(function() {
|
||||
var delegate = {
|
||||
sendMessage: function(message, params) {
|
||||
actualMessages.push(message);
|
||||
}
|
||||
};
|
||||
|
||||
var domAgent = new DOMAgent(delegate);
|
||||
domAgent.enable();
|
||||
|
||||
var adding = document.createElement('adding');
|
||||
var container = document.querySelector('div');
|
||||
container.firstChild.remove();
|
||||
container.appendChild(document.createElement('adding'));
|
||||
|
||||
setTimeout(function() {
|
||||
assert.equal(JSON.stringify(expectedMessages),
|
||||
JSON.stringify(actualMessages));
|
||||
internals.notifyTestComplete("Done!");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
Got message!
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 PageAgent.getResourceTree should dump the current resource tree
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,43 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<import src="/sky/framework/inspector/page-agent.sky" as="PageAgent" />
|
||||
<img src='does_not_exist.jpg' />
|
||||
<script>
|
||||
describe('PageAgent.getResourceTree', function() {
|
||||
it('should dump the current resource tree', function() {
|
||||
var pageAgent = new PageAgent();
|
||||
pageAgent.enable();
|
||||
var resourceTree = pageAgent.getResourceTree();
|
||||
assert.deepEqual(resourceTree, {
|
||||
"frameTree": {
|
||||
"frame": {
|
||||
"id": "1",
|
||||
"loaderId": "1",
|
||||
"url": "http://127.0.0.1:8000/sky/tests/inspector/page-agent-get-resource-tree.sky",
|
||||
"mimeType": "text/html",
|
||||
"securityOrigin": "http://127.0.0.1:8000/sky/tests/inspector/page-agent-get-resource-tree.sky"
|
||||
},
|
||||
"resources": [{
|
||||
"url": "http://127.0.0.1:8000/sky/tests/resources/chai.sky",
|
||||
"type": "Document",
|
||||
"mimeType": "text/html"
|
||||
}, {
|
||||
"url": "http://127.0.0.1:8000/sky/tests/resources/mocha.sky",
|
||||
"type": "Document",
|
||||
"mimeType": "text/html"
|
||||
}, {
|
||||
"url": "http://127.0.0.1:8000/sky/framework/inspector/page-agent.sky",
|
||||
"type": "Document",
|
||||
"mimeType": "text/html"
|
||||
}, {
|
||||
"url": "http://127.0.0.1:8000/sky/tests/inspector/does_not_exist.jpg",
|
||||
"type": "Image",
|
||||
"mimeType": "image/unknown"
|
||||
}]
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,14 +0,0 @@
|
||||
Running 10 tests
|
||||
ok 1 ES6 classes should create instances
|
||||
ok 2 ES6 classes should create subclasses
|
||||
ok 3 ES6 classes should create anonymous classes
|
||||
ok 4 ES6 classes should put methods on the prototype
|
||||
ok 5 ES6 classes should call methods with |this|
|
||||
ok 6 ES6 classes should let toMethod rebind super
|
||||
ok 7 ES6 classes should support super() constructor calls
|
||||
ok 8 ES6 classes should automatically call super() in default constructor
|
||||
ok 9 ES6 classes should call super.method()
|
||||
ok 10 ES6 classes should support getters and setters
|
||||
10 tests
|
||||
10 pass
|
||||
0 fail
|
||||
@@ -1,163 +0,0 @@
|
||||
<sky>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe("ES6 classes", function() {
|
||||
it("should create instances", function() {
|
||||
class Example {}
|
||||
var instance = new Example();
|
||||
assert.instanceOf(instance, Example);
|
||||
});
|
||||
|
||||
it("should create subclasses", function() {
|
||||
class Parent {}
|
||||
class Child extends Parent {}
|
||||
var instance = new Child();
|
||||
assert.instanceOf(instance, Child);
|
||||
assert.instanceOf(instance, Parent);
|
||||
});
|
||||
|
||||
it("should create anonymous classes", function() {
|
||||
var Parent = class {}
|
||||
var Child = class extends Parent {}
|
||||
var instance = new Child();
|
||||
assert.instanceOf(instance, Child);
|
||||
assert.instanceOf(instance, Parent);
|
||||
});
|
||||
|
||||
it("should put methods on the prototype", function() {
|
||||
class Test {
|
||||
exampleMethod() { }
|
||||
}
|
||||
var instance = new Test();
|
||||
assert.isFalse(instance.hasOwnProperty("exampleMethod"));
|
||||
var proto = Object.getPrototypeOf(instance);
|
||||
assert.isTrue(proto.hasOwnProperty("exampleMethod"));
|
||||
});
|
||||
|
||||
it("should call methods with |this|", function() {
|
||||
class Adder {
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
add(other) {
|
||||
return this.value + other;
|
||||
}
|
||||
}
|
||||
|
||||
var adder = new Adder(10);
|
||||
assert.equal(adder.add(15), 25);
|
||||
});
|
||||
|
||||
it("should let toMethod rebind super", function() {
|
||||
var getValue = function() {
|
||||
assert.isFunction(this.value);
|
||||
assert.isFunction(this.superValue);
|
||||
return this.value() + super.superValue();
|
||||
}
|
||||
|
||||
class HolderParent {
|
||||
superValue() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
class Holder extends HolderParent {
|
||||
constructor() {
|
||||
this.value_ = 5;
|
||||
}
|
||||
value() {
|
||||
return this.value_;
|
||||
}
|
||||
}
|
||||
|
||||
var holder = new Holder();
|
||||
var getValueMethod = getValue.toMethod(Holder.prototype);
|
||||
assert.equal(getValueMethod.call(holder), 10);
|
||||
});
|
||||
|
||||
it("should support super() constructor calls", function() {
|
||||
class Parent {
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
constructor(value) {
|
||||
super(value + 5);
|
||||
}
|
||||
}
|
||||
|
||||
var child = new Child(10);
|
||||
assert.equal(child.value, 15);
|
||||
});
|
||||
|
||||
it("should automatically call super() in default constructor", function() {
|
||||
class Parent {
|
||||
constructor() {
|
||||
this.value = 10;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
}
|
||||
|
||||
var child = new Child();
|
||||
assert.equal(child.value, 10);
|
||||
});
|
||||
|
||||
it("should call super.method()", function() {
|
||||
class Parent {
|
||||
value() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Parent {
|
||||
value() {
|
||||
return super.value() + 5;
|
||||
}
|
||||
}
|
||||
|
||||
var child = new Child();
|
||||
assert.equal(child.value(), 15);
|
||||
});
|
||||
|
||||
it("should support getters and setters", function() {
|
||||
class Variable {
|
||||
constructor(value) {
|
||||
this.value_ = value;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.value_;
|
||||
}
|
||||
|
||||
set value(newValue) {
|
||||
this.value_ = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
var variable = new Variable("first");
|
||||
|
||||
// Methods are on the prototype.
|
||||
var proto = Object.getPrototypeOf(variable);
|
||||
var descriptor = Object.getOwnPropertyDescriptor(proto, "value");
|
||||
assert.isObject(descriptor);
|
||||
assert.isFunction(descriptor.get);
|
||||
assert.isFunction(descriptor.set);
|
||||
assert.isUndefined(descriptor.value);
|
||||
|
||||
// Getter and setter should not be on the instance.
|
||||
assert.isUndefined(Object.getOwnPropertyDescriptor(variable, "value"));
|
||||
|
||||
assert.equal(variable.value, "first");
|
||||
assert.equal(variable.value_, "first");
|
||||
variable.value = "second";
|
||||
assert.equal(variable.value, "second");
|
||||
assert.equal(variable.value_, "second");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</sky>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 This suite should run this test
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,20 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
|
||||
describe.only('This suite', function() {
|
||||
it('should run this test', function() {
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('That suite', function() {
|
||||
it('should not run this test', function() {
|
||||
assert.ok(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 This suite should only run this test
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,18 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
|
||||
describe('This suite', function() {
|
||||
it.only('should only run this test', function() {
|
||||
assert.ok(true);
|
||||
});
|
||||
|
||||
it('should not run this test', function() {
|
||||
assert.ok(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver should pass the callback and observer arguments
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,18 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver', function() {
|
||||
it('should pass the callback and observer arguments', function(done) {
|
||||
var mutationObserver = new MutationObserver(function(mutations, observer) {
|
||||
assert.equal(this, mutationObserver);
|
||||
assert.equal(mutationObserver, observer);
|
||||
done();
|
||||
});
|
||||
var div = document.createElement('div');
|
||||
mutationObserver.observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'bar');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 Transient registrations should be cleared even without delivery
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,28 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('Transient registrations', function() {
|
||||
it('should be cleared even without delivery', function(done) {
|
||||
var mutationsDelivered = false;
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutationsDelivered = true;
|
||||
});
|
||||
var div = document.createElement('div');
|
||||
var span = div.appendChild(document.createElement('span'));
|
||||
observer.observe(div, {attributes: true, subtree: true});
|
||||
div.removeChild(span);
|
||||
setTimeout(function() {
|
||||
// By the time this function runs the transient registration should
|
||||
// be cleared, so we expect not to be notified of this attribute
|
||||
// mutation.
|
||||
span.setAttribute('bar', 'baz');
|
||||
setTimeout(function() {
|
||||
assert.notOk(mutationsDelivered);
|
||||
done();
|
||||
}, 0);
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObservers must wait for the next loop when created during delivery
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,37 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
window.jsTestIsAsync = true;
|
||||
|
||||
describe('MutationObservers', function() {
|
||||
it ('must wait for the next loop when created during delivery', function(done) {
|
||||
var order = [];
|
||||
var div = document.createElement('div');
|
||||
|
||||
var observer3;
|
||||
var observer1 = new MutationObserver(function(mutations) {
|
||||
order.push(1);
|
||||
if (!observer3) {
|
||||
observer3 = new MutationObserver(function(mutations) {
|
||||
order.push(3);
|
||||
});
|
||||
observer3.observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'baz');
|
||||
}
|
||||
});
|
||||
var observer2 = new MutationObserver(function(mutations) {
|
||||
order.push(2);
|
||||
});
|
||||
|
||||
observer1.observe(div, {attributes: true});
|
||||
observer2.observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'bar');
|
||||
setTimeout(function() {
|
||||
assert.deepEqual(order, [1, 2, 1, 3]);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,6 +0,0 @@
|
||||
Running 2 tests
|
||||
ok 1 MutationObserver cross document moves should handle basic observation
|
||||
ok 2 MutationObserver cross document moves should handle subtree observation
|
||||
2 tests
|
||||
2 pass
|
||||
0 fail
|
||||
@@ -1,49 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver cross document moves', function() {
|
||||
it('should handle basic observation', function(done) {
|
||||
var mutations;
|
||||
var div = document.createElement('div');
|
||||
var observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true});
|
||||
var newDoc = new Document();
|
||||
newDoc.appendChild(div);
|
||||
div.id = 'foo';
|
||||
setTimeout(function() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, 'attributes');
|
||||
assert.equal(mutations[0].target, div);
|
||||
assert.equal(mutations[0].attributeName, 'id');
|
||||
observer.disconnect();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
it('should handle subtree observation', function(done) {
|
||||
var mutations;
|
||||
var div = document.createElement('div');
|
||||
var subDiv = div.appendChild(document.createElement('div'));
|
||||
var observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, subtree: true});
|
||||
var newDoc = new Document();
|
||||
newDoc.appendChild(div);
|
||||
subDiv.id = 'foo';
|
||||
setTimeout(function() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, 'attributes');
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, 'id');
|
||||
observer.disconnect();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver should deliver in order of creation
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,40 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver', function() {
|
||||
it('should deliver in order of creation', function(done) {
|
||||
var order = [];
|
||||
var observers = [];
|
||||
|
||||
function setUpOrdering(num) {
|
||||
observers.push(new MutationObserver(function(mutations) {
|
||||
order.push(num);
|
||||
}));
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10; ++i)
|
||||
setUpOrdering(i);
|
||||
|
||||
var div = document.createElement('div');
|
||||
observers[3].observe(div, {attributes: true});
|
||||
observers[2].observe(div, {characterData: true, subtree: true});
|
||||
observers[1].observe(div, {attributes: true});
|
||||
observers[7].observe(div, {childList: true});
|
||||
observers[4].observe(div, {attributes: true});
|
||||
observers[9].observe(div, {attributes: true});
|
||||
observers[0].observe(div, {childList: true});
|
||||
observers[5].observe(div, {attributes: true});
|
||||
observers[6].observe(div, {characterData: true, subtree: true});
|
||||
observers[8].observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'bar');
|
||||
div.appendChild(new Text('hello'));
|
||||
div.firstChild.textContent = 'goodbye';
|
||||
setTimeout(function() {
|
||||
assert.deepEqual(order, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver.disconnect should cancel pending delivery
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,44 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver.disconnect', function() {
|
||||
it('should cancel pending delivery', function(done) {
|
||||
var mutations;
|
||||
var observer;
|
||||
var div;
|
||||
|
||||
function start() {
|
||||
mutations = null;
|
||||
div = document.createElement('div');
|
||||
|
||||
observer = new MutationObserver(function(m) {
|
||||
mutations = m;
|
||||
});
|
||||
|
||||
observer.observe(div, { attributes: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
observer.disconnect();
|
||||
setTimeout(next, 0);
|
||||
}
|
||||
|
||||
function next() {
|
||||
// Disconnecting should cancel any pending delivery...
|
||||
assert.equal(mutations, null);
|
||||
observer.observe(div, { attributes: true });
|
||||
div.setAttribute('bar', 'baz');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...and re-observing should not see any of the previously-generated records.
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].attributeName, "bar");
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
Running 3 tests
|
||||
ok 1 DocumentFragments should remove all children of the fragment before moving children, using appendChild
|
||||
ok 2 DocumentFragments should remove all children of the fragment before moving children, using insertBefore
|
||||
ok 3 DocumentFragments should remove all children of the fragment before moving children, using replaceChild
|
||||
3 tests
|
||||
3 pass
|
||||
0 fail
|
||||
@@ -1,69 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/mocha.sky" />
|
||||
<import src="../resources/chai.sky" />
|
||||
<script>
|
||||
describe('DocumentFragments should remove all children of the fragment before moving children, ', function() {
|
||||
var mutations;
|
||||
var observer;
|
||||
|
||||
beforeEach(function() {
|
||||
mutations = null;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
});
|
||||
|
||||
function createObservedFragment() {
|
||||
var fragment = document.createDocumentFragment();
|
||||
fragment.appendChild(document.createElement('b'));
|
||||
fragment.appendChild(document.createElement('i'));
|
||||
observer.observe(fragment, {childList: true});
|
||||
return fragment;
|
||||
}
|
||||
|
||||
it('using appendChild', function(done) {
|
||||
var div = document.createElement('div');
|
||||
observer.observe(div, {childList: true});
|
||||
div.appendChild(createObservedFragment());
|
||||
setTimeout(function() {
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].addedNodes.length, 0);
|
||||
assert.equal(mutations[0].removedNodes.length, 2);
|
||||
assert.equal(mutations[1].addedNodes.length, 2);
|
||||
assert.equal(mutations[1].removedNodes.length, 0);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('using insertBefore', function(done) {
|
||||
var div = document.createElement('div');
|
||||
div.appendChild(document.createElement('span'));
|
||||
observer.observe(div, {childList: true});
|
||||
div.insertBefore(createObservedFragment(), div.firstChild);
|
||||
setTimeout(function() {
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].addedNodes.length, 0);
|
||||
assert.equal(mutations[0].removedNodes.length, 2);
|
||||
assert.equal(mutations[1].addedNodes.length, 2);
|
||||
assert.equal(mutations[1].removedNodes.length, 0);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('using replaceChild', function(done) {
|
||||
var div = document.createElement('div');
|
||||
div.appendChild(document.createElement('span'));
|
||||
observer.observe(div, {childList: true});
|
||||
div.replaceChild(createObservedFragment(), div.firstChild);
|
||||
setTimeout(function() {
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].addedNodes.length, 0);
|
||||
assert.equal(mutations[0].removedNodes.length, 2);
|
||||
assert.equal(mutations[1].addedNodes.length, 2);
|
||||
assert.equal(mutations[1].removedNodes.length, 1);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver should not interrupt delivery order on getting mutations during delivery
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,34 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver', function() {
|
||||
it('should not interrupt delivery order on getting mutations during delivery', function(done) {
|
||||
function finish() {
|
||||
assert.deepEqual(order, [1, 3, 2]);
|
||||
done();
|
||||
}
|
||||
|
||||
var order = [];
|
||||
var div = document.createElement('div');
|
||||
|
||||
var observer1 = new MutationObserver(function(mutations) {
|
||||
order.push(1);
|
||||
div.appendChild(document.createElement('span'));
|
||||
});
|
||||
var observer2 = new MutationObserver(function(mutations) {
|
||||
order.push(2);
|
||||
});
|
||||
var observer3 = new MutationObserver(function(mutations) {
|
||||
order.push(3);
|
||||
});
|
||||
|
||||
observer1.observe(div, {attributes: true});
|
||||
observer2.observe(div, {childList: true});
|
||||
observer3.observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'bar');
|
||||
setTimeout(finish, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
PASS. We didn't crash
|
||||
@@ -1,15 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/dump-as-text.sky" />
|
||||
<body id="body">
|
||||
<script>
|
||||
function mutationCallback(mutations, observer) {
|
||||
mutations[0].addedNodes[-1];
|
||||
}
|
||||
|
||||
var mutationObserver = new MutationObserver(mutationCallback);
|
||||
var body = document.getElementById("body");
|
||||
mutationObserver.observe(body, {childList: true});
|
||||
body.appendChild(new Text("PASS. We didn't crash"));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +0,0 @@
|
||||
Running 2 tests
|
||||
ok 1 MutationObserver should have methods
|
||||
ok 2 MutationObserver should throw with incorrect constructor args
|
||||
2 tests
|
||||
2 pass
|
||||
0 fail
|
||||
@@ -1,28 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver', function() {
|
||||
var observer = new MutationObserver(function(mutations) { });
|
||||
|
||||
it('should have methods', function() {
|
||||
assert.equal(typeof observer.observe, 'function');
|
||||
assert.equal(typeof observer.disconnect, 'function');
|
||||
});
|
||||
it('should throw with incorrect constructor args', function() {
|
||||
assert.throw(function() {
|
||||
new MutationObserver({ handleEvent: function() {} });
|
||||
}, TypeError);
|
||||
assert.throw(function() {
|
||||
new MutationObserver({});
|
||||
}, TypeError);
|
||||
assert.throw(function() {
|
||||
new MutationObserver(42);
|
||||
}, TypeError);
|
||||
assert.throw(function() {
|
||||
new MutationObserver("foo");
|
||||
}, TypeError);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationRecord should be exposed on window but not constructable
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,22 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationRecord', function() {
|
||||
it('should be exposed on window but not constructable', function() {
|
||||
assert.ok(window.MutationRecord);
|
||||
assert.equal(typeof MutationRecord, "function");
|
||||
assert.throw(function() {
|
||||
new MutationRecord
|
||||
}, TypeError);
|
||||
|
||||
var div = document.createElement('div');
|
||||
var observer = new MutationObserver(function(){});
|
||||
observer.observe(div, {attributes: true});
|
||||
div.id = 'foo';
|
||||
var record = observer.takeRecords()[0];
|
||||
assert.ok(record instanceof MutationRecord);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,7 +0,0 @@
|
||||
Running 3 tests
|
||||
ok 1 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on characterData records
|
||||
ok 2 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on childList records
|
||||
ok 3 Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty on attribute records
|
||||
3 tests
|
||||
3 pass
|
||||
0 fail
|
||||
@@ -1,42 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty', function() {
|
||||
|
||||
var observer = new MutationObserver(function() {});
|
||||
|
||||
it('on characterData records', function() {
|
||||
var text = new Text('something');
|
||||
observer.observe(text, {characterData: true});
|
||||
text.data = 'something else';
|
||||
var record = observer.takeRecords()[0];
|
||||
assert.isNull(record.attributeName);
|
||||
assert.isNull(record.oldValue);
|
||||
assert.isNull(record.previousSibling);
|
||||
assert.isNull(record.nextSibling);
|
||||
assert.equal(record.addedNodes.length, 0);
|
||||
assert.equal(record.removedNodes.length, 0);
|
||||
});
|
||||
it('on childList records', function() {
|
||||
var div = document.createElement('div');
|
||||
observer.observe(div, {childList: true});
|
||||
div.appendChild(document.createElement('span'));
|
||||
var record = observer.takeRecords()[0];
|
||||
assert.isNull(record.attributeName);
|
||||
assert.isNull(record.oldValue);
|
||||
});
|
||||
it('on attribute records', function() {
|
||||
var div = document.createElement('div');
|
||||
observer.observe(div, {attributes: true});
|
||||
div.setAttribute('data-foo', 'bar');
|
||||
var record = observer.takeRecords()[0];
|
||||
assert.isNull(record.oldValue);
|
||||
assert.isNull(record.previousSibling);
|
||||
assert.isNull(record.nextSibling);
|
||||
assert.equal(record.addedNodes.length, 0);
|
||||
assert.equal(record.removedNodes.length, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,20 +0,0 @@
|
||||
ERROR: Failed to load resource: the server responded with a status of 404 ()
|
||||
SOURCE: http://127.0.0.1:8000/sky/tests/mutation-observer/baz.png:0
|
||||
Running 14 tests
|
||||
ok 1 MutationObserver.observe on attributes should handle basic aspects of attribute observation
|
||||
ok 2 MutationObserver.observe on attributes should not notify of attribute changes without asking
|
||||
ok 3 MutationObserver.observe on attributes re-observing the same node with the same observer has the effect of resetting the options
|
||||
ok 4 MutationObserver.observe on attributes multiple observers can be registered to a given node and both receive mutations
|
||||
ok 5 MutationObserver.observe on attributes should deliver mutations on modifications to node properties which delegate to attribute storage
|
||||
ok 6 MutationObserver.observe on attributes should handle basic oldValue delivery
|
||||
ok 7 MutationObserver.observe on attributes should deliver oldValue when needed
|
||||
ok 8 MutationObserver.observe on attributes should give attributeOldValue if any entries request it with multiple observers
|
||||
ok 9 MutationObserver.observe on attributes should handle setting an attribute via reflected IDL attribute
|
||||
ok 10 MutationObserver.observe on attributes should respect attributeFilter on HTML elements
|
||||
ok 11 MutationObserver.observe on attributes should respect different attributeFilters when observing multiple subtree nodes
|
||||
ok 12 MutationObserver.observe on attributes should create records for the style property
|
||||
ok 13 MutationObserver.observe on attributes should have oldValue for style property mutations
|
||||
ok 14 MutationObserver.observe on attributes should not create records for noop style property mutation
|
||||
14 tests
|
||||
14 pass
|
||||
0 fail
|
||||
@@ -1,569 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver.observe on attributes', function() {
|
||||
it('should handle basic aspects of attribute observation', function(done) {
|
||||
var div;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('bar', 'foo');
|
||||
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, { attributes: true, characterData: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
div.removeAttribute('bar');
|
||||
setTimeout(checkDisconnectAndMutate, 0);
|
||||
}
|
||||
|
||||
function checkDisconnectAndMutate() {
|
||||
// ...can attribute changes be observed at all
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "bar");
|
||||
|
||||
mutations = null;
|
||||
observer.disconnect();
|
||||
div.setAttribute('foo', 'baz');
|
||||
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
|
||||
}
|
||||
|
||||
function checkNotDeliveredAndMutateMultiple() {
|
||||
// ...observer.disconnect() should prevent further delivery of mutations.
|
||||
|
||||
assert.equal(mutations, null);
|
||||
observer.observe(div, { attributes: true });
|
||||
div.setAttribute('foo', 'bat');
|
||||
div.setAttribute('bar', 'foo');
|
||||
setTimeout(finish);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...re-observing after disconnect works with the same observer.
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "bar");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should not notify of attribute changes without asking', function(done) {
|
||||
var div;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, { childList: true, characterData: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations, null);
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('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(records) {
|
||||
mutations = records;
|
||||
calls++;
|
||||
});
|
||||
|
||||
observer.observe(div, { attributes: true, characterData: true });
|
||||
observer.observe(div, { attributes: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
setTimeout(checkDisconnectAndMutate, 0);
|
||||
}
|
||||
|
||||
function checkDisconnectAndMutate() {
|
||||
assert.equal(calls, 1);
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
mutations = null;
|
||||
observer.observe(div, { attributes: true, characterData: true });
|
||||
observer.observe(div, { childList: true });
|
||||
div.setAttribute('foo', 'baz');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations, null);
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('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(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer2 = new MutationObserver(function(records) {
|
||||
mutations2 = records;
|
||||
});
|
||||
observer.observe(div, { attributes: true });
|
||||
observer2.observe(div, { attributes: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations2.length, 1);
|
||||
assert.equal(mutations2[0].type, "attributes");
|
||||
assert.equal(mutations2[0].attributeName, "foo");
|
||||
observer.disconnect();
|
||||
observer2.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should deliver mutations on modifications to node properties which delegate to attribute storage', function(done) {
|
||||
var img, a;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
img = document.createElement('img');
|
||||
a = document.createElement('a');
|
||||
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(img, { attributes: true });
|
||||
observer.observe(a, { attributes: true });
|
||||
|
||||
img.src = 'baz.png';
|
||||
a.href = 'foo.html';
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "src");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "href");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should handle basic oldValue delivery', function(done) {
|
||||
var div;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('bar', 'boo');
|
||||
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer.observe(div, { attributes: true, attributeOldValue: true });
|
||||
div.setAttribute('foo', 'bar');
|
||||
div.setAttribute('foo', 'baz');
|
||||
div.removeAttribute('bar');
|
||||
div.removeAttribute('non-existant');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[0].oldValue, null);
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "foo");
|
||||
assert.equal(mutations[1].oldValue, "bar");
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "bar");
|
||||
assert.equal(mutations[2].oldValue, "boo");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should deliver oldValue when needed', function(done) {
|
||||
var div;
|
||||
var observerWithOldValue;
|
||||
var observer;
|
||||
var mutationsWithOldValue;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('foo', 'bar');
|
||||
observerWithOldValue = new MutationObserver(function(records) {
|
||||
mutationsWithOldValue = records;
|
||||
});
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observerWithOldValue.observe(div, { attributes: true, attributeOldValue: true });
|
||||
observer.observe(div, { attributes: true });
|
||||
div.setAttribute('foo', 'baz');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutationsWithOldValue.length, 1);
|
||||
assert.equal(mutationsWithOldValue[0].type, "attributes");
|
||||
assert.equal(mutationsWithOldValue[0].attributeName, "foo");
|
||||
assert.equal(mutationsWithOldValue[0].oldValue, "bar");
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[0].oldValue, null);
|
||||
observerWithOldValue.disconnect();
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should give attributeOldValue if any entries request it with multiple observers', function(done) {
|
||||
var div;
|
||||
var span;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
span = div.appendChild(document.createElement('span'));
|
||||
span.setAttribute('foo', 'bar');
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer.observe(div, { attributes: true, attributeOldValue: true, subtree: true });
|
||||
observer.observe(span, { attributes: true });
|
||||
span.setAttribute('foo', 'baz');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[0].oldValue, "bar");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should handle setting an attribute via reflected IDL attribute', function(done) {
|
||||
var div;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer.observe(div, { attributes: true, attributeOldValue: true });
|
||||
div.id = 'foo';
|
||||
div.id = 'bar';
|
||||
div.id = null;
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "id");
|
||||
assert.equal(mutations[0].oldValue, null);
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "id");
|
||||
assert.equal(mutations[1].oldValue, "foo");
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "id");
|
||||
assert.equal(mutations[2].oldValue, "bar");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should respect attributeFilter on HTML elements', function(done) {
|
||||
var div, path;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
div = document.createElement('div');
|
||||
observer.observe(div, { attributes: true, attributeFilter: ['foo', 'bar', 'booM'] });
|
||||
div.setAttribute('foo', 'foo');
|
||||
div.setAttribute('bar', 'bar');
|
||||
div.setAttribute('baz', 'baz');
|
||||
div.setAttribute('BOOm', 'boom');
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...only foo and bar should be received.
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "bar");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should respect different attributeFilters when observing multiple subtree nodes', function(done) {
|
||||
var div, div2, div3;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
div = document.createElement('div');
|
||||
div2 = div.appendChild(document.createElement('div'));
|
||||
div3 = div2.appendChild(document.createElement('div'));
|
||||
|
||||
observer.observe(div, { attributes: true, subtree: true, attributeFilter: ['foo', 'bar'] });
|
||||
observer.observe(div2, { attributes: true, subtree: true, attributeFilter: ['bar', 'bat'] });
|
||||
|
||||
div3.setAttribute('foo', 'foo');
|
||||
div3.setAttribute('bar', 'bar');
|
||||
div3.setAttribute('bat', 'bat');
|
||||
div3.setAttribute('baz', 'baz');
|
||||
|
||||
setTimeout(checkAndObserveAll, 0);
|
||||
}
|
||||
|
||||
function checkAndObserveAll() {
|
||||
// ...only foo, bar & bat should be received.
|
||||
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "bar");
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "bat");
|
||||
|
||||
observer.observe(div2, { attributes: true, subtree: true });
|
||||
div3.setAttribute('bar', 'bar');
|
||||
div3.setAttribute('bat', 'bat');
|
||||
div3.setAttribute('baz', 'baz');
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...bar, bat & baz should all be received.
|
||||
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "bar");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "bat");
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "baz");
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should create records for the style property', function(done) {
|
||||
var div, path;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('style', 'color: yellow; width: 100px;');
|
||||
observer.observe(div, { attributes: true });
|
||||
div.style.color = 'red';
|
||||
div.style.width = '200px';
|
||||
div.style.color = 'blue';
|
||||
|
||||
setTimeout(checkAndContinue, 0);
|
||||
}
|
||||
|
||||
function checkAndContinue() {
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "style");
|
||||
assert.equal(mutations[0].oldValue, null);
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "style");
|
||||
assert.equal(mutations[1].oldValue, null);
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "style");
|
||||
assert.equal(mutations[2].oldValue, null);
|
||||
|
||||
mutations = null;
|
||||
div.getAttribute('style');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...mutation record created.
|
||||
|
||||
assert.equal(mutations, null);
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should have oldValue for style property mutations', function(done) {
|
||||
var div, path;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('style', 'color: yellow; width: 100px;');
|
||||
observer.observe(div, { attributes: true, attributeOldValue: true });
|
||||
div.style.color = 'red';
|
||||
div.style.width = '200px';
|
||||
div.style.color = 'blue';
|
||||
|
||||
setTimeout(checkAndContinue, 0);
|
||||
}
|
||||
|
||||
function checkAndContinue() {
|
||||
assert.equal(mutations.length, 3);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].attributeName, "style");
|
||||
assert.equal(mutations[0].oldValue, "color: yellow; width: 100px;");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].attributeName, "style");
|
||||
assert.equal(mutations[1].oldValue, "color: rgb(255, 0, 0); width: 100px;");
|
||||
assert.equal(mutations[2].type, "attributes");
|
||||
assert.equal(mutations[2].attributeName, "style");
|
||||
assert.equal(mutations[2].oldValue, "color: rgb(255, 0, 0); width: 200px;");
|
||||
|
||||
mutations = null;
|
||||
div.getAttribute('style');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...mutation record created.
|
||||
|
||||
assert.equal(mutations, null);
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should not create records for noop style property mutation', function(done) {
|
||||
var div, path;
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
div = document.createElement('div');
|
||||
div.setAttribute('style', 'color: yellow; width: 100px;');
|
||||
observer.observe(div, { attributes: true });
|
||||
div.style.removeProperty('height');
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations, null);
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +0,0 @@
|
||||
Running 6 tests
|
||||
ok 1 MutationObserver on character data should handle basic aspects of characterData observation
|
||||
ok 2 MutationObserver on character data should only notify of characterData changes when requested
|
||||
ok 3 MutationObserver on character data should allow multiple observers can be registered to a given node and both receive mutations
|
||||
ok 4 MutationObserver on character data should provide oldValue is returned when requested
|
||||
ok 5 MutationObserver on character data should allow observing both with and without oldValue
|
||||
ok 6 MutationObserver on character data should provide oldValue if any observation requests it
|
||||
6 tests
|
||||
6 pass
|
||||
0 fail
|
||||
@@ -1,229 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<body id="body">
|
||||
<script>
|
||||
document.body = document.getElementById("body");
|
||||
|
||||
describe('MutationObserver on character data', function() {
|
||||
it('should handle basic aspects of characterData observation', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
var charDataNode;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'foo';
|
||||
charDataNode = div.firstChild;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(charDataNode, {characterData: true});
|
||||
charDataNode.textContent = 'bar';
|
||||
setTimeout(checkDisconnectAndMutate, 0);
|
||||
}
|
||||
|
||||
function checkDisconnectAndMutate() {
|
||||
// ...can characterData changes be observed at all
|
||||
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].target, charDataNode);
|
||||
|
||||
mutations = null;
|
||||
observer.disconnect();
|
||||
charDataNode.textContent = 'baz';
|
||||
setTimeout(checkNotDeliveredAndMutateMultiple, 0);
|
||||
}
|
||||
|
||||
function checkNotDeliveredAndMutateMultiple() {
|
||||
// ...observer.disconnect() should prevent further delivery of mutations.
|
||||
|
||||
assert.equal(mutations, null);
|
||||
charDataNode = new Text('');
|
||||
observer.observe(charDataNode, { characterData: true });
|
||||
charDataNode.textContent = 'foo';
|
||||
charDataNode.textContent = 'bar';
|
||||
setTimeout(finish);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...re-observing after disconnect works with the same observer.
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].target, charDataNode);
|
||||
assert.equal(mutations[1].type, "characterData");
|
||||
assert.equal(mutations[1].target, charDataNode);
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should only notify of characterData changes when requested', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'hello';
|
||||
var charDataNode = div.firstChild;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(charDataNode, {childList: true, attributes: true});
|
||||
charDataNode = 'goodbye';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations, null);
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should allow multiple observers can be registered to a given node and both receive mutations', function(done) {
|
||||
var observer;
|
||||
var observer2;
|
||||
var charDataNode;
|
||||
var mutations;
|
||||
var mutations2;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'foo';
|
||||
charDataNode = div.firstChild;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer2 = new MutationObserver(function(records) {
|
||||
mutations2 = records;
|
||||
});
|
||||
observer.observe(charDataNode, {characterData: true});
|
||||
observer2.observe(charDataNode, {characterData: true});
|
||||
charDataNode.textContent = 'bar';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].target, charDataNode);
|
||||
assert.equal(mutations2.length, 1);
|
||||
assert.equal(mutations2[0].type, "characterData");
|
||||
assert.equal(mutations2[0].target, charDataNode);
|
||||
observer.disconnect();
|
||||
observer2.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should provide oldValue is returned when requested', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
var charDataNode;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'foo';
|
||||
charDataNode = div.firstChild;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer.observe(charDataNode, {characterData: true, characterDataOldValue: true});
|
||||
charDataNode.textContent = 'bar';
|
||||
charDataNode.textContent = 'baz';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].target, charDataNode);
|
||||
assert.equal(mutations[0].oldValue, "foo");
|
||||
assert.equal(mutations[1].type, "characterData");
|
||||
assert.equal(mutations[1].target, charDataNode);
|
||||
assert.equal(mutations[1].oldValue, "bar");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should allow observing both with and without oldValue', function(done) {
|
||||
var observerWithOldValue;
|
||||
var observer;
|
||||
var mutations;
|
||||
var mutationsWithOldValue;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'foo';
|
||||
var charDataNode = div.firstChild;
|
||||
observerWithOldValue = new MutationObserver(function(records) {
|
||||
mutationsWithOldValue = records;
|
||||
});
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observerWithOldValue.observe(charDataNode, {characterData: true, characterDataOldValue: true});
|
||||
observer.observe(charDataNode, {characterData: true});
|
||||
charDataNode.textContent = 'bar';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutationsWithOldValue.length, 1);
|
||||
assert.equal(mutationsWithOldValue[0].type, "characterData");
|
||||
assert.equal(mutationsWithOldValue[0].oldValue, "foo");
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].oldValue, null);
|
||||
observerWithOldValue.disconnect();
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should provide oldValue if any observation requests it', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
div.textContent = 'foo';
|
||||
var charDataNode = div.firstChild;
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer.observe(div, {characterData: true, characterDataOldValue: true, subtree: true});
|
||||
observer.observe(charDataNode, {characterData: true});
|
||||
charDataNode.textContent = 'bar';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].oldValue, "foo");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,11 +0,0 @@
|
||||
Running 7 tests
|
||||
ok 1 MutationObserver.observe on childList should handle basic observation
|
||||
ok 2 MutationObserver.observe on childList should handle observing without specifying "childList" does not result in hearing about childList changes
|
||||
ok 3 MutationObserver.observe on childList should handle re-observing the same node with the same observer has the effect of resetting the options
|
||||
ok 4 MutationObserver.observe on childList should handle multiple observers can be registered to a given node and both receive mutations
|
||||
ok 5 MutationObserver.observe on childList should create minimal mutations for replaceChild
|
||||
ok 6 MutationObserver.observe on childList should create minimal mutations for insertBefore
|
||||
ok 7 MutationObserver.observe on childList should create minimal mutations for appendChild
|
||||
7 tests
|
||||
7 pass
|
||||
0 fail
|
||||
@@ -1,322 +0,0 @@
|
||||
<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>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver observe should throw on invalid input
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,54 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver observe', function() {
|
||||
it('should throw on invalid input', function() {
|
||||
var div = document.createElement('div');
|
||||
var observer = new MutationObserver(function(mutations) { });
|
||||
assert.throw(function() {
|
||||
observer.observe();
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(null);
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(undefined)
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div);
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, null);
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, undefined);
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(null, {attributes: true});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(undefined, {attributes: true});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {subtree: true});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {attributes: false, attributeOldValue: true});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {attributes: false, attributeFilter: ["id"]});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {attributes: false, attributeOldValue: false});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {characterData: false, characterDataOldValue: true});
|
||||
});
|
||||
assert.throw(function() {
|
||||
observer.observe(div, {characterData: false, characterDataOldValue: false});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver.observe should observe attributes
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,34 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver.observe', function() {
|
||||
it('should observe attributes', function() {
|
||||
var observer = new MutationObserver(function() {});
|
||||
var element = document.createElement('div');
|
||||
element.setAttribute('data-test', '1');
|
||||
|
||||
observer.observe(element, {attributeOldValue: true});
|
||||
element.setAttribute('data-test', '2');
|
||||
var records = observer.takeRecords();
|
||||
assert.equal(records.length, 1);
|
||||
assert.equal(records[0].oldValue, 1);
|
||||
observer.disconnect();
|
||||
|
||||
observer.observe(element, {attributeOldValue: false});
|
||||
element.setAttribute('data-test', '3');
|
||||
var records = observer.takeRecords();
|
||||
assert.equal(records.length, 1);
|
||||
assert.isNull(records[0].oldValue);
|
||||
observer.disconnect();
|
||||
|
||||
observer.observe(element, {attributeFilter: ['data-test']});
|
||||
element.setAttribute('data-test', '4');
|
||||
var records = observer.takeRecords();
|
||||
assert.equal(records.length, 1);
|
||||
assert.isNull(records[0].oldValue);
|
||||
observer.disconnect();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 Test MutationObserver.observe should respect character data options
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,26 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('Test MutationObserver.observe', function() {
|
||||
it('should respect character data options', function() {
|
||||
var observer = new MutationObserver(function() {});
|
||||
var text = new Text('0');
|
||||
|
||||
observer.observe(text, {characterDataOldValue: true});
|
||||
text.data = '1';
|
||||
var records = observer.takeRecords();
|
||||
assert.equal(records.length, 1);
|
||||
assert.equal(records[0].oldValue, 0);
|
||||
observer.disconnect();
|
||||
|
||||
observer.observe(text, {characterDataOldValue: false});
|
||||
text.data = '2';
|
||||
var records = observer.takeRecords();
|
||||
assert.equal(records.length, 1);
|
||||
assert.isNull(records[0].oldValue);
|
||||
observer.disconnect();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,9 +0,0 @@
|
||||
Running 5 tests
|
||||
ok 1 MutationObserver.observe on a subtree should handle basic aspects of subtree observation
|
||||
ok 2 MutationObserver.observe on a subtree should handle two observers at different depths
|
||||
ok 3 MutationObserver.observe on a subtree should handle one observer at two different depths
|
||||
ok 4 MutationObserver.observe on a subtree should handle transiently detached nodes are still observed via subtree
|
||||
ok 5 MutationObserver.observe on a subtree should have correct behavior of transient observation with complex movement
|
||||
5 tests
|
||||
5 pass
|
||||
0 fail
|
||||
@@ -1,267 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver.observe on a subtree', function() {
|
||||
it('should handle basic aspects of subtree observation', function(done) {
|
||||
var observer;
|
||||
var subDiv;
|
||||
var mutations;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
subDiv.textContent = 'hello, world';
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, characterData: true, subtree: true});
|
||||
subDiv.setAttribute('foo', 'bar');
|
||||
subDiv.firstChild.textContent = 'goodbye!';
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...attribute and characterData changes in subtree
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "characterData");
|
||||
assert.equal(mutations[1].target, subDiv.firstChild);
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should handle two observers at different depths', function(done) {
|
||||
var observer;
|
||||
var observer2;
|
||||
var mutations;
|
||||
var mutations2;
|
||||
var subDiv;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
observer2 = new MutationObserver(function(records) {
|
||||
mutations2 = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, subtree: true});
|
||||
observer2.observe(subDiv, {attributes: true});
|
||||
subDiv.setAttribute('foo', 'bar');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations2.length, 1);
|
||||
assert.equal(mutations2[0].type, "attributes");
|
||||
assert.equal(mutations2[0].target, subDiv);
|
||||
assert.equal(mutations2[0].attributeName, "foo");
|
||||
observer.disconnect();
|
||||
observer2.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should handle one observer at two different depths', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
var calls = 0;
|
||||
var subDiv;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
++calls;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, subtree: true});
|
||||
observer.observe(subDiv, {attributes: true, subtree: true});
|
||||
subDiv.setAttribute('foo', 'bar');
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
assert.equal(calls, 1);
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
// FIXME(sky): This test is huge, it should be broken up.
|
||||
it('should handle transiently detached nodes are still observed via subtree', function(done) {
|
||||
var observer;
|
||||
var mutations;
|
||||
var div;
|
||||
var subDiv;
|
||||
|
||||
function start() {
|
||||
div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
subDiv.textContent = 'hello, world';
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, characterData: true, subtree: true});
|
||||
subDiv.setAttribute('foo', 'bar');
|
||||
div.removeChild(subDiv);
|
||||
subDiv.setAttribute('test', 'test');
|
||||
setTimeout(checkDeliveredAndChangeAgain, 0);
|
||||
}
|
||||
|
||||
function checkDeliveredAndChangeAgain() {
|
||||
// ...both changes should be received. Change detached subDiv again.
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].target, subDiv);
|
||||
assert.equal(mutations[1].attributeName, "test");
|
||||
|
||||
mutations = null;
|
||||
subDiv.setAttribute('foo', 'baz');
|
||||
|
||||
setTimeout(checkNotDeliveredAndReattach, 0);
|
||||
}
|
||||
|
||||
function checkNotDeliveredAndReattach() {
|
||||
// ...transient subtree observation was stopped after delivery, so subDiv change should not be received. Reattach and change again.
|
||||
|
||||
assert.equal(mutations, null);
|
||||
|
||||
mutations = null
|
||||
div.appendChild(subDiv);
|
||||
subDiv.setAttribute('foo', 'bat');
|
||||
|
||||
setTimeout(checkDeliveredAndReobserve, 0);
|
||||
}
|
||||
|
||||
function checkDeliveredAndReobserve() {
|
||||
//...reattached subtree should now be observable. Try detaching and re-observing.
|
||||
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
|
||||
mutations = null;
|
||||
div.removeChild(subDiv);
|
||||
subDiv.firstChild.textContent = 'badbye';
|
||||
observer.observe(div, {attributes: true, characterData: true, subtree: true});
|
||||
subDiv.setAttribute('foo', 'boo');
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...The change made before re-observing should be received, but not the one after.
|
||||
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "characterData");
|
||||
assert.equal(mutations[0].target, subDiv.firstChild);
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
it('should have correct behavior of transient observation with complex movement', function(done) {
|
||||
var observer;
|
||||
var text;
|
||||
var subDiv;
|
||||
var mutations;
|
||||
var subDiv2;
|
||||
var subDiv3;
|
||||
|
||||
function start() {
|
||||
var div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
subDiv2 = subDiv.appendChild(document.createElement('div'));
|
||||
subDiv2.textContent = 'hello, world';
|
||||
subDiv3 = document.createElement('div');
|
||||
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, characterData: true, subtree: true});
|
||||
div.removeChild(subDiv);
|
||||
subDiv.removeChild(subDiv2);
|
||||
text = subDiv2.removeChild(subDiv2.firstChild);
|
||||
|
||||
subDiv.setAttribute('a', 'a');
|
||||
subDiv2.setAttribute('b', 'b');
|
||||
text.textContent = 'c';
|
||||
subDiv3.appendChild(subDiv2);
|
||||
subDiv3.setAttribute('d', 'd');
|
||||
subDiv2.setAttribute('e', 'e');
|
||||
div.appendChild(subDiv3);
|
||||
subDiv3.setAttribute('f', 'f');
|
||||
subDiv2.setAttribute('g', 'g');
|
||||
|
||||
setTimeout(finish, 0);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
// ...All changes should be received except for setting the "d" attribute on subDiv3 before it was reachable from div.
|
||||
|
||||
assert.equal(mutations.length, 6);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "a");
|
||||
|
||||
assert.equal(mutations[1].type, "attributes");
|
||||
assert.equal(mutations[1].target, subDiv2);
|
||||
assert.equal(mutations[1].attributeName, "b");
|
||||
|
||||
assert.equal(mutations[2].type, "characterData");
|
||||
assert.equal(mutations[2].target, text);
|
||||
|
||||
assert.equal(mutations[3].type, "attributes");
|
||||
assert.equal(mutations[3].target, subDiv2);
|
||||
assert.equal(mutations[3].attributeName, "e");
|
||||
|
||||
assert.equal(mutations[4].type, "attributes");
|
||||
assert.equal(mutations[4].target, subDiv3);
|
||||
assert.equal(mutations[4].attributeName, "f");
|
||||
|
||||
assert.equal(mutations[5].type, "attributes");
|
||||
assert.equal(mutations[5].target, subDiv2);
|
||||
assert.equal(mutations[5].attributeName, "g");
|
||||
|
||||
observer.disconnect();
|
||||
done();
|
||||
}
|
||||
start();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,29 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver wrappers', function() {
|
||||
it('should survive GC for passing into the callback even if JS has lost references and the only remaining observations are transient.', function(done) {
|
||||
function addObserver(node, fn) {
|
||||
var observer = new MutationObserver(fn);
|
||||
observer.testProperty = true;
|
||||
observer.observe(node, {attributes:true, subtree: true});
|
||||
}
|
||||
|
||||
var root = document.createElement('div');
|
||||
var child = root.appendChild(document.createElement('span'));
|
||||
addObserver(root, function(records, observer) {
|
||||
window.observer = observer;
|
||||
assert.ok(observer.testProperty);
|
||||
done();
|
||||
});
|
||||
|
||||
root.removeChild(child);
|
||||
child.setAttribute('foo', 'bar');
|
||||
root = null;
|
||||
|
||||
gc();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<script src="../../../resources/js-test.js"></script>
|
||||
|
||||
<script>
|
||||
description('MutationObserver wrappers should survive GC for passing into the callback even if JS has lost references.');
|
||||
|
||||
jsTestIsAsync = true;
|
||||
|
||||
function addObserver(node, fn) {
|
||||
var observer = new MutationObserver(fn);
|
||||
observer.testProperty = true;
|
||||
observer.observe(node, {attributes:true});
|
||||
}
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
addObserver(document.body, function(records, observer) {
|
||||
window.observer = observer;
|
||||
shouldBe('observer.testProperty', 'true');
|
||||
finishJSTest();
|
||||
});
|
||||
|
||||
gc();
|
||||
|
||||
document.body.setAttribute('touch', 'the node');
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver should not invoke callbacks when appending a script
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,27 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver', function() {
|
||||
it('should not invoke callbacks when appending a script', function() {
|
||||
var mutationsDelivered = false;
|
||||
function callback(mutations) {
|
||||
mutationsDelivered = true;
|
||||
}
|
||||
|
||||
var observer = new MutationObserver(callback);
|
||||
var div = document.createElement('div');
|
||||
observer.observe(div, {attributes: true});
|
||||
div.setAttribute('foo', 'bar');
|
||||
assert.notOk(mutationsDelivered);
|
||||
var scriptDidRun = false;
|
||||
var script = document.createElement('script');
|
||||
script.textContent = 'scriptDidRun = true';
|
||||
assert.notOk(scriptDidRun);
|
||||
document.documentElement.appendChild(script);
|
||||
assert.notOk(scriptDidRun);
|
||||
assert.notOk(mutationsDelivered);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObservers should handle shadow dom
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,40 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<div id="range"></div>
|
||||
<script>
|
||||
describe('MutationObservers', function() {
|
||||
it('should handle shadow dom', function() {
|
||||
function mutate(element) {
|
||||
element.setAttribute('data-foo', 'bar');
|
||||
element.insertBefore(new Text('hello'), element.firstChild);
|
||||
element.firstChild.textContent = 'goodbye';
|
||||
element.removeChild(element.firstChild);
|
||||
}
|
||||
|
||||
var range = document.getElementById('range');
|
||||
var shadowRoot = range.ensureShadowRoot();
|
||||
shadowRoot.appendChild(document.createElement('div'));
|
||||
var observer = new MutationObserver(function() { });
|
||||
|
||||
observer.observe(shadowRoot.firstChild, {attributes: true, childList: true, characterData: true, subtree: true});
|
||||
mutate(shadowRoot.firstChild);
|
||||
|
||||
var mutations = observer.takeRecords();
|
||||
// Mutations in shadow DOM should have been observed:
|
||||
assert.equal(mutations.length, 4);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[1].type, "childList");
|
||||
assert.equal(mutations[2].type, "characterData");
|
||||
assert.equal(mutations[3].type, "childList");
|
||||
observer.disconnect();
|
||||
|
||||
mutations = observer.takeRecords();
|
||||
observer.observe(document, {attributes: true, childList: true, characterData: true, subtree: true});
|
||||
mutate(shadowRoot.firstChild);
|
||||
// Observing from outside shadow DOM should not see mutations in the shadow:
|
||||
assert.equal(mutations.length, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
Running 1 tests
|
||||
ok 1 MutationObserver.takeRecords should allow taking records synchronously or getting a notification
|
||||
1 tests
|
||||
1 pass
|
||||
0 fail
|
||||
@@ -1,53 +0,0 @@
|
||||
<html>
|
||||
<import src="../resources/chai.sky" />
|
||||
<import src="../resources/mocha.sky" />
|
||||
<script>
|
||||
describe('MutationObserver.takeRecords', function() {
|
||||
it('should allow taking records synchronously or getting a notification', function(done) {
|
||||
var mutations;
|
||||
var div;
|
||||
var subDiv;
|
||||
var observer;
|
||||
|
||||
// Testing takeRecords.
|
||||
mutations = null;
|
||||
div = document.createElement('div');
|
||||
subDiv = div.appendChild(document.createElement('div'));
|
||||
subDiv.textContent = 'hello, world';
|
||||
observer = new MutationObserver(function(records) {
|
||||
mutations = records;
|
||||
});
|
||||
|
||||
observer.observe(div, {attributes: true, characterData: true, subtree: true});
|
||||
subDiv.setAttribute('foo', 'bar');
|
||||
subDiv.firstChild.textContent = 'goodbye!';
|
||||
div.removeChild(subDiv);
|
||||
|
||||
mutations = observer.takeRecords();
|
||||
|
||||
// ...records are taken synchronously.
|
||||
|
||||
assert.equal(mutations.length, 2);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
assert.equal(mutations[1].type, "characterData");
|
||||
assert.equal(mutations[1].target, subDiv.firstChild);
|
||||
|
||||
subDiv.setAttribute('foo', 'baz');
|
||||
|
||||
setTimeout(function() {
|
||||
// ...takeRecord took records, but did not clear transient observers.
|
||||
|
||||
assert.equal(mutations.length, 1);
|
||||
assert.equal(mutations[0].type, "attributes");
|
||||
assert.equal(mutations[0].target, subDiv);
|
||||
assert.equal(mutations[0].attributeName, "foo");
|
||||
observer.disconnect();
|
||||
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,22 +0,0 @@
|
||||
<script src="../../../resources/js-test.js"></script>
|
||||
<script>
|
||||
window.jsTestIsAsync = true;
|
||||
description('Clearing transient observers after observation node is GCed should not cause a crash.');
|
||||
|
||||
function callback(mutations) {
|
||||
window.mutations = mutations;
|
||||
}
|
||||
var observer = new MutationObserver(callback);
|
||||
|
||||
var div = document.createElement('div');
|
||||
var span = div.appendChild(document.createElement('span'));
|
||||
observer.observe(div, {attributes: true, subtree: true});
|
||||
div.removeChild(span);
|
||||
div = null;
|
||||
gc();
|
||||
span.setAttribute('foo', 'bar');
|
||||
setTimeout(function() {
|
||||
shouldBe('mutations.length', '1');
|
||||
finishJSTest();
|
||||
}, 0);
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<div>Test passes if it does not crash</div>
|
||||
<script src="../../../resources/gc.js"></script>
|
||||
<script>
|
||||
if (window.testRunner) {
|
||||
testRunner.waitUntilDone();
|
||||
testRunner.dumpAsText();
|
||||
}
|
||||
var observer = new MutationObserver(function() {console.log('Should not appear')});
|
||||
var div = document.createElement('div');
|
||||
observer.observe(div, {attributes: true});
|
||||
div.id = 'foo';
|
||||
div = null;
|
||||
observer = null;
|
||||
gc();
|
||||
setTimeout(function() { testRunner.notifyDone(); }, 0);
|
||||
</script>
|
||||
Reference in New Issue
Block a user