supports event capturing and bubbling phases in Navigation context.

Summary: Adds the API that enables the navigation events capturing and bubbling which is the feature
that is enabled if the nested navigation contexts is created by the navigator.

This would allow developer to observe or reconcile navigation events within the navigation tree.

public

./Libraries/FBReactKit/jest

Reviewed By: zjj010104

Differential Revision: D2546451

fb-gh-sync-id: dfc9d16defaa563b9e80fd751a20570f6e524b74
This commit is contained in:
Hedger Wang
2015-10-19 10:03:04 -07:00
committed by facebook-github-bot-9
parent 1076f4a172
commit 73b80773ba
4 changed files with 431 additions and 35 deletions

View File

@@ -29,6 +29,7 @@ jest
.mock('ErrorUtils');
var NavigationContext = require('NavigationContext');
var NavigationEvent = require('NavigationEvent');
describe('NavigationContext', () => {
it('defaults `currentRoute` to null', () => {
@@ -48,4 +49,206 @@ describe('NavigationContext', () => {
parent.appendChild(child);
expect(child.parent).toBe(parent);
});
it('captures event', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var logs = [];
var listener = (event) => {
var {currentTarget, eventPhase, target, type} = event;
logs.push({
currentTarget,
eventPhase,
target,
type,
});
};
parent.addListener('yo', listener, null, true);
child.addListener('yo', listener, null, true);
child.emit('yo');
expect(logs).toEqual([
{
currentTarget: parent,
eventPhase: NavigationEvent.CAPTURING_PHASE,
target: child,
type: 'yo',
},
{
currentTarget: child,
eventPhase: NavigationEvent.AT_TARGET,
target: child,
type: 'yo',
}
]);
});
it('bubbles events', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var logs = [];
var listener = (event) => {
var {currentTarget, eventPhase, target, type} = event;
logs.push({
currentTarget,
eventPhase,
target,
type,
});
};
parent.addListener('yo', listener);
child.addListener('yo', listener);
child.emit('yo');
expect(logs).toEqual([
{
currentTarget: child,
eventPhase: NavigationEvent.AT_TARGET,
target: child,
type: 'yo',
},
{
currentTarget: parent,
eventPhase: NavigationEvent.BUBBLING_PHASE,
target: child,
type: 'yo',
},
]);
});
it('stops event propagation at capture phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var counter = 0;
parent.addListener('yo', event => event.stopPropagation(), null, true);
child.addListener('yo', event => counter++, null, true);
child.emit('yo');
expect(counter).toBe(0);
});
it('stops event propagation at bubbling phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var counter = 0;
parent.addListener('yo', event => counter++);
child.addListener('yo', event => event.stopPropagation());
child.emit('yo');
expect(counter).toBe(0);
});
it('prevents event at capture phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var val;
parent.addListener('yo', event => event.preventDefault(), null, true);
child.addListener('yo', event => val = event.defaultPrevented, null, true);
child.emit('yo');
expect(val).toBe(true);
});
it('prevents event at bubble phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var val;
parent.addListener('yo', event => val = event.defaultPrevented);
child.addListener('yo', event => event.preventDefault());
child.emit('yo');
expect(val).toBe(true);
});
it('emits nested events in order at capture phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var logs = [];
var listener = (event) => {
var {currentTarget, type} = event;
logs.push({
currentTarget,
type,
});
};
child.addListener('yo', event => {
// event `didyo` should be fired after the full propagation cycle of the
// `yo` event.
child.emit('didyo');
});
parent.addListener('yo', listener, null, true);
parent.addListener('didyo', listener, null, true);
child.addListener('yo', listener, null, true);
child.emit('yo');
expect(logs).toEqual([
{type: 'yo', currentTarget: parent},
{type: 'yo', currentTarget: child},
{type: 'didyo', currentTarget: parent},
]);
});
it('emits nested events in order at bubbling phase', () => {
var parent = new NavigationContext();
var child = new NavigationContext();
parent.appendChild(child);
var logs = [];
var listener = (event) => {
var {currentTarget, type} = event;
logs.push({
currentTarget,
type,
});
};
child.addListener('yo', event => {
// event `didyo` should be fired after the full propagation cycle of the
// `yo` event.
child.emit('didyo');
});
parent.addListener('yo', listener);
child.addListener('yo', listener);
parent.addListener('didyo', listener);
child.emit('yo');
expect(logs).toEqual([
{type: 'yo', currentTarget: child},
{type: 'yo', currentTarget: parent},
{type: 'didyo', currentTarget: parent},
]);
});
});