From c3d0587023d0ec772cdb73a2b21584de9c81f0a7 Mon Sep 17 00:00:00 2001 From: Shaheen Gandhi Date: Wed, 3 Jul 2019 03:17:09 -0400 Subject: [PATCH] Get focus and blur working --- src/fiber/ScreenEventTypes.js | 6 ++- src/fiber/SyntheticFocusEvent.js | 18 ++++++++ src/fiber/events.js | 71 +++++++++++++++++++++++++------- 3 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 src/fiber/SyntheticFocusEvent.js diff --git a/src/fiber/ScreenEventTypes.js b/src/fiber/ScreenEventTypes.js index 604b21e..dc7978e 100644 --- a/src/fiber/ScreenEventTypes.js +++ b/src/fiber/ScreenEventTypes.js @@ -1,8 +1,12 @@ // Constants for native events emitted by screen export const SCREEN_KEYPRESS = 'keypress'; +export const SCREEN_FOCUS = 'focus'; +export const SCREEN_BLUR = 'blur'; export const all = [ - SCREEN_KEYPRESS + SCREEN_KEYPRESS, + SCREEN_FOCUS, + SCREEN_BLUR ]; export function screenEventName(eventType) { diff --git a/src/fiber/SyntheticFocusEvent.js b/src/fiber/SyntheticFocusEvent.js new file mode 100644 index 0000000..8a2d14f --- /dev/null +++ b/src/fiber/SyntheticFocusEvent.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import SyntheticUIEvent from './SyntheticUIEvent'; + +/** + * @interface FocusEvent + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ +const SyntheticFocusEvent = SyntheticUIEvent.extend({ + relatedTarget: null, +}); + +export default SyntheticFocusEvent; diff --git a/src/fiber/events.js b/src/fiber/events.js index 867f5a2..ed0a90c 100644 --- a/src/fiber/events.js +++ b/src/fiber/events.js @@ -1,5 +1,6 @@ import * as ScreenEventTypes from './ScreenEventTypes'; import SyntheticKeyboardEvent from './SyntheticKeyboardEvent'; +import SyntheticFocusEvent from './SyntheticFocusEvent'; const eventSubscriptionMappings = {}; const eventDispatchConfigs = {}; @@ -8,8 +9,6 @@ const eventRegistrationNameToConfig = {} const screenEventTransforms = { [ScreenEventTypes.SCREEN_KEYPRESS]: (dispatchConfig, targetInst, eventTarget, ...args) => { const [ch, key] = args; - console.log(ch); - console.log(key); const eventData = { type: ScreenEventTypes.SCREEN_KEYPRESS, @@ -22,7 +21,8 @@ const screenEventTransforms = { ctrlKey: key.ctrl, shiftKey: key.shift, repeat: false, - key: ch + key: ch, + charCode: ch.charCodeAt(0) }; return SyntheticKeyboardEvent.getPooled( dispatchConfig, @@ -30,12 +30,48 @@ const screenEventTransforms = { eventData, eventTarget ); + }, + [ScreenEventTypes.SCREEN_FOCUS]: (dispatchConfig, targetInst, eventTarget, ...args) => { + const [old] = args; + const eventData = { + type: ScreenEventTypes.SCREEN_FOCUS, + target: targetInst, + bubbles: false, + cancelable: false, + + relatedTarget: old + }; + return SyntheticFocusEvent.getPooled( + dispatchConfig, + targetInst, + eventData, + eventTarget + ) + }, + [ScreenEventTypes.SCREEN_BLUR]: (dispatchConfig, targetInst, eventTarget, ...args) => { + const [next] = args; + const eventData = { + type: ScreenEventTypes.SCREEN_BLUR, + target: targetInst, + bubbles: false, + cancelable: false, + + relatedTarget: next + }; + return SyntheticFocusEvent.getPooled( + dispatchConfig, + targetInst, + eventData, + eventTarget + ) } }; // Pairs of react events and screen native events const eventTuples = [ - ['keyPress', ScreenEventTypes.SCREEN_KEYPRESS] + ['keyPress', ScreenEventTypes.SCREEN_KEYPRESS], + ['focus', ScreenEventTypes.SCREEN_FOCUS], + ['blur', ScreenEventTypes.SCREEN_BLUR] ]; function addEventConfiguration(eventName, screenEventType) { @@ -67,18 +103,19 @@ function ensureListeningTo(root, screenEventType) { if (!isListening.has(screenEventType)) { isListening.add(screenEventType); - root.screen.on(screenEventName, dispatchScreenEvent.bind(null, root, screenEventType)); + root.screen.on(screenEventName, dispatchScreenEvent.bind(null, root, screenEventType, false)); + root.screen.on('element ' + screenEventName, dispatchScreenEvent.bind(null, root, screenEventType, true)); } } -function dispatchScreenEvent(root, screenEventType, ...args) { - if (screenEventType != ScreenEventTypes.SCREEN_KEYPRESS) { - return; - } - +function dispatchScreenEvent(root, screenEventType, firstArgIsTarget, ...args) { const dispatchConfig = eventDispatchConfigs[screenEventType]; - const targetInst = root.screen.focused; + const targetInst = firstArgIsTarget ? args.shift() : root.screen.focused; const eventTransform = screenEventTransforms[screenEventType]; + + if (!eventTransform) { + throw new Error('unhandled event: ' + screenEventType); + } const syntheticEvent = eventTransform( dispatchConfig, targetInst, @@ -91,11 +128,13 @@ function dispatchScreenEvent(root, screenEventType, ...args) { const bubbleListeners = []; var node = targetInst; do { - if (dispatchConfig.phasedRegistrationNames.captured in node.props) { - captureListeners.unshift(node); - } - if (dispatchConfig.phasedRegistrationNames.bubbled in node.props) { - bubbleListeners.push(node); + if (node.props) { + if (dispatchConfig.phasedRegistrationNames.captured in node.props) { + captureListeners.unshift(node); + } + if (dispatchConfig.phasedRegistrationNames.bubbled in node.props) { + bubbleListeners.push(node); + } } node = node.parent; } while (node != root);