From a53bd11ad0ab78a50956aff4c42891eb1ee482b7 Mon Sep 17 00:00:00 2001 From: zcorpan Date: Thu, 8 Feb 2024 10:58:34 +0100 Subject: [PATCH] UIEvents: Test the textInput event See https://github.com/w3c/uievents/pull/362 --- uievents/textInput/api.html | 68 +++++++++++++++++++ uievents/textInput/backspace.html | 16 +++++ uievents/textInput/basic.html | 16 +++++ uievents/textInput/delete.html | 16 +++++ uievents/textInput/enter-input.html | 14 ++++ .../enter-textarea-contenteditable.html | 15 ++++ uievents/textInput/support/basic.sub.js | 37 ++++++++++ uievents/textInput/support/common.js | 31 +++++++++ .../textInput/support/no-textInput.sub.js | 24 +++++++ 9 files changed, 237 insertions(+) create mode 100644 uievents/textInput/api.html create mode 100644 uievents/textInput/backspace.html create mode 100644 uievents/textInput/basic.html create mode 100644 uievents/textInput/delete.html create mode 100644 uievents/textInput/enter-input.html create mode 100644 uievents/textInput/enter-textarea-contenteditable.html create mode 100644 uievents/textInput/support/basic.sub.js create mode 100644 uievents/textInput/support/common.js create mode 100644 uievents/textInput/support/no-textInput.sub.js diff --git a/uievents/textInput/api.html b/uievents/textInput/api.html new file mode 100644 index 000000000000000..c313c89e0d8e672 --- /dev/null +++ b/uievents/textInput/api.html @@ -0,0 +1,68 @@ + + +textInput: API + + + diff --git a/uievents/textInput/backspace.html b/uievents/textInput/backspace.html new file mode 100644 index 000000000000000..33c2f2e5e5c4e4a --- /dev/null +++ b/uievents/textInput/backspace.html @@ -0,0 +1,16 @@ + + +textInput: backspace + + + + + +

Press Backspace in each text field below.

+ + +
a
+ + diff --git a/uievents/textInput/basic.html b/uievents/textInput/basic.html new file mode 100644 index 000000000000000..2ef82289ab97f69 --- /dev/null +++ b/uievents/textInput/basic.html @@ -0,0 +1,16 @@ + + +textInput: basic + + + + + +

Type "a" into each text field below.

+ + +
+ + diff --git a/uievents/textInput/delete.html b/uievents/textInput/delete.html new file mode 100644 index 000000000000000..b5a6ff8579df5cf --- /dev/null +++ b/uievents/textInput/delete.html @@ -0,0 +1,16 @@ + + +textInput: delete + + + + + +

Press Delete (Fn+Backspace for macOS) in each text field below.

+ + +
a
+ + diff --git a/uievents/textInput/enter-input.html b/uievents/textInput/enter-input.html new file mode 100644 index 000000000000000..bb00c039258268f --- /dev/null +++ b/uievents/textInput/enter-input.html @@ -0,0 +1,14 @@ + + +textInput: Enter key for input element + + + + + +

Press Enter in the text field below.

+ + + diff --git a/uievents/textInput/enter-textarea-contenteditable.html b/uievents/textInput/enter-textarea-contenteditable.html new file mode 100644 index 000000000000000..5e7bc3c0ec97b08 --- /dev/null +++ b/uievents/textInput/enter-textarea-contenteditable.html @@ -0,0 +1,15 @@ + + +textInput: Enter key for textarea and contenteditable + + + + + +

Press Enter in each text field below.

+ +
+ + diff --git a/uievents/textInput/support/basic.sub.js b/uievents/textInput/support/basic.sub.js new file mode 100644 index 000000000000000..ad87195bc23cce6 --- /dev/null +++ b/uievents/textInput/support/basic.sub.js @@ -0,0 +1,37 @@ +const els = document.querySelectorAll('.test-el'); +const key = "{{GET[key]}}"; +const keyRaw = keyMapping[key] || key; +const expectedData = key === "Enter" ? "\n" : key; +const selectionStart = {{GET[selectionStart]}}; +const selectionEnd = {{GET[selectionEnd]}}; + +for (const el of els) { + promise_test(t => { + return new Promise((resolve, reject) => { + let textInputEvents = 0; + el.addEventListener('textInput', t.step_func(e => { + textInputEvents++; + assert_equals(e.data, expectedData); + assert_true(e.bubbles); + assert_true(e.cancelable); + assert_equals(e.view, window); + assert_equals(e.detail, 0); + assert_true(e instanceof window.TextEvent); + el.removeEventListener('input', reject); + })); + el.addEventListener('input', reject); + el.addEventListener('keyup', t.step_func(e => { + if (e.key !== key) { + return; + } + assert_equals(textInputEvents, 1); + resolve(); + })); + el.onfocus = t.step_func(e => { + test_driver.send_keys(el, keyRaw); + }); + el.focus(); + setSelection(el, selectionStart, selectionEnd); + }); + }, `${document.title}, ${elDesc(el)}`); +} diff --git a/uievents/textInput/support/common.js b/uievents/textInput/support/common.js new file mode 100644 index 000000000000000..bdda6e1fe82254f --- /dev/null +++ b/uievents/textInput/support/common.js @@ -0,0 +1,31 @@ +function elDesc(el) { + let rv = `<${el.localName}`; + if (el.hasAttribute('contenteditable')) { + rv += ` contenteditable="${el.getAttribute('contenteditable')}"`; + } + if (el.hasAttribute('type')) { + rv += ` type="${el.getAttribute('type')}"`; + } + rv += `>`; + return rv; +} + +function setSelection(el) { + if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) { + el.selectionStart = selectionStart; + el.selectionEnd = selectionEnd; + } else { + const s = getSelection(); + s.removeAllRanges(); + const r = new Range(); + r.setStart(el, selectionStart); + r.setEnd(el, selectionEnd); + s.addRange(r); + } +} + +const keyMapping = { + "Enter": "\uE006", + "Backspace": "\uE003", + "Delete": "\uE017", +}; diff --git a/uievents/textInput/support/no-textInput.sub.js b/uievents/textInput/support/no-textInput.sub.js new file mode 100644 index 000000000000000..b952b95cf62e960 --- /dev/null +++ b/uievents/textInput/support/no-textInput.sub.js @@ -0,0 +1,24 @@ +const els = document.querySelectorAll('.test-el'); +const key = "{{GET[key]}}"; +const keyRaw = keyMapping[key] || key; +const selectionStart = {{GET[selectionStart]}}; +const selectionEnd = {{GET[selectionEnd]}}; + +for (const el of els) { + promise_test(t => { + return new Promise((resolve, reject) => { + el.addEventListener('textInput', reject); + el.addEventListener('keyup', t.step_func(e => { + if (e.key !== key) { + return; + } + resolve(); + })); + el.onfocus = t.step_func(e => { + test_driver.send_keys(el, keyRaw); + }); + el.focus(); + setSelection(el, selectionStart, selectionEnd); + }); + }, `${document.title}, ${elDesc(el)}`); +}