Skip to content

Commit

Permalink
[added] convertTouchEventsToPointerEvents(touchEvent$)
Browse files Browse the repository at this point in the history
Summary: Closes #211

Reviewers: O2 Material Motion, O3 Material JavaScript platform reviewers, #material_motion, featherless

Reviewed By: O2 Material Motion, #material_motion, featherless

Tags: #material_motion

Differential Revision: http://codereview.cc/D3120
  • Loading branch information
appsforartists committed Apr 27, 2017
1 parent b820142 commit 8d9a3d3
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export type Point2D = {
export type PartialPointerEvent = {
pageX: number;
pageY: number;
pointerId: number;
pointerId?: number; // Can be undefined for MouseEvent
type: 'pointerdown' | 'pointermove' | 'pointerup';
};

Expand Down
3 changes: 3 additions & 0 deletions packages/views-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"material-motion": "0.0.0",
"tslib": "^1.2.0"
},
"devDependencies": {
"material-motion-testing-utils": "0.0.0"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com:material-motion/material-motion-js.git"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/** @license
* Copyright 2016 - present The Material Motion Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import { expect } from 'chai';

import {
beforeEach,
describe,
it,
} from 'mocha-sugar-free';

import {
stub,
} from 'sinon';

declare function require(name: string);

// chai really doesn't like being imported as an ES2015 module; will be fixed in v4
require('chai').use(
require('sinon-chai')
);

import {
createMockObserver,
} from 'material-motion-testing-utils';

import {
MotionObservable,
} from 'material-motion';

import {
convertTouchEventsToPointerEvents,
} from '../convertTouchEventsToPointerEvents';

describe('convertTouchEventsToPointerEvents',
() => {
let stream;
let mockObserver;
let listener;

beforeEach(
() => {
mockObserver = createMockObserver();
stream = convertTouchEventsToPointerEvents(
new MotionObservable(mockObserver.connect)
);
listener = stub();
}
);

it('should dispatch partial pointer events for all the targetTouches in a TouchEvent',
() => {
stream.subscribe(listener);

mockObserver.next({
type: 'touchstart',
targetTouches: [
{
pageX: 0,
pageY: 0,
identifier: 3424080648,
},
{
pageX: 10,
pageY: 20,
identifier: 3424080649,
},
]
});

expect(listener).to.have.been.calledTwice
.and.to.have.been.calledWith({
pageX: 0,
pageY: 0,
pointerId: 3424080648,
type: 'pointerdown',
}).and.to.have.been.calledWith({
pageX: 10,
pageY: 20,
pointerId: 3424080649,
type: 'pointerdown',
});
}
);

it('should dispatch pointerdown for touchstart',
() => {
stream.subscribe(listener);

mockObserver.next({
type: 'touchstart',
targetTouches: [
{
pageX: 0,
pageY: 0,
identifier: 3424080648,
},
]
});

expect(listener).to.have.been.calledWith({
pageX: 0,
pageY: 0,
pointerId: 3424080648,
type: 'pointerdown',
});
}
);

it('should dispatch pointermove for touchmove',
() => {
stream.subscribe(listener);

mockObserver.next({
type: 'touchmove',
targetTouches: [
{
pageX: 0,
pageY: 0,
identifier: 3424080648,
},
]
});

expect(listener).to.have.been.calledWith({
pageX: 0,
pageY: 0,
pointerId: 3424080648,
type: 'pointermove',
});
}
);

it('should dispatch pointerup for touchend',
() => {
stream.subscribe(listener);

mockObserver.next({
type: 'touchend',
changedTouches: [
{
pageX: 0,
pageY: 0,
identifier: 3424080648,
},
]
});

expect(listener).to.have.been.calledWith({
pageX: 0,
pageY: 0,
pointerId: 3424080648,
type: 'pointerup',
});
}
);

it('should dispatch pointercancel for touchcancel',
() => {
stream.subscribe(listener);

mockObserver.next({
type: 'touchcancel',
targetTouches: [
{
pageX: 0,
pageY: 0,
identifier: 3424080648,
},
]
});

expect(listener).to.have.been.calledWith({
pageX: 0,
pageY: 0,
pointerId: 3424080648,
type: 'pointercancel',
});
}
);

// test touch start/end/cancel
}
);
50 changes: 50 additions & 0 deletions packages/views-dom/src/convertTouchEventsToPointerEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/** @license
* Copyright 2016 - present The Material Motion Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import {
Dict,
MotionObservable,
PartialPointerEvent,
} from 'material-motion';

// TouchEvent types from https://developer.apple.com/reference/webkitjs/touchevent/
// PointerEvent types from https://w3c.github.io/pointerevents/
const TOUCH_TYPE_TO_POINTER_TYPE: Dict<string> = {
'touchstart': 'pointerdown',
'touchmove': 'pointermove',
'touchend': 'pointerup',
'touchcancel': 'pointercancel',
};

export function convertTouchEventsToPointerEvents(touchEvent$: MotionObservable<TouchEvent>): MotionObservable<PartialPointerEvent> {
return touchEvent$._map(
({ type, targetTouches, changedTouches }: TouchEvent) => Array.from(
type === 'touchend'
? changedTouches
: targetTouches
).map(
({ pageX, pageY, identifier }: Touch) => (
{
pageX,
pageY,
pointerId: identifier,
type: TOUCH_TYPE_TO_POINTER_TYPE[type]
}
)
)
)._flattenIterables();
}
export default convertTouchEventsToPointerEvents;

0 comments on commit 8d9a3d3

Please sign in to comment.