425 lines
13 KiB
HTML
425 lines
13 KiB
HTML
<!doctype html>
|
|
<title>Synthetic click event "magic"</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<div id=log></div>
|
|
<div id=dump style=display:none></div>
|
|
<script>
|
|
var dump = document.getElementById("dump")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_true(input.checked)
|
|
})
|
|
input.click()
|
|
}, "basic with click()")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_true(input.checked)
|
|
})
|
|
input.dispatchEvent(new MouseEvent("click", {bubbles:true})) // equivalent to the above
|
|
}, "basic with dispatchEvent()")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_false(input.checked)
|
|
})
|
|
input.dispatchEvent(new Event("click", {bubbles:true})) // no MouseEvent
|
|
}, "basic with wrong event class")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
var child = input.appendChild(new Text("does not matter"))
|
|
child.dispatchEvent(new MouseEvent("click")) // does not bubble
|
|
assert_false(input.checked)
|
|
t.done()
|
|
}, "look at parents only when event bubbles")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_true(input.checked)
|
|
})
|
|
var child = input.appendChild(new Text("does not matter"))
|
|
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
|
|
}, "look at parents when event bubbles")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func(function() {
|
|
assert_false(input.checked, "input pre-click must not be triggered")
|
|
})
|
|
var child = input.appendChild(document.createElement("input"))
|
|
child.type = "checkbox"
|
|
child.onclick = t.step_func(function() {
|
|
assert_true(child.checked, "child pre-click must be triggered")
|
|
})
|
|
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
|
|
t.done()
|
|
}, "pick the first with activation behavior <input type=checkbox>")
|
|
|
|
async_test(function(t) { // as above with <a>
|
|
window.hrefComplete = t.step_func(function(a) {
|
|
assert_equals(a, 'child');
|
|
t.done();
|
|
});
|
|
var link = document.createElement("a")
|
|
link.href = "javascript:hrefComplete('link')" // must not be triggered
|
|
dump.appendChild(link)
|
|
var child = link.appendChild(document.createElement("a"))
|
|
child.href = "javascript:hrefComplete('child')"
|
|
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
|
|
}, "pick the first with activation behavior <a href>")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "radio"
|
|
dump.appendChild(input)
|
|
input.onclick = t.step_func(function() {
|
|
assert_false(input.checked, "input pre-click must not be triggered")
|
|
})
|
|
var child = input.appendChild(document.createElement("input"))
|
|
child.type = "radio"
|
|
child.onclick = t.step_func(function() {
|
|
assert_true(child.checked, "child pre-click must be triggered")
|
|
})
|
|
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
|
|
t.done()
|
|
}, "pick the first with activation behavior <input type=radio>")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
var clickEvent = new MouseEvent("click")
|
|
input.onchange = t.step_func_done(function() {
|
|
assert_false(clickEvent.defaultPrevented)
|
|
assert_true(clickEvent.returnValue)
|
|
assert_equals(clickEvent.eventPhase, 0)
|
|
assert_equals(clickEvent.currentTarget, null)
|
|
assert_equals(clickEvent.target, input)
|
|
assert_equals(clickEvent.srcElement, input)
|
|
assert_equals(clickEvent.composedPath().length, 0)
|
|
})
|
|
input.dispatchEvent(clickEvent)
|
|
}, "event state during post-click handling")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
var clickEvent = new MouseEvent("click")
|
|
var finalTarget = document.createElement("doesnotmatter")
|
|
finalTarget.onclick = t.step_func_done(function() {
|
|
assert_equals(clickEvent.target, finalTarget)
|
|
assert_equals(clickEvent.srcElement, finalTarget)
|
|
})
|
|
input.onchange = t.step_func(function() {
|
|
finalTarget.dispatchEvent(clickEvent)
|
|
})
|
|
input.dispatchEvent(clickEvent)
|
|
}, "redispatch during post-click handling")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
dump.appendChild(input)
|
|
var child = input.appendChild(document.createElement("input"))
|
|
child.type = "checkbox"
|
|
child.disabled = true
|
|
child.click()
|
|
assert_false(input.checked)
|
|
assert_false(child.checked)
|
|
t.done()
|
|
}, "disabled checkbox still has activation behavior")
|
|
|
|
async_test(function(t) {
|
|
var state = "start"
|
|
|
|
var form = document.createElement("form")
|
|
form.onsubmit = t.step_func(() => {
|
|
if(state == "start" || state == "checkbox") {
|
|
state = "failure"
|
|
} else if(state == "form") {
|
|
state = "done"
|
|
}
|
|
return false
|
|
})
|
|
dump.appendChild(form)
|
|
var button = form.appendChild(document.createElement("button"))
|
|
button.type = "submit"
|
|
var checkbox = button.appendChild(document.createElement("input"))
|
|
checkbox.type = "checkbox"
|
|
checkbox.onclick = t.step_func(() => {
|
|
if(state == "start") {
|
|
assert_unreached()
|
|
} else if(state == "checkbox") {
|
|
assert_true(checkbox.checked)
|
|
}
|
|
})
|
|
checkbox.disabled = true
|
|
checkbox.click()
|
|
assert_equals(state, "start")
|
|
|
|
state = "checkbox"
|
|
checkbox.disabled = false
|
|
checkbox.click()
|
|
assert_equals(state, "checkbox")
|
|
|
|
state = "form"
|
|
button.click()
|
|
assert_equals(state, "done")
|
|
|
|
t.done()
|
|
}, "disabled checkbox still has activation behavior, part 2")
|
|
|
|
async_test(function(t) {
|
|
var state = "start"
|
|
|
|
var form = document.createElement("form")
|
|
form.onsubmit = t.step_func(() => {
|
|
if(state == "start" || state == "radio") {
|
|
state = "failure"
|
|
} else if(state == "form") {
|
|
state = "done"
|
|
}
|
|
return false
|
|
})
|
|
dump.appendChild(form)
|
|
var button = form.appendChild(document.createElement("button"))
|
|
button.type = "submit"
|
|
var radio = button.appendChild(document.createElement("input"))
|
|
radio.type = "radio"
|
|
radio.onclick = t.step_func(() => {
|
|
if(state == "start") {
|
|
assert_unreached()
|
|
} else if(state == "radio") {
|
|
assert_true(radio.checked)
|
|
}
|
|
})
|
|
radio.disabled = true
|
|
radio.click()
|
|
assert_equals(state, "start")
|
|
|
|
state = "radio"
|
|
radio.disabled = false
|
|
radio.click()
|
|
assert_equals(state, "radio")
|
|
|
|
state = "form"
|
|
button.click()
|
|
assert_equals(state, "done")
|
|
|
|
t.done()
|
|
}, "disabled radio still has activation behavior")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "checkbox"
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_true(input.checked)
|
|
})
|
|
input.click()
|
|
}, "disconnected checkbox should be checked")
|
|
|
|
async_test(function(t) {
|
|
var input = document.createElement("input")
|
|
input.type = "radio"
|
|
input.onclick = t.step_func_done(function() {
|
|
assert_true(input.checked)
|
|
})
|
|
input.click()
|
|
}, "disconnected radio should be checked")
|
|
|
|
async_test(t => {
|
|
const input = document.createElement('input');
|
|
input.type = 'checkbox';
|
|
input.onclick = t.step_func_done(() => {
|
|
assert_true(input.checked);
|
|
});
|
|
input.dispatchEvent(new MouseEvent('click'));
|
|
}, `disconnected checkbox should be checked from dispatchEvent(new MouseEvent('click'))`);
|
|
|
|
async_test(t => {
|
|
const input = document.createElement('input');
|
|
input.type = 'radio';
|
|
input.onclick = t.step_func_done(() => {
|
|
assert_true(input.checked);
|
|
});
|
|
input.dispatchEvent(new MouseEvent('click'));
|
|
}, `disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))`);
|
|
|
|
test(() => {
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.disabled = true;
|
|
input.dispatchEvent(new MouseEvent("click"));
|
|
assert_true(input.checked);
|
|
}, `disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))`);
|
|
|
|
test(() => {
|
|
const input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.disabled = true;
|
|
input.dispatchEvent(new MouseEvent("click"));
|
|
assert_true(input.checked);
|
|
}, `disabled radio should be checked from dispatchEvent(new MouseEvent("click"))`);
|
|
|
|
async_test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.disabled = true;
|
|
input.onclick = t.step_func_done();
|
|
input.dispatchEvent(new MouseEvent("click"));
|
|
}, `disabled checkbox should fire onclick`);
|
|
|
|
async_test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.disabled = true;
|
|
input.onclick = t.step_func_done();
|
|
input.dispatchEvent(new MouseEvent("click"));
|
|
}, `disabled radio should fire onclick`);
|
|
|
|
async_test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.disabled = true;
|
|
input.onclick = t.step_func(ev => {
|
|
assert_true(input.checked);
|
|
ev.preventDefault();
|
|
queueMicrotask(t.step_func_done(() => {
|
|
assert_false(input.checked);
|
|
}));
|
|
});
|
|
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
|
|
}, `disabled checkbox should get legacy-canceled-activation behavior`);
|
|
|
|
async_test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.disabled = true;
|
|
input.onclick = t.step_func(ev => {
|
|
assert_true(input.checked);
|
|
ev.preventDefault();
|
|
queueMicrotask(t.step_func_done(() => {
|
|
assert_false(input.checked);
|
|
}));
|
|
});
|
|
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
|
|
}, `disabled radio should get legacy-canceled-activation behavior`);
|
|
|
|
test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.disabled = true;
|
|
const ev = new MouseEvent("click", { cancelable: true });
|
|
ev.preventDefault();
|
|
input.dispatchEvent(ev);
|
|
assert_false(input.checked);
|
|
}, `disabled checkbox should get legacy-canceled-activation behavior 2`);
|
|
|
|
test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.disabled = true;
|
|
const ev = new MouseEvent("click", { cancelable: true });
|
|
ev.preventDefault();
|
|
input.dispatchEvent(ev);
|
|
assert_false(input.checked);
|
|
}, `disabled radio should get legacy-canceled-activation behavior 2`);
|
|
|
|
for (const type of ["checkbox", "radio"]) {
|
|
for (const handler of ["oninput", "onchange"]) {
|
|
async_test(t => {
|
|
const input = document.createElement("input");
|
|
input.type = type;
|
|
input.onclick = t.step_func(ev => {
|
|
input.disabled = true;
|
|
});
|
|
input[handler] = t.step_func(ev => {
|
|
assert_equals(input.checked, true);
|
|
t.done();
|
|
});
|
|
dump.append(input);
|
|
input.click();
|
|
}, `disabling ${type} in onclick listener shouldn't suppress ${handler}`);
|
|
}
|
|
}
|
|
|
|
async_test(function(t) {
|
|
var form = document.createElement("form")
|
|
var didSubmit = false
|
|
form.onsubmit = t.step_func(() => {
|
|
didSubmit = true
|
|
return false
|
|
})
|
|
var input = form.appendChild(document.createElement("input"))
|
|
input.type = "submit"
|
|
input.click()
|
|
assert_false(didSubmit)
|
|
t.done()
|
|
}, "disconnected form should not submit")
|
|
|
|
async_test(t => {
|
|
const form = document.createElement("form");
|
|
form.onsubmit = t.step_func(ev => {
|
|
ev.preventDefault();
|
|
assert_unreached("The form is unexpectedly submitted.");
|
|
});
|
|
dump.append(form);
|
|
const input = form.appendChild(document.createElement("input"));
|
|
input.type = "submit"
|
|
input.disabled = true;
|
|
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
|
|
t.done();
|
|
}, "disabled submit button should not activate");
|
|
|
|
async_test(t => {
|
|
const form = document.createElement("form");
|
|
form.onsubmit = t.step_func(ev => {
|
|
ev.preventDefault();
|
|
assert_unreached("The form is unexpectedly submitted.");
|
|
});
|
|
dump.append(form);
|
|
const input = form.appendChild(document.createElement("input"));
|
|
input.onclick = t.step_func(() => {
|
|
input.disabled = true;
|
|
});
|
|
input.type = "submit"
|
|
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
|
|
t.done();
|
|
}, "submit button should not activate if the event listener disables it");
|
|
|
|
async_test(t => {
|
|
const form = document.createElement("form");
|
|
form.onsubmit = t.step_func(ev => {
|
|
ev.preventDefault();
|
|
assert_unreached("The form is unexpectedly submitted.");
|
|
});
|
|
dump.append(form);
|
|
const input = form.appendChild(document.createElement("input"));
|
|
input.onclick = t.step_func(() => {
|
|
input.type = "submit"
|
|
input.disabled = true;
|
|
});
|
|
input.click();
|
|
t.done();
|
|
}, "submit button that morphed from checkbox should not activate");
|
|
</script>
|