diff --git a/uievents/textInput/api.html b/uievents/textInput/api.html new file mode 100644 index 00000000000000..a88184e500178c --- /dev/null +++ b/uievents/textInput/api.html @@ -0,0 +1,88 @@ + + +textInput: API + + + + +
+ + diff --git a/uievents/textInput/backspace.html b/uievents/textInput/backspace.html new file mode 100644 index 00000000000000..c9b2f8bee4e1e4 --- /dev/null +++ b/uievents/textInput/backspace.html @@ -0,0 +1,16 @@ + + +textInput: backspace + + + + + +

Press Backspace in each text field below.

+ + +
abc
+ + diff --git a/uievents/textInput/basic.html b/uievents/textInput/basic.html new file mode 100644 index 00000000000000..6335167faa84f5 --- /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-selection.html b/uievents/textInput/delete-selection.html new file mode 100644 index 00000000000000..f77e8c6e98a1ec --- /dev/null +++ b/uievents/textInput/delete-selection.html @@ -0,0 +1,16 @@ + + +textInput: delete selection + + + + + +

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

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

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

+ + +
abc
+ + diff --git a/uievents/textInput/enter-input.html b/uievents/textInput/enter-input.html new file mode 100644 index 00000000000000..032503694dc8f8 --- /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 00000000000000..60891df982e9f6 --- /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/smiley-manual.html b/uievents/textInput/smiley-manual.html new file mode 100644 index 00000000000000..7781f6e1b06b56 --- /dev/null +++ b/uievents/textInput/smiley-manual.html @@ -0,0 +1,17 @@ + + +textInput: smiley (manual) + + + +

Type "🙂" into 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 00000000000000..53ff826743a317 --- /dev/null +++ b/uievents/textInput/support/basic.sub.js @@ -0,0 +1,44 @@ +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]}}; +const expectedValue = "{{GET[expectedValue]}}"; + +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.addEventListener('input', t.step_func(e => { + assert_equals(textInputEvents, 1); + if (expectedValue === "\n" && !(el instanceof HTMLInputElement) && !(el instanceof HTMLTextAreaElement)) { + // New paragraph in contenteditable during editing is weird. + // innerHTML is


+ // ...but later changes to
+ // So, check that there's at least one
. + assert_true(getValue(el).indexOf('
') > -1); + } else { + assert_equals(getValue(el), expectedValue); + } + resolve(); + })); + el.onfocus = t.step_func(e => { + if (window.test_driver) { + 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 00000000000000..05600d464c879e --- /dev/null +++ b/uievents/textInput/support/common.js @@ -0,0 +1,38 @@ +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.firstChild || el, selectionStart); + r.setEnd(el.firstChild || el, selectionEnd); + s.addRange(r); + } +} + +function getValue(el) { + if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) { + return el.value; + } + return el.innerHTML; +} + +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 00000000000000..332cbf08f2b3c8 --- /dev/null +++ b/uievents/textInput/support/no-textInput.sub.js @@ -0,0 +1,29 @@ +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]}}; +const expectedValue = "{{GET[expectedValue]}}"; + +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; + } + assert_equals(getValue(el), expectedValue); + resolve(); + })); + el.onfocus = t.step_func(e => { + if (window.test_driver) { + test_driver.send_keys(el, keyRaw); + } + }); + el.focus(); + setSelection(el, selectionStart, selectionEnd); + }); + }, `${document.title}, ${elDesc(el)}`); +}