Permalink
Browse files

build nested navigation context based on the hierarchy of navigators.

Reviewed By: zjj010104

Differential Revision: D2598388

fb-gh-sync-id: 9655bcc86021678984e2a29df20ad2496a1762d1
  • Loading branch information...
Hedger Wang facebook-github-bot-9
Hedger Wang authored and facebook-github-bot-9 committed Oct 30, 2015
1 parent 854689d commit a33fe94dace7863131a3fa8d87a8ad75bfeaff02
Showing with 76 additions and 39 deletions.
  1. +76 −39 Libraries/CustomComponents/Navigator/Navigation/NavigationContext.js
@@ -30,6 +30,8 @@ var NavigationEvent = require('NavigationEvent');
var NavigationEventEmitter = require('NavigationEventEmitter');
var NavigationTreeNode = require('NavigationTreeNode');
+var Set = require('Set');
+
var emptyFunction = require('emptyFunction');
var invariant = require('invariant');
@@ -41,6 +43,13 @@ var {
CAPTURING_PHASE,
} = NavigationEvent;
+// Event types that do not support event bubbling, capturing and
+// reconciliation API (e.g event.preventDefault(), event.stopPropagation()).
+var LegacyEventTypes = new Set([
+ 'willfocus',
+ 'didfocus',
+]);
+
/**
* Class that contains the info and methods for app navigation.
*/
@@ -88,9 +97,14 @@ class NavigationContext {
context: ?Object,
useCapture: ?boolean
): EventSubscription {
+ if (LegacyEventTypes.has(eventType)) {
+ useCapture = false;
+ }
+
var emitter = useCapture ?
this._captureEventEmitter :
this._bubbleEventEmitter;
+
if (emitter) {
return emitter.addListener(eventType, listener, context);
} else {
@@ -109,49 +123,64 @@ class NavigationContext {
this._emitCounter++;
- var targets = [this];
- var parentTarget = this.parent;
- while (parentTarget) {
- targets.unshift(parentTarget);
- parentTarget = parentTarget.parent;
- }
-
- var propagationStopped = false;
- var defaultPrevented = false;
- var callback = (event) => {
- propagationStopped = propagationStopped || event.isPropagationStopped();
- defaultPrevented = defaultPrevented || event.defaultPrevented;
- };
-
- // capture phase
- targets.some((currentTarget) => {
- if (propagationStopped) {
- return true;
+ if (LegacyEventTypes.has(eventType)) {
+ // Legacy events does not support event bubbling and reconciliation.
+ this.__emit(
+ eventType,
+ data,
+ null,
+ {
+ defaultPrevented: false,
+ eventPhase: AT_TARGET,
+ propagationStopped: true,
+ target: this,
+ }
+ );
+ } else {
+ var targets = [this];
+ var parentTarget = this.parent;
+ while (parentTarget) {
+ targets.unshift(parentTarget);
+ parentTarget = parentTarget.parent;
}
- var extraInfo = {
- defaultPrevented,
- eventPhase: CAPTURING_PHASE,
- propagationStopped,
- target: this,
+ var propagationStopped = false;
+ var defaultPrevented = false;
+ var callback = (event) => {
+ propagationStopped = propagationStopped || event.isPropagationStopped();
+ defaultPrevented = defaultPrevented || event.defaultPrevented;
};
- currentTarget.__emit(eventType, data, callback, extraInfo);
- }, this);
+ // Capture phase
+ targets.some((currentTarget) => {
+ if (propagationStopped) {
+ return true;
+ }
- // bubble phase
- targets.reverse().some((currentTarget) => {
- if (propagationStopped) {
- return true;
- }
- var extraInfo = {
- defaultPrevented,
- eventPhase: BUBBLING_PHASE,
- propagationStopped,
- target: this,
- };
- currentTarget.__emit(eventType, data, callback, extraInfo);
- }, this);
+ var extraInfo = {
+ defaultPrevented,
+ eventPhase: CAPTURING_PHASE,
+ propagationStopped,
+ target: this,
+ };
+
+ currentTarget.__emit(eventType, data, callback, extraInfo);
+ }, this);
+
+ // bubble phase
+ targets.reverse().some((currentTarget) => {
+ if (propagationStopped) {
+ return true;
+ }
+ var extraInfo = {
+ defaultPrevented,
+ eventPhase: BUBBLING_PHASE,
+ propagationStopped,
+ target: this,
+ };
+ currentTarget.__emit(eventType, data, callback, extraInfo);
+ }, this);
+ }
if (didEmitCallback) {
var event = NavigationEvent.pool(eventType, this, data);
@@ -189,9 +218,15 @@ class NavigationContext {
case CAPTURING_PHASE: // phase = 1
emitter = this._captureEventEmitter;
break;
+
+ case AT_TARGET: // phase = 2
+ emitter = this._bubbleEventEmitter;
+ break;
+
case BUBBLING_PHASE: // phase = 3
emitter = this._bubbleEventEmitter;
break;
+
default:
invariant(false, 'invalid event phase %s', extraInfo.eventPhase);
}
@@ -214,8 +249,10 @@ class NavigationContext {
_onFocus(event: NavigationEvent): void {
invariant(
event.data && event.data.hasOwnProperty('route'),
- 'didfocus event should provide route'
+ 'event type "%s" should provide route',
+ event.type
);
+
this._currentRoute = event.data.route;
}
}

0 comments on commit a33fe94

Please sign in to comment.