mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-08 04:31:19 +00:00
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
This commit is contained in:
committed by
Nicolas Gallagher
parent
32a4bf8e51
commit
bbffe86fd6
+8
-4
@@ -150,7 +150,7 @@ import {
|
|||||||
isPrimaryPointerDown,
|
isPrimaryPointerDown,
|
||||||
setResponderId
|
setResponderId
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
|
import { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore';
|
||||||
import canUseDOM from '../canUseDom';
|
import canUseDOM from '../canUseDom';
|
||||||
|
|
||||||
/* ------------ TYPES ------------ */
|
/* ------------ TYPES ------------ */
|
||||||
@@ -232,6 +232,7 @@ let currentResponder: ResponderInstance = {
|
|||||||
node: null,
|
node: null,
|
||||||
idPath: null
|
idPath: null
|
||||||
};
|
};
|
||||||
|
const responderTouchHistoryStore = new ResponderTouchHistoryStore();
|
||||||
|
|
||||||
function changeCurrentResponder(responder: ResponderInstance) {
|
function changeCurrentResponder(responder: ResponderInstance) {
|
||||||
currentResponder = responder;
|
currentResponder = responder;
|
||||||
@@ -294,7 +295,10 @@ function eventListener(domEvent: any) {
|
|||||||
const isEndEvent = isEndish(eventType);
|
const isEndEvent = isEndish(eventType);
|
||||||
const isScrollEvent = isScroll(eventType);
|
const isScrollEvent = isScroll(eventType);
|
||||||
const isSelectionChangeEvent = isSelectionChange(eventType);
|
const isSelectionChangeEvent = isSelectionChange(eventType);
|
||||||
const responderEvent = createResponderEvent(domEvent);
|
const responderEvent = createResponderEvent(
|
||||||
|
domEvent,
|
||||||
|
responderTouchHistoryStore
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record the state of active pointers
|
* Record the state of active pointers
|
||||||
@@ -310,7 +314,7 @@ function eventListener(domEvent: any) {
|
|||||||
trackedTouchCount = 0;
|
trackedTouchCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponderTouchHistoryStore.recordTouchTrack(
|
responderTouchHistoryStore.recordTouchTrack(
|
||||||
eventType,
|
eventType,
|
||||||
responderEvent.nativeEvent
|
responderEvent.nativeEvent
|
||||||
);
|
);
|
||||||
@@ -665,7 +669,7 @@ export function terminateResponder() {
|
|||||||
if (id != null && node != null) {
|
if (id != null && node != null) {
|
||||||
const { onResponderTerminate } = getResponderConfig(id);
|
const { onResponderTerminate } = getResponderConfig(id);
|
||||||
if (onResponderTerminate != null) {
|
if (onResponderTerminate != null) {
|
||||||
const event = createResponderEvent({});
|
const event = createResponderEvent({}, responderTouchHistoryStore);
|
||||||
event.currentTarget = node;
|
event.currentTarget = node;
|
||||||
onResponderTerminate(event);
|
onResponderTerminate(event);
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-34
@@ -11,18 +11,25 @@ import type { Touch, TouchEvent } from './ResponderEventTypes';
|
|||||||
import { isStartish, isMoveish, isEndish } from './ResponderEventTypes';
|
import { isStartish, isMoveish, isEndish } from './ResponderEventTypes';
|
||||||
|
|
||||||
type TouchRecord = {|
|
type TouchRecord = {|
|
||||||
touchActive: boolean,
|
|
||||||
startPageX: number,
|
|
||||||
startPageY: number,
|
|
||||||
startTimeStamp: number,
|
|
||||||
currentPageX: number,
|
currentPageX: number,
|
||||||
currentPageY: number,
|
currentPageY: number,
|
||||||
currentTimeStamp: number,
|
currentTimeStamp: number,
|
||||||
previousPageX: number,
|
previousPageX: number,
|
||||||
previousPageY: number,
|
previousPageY: number,
|
||||||
previousTimeStamp: number
|
previousTimeStamp: number,
|
||||||
|
startPageX: number,
|
||||||
|
startPageY: number,
|
||||||
|
startTimeStamp: number,
|
||||||
|
touchActive: boolean
|
||||||
|};
|
|};
|
||||||
|
|
||||||
|
export type TouchHistory = $ReadOnly<{|
|
||||||
|
indexOfSingleActiveTouch: number,
|
||||||
|
mostRecentTimeStamp: number,
|
||||||
|
numberActiveTouches: number,
|
||||||
|
touchBank: Array<TouchRecord>
|
||||||
|
|}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks the position and time of each active touch by `touch.identifier`. We
|
* Tracks the position and time of each active touch by `touch.identifier`. We
|
||||||
* should typically only see IDs in the range of 1-20 because IDs get recycled
|
* should typically only see IDs in the range of 1-20 because IDs get recycled
|
||||||
@@ -31,16 +38,6 @@ type TouchRecord = {|
|
|||||||
|
|
||||||
const __DEV__ = process.env.NODE_ENV !== 'production';
|
const __DEV__ = process.env.NODE_ENV !== 'production';
|
||||||
const MAX_TOUCH_BANK = 20;
|
const MAX_TOUCH_BANK = 20;
|
||||||
const touchBank: Array<TouchRecord> = [];
|
|
||||||
const touchHistory = {
|
|
||||||
touchBank,
|
|
||||||
numberActiveTouches: 0,
|
|
||||||
// If there is only one active touch, we remember its location. This prevents
|
|
||||||
// us having to loop through all of the touches all the time in the most
|
|
||||||
// common case.
|
|
||||||
indexOfSingleActiveTouch: -1,
|
|
||||||
mostRecentTimeStamp: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
function timestampForTouch(touch: Touch): number {
|
function timestampForTouch(touch: Touch): number {
|
||||||
// The legacy internal implementation provides "timeStamp", which has been
|
// The legacy internal implementation provides "timeStamp", which has been
|
||||||
@@ -97,19 +94,19 @@ function getTouchIdentifier({ identifier }: Touch): number {
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordTouchStart(touch: Touch): void {
|
function recordTouchStart(touch: Touch, touchHistory): void {
|
||||||
const identifier = getTouchIdentifier(touch);
|
const identifier = getTouchIdentifier(touch);
|
||||||
const touchRecord = touchBank[identifier];
|
const touchRecord = touchHistory.touchBank[identifier];
|
||||||
if (touchRecord) {
|
if (touchRecord) {
|
||||||
resetTouchRecord(touchRecord, touch);
|
resetTouchRecord(touchRecord, touch);
|
||||||
} else {
|
} else {
|
||||||
touchBank[identifier] = createTouchRecord(touch);
|
touchHistory.touchBank[identifier] = createTouchRecord(touch);
|
||||||
}
|
}
|
||||||
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordTouchMove(touch: Touch): void {
|
function recordTouchMove(touch: Touch, touchHistory): void {
|
||||||
const touchRecord = touchBank[getTouchIdentifier(touch)];
|
const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
|
||||||
if (touchRecord) {
|
if (touchRecord) {
|
||||||
touchRecord.touchActive = true;
|
touchRecord.touchActive = true;
|
||||||
touchRecord.previousPageX = touchRecord.currentPageX;
|
touchRecord.previousPageX = touchRecord.currentPageX;
|
||||||
@@ -123,13 +120,13 @@ function recordTouchMove(touch: Touch): void {
|
|||||||
console.warn(
|
console.warn(
|
||||||
'Cannot record touch move without a touch start.\n',
|
'Cannot record touch move without a touch start.\n',
|
||||||
`Touch Move: ${printTouch(touch)}\n`,
|
`Touch Move: ${printTouch(touch)}\n`,
|
||||||
`Touch Bank: ${printTouchBank()}`
|
`Touch Bank: ${printTouchBank(touchHistory)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordTouchEnd(touch: Touch): void {
|
function recordTouchEnd(touch: Touch, touchHistory): void {
|
||||||
const touchRecord = touchBank[getTouchIdentifier(touch)];
|
const touchRecord = touchHistory.touchBank[getTouchIdentifier(touch)];
|
||||||
if (touchRecord) {
|
if (touchRecord) {
|
||||||
touchRecord.touchActive = false;
|
touchRecord.touchActive = false;
|
||||||
touchRecord.previousPageX = touchRecord.currentPageX;
|
touchRecord.previousPageX = touchRecord.currentPageX;
|
||||||
@@ -143,7 +140,7 @@ function recordTouchEnd(touch: Touch): void {
|
|||||||
console.warn(
|
console.warn(
|
||||||
'Cannot record touch end without a touch start.\n',
|
'Cannot record touch end without a touch start.\n',
|
||||||
`Touch End: ${printTouch(touch)}\n`,
|
`Touch End: ${printTouch(touch)}\n`,
|
||||||
`Touch Bank: ${printTouchBank()}`
|
`Touch Bank: ${printTouchBank(touchHistory)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +154,8 @@ function printTouch(touch: Touch): string {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function printTouchBank(): string {
|
function printTouchBank(touchHistory): string {
|
||||||
|
const { touchBank } = touchHistory;
|
||||||
let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
|
let printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
|
||||||
if (touchBank.length > MAX_TOUCH_BANK) {
|
if (touchBank.length > MAX_TOUCH_BANK) {
|
||||||
printed += ' (original size: ' + touchBank.length + ')';
|
printed += ' (original size: ' + touchBank.length + ')';
|
||||||
@@ -165,21 +163,39 @@ function printTouchBank(): string {
|
|||||||
return printed;
|
return printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResponderTouchHistoryStore = {
|
export class ResponderTouchHistoryStore {
|
||||||
|
_touchHistory = {
|
||||||
|
touchBank: [], //Array<TouchRecord>
|
||||||
|
numberActiveTouches: 0,
|
||||||
|
// If there is only one active touch, we remember its location. This prevents
|
||||||
|
// us having to loop through all of the touches all the time in the most
|
||||||
|
// common case.
|
||||||
|
indexOfSingleActiveTouch: -1,
|
||||||
|
mostRecentTimeStamp: 0
|
||||||
|
};
|
||||||
|
|
||||||
recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void {
|
recordTouchTrack(topLevelType: string, nativeEvent: TouchEvent): void {
|
||||||
|
const touchHistory = this._touchHistory;
|
||||||
if (isMoveish(topLevelType)) {
|
if (isMoveish(topLevelType)) {
|
||||||
nativeEvent.changedTouches.forEach(recordTouchMove);
|
nativeEvent.changedTouches.forEach((touch) =>
|
||||||
|
recordTouchMove(touch, touchHistory)
|
||||||
|
);
|
||||||
} else if (isStartish(topLevelType)) {
|
} else if (isStartish(topLevelType)) {
|
||||||
nativeEvent.changedTouches.forEach(recordTouchStart);
|
nativeEvent.changedTouches.forEach((touch) =>
|
||||||
|
recordTouchStart(touch, touchHistory)
|
||||||
|
);
|
||||||
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
||||||
if (touchHistory.numberActiveTouches === 1) {
|
if (touchHistory.numberActiveTouches === 1) {
|
||||||
touchHistory.indexOfSingleActiveTouch =
|
touchHistory.indexOfSingleActiveTouch =
|
||||||
nativeEvent.touches[0].identifier;
|
nativeEvent.touches[0].identifier;
|
||||||
}
|
}
|
||||||
} else if (isEndish(topLevelType)) {
|
} else if (isEndish(topLevelType)) {
|
||||||
nativeEvent.changedTouches.forEach(recordTouchEnd);
|
nativeEvent.changedTouches.forEach((touch) =>
|
||||||
|
recordTouchEnd(touch, touchHistory)
|
||||||
|
);
|
||||||
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
||||||
if (touchHistory.numberActiveTouches === 1) {
|
if (touchHistory.numberActiveTouches === 1) {
|
||||||
|
const { touchBank } = touchHistory;
|
||||||
for (let i = 0; i < touchBank.length; i++) {
|
for (let i = 0; i < touchBank.length; i++) {
|
||||||
const touchTrackToCheck = touchBank[i];
|
const touchTrackToCheck = touchBank[i];
|
||||||
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
|
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
|
||||||
@@ -195,9 +211,9 @@ const ResponderTouchHistoryStore = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
touchHistory
|
get touchHistory(): TouchHistory {
|
||||||
};
|
return this._touchHistory;
|
||||||
|
}
|
||||||
export default ResponderTouchHistoryStore;
|
}
|
||||||
|
|||||||
+10
-20
@@ -7,10 +7,13 @@
|
|||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ResponderTouchHistoryStore,
|
||||||
|
TouchHistory
|
||||||
|
} from './ResponderTouchHistoryStore';
|
||||||
import type { TouchEvent } from './ResponderEventTypes';
|
import type { TouchEvent } from './ResponderEventTypes';
|
||||||
|
|
||||||
import getBoundingClientRect from '../../modules/getBoundingClientRect';
|
import getBoundingClientRect from '../../modules/getBoundingClientRect';
|
||||||
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
|
|
||||||
|
|
||||||
export type ResponderEvent = {|
|
export type ResponderEvent = {|
|
||||||
bubbles: boolean,
|
bubbles: boolean,
|
||||||
@@ -34,23 +37,7 @@ export type ResponderEvent = {|
|
|||||||
persist: () => void,
|
persist: () => void,
|
||||||
target: ?any,
|
target: ?any,
|
||||||
timeStamp: number,
|
timeStamp: number,
|
||||||
touchHistory: $ReadOnly<{|
|
touchHistory: TouchHistory
|
||||||
indexOfSingleActiveTouch: number,
|
|
||||||
mostRecentTimeStamp: number,
|
|
||||||
numberActiveTouches: number,
|
|
||||||
touchBank: Array<{|
|
|
||||||
currentPageX: number,
|
|
||||||
currentPageY: number,
|
|
||||||
currentTimeStamp: number,
|
|
||||||
previousPageX: number,
|
|
||||||
previousPageY: number,
|
|
||||||
previousTimeStamp: number,
|
|
||||||
startPageX: number,
|
|
||||||
startPageY: number,
|
|
||||||
startTimeStamp: number,
|
|
||||||
touchActive: boolean
|
|
||||||
|}>
|
|
||||||
|}>
|
|
||||||
|};
|
|};
|
||||||
|
|
||||||
const emptyFunction = () => {};
|
const emptyFunction = () => {};
|
||||||
@@ -70,7 +57,10 @@ function normalizeIdentifier(identifier) {
|
|||||||
* Converts a native DOM event to a ResponderEvent.
|
* Converts a native DOM event to a ResponderEvent.
|
||||||
* Mouse events are transformed into fake touch events.
|
* Mouse events are transformed into fake touch events.
|
||||||
*/
|
*/
|
||||||
export default function createResponderEvent(domEvent: any): ResponderEvent {
|
export default function createResponderEvent(
|
||||||
|
domEvent: any,
|
||||||
|
responderTouchHistoryStore: ResponderTouchHistoryStore
|
||||||
|
): ResponderEvent {
|
||||||
let rect;
|
let rect;
|
||||||
let propagationWasStopped = false;
|
let propagationWasStopped = false;
|
||||||
let changedTouches;
|
let changedTouches;
|
||||||
@@ -193,7 +183,7 @@ export default function createResponderEvent(domEvent: any): ResponderEvent {
|
|||||||
},
|
},
|
||||||
target: domEvent.target,
|
target: domEvent.target,
|
||||||
timeStamp: timestamp,
|
timeStamp: timestamp,
|
||||||
touchHistory: ResponderTouchHistoryStore.touchHistory
|
touchHistory: responderTouchHistoryStore.touchHistory
|
||||||
};
|
};
|
||||||
|
|
||||||
// Using getters and functions serves two purposes:
|
// Using getters and functions serves two purposes:
|
||||||
|
|||||||
Reference in New Issue
Block a user