From e020ae2789383ac7ceaf1b66b3563007ae7a31ff Mon Sep 17 00:00:00 2001 From: Mu-An Chiou Date: Wed, 23 Oct 2019 15:29:01 -0400 Subject: [PATCH 1/2] Prevent keyboard events during text composition inside of details-menu --- index.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 9a550ca..a042703 100644 --- a/index.js +++ b/index.js @@ -37,6 +37,8 @@ class DetailsMenuElement extends HTMLElement { if (!summary.hasAttribute('role')) summary.setAttribute('role', 'button') } + this.addEventListener('compositionstart', trackComposition) + this.addEventListener('compositionend', trackComposition) details.addEventListener('click', shouldCommit) details.addEventListener('change', shouldCommit) details.addEventListener('keydown', keydown) @@ -47,7 +49,7 @@ class DetailsMenuElement extends HTMLElement { } const subscriptions = [focusOnOpen(details)] - states.set(this, {details, subscriptions, loaded: false}) + states.set(this, {details, subscriptions, loaded: false, isComposing: false}) } disconnectedCallback() { @@ -60,6 +62,9 @@ class DetailsMenuElement extends HTMLElement { for (const sub of subscriptions) { sub.unsubscribe() } + + this.addEventListener('compositionstart', trackComposition) + this.addEventListener('compositionend', trackComposition) details.removeEventListener('click', shouldCommit) details.removeEventListener('change', shouldCommit) details.removeEventListener('keydown', keydown) @@ -222,6 +227,13 @@ function commit(selected: Element, details: Element) { function keydown(event: KeyboardEvent) { const details = event.currentTarget if (!(details instanceof Element)) return + const menu = details.querySelector('details-menu') + if (!menu) return + const state = states.get(menu) + if (!state) return + const {isComposing} = state + if (isComposing) return + const isSummaryFocused = event.target instanceof Element && event.target.tagName === 'SUMMARY' // Ignore key presses from nested details. @@ -326,6 +338,12 @@ function labelHTML(el: ?Element): ?string { return contentsEl ? contentsEl.innerHTML : null } +function trackComposition(event: Event) { + const state = states.get(event.currentTarget) + if (!state) return + state.isComposing = event.type === 'compositionstart' +} + export default DetailsMenuElement if (!window.customElements.get('details-menu')) { From 2590a24de36b9bddf31208d1cdf640a4a56e1b7c Mon Sep 17 00:00:00 2001 From: Mu-An Chiou Date: Fri, 15 Nov 2019 09:17:07 -0800 Subject: [PATCH 2/2] Prioritize ignoring keyscroke from nested details --- index.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index b0d216d..e754e8d 100644 --- a/index.js +++ b/index.js @@ -216,13 +216,12 @@ function commit(selected: Element, details: Element) { function keydown(details: Element, menu: DetailsMenuElement, event: Event) { if (!(event instanceof KeyboardEvent)) return - const state = states.get(menu) - if (!state) return - if (state.isComposing) return - const isSummaryFocused = event.target instanceof Element && event.target.tagName === 'SUMMARY' - // Ignore key presses from nested details. if (details.querySelector('details[open]')) return + const state = states.get(menu) + if (!state || state.isComposing) return + + const isSummaryFocused = event.target instanceof Element && event.target.tagName === 'SUMMARY' switch (event.key) { case 'Escape':