blob: 2819227c483f131525165718039d019c448d443b [file] [log] [blame]
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="test-harness-utils.js"></script>
<body>
<script>
test(function() {
var createdInvocations = 0;
function created() {
createdInvocations++;
}
var getterInvocations = 0;
function getter() {
getterInvocations++;
return created;
}
function failer() {
assert_unreached('the created callback must not be retrieved after registration');
}
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
get: getter
}
});
var ctor = document.registerElement('x-a', {prototype: proto});
assert_equals(getterInvocations, 1, 'the created callback must have been retrieved');
proto.createdCallback = failer;
var element = new ctor();
assert_equals(createdInvocations, 1, 'the created callback retrieved at registration must be invoked');
}, 'transfer created callback');
(function() {
t = async_test('__proto__, :unresolved and created callback timing');
t.step(function() {
var createdInvocations = 0;
function created() {
createdInvocations++;
if (this.id != 'u')
return;
t.step(function() {
var t = div.querySelector('#t');
var v = div.querySelector('#v');
var w = div.querySelector('#w');
assert_equals(div.querySelector('x-b:not(:unresolved)'), this, 'the :unresolved pseudoclass should cease to apply when the created callback is invoked');
assert_array_equals(div.querySelectorAll(':unresolved'), [v, w], 'the :unresolved pseudoclass should be processed in order');
assert_true(t instanceof C, 'prototype upgrade should happen in order (#t)');
assert_false(v instanceof C, 'prototype upgrade should happen in order (#v)');
}, this);
}
var protoB = Object.create(HTMLElement.prototype);
var B = document.registerElement('x-b', {prototype: protoB});
var protoC = Object.create(HTMLElement.prototype);
protoC.createdCallback = created;
var C = document.registerElement('x-c', {prototype: protoC});
var div = document.createElement('div');
div.innerHTML = '<x-c id="t"></x-c>' +
'<x-b id="u"></x-b>' +
'<x-c id="v"></x-c>' +
'<x-b id="w"></x-b>';
assert_equals(createdInvocations, 2, 'the created callback should have been invoked once for each x-c element');
assert_true(div.querySelector('#w') instanceof B, '#w\'s prototype should have ultimately been upgraded');
t.done();
});
})();
(function() {
t = async_test('other callbacks for a given element are queued during the ' +
'created callback and dispatched when the created callback ' +
'completes');
withFrame(t.step_func(function(frame) {
var messages = [];
function log(msg) {
messages.push(msg);
}
var proto = Object.create(frame.contentWindow.HTMLElement.prototype);
proto.createdCallback = function() {
log('created started');
this.remove();
this.setAttribute('prey', 'gargoyles');
log('created finished');
};
proto.attachedCallback = function() { log('entered'); };
proto.detachedCallback = function() { log('left'); };
proto.attributeChangedCallback = function() { log('attribute changed'); };
var D = frame.contentDocument.registerElement('x-d', {prototype: proto});
frame.contentDocument.body.innerHTML = '<x-d></x-d>';
log('done');
assert_array_equals(
messages,
['created started', 'created finished', 'entered', 'left',
'attribute changed', 'done'],
'callbacks should not be dispatched until the created callback has ' +
'finished');
t.done();
}));
})();
(function() {
t = async_test('callback is called even if the element is moved to foreign document');
var callbackInvoked = false;
withFrame(t.step_func(function(originalFrame) {
withFrame(function(destinationFrame) {
var protoA = Object.create(originalFrame.contentWindow.HTMLElement.prototype);
protoA.createdCallback = function() {
var toBeMoved = originalFrame.contentDocument.getElementById('toBeMoved');
destinationFrame.contentDocument.body.appendChild(toBeMoved);
};
var protoB = Object.create(originalFrame.contentWindow.HTMLElement.prototype);
protoB.createdCallback = function() {
callbackInvoked = true;
};
originalFrame.contentDocument.registerElement('x-a', {prototype: protoA});
originalFrame.contentDocument.registerElement('x-b', {prototype: protoB});
originalFrame.contentDocument.body.innerHTML = '<x-a></x-a><x-b id="toBeMoved"></x-b>';
assert_true(callbackInvoked);
t.done();
});
}));
})();
</script>