Modern Event System: refactor legacy FB support logic (#18336)

This commit is contained in:
Dominic Gannaway
2020-03-19 13:22:36 +00:00
committed by GitHub
parent 1cf4a170ac
commit 8311cb5d24
13 changed files with 1763 additions and 1728 deletions
@@ -16,3 +16,4 @@ export const IS_ACTIVE = 1 << 3;
export const PASSIVE_NOT_SUPPORTED = 1 << 4;
export const IS_REPLAYED = 1 << 5;
export const IS_FIRST_ANCESTOR = 1 << 6;
export const LEGACY_FB_SUPPORT = 1 << 7;
-1
View File
@@ -1365,7 +1365,6 @@ export function listenToEventResponderEventTypes(
(targetEventType: any),
true,
passiveItem.listener,
true,
);
listenerMap.delete(passiveKey);
}
+29 -39
View File
@@ -24,6 +24,7 @@ import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
import {batchedEventUpdates} from 'legacy-events/ReactGenericBatching';
import {executeDispatchesInOrder} from 'legacy-events/EventPluginUtils';
import {plugins} from 'legacy-events/EventPluginRegistry';
import {LEGACY_FB_SUPPORT, IS_REPLAYED} from 'legacy-events/EventSystemFlags';
import {HostRoot, HostPortal} from 'shared/ReactWorkTags';
@@ -66,6 +67,7 @@ import {
TOP_RATE_CHANGE,
TOP_PROGRESS,
TOP_PLAYING,
TOP_CLICK,
} from './DOMTopLevelEventTypes';
import {
getClosestInstanceFromNode,
@@ -78,7 +80,7 @@ import {
ELEMENT_NODE,
} from '../shared/HTMLNodeType';
import {enableLegacyFBPrimerSupport} from 'shared/ReactFeatureFlags';
import {enableLegacyFBSupport} from 'shared/ReactFeatureFlags';
const capturePhaseEvents = new Set([
TOP_FOCUS,
@@ -197,7 +199,6 @@ export function listenToTopLevelEvent(
topLevelType,
isCapturePhase,
((listenerEntry: any): ElementListenerMapEntry).listener,
((listenerEntry: any): ElementListenerMapEntry).passive,
);
}
const listener = addTrappedEventListener(
@@ -225,42 +226,24 @@ export function listenToEvent(
}
}
const validFBLegacyPrimerRels = new Set([
'dialog',
'dialog-post',
'async',
'async-post',
'theater',
'toggle',
]);
function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {
let node = nativeEvent.target;
const type = nativeEvent.type;
if (type !== 'click') {
function willDeferLaterForLegacyFBSupport(
topLevelType: DOMTopLevelEventType,
targetContainer: EventTarget,
): boolean {
if (topLevelType !== TOP_CLICK) {
return false;
}
while (node !== null) {
// Primer works by intercepting a click event on an <a> element
// that has a "rel" attribute that matches one of the valid ones
// in the Set above. If we intercept this before Primer does, we
// will need to defer the current event till later and discontinue
// execution of the current event. To do this we can add a document
// event listener and continue again later after propagation.
if (node.tagName === 'A' && validFBLegacyPrimerRels.has(node.rel)) {
const legacyFBSupport = true;
const isCapture = nativeEvent.eventPhase === 1;
addTrappedEventListener(
null,
((type: any): DOMTopLevelEventType),
isCapture,
legacyFBSupport,
);
return true;
}
node = node.parentNode;
}
return false;
// We defer all click events with legacy FB support mode on.
// This means we add a one time event listener to trigger
// after the FB delegated listeners fire.
const isDeferredListenerForLegacyFBSupport = true;
addTrappedEventListener(
targetContainer,
topLevelType,
false,
isDeferredListenerForLegacyFBSupport,
);
return true;
}
function isMatchingRootContainer(
@@ -303,12 +286,19 @@ export function dispatchEventForPluginEventSystem(
// TODO: useEvent for document and window
return;
}
// If we detect the FB legacy primer system, we
// If we are using the legacy FB support flag, we
// defer the event to the null with a one
// time event listener so we can defer the event.
if (
enableLegacyFBPrimerSupport &&
willDeferLaterForFBLegacyPrimer(nativeEvent)
enableLegacyFBSupport &&
// We do not want to defer if the event system has already been
// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
// we call willDeferLaterForLegacyFBSupport, thus not bailing out
// will result in endless cycles like an infinite loop.
(eventSystemFlags & LEGACY_FB_SUPPORT) === 0 &&
// We also don't want to defer during event replaying.
(eventSystemFlags & IS_REPLAYED) === 0 &&
willDeferLaterForLegacyFBSupport(topLevelType, targetContainer)
) {
return;
}
+20 -13
View File
@@ -42,6 +42,7 @@ import {
IS_PASSIVE,
IS_ACTIVE,
PASSIVE_NOT_SUPPORTED,
LEGACY_FB_SUPPORT,
} from 'legacy-events/EventSystemFlags';
import {
@@ -59,7 +60,7 @@ import {passiveBrowserEventsSupported} from './checkPassiveEvents';
import {
enableDeprecatedFlareAPI,
enableModernEventSystem,
enableLegacyFBPrimerSupport,
enableLegacyFBSupport,
enableUseEventAPI,
} from 'shared/ReactFeatureFlags';
import {
@@ -129,10 +130,10 @@ export function addResponderEventSystemEvent(
}
export function addTrappedEventListener(
targetContainer: null | EventTarget,
targetContainer: EventTarget,
topLevelType: DOMTopLevelEventType,
capture: boolean,
legacyFBSupport?: boolean,
isDeferredListenerForLegacyFBSupport?: boolean,
passive?: boolean,
priority?: EventPriority,
): any => void {
@@ -159,11 +160,15 @@ export function addTrappedEventListener(
if (passive === true && !passiveBrowserEventsSupported) {
passive = false;
}
const eventSystemFlags =
enableLegacyFBSupport && isDeferredListenerForLegacyFBSupport
? PLUGIN_EVENT_SYSTEM | LEGACY_FB_SUPPORT
: PLUGIN_EVENT_SYSTEM;
listener = listenerWrapper.bind(
null,
topLevelType,
PLUGIN_EVENT_SYSTEM,
eventSystemFlags,
targetContainer,
);
@@ -177,14 +182,17 @@ export function addTrappedEventListener(
targetContainer = document;
}
const validTargetContainer = ((targetContainer: any): EventTarget);
targetContainer =
enableLegacyFBSupport && isDeferredListenerForLegacyFBSupport
? (targetContainer: any).ownerDocument
: targetContainer;
const rawEventName = getRawEventName(topLevelType);
let unsubscribeListener;
// When legacyFBSupport is enabled, it's for when we
// want to add a one time event listener to a container.
// This should only be used with enableLegacyFBPrimerSupport
// This should only be used with enableLegacyFBSupport
// due to requirement to provide compatibility with
// internal FB www event tooling. This works by removing
// the event listener as soon as it is invoked. We could
@@ -193,14 +201,14 @@ export function addTrappedEventListener(
// browsers do not support this today, and given this is
// to support legacy code patterns, it's likely they'll
// need support for such browsers.
if (enableLegacyFBPrimerSupport && legacyFBSupport) {
if (enableLegacyFBSupport && isDeferredListenerForLegacyFBSupport) {
const originalListener = listener;
listener = function(...p) {
try {
return originalListener.apply(this, p);
} finally {
removeEventListener(
validTargetContainer,
targetContainer,
rawEventName,
unsubscribeListener,
capture,
@@ -212,14 +220,14 @@ export function addTrappedEventListener(
if (enableUseEventAPI && passive !== undefined) {
// This is only used with passive is either true or false.
unsubscribeListener = addEventCaptureListenerWithPassiveFlag(
validTargetContainer,
targetContainer,
rawEventName,
listener,
passive,
);
} else {
unsubscribeListener = addEventCaptureListener(
validTargetContainer,
targetContainer,
rawEventName,
listener,
);
@@ -228,14 +236,14 @@ export function addTrappedEventListener(
if (enableUseEventAPI && passive !== undefined) {
// This is only used with passive is either true or false.
unsubscribeListener = addEventBubbleListenerWithPassiveFlag(
validTargetContainer,
targetContainer,
rawEventName,
listener,
passive,
);
} else {
unsubscribeListener = addEventBubbleListener(
validTargetContainer,
targetContainer,
rawEventName,
listener,
);
@@ -249,7 +257,6 @@ export function removeTrappedEventListener(
topLevelType: DOMTopLevelEventType,
capture: boolean,
listener: any => void,
passive: void | boolean,
): void {
const rawEventName = getRawEventName(topLevelType);
removeEventListener(targetContainer, rawEventName, listener, capture);
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -140,4 +140,4 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
export const enableModernEventSystem = false;
// Support legacy Primer support on internal FB www
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
@@ -47,7 +47,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = true;
@@ -46,7 +46,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;
@@ -46,7 +46,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;
@@ -46,7 +46,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;
@@ -46,7 +46,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = false;
export const enableLegacyFBSupport = false;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;
@@ -46,7 +46,7 @@ export const deferPassiveEffectCleanupDuringUnmount = false;
export const runAllPassiveEffectDestroysBeforeCreates = false;
export const enableModernEventSystem = false;
export const warnAboutSpreadingKeyToJSX = false;
export const enableLegacyFBPrimerSupport = !__EXPERIMENTAL__;
export const enableLegacyFBSupport = !__EXPERIMENTAL__;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;
@@ -104,7 +104,7 @@ export const disableModulePatternComponents = __EXPERIMENTAL__;
export const warnUnstableRenderSubtreeIntoContainer = false;
export const enableLegacyFBPrimerSupport = !__EXPERIMENTAL__;
export const enableLegacyFBSupport = !__EXPERIMENTAL__;
// Internal-only attempt to debug a React Native issue. See D20130868.
export const throwEarlyForMysteriousError = false;