Closed Bug 1490840 Opened 6 years ago Closed 6 years ago

HyperTextAccessible::ReplaceText causes two distinct DOM 'input' events

Categories

(Core :: Disability Access APIs, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla64
Tracking Status
firefox64 --- fixed

People

(Reporter: eeejay, Assigned: eeejay)

Details

Attachments

(1 file, 3 obsolete files)

When calling ReplaceText() with a string on an input element, we get two DOM events. The first is a delete action. The second is an insert action. It really should only have a single event with the new value. I tried solving this with TextEditor::ReplaceTextAsAction, but it caused some regressions with editable divs. Something to do with selection ranges. So I went with a less disruptive patch that deletes the text if the replacement is an empty string. Otherwise, it selects the whole range and does an insert which will overwrite the range.
Comment on attachment 9008561 [details] [diff] [review] Only delete text in ReplaceTextAsAction if the string is empty. r?Jamie Review of attachment 9008561 [details] [diff] [review]: ----------------------------------------------------------------- nit: In the commit message, you wrote ReplaceTextAsAction. I'm guessing this should be HyperTextAccessible::ReplaceText. ::: accessible/tests/browser/text/browser_test_settextcontents.js @@ +1,1 @@ > +function waitForDOMInputEvent() { nit: Missing license header. @@ +3,5 @@ > + content.document.getElementById("input").addEventListener("input", evt => { > + resolve(evt.target.value); > + }, { once: true }); > + }); > +} Any reason not to use BrowserTestUtils.waitForEvent here? @@ +10,5 @@ > + let input = findAccessibleChildByID(accDoc, "input", [nsIAccessibleEditableText]); > + let contentListener = ContentTask.spawn(browser, {}, waitForDOMInputEvent); > + input.setTextContents("goodbye"); > + let newValue = await contentListener; > + is(newValue, "goodbye", "input set to new value in first event."); I feel I'm missing some context here. How does the DOM input event affect a11y? I understand it fires two events, but why does that matter to us? And if it does affect a11y events in a way that matters to you, should we not be testing for a11y events rather than DOM events? @@ +14,5 @@ > + is(newValue, "goodbye", "input set to new value in first event."); > +} > + > +/** > + * Test caching of accessible object states I'm guessing this comment needs to be updated?
(In reply to James Teh [:Jamie] from comment #2) > Comment on attachment 9008561 [details] [diff] [review] > Only delete text in ReplaceTextAsAction if the string is empty. r?Jamie > > Review of attachment 9008561 [details] [diff] [review]: > ----------------------------------------------------------------- > > nit: In the commit message, you wrote ReplaceTextAsAction. I'm guessing this > should be HyperTextAccessible::ReplaceText. > > ::: accessible/tests/browser/text/browser_test_settextcontents.js > @@ +1,1 @@ > > +function waitForDOMInputEvent() { > > nit: Missing license header. > > @@ +3,5 @@ > > + content.document.getElementById("input").addEventListener("input", evt => { > > + resolve(evt.target.value); > > + }, { once: true }); > > + }); > > +} > > Any reason not to use BrowserTestUtils.waitForEvent here? ContentTaskUtils, good idea. > > @@ +10,5 @@ > > + let input = findAccessibleChildByID(accDoc, "input", [nsIAccessibleEditableText]); > > + let contentListener = ContentTask.spawn(browser, {}, waitForDOMInputEvent); > > + input.setTextContents("goodbye"); > > + let newValue = await contentListener; > > + is(newValue, "goodbye", "input set to new value in first event."); > > I feel I'm missing some context here. How does the DOM input event affect > a11y? I understand it fires two events, but why does that matter to us? And > if it does affect a11y events in a way that matters to you, should we not be > testing for a11y events rather than DOM events? It doesn't affect a11y events in a bad way. At least not that I know. A web app would expect a single input event after the user pastes a value into a field, not a deletion and then insertion. So this patch aligns our API to work more similarly to how a non-AT user would interact with a page in that case. I stumbled on this when trying to migrate our Android auto-fill JS code to the a11y API. The test expects one "input" event after the input's DOM node gets assigned a new value. If it is a pair of events (delete-insert) there is no certain way of knowing that an expected delete happened (you would need to wait for an arbitrary period to know no followup inserts came in). So yeah, I admit this patch is more for reliable tests and less for a user case. > > @@ +14,5 @@ > > + is(newValue, "goodbye", "input set to new value in first event."); > > +} > > + > > +/** > > + * Test caching of accessible object states > > I'm guessing this comment needs to be updated? Oops.
Attachment #9008561 - Attachment is obsolete: true
Attachment #9008561 - Flags: review?(jteh)
Made it a mochitest.
Attachment #9010107 - Flags: review?(jteh)
Attachment #9010075 - Attachment is obsolete: true
Attachment #9010075 - Flags: review?(jteh)
Oops. ignore that last one. Forgot to stage files.
Attachment #9010109 - Flags: review?(jteh)
Attachment #9010107 - Attachment is obsolete: true
Attachment #9010107 - Flags: review?(jteh)
Attachment #9010109 - Flags: review?(jteh) → review+
Keywords: checkin-needed
Pushed by ryanvm@gmail.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/c4923d4f4dc0 Only delete text in ReplaceText if the string is empty. r=Jamie
Keywords: checkin-needed
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla64
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: