From 0e93b7a02d32e6ba1778fa3a4a0940c8bf075ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mu-An=20=E2=9C=8C=EF=B8=8F=20Chiou?= Date: Tue, 18 Dec 2018 14:36:04 -0500 Subject: [PATCH 1/4] Clear selection and return keydown event during composition keydown and composition events get triggered in different orders across browsers so we can't rely on the 'mid composition' state and would need to clear selection to prevent triggering activation unintentionally --- combobox-nav.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/combobox-nav.js b/combobox-nav.js index ac6a8b0..68b8719 100644 --- a/combobox-nav.js +++ b/combobox-nav.js @@ -1,12 +1,18 @@ /* @flow strict */ +const compositionMap = new WeakMap() + export function install(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement): void { + input.addEventListener('compositionstart', trackComposition) + input.addEventListener('compositionend', trackComposition) input.addEventListener('keydown', keyboardBindings) list.addEventListener('click', commitWithElement) } export function uninstall(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement): void { input.removeAttribute('aria-activedescendant') + input.removeEventListener('compositionstart', trackComposition) + input.removeEventListener('compositionend', trackComposition) input.removeEventListener('keydown', keyboardBindings) list.removeEventListener('click', commitWithElement) } @@ -17,6 +23,7 @@ function keyboardBindings(event: KeyboardEvent) { if (event.shiftKey || event.metaKey || event.altKey) return const input = event.currentTarget if (!(input instanceof HTMLTextAreaElement || input instanceof HTMLInputElement)) return + if (compositionMap.get(input)) return const list = document.getElementById(input.getAttribute('aria-owns') || '') if (!list) return @@ -96,3 +103,15 @@ export function navigate( } } } + +function trackComposition(event: Event) { + const input = event.currentTarget + if (!(input instanceof HTMLTextAreaElement || input instanceof HTMLInputElement)) return + compositionMap.set(input, event.type === 'compositionstart') + + const list = document.getElementById(input.getAttribute('aria-owns') || '') + if (!list) return + const target = list.querySelector('[aria-selected="true"]') + if (!target) return + target.setAttribute('aria-selected', 'false') +} From b4450a8a54e9fca200e197896a273333cfcda1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mu-An=20=E2=9C=8C=EF=B8=8F=20Chiou?= Date: Tue, 18 Dec 2018 14:53:29 -0500 Subject: [PATCH 2/4] Add wrapping form to test default prevention --- examples/index.html | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/index.html b/examples/index.html index 4f114d9..c49a511 100644 --- a/examples/index.html +++ b/examples/index.html @@ -8,16 +8,18 @@ - - +
+ +
    +
  • Baymax
  • +
  • BB-8
  • +
  • Hubot
  • +
  • R2-D2
  • +
+