1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | 'use strict';
|
10 |
|
11 | var _assign = require('object-assign');
|
12 |
|
13 | var EventListener = require('fbjs/lib/EventListener');
|
14 | var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
15 | var PooledClass = require('./PooledClass');
|
16 | var ReactDOMComponentTree = require('./ReactDOMComponentTree');
|
17 | var ReactUpdates = require('./ReactUpdates');
|
18 |
|
19 | var getEventTarget = require('./getEventTarget');
|
20 | var getUnboundedScrollPosition = require('fbjs/lib/getUnboundedScrollPosition');
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | function findParent(inst) {
|
28 |
|
29 |
|
30 |
|
31 | while (inst._hostParent) {
|
32 | inst = inst._hostParent;
|
33 | }
|
34 | var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst);
|
35 | var container = rootNode.parentNode;
|
36 | return ReactDOMComponentTree.getClosestInstanceFromNode(container);
|
37 | }
|
38 |
|
39 |
|
40 | function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
|
41 | this.topLevelType = topLevelType;
|
42 | this.nativeEvent = nativeEvent;
|
43 | this.ancestors = [];
|
44 | }
|
45 | _assign(TopLevelCallbackBookKeeping.prototype, {
|
46 | destructor: function () {
|
47 | this.topLevelType = null;
|
48 | this.nativeEvent = null;
|
49 | this.ancestors.length = 0;
|
50 | }
|
51 | });
|
52 | PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler);
|
53 |
|
54 | function handleTopLevelImpl(bookKeeping) {
|
55 | var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent);
|
56 | var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget);
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | var ancestor = targetInst;
|
63 | do {
|
64 | bookKeeping.ancestors.push(ancestor);
|
65 | ancestor = ancestor && findParent(ancestor);
|
66 | } while (ancestor);
|
67 |
|
68 | for (var i = 0; i < bookKeeping.ancestors.length; i++) {
|
69 | targetInst = bookKeeping.ancestors[i];
|
70 | ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
|
71 | }
|
72 | }
|
73 |
|
74 | function scrollValueMonitor(cb) {
|
75 | var scrollPosition = getUnboundedScrollPosition(window);
|
76 | cb(scrollPosition);
|
77 | }
|
78 |
|
79 | var ReactEventListener = {
|
80 | _enabled: true,
|
81 | _handleTopLevel: null,
|
82 |
|
83 | WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
|
84 |
|
85 | setHandleTopLevel: function (handleTopLevel) {
|
86 | ReactEventListener._handleTopLevel = handleTopLevel;
|
87 | },
|
88 |
|
89 | setEnabled: function (enabled) {
|
90 | ReactEventListener._enabled = !!enabled;
|
91 | },
|
92 |
|
93 | isEnabled: function () {
|
94 | return ReactEventListener._enabled;
|
95 | },
|
96 |
|
97 | |
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | trapBubbledEvent: function (topLevelType, handlerBaseName, element) {
|
108 | if (!element) {
|
109 | return null;
|
110 | }
|
111 | return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
|
112 | },
|
113 |
|
114 | |
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | trapCapturedEvent: function (topLevelType, handlerBaseName, element) {
|
125 | if (!element) {
|
126 | return null;
|
127 | }
|
128 | return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType));
|
129 | },
|
130 |
|
131 | monitorScrollValue: function (refresh) {
|
132 | var callback = scrollValueMonitor.bind(null, refresh);
|
133 | EventListener.listen(window, 'scroll', callback);
|
134 | },
|
135 |
|
136 | dispatchEvent: function (topLevelType, nativeEvent) {
|
137 | if (!ReactEventListener._enabled) {
|
138 | return;
|
139 | }
|
140 |
|
141 | var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent);
|
142 | try {
|
143 |
|
144 |
|
145 | ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
|
146 | } finally {
|
147 | TopLevelCallbackBookKeeping.release(bookKeeping);
|
148 | }
|
149 | }
|
150 | };
|
151 |
|
152 | module.exports = ReactEventListener; |
\ | No newline at end of file |