Skip to content

Commit bbffe86

Browse files
zarubondnecolas
authored andcommitted
ResponderTouchHistoryStore into instanciated class
Refactor ResponderTouchHistoryStore from singleton to class instantiated in ResponderSystem. This is a part of greater effort to enable support for multiple browser windows Close #2190
1 parent 32a4bf8 commit bbffe86

File tree

3 files changed

+68
-58
lines changed

3 files changed

+68
-58
lines changed

packages/react-native-web/src/modules/useResponderEvents/ResponderSystem.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ import {
150150
isPrimaryPointerDown,
151151
setResponderId
152152
} from './utils';
153-
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
153+
import { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore';
154154
import canUseDOM from '../canUseDom';
155155

156156
/* ------------ TYPES ------------ */
@@ -232,6 +232,7 @@ let currentResponder: ResponderInstance = {
232232
node: null,
233233
idPath: null
234234
};
235+
const responderTouchHistoryStore = new ResponderTouchHistoryStore();
235236

236237
function changeCurrentResponder(responder: ResponderInstance) {
237238
currentResponder = responder;
@@ -294,7 +295,10 @@ function eventListener(domEvent: any) {
294295
const isEndEvent = isEndish(eventType);
295296
const isScrollEvent = isScroll(eventType);
296297
const isSelectionChangeEvent = isSelectionChange(eventType);
297-
const responderEvent = createResponderEvent(domEvent);
298+
const responderEvent = createResponderEvent(
299+
domEvent,
300+
responderTouchHistoryStore
301+
);
298302

299303
/**
300304
* Record the state of active pointers
@@ -310,7 +314,7 @@ function eventListener(domEvent: any) {
310314
trackedTouchCount = 0;
311315
}
312316
}
313-
ResponderTouchHistoryStore.recordTouchTrack(
317+
responderTouchHistoryStore.recordTouchTrack(
314318
eventType,
315319
responderEvent.nativeEvent
316320
);
@@ -665,7 +669,7 @@ export function terminateResponder() {
665669
if (id != null && node != null) {
666670
const { onResponderTerminate } = getResponderConfig(id);
667671
if (onResponderTerminate != null) {
668-
const event = createResponderEvent({});
672+
const event = createResponderEvent({}, responderTouchHistoryStore);
669673
event.currentTarget = node;
670674
onResponderTerminate(event);
671675
}

packages/react-native-web/src/modules/useResponderEvents/ResponderTouchHistoryStore.js

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,25 @@ import type { Touch, TouchEvent } from './ResponderEventTypes';
1111
import { isStartish, isMoveish, isEndish } from './ResponderEventTypes';
1212

1313
type TouchRecord = {|
14-
touchActive: boolean,
15-
startPageX: number,
16-
startPageY: number,
17-
startTimeStamp: number,
1814
currentPageX: number,
1915
currentPageY: number,
2016
currentTimeStamp: number,
2117
previousPageX: number,
2218
previousPageY: number,
23-
previousTimeStamp: number
19+
previousTimeStamp: number,
20+
startPageX: number,
21+
startPageY: number,
22+
startTimeStamp: number,
23+
touchActive: boolean
2424
|};
2525

26+
export type TouchHistory = $ReadOnly<{|
27+
indexOfSingleActiveTouch: number,
28+
mostRecentTimeStamp: number,
29+
numberActiveTouches: number,
30+
touchBank: Array<TouchRecord>
31+
|}>;
32+
2633
/**
2734
* Tracks the position and time of each active touch by `touch.identifier`. We
2835
* should typically only see IDs in the range of 1-20 because IDs get recycled
@@ -31,16 +38,6 @@ type TouchRecord = {|
3138

3239
const __DEV__ = process.env.NODE_ENV !== 'production';
3340
const MAX_TOUCH_BANK = 20;
34-
const touchBank: Array<TouchRecord> = [];
35-
const touchHistory = {
36-
touchBank,
37-
numberActiveTouches: 0,
38-
// If there is only one active touch, we remember its location. This prevents
39-
// us having to loop through all of the touches all the time in the most
40-
// common case.
41-
indexOfSingleActiveTouch: -1,
42-
mostRecentTimeStamp: 0
43-
};
4441

4542
function timestampForTouch(touch: Touch): number {
4643
// The legacy internal implementation provides "timeStamp", which has been
@@ -97,19 +94,19 @@ function getTouchIdentifier({ identifier }: Touch): number {
9794
return identifier;
9895
}
9996

100-
function recordTouchStart(touch: Touch): void {
97+
function recordTouchStart(touch: Touch, touchHistory): void {
10198
const identifier = getTouchIdentifier(touch);
102-
const touchRecord = touchBank[identifier];
99+
const touchRecord = touchHistory.touchBank[identifier];
103100
if (touchRecord) {
104101
resetTouchRecord(touchRecord, touch);
105102
} else {
106-
touchBank[identifier] = createTouchRecord(touch);
103+
touchHistory.touchBank[identifier] = createTouchRecord(touch);
107104
}
108105
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
109106
}
110107

111-
function recordTouchMove(touch: Touch): void {
112-
const touchRecord = touchBank[getTouchIdentifier(touch)];
108+
function recordTouchMove(touch: Touch, touchHistory): void {
109+
const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
113110
if (touchRecord) {
114111
touchRecord.touchActive = true;
115112
touchRecord.previousPageX = touchRecord.currentPageX;
@@ -123,13 +120,13 @@ function recordTouchMove(touch: Touch): void {
123120
console.warn(
124121
'Cannot record touch move without a touch start.\n',
125122
`Touch Move: ${printTouch(touch)}\n`,
126-
`Touch Bank: ${printTouchBank()}`
123+
`Touch Bank: ${printTouchBank(touchHistory)}`
127124
);
128125
}
129126
}
130127

131-
function recordTouchEnd(touch: Touch): void {
132-
const touchRecord = touchBank[getTouchIdentifier(touch)];
128+
function recordTouchEnd(touch: Touch, touchHistory): void {
129+
const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
133130
if (touchRecord) {
134131
touchRecord.touchActive = false;
135132
touchRecord.previousPageX = touchRecord.currentPageX;
@@ -143,7 +140,7 @@ function recordTouchEnd(touch: Touch): void {
143140
console.warn(
144141
'Cannot record touch end without a touch start.\n',
145142
`Touch End: ${printTouch(touch)}\n`,
146-
`Touch Bank: ${printTouchBank()}`
143+
`Touch Bank: ${printTouchBank(touchHistory)}`
147144
);
148145
}
149146
}
@@ -157,29 +154,48 @@ function printTouch(touch: Touch): string {
157154
});
158155
}
159156

160-
function printTouchBank(): string {
157+
function printTouchBank(touchHistory): string {
158+
const { touchBank } = touchHistory;
161159
let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
162160
if (touchBank.length > MAX_TOUCH_BANK) {
163161
printed += ' (original size: ' + touchBank.length + ')';
164162
}
165163
return printed;
166164
}
167165

168-
const ResponderTouchHistoryStore = {
166+
export class ResponderTouchHistoryStore {
167+
_touchHistory = {
168+
touchBank: [], //Array<TouchRecord>
169+
numberActiveTouches: 0,
170+
// If there is only one active touch, we remember its location. This prevents
171+
// us having to loop through all of the touches all the time in the most
172+
// common case.
173+
indexOfSingleActiveTouch: -1,
174+
mostRecentTimeStamp: 0
175+
};
176+
169177
recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void {
178+
const touchHistory = this._touchHistory;
170179
if (isMoveish(topLevelType)) {
171-
nativeEvent.changedTouches.forEach(recordTouchMove);
180+
nativeEvent.changedTouches.forEach((touch) =>
181+
recordTouchMove(touch, touchHistory)
182+
);
172183
} else if (isStartish(topLevelType)) {
173-
nativeEvent.changedTouches.forEach(recordTouchStart);
184+
nativeEvent.changedTouches.forEach((touch) =>
185+
recordTouchStart(touch, touchHistory)
186+
);
174187
touchHistory.numberActiveTouches = nativeEvent.touches.length;
175188
if (touchHistory.numberActiveTouches === 1) {
176189
touchHistory.indexOfSingleActiveTouch =
177190
nativeEvent.touches[0].identifier;
178191
}
179192
} else if (isEndish(topLevelType)) {
180-
nativeEvent.changedTouches.forEach(recordTouchEnd);
193+
nativeEvent.changedTouches.forEach((touch) =>
194+
recordTouchEnd(touch, touchHistory)
195+
);
181196
touchHistory.numberActiveTouches = nativeEvent.touches.length;
182197
if (touchHistory.numberActiveTouches === 1) {
198+
const { touchBank } = touchHistory;
183199
for (let i = 0; i < touchBank.length; i++) {
184200
const touchTrackToCheck = touchBank[i];
185201
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
@@ -195,9 +211,9 @@ const ResponderTouchHistoryStore = {
195211
}
196212
}
197213
}
198-
},
199-
200-
touchHistory
201-
};
214+
}
202215

203-
export default ResponderTouchHistoryStore;
216+
get touchHistory(): TouchHistory {
217+
return this._touchHistory;
218+
}
219+
}

packages/react-native-web/src/modules/useResponderEvents/createResponderEvent.js

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
* @flow
88
*/
99

10+
import type {
11+
ResponderTouchHistoryStore,
12+
TouchHistory
13+
} from './ResponderTouchHistoryStore';
1014
import type { TouchEvent } from './ResponderEventTypes';
1115

1216
import getBoundingClientRect from '../../modules/getBoundingClientRect';
13-
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
1417

1518
export type ResponderEvent = {|
1619
bubbles: boolean,
@@ -34,23 +37,7 @@ export type ResponderEvent = {|
3437
persist: () => void,
3538
target: ?any,
3639
timeStamp: number,
37-
touchHistory: $ReadOnly<{|
38-
indexOfSingleActiveTouch: number,
39-
mostRecentTimeStamp: number,
40-
numberActiveTouches: number,
41-
touchBank: Array<{|
42-
currentPageX: number,
43-
currentPageY: number,
44-
currentTimeStamp: number,
45-
previousPageX: number,
46-
previousPageY: number,
47-
previousTimeStamp: number,
48-
startPageX: number,
49-
startPageY: number,
50-
startTimeStamp: number,
51-
touchActive: boolean
52-
|}>
53-
|}>
40+
touchHistory: TouchHistory
5441
|};
5542

5643
const emptyFunction = () => {};
@@ -70,7 +57,10 @@ function normalizeIdentifier(identifier) {
7057
* Converts a native DOM event to a ResponderEvent.
7158
* Mouse events are transformed into fake touch events.
7259
*/
73-
export default function createResponderEvent(domEvent: any): ResponderEvent {
60+
export default function createResponderEvent(
61+
domEvent: any,
62+
responderTouchHistoryStore: ResponderTouchHistoryStore
63+
): ResponderEvent {
7464
let rect;
7565
let propagationWasStopped = false;
7666
let changedTouches;
@@ -193,7 +183,7 @@ export default function createResponderEvent(domEvent: any): ResponderEvent {
193183
},
194184
target: domEvent.target,
195185
timeStamp: timestamp,
196-
touchHistory: ResponderTouchHistoryStore.touchHistory
186+
touchHistory: responderTouchHistoryStore.touchHistory
197187
};
198188

199189
// Using getters and functions serves two purposes:

0 commit comments

Comments
 (0)