182 lines
7.3 KiB
HTML
182 lines
7.3 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>EditContext: Inherited Editability</title>
|
|
<meta name="author" title="Dan Clark" href="mailto:daniec@microsoft.com">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/testdriver.js"></script>
|
|
<script src="/resources/testdriver-actions.js"></script>
|
|
<script src="/resources/testdriver-vendor.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="edit-context-top-0">Text in EditContext-associated element, should be editable</div>
|
|
|
|
<div id="edit-context-top-1">
|
|
<div id="default-1">
|
|
Element child of EditContext, should be editable
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-context-top-2">
|
|
<div id="noteditable-2" contenteditable="false">
|
|
<div id="editable-in-noteditable-2" contenteditable="">
|
|
This is a contenteditable="" child of contenteditable="false" parent.
|
|
This node should be editable. It should be the target of beforeinput/input events when the user edits here.
|
|
The grandparent node #edit-context-0 should not be the target of beforeinput/input events,
|
|
and the EditContext should not receive
|
|
textupdate events
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-context-top-3">
|
|
<div id="noteditable-3" contenteditable="false">
|
|
<div id="editable-in-noteditable-3" contenteditable="">
|
|
<div id="contenteditable-in-contenteditable-3" contenteditable="">
|
|
This is an contenteditable="" child of a contenteditable="". Since this is the child of an
|
|
editable element, when the user types here, it's the parent contenteditable="" that gets
|
|
input/beforeinput events, and this doesn't. Basically the child contenteditable="" attribute
|
|
is a no-op.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-context-top-4">
|
|
<div id="noteditable-4" contenteditable="false">
|
|
<div id="edit-context-in-noteditable-4">
|
|
This is an EditContext child of contenteditable="false" parent.
|
|
This node should be editable, and this EditContext (but not the
|
|
grandparent EditContext) should get events, since there is an
|
|
intermediate non-editable parent.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-context-top-5">
|
|
<div id="contenteditable-in-ec-5" contenteditable="">
|
|
This is a contenteditable="" child of EditContext.
|
|
It inherits editability from the parent and it should not be the target of beforeinput/input events.
|
|
Setting contenteditable="" on this node is basically a no-op.
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-context-top-6">
|
|
<input id="input-in-ec-6" value="Input in EditContext. Events are fired against this element, and not against any parent EditContext.">
|
|
</div>
|
|
|
|
<div id="edit-context-top-7">
|
|
<div id="edit-context-in-ec-7">
|
|
EditContext child of EditContext. When user types here,
|
|
events are fired only against the parent EditContext, not this one.
|
|
Since the parent element was editable, the EditContext association is basically a no-op.
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const event_log = [];
|
|
|
|
const editContextElements = document.querySelectorAll("div[id^='edit-context-']");
|
|
editContextElements.forEach((element) => {
|
|
element.editContext = new EditContext();
|
|
});
|
|
|
|
const divs = Array.from(document.querySelectorAll("div"));
|
|
const inputs = Array.from(document.querySelectorAll("input"));
|
|
const eventTargets = divs.concat(inputs);
|
|
eventTargets.forEach((element) => {
|
|
element.addEventListener("beforeinput", (e) => {
|
|
if (element == e.target) {
|
|
event_log.push(`beforeinput: ${element.id}`);
|
|
}
|
|
});
|
|
|
|
element.addEventListener("input", (e) => {
|
|
if (element === e.target) {
|
|
event_log.push(`input: ${element.id}`);
|
|
}
|
|
});
|
|
|
|
if (element.editContext) {
|
|
element.editContext.addEventListener("textupdate", () => {
|
|
event_log.push(`textupdate: ${element.id}`);
|
|
});
|
|
}
|
|
});
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#edit-context-top-0");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: edit-context-top-0", "textupdate: edit-context-top-0"]);
|
|
}, 'Check that element with EditContext is editable and gets events');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#default-1");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: edit-context-top-1", "textupdate: edit-context-top-1"]);
|
|
}, 'Check that child of EditContext is editable and the parent EditContext gets the events');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#editable-in-noteditable-2");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: editable-in-noteditable-2", "input: editable-in-noteditable-2"]);
|
|
}, 'Check that a contenteditable child of a contenteditable="false" is editable');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#contenteditable-in-contenteditable-3");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: editable-in-noteditable-3", "input: editable-in-noteditable-3"]);
|
|
}, 'Check that a contenteditable child of a contenteditable is editable, but the parent contenteditable gets the events');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#edit-context-in-noteditable-4");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: edit-context-in-noteditable-4", "textupdate: edit-context-in-noteditable-4"]);
|
|
}, 'Check that an EditContext child of a contenteditable="false" parent is editable and gets events');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#contenteditable-in-ec-5");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: edit-context-top-5", "textupdate: edit-context-top-5"]);
|
|
}, 'Check that an contenteditable child of an EditContext is editable, but the EditContext gets the events');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#input-in-ec-6");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: input-in-ec-6", "input: input-in-ec-6"]);
|
|
}, 'Check that an input element in an EditContext is the event target for beforeinput/input');
|
|
|
|
promise_test(async () => {
|
|
event_log.length = 0;
|
|
|
|
const input_target = document.querySelector("#edit-context-in-ec-7");
|
|
await test_driver.click(input_target);
|
|
await test_driver.send_keys(input_target, "a");
|
|
assert_array_equals(event_log, ["beforeinput: edit-context-top-7", "textupdate: edit-context-top-7"]);
|
|
}, 'Check that for an EditContext child of an EditContext, the parent is the one that gets the events');
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|