This repository has been archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(interaction): added service to detect last interaction
- Loading branch information
1 parent
317c1c8
commit e9faf66
Showing
5 changed files
with
211 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
angular | ||
.module('material.core.interaction', []) | ||
.service('$mdInteraction', MdInteractionService); | ||
|
||
/* | ||
* @ngdoc service | ||
* @name $mdInteraction | ||
* @module material.core.interaction | ||
* | ||
* @description | ||
* | ||
* Service which keeps track of the last interaction type and validates them for several browsers. | ||
* The service hooks into the document's body and listens for touch, mouse and keyboard events. | ||
* | ||
* The last interaction type can be retrieved by using the `getLastInteractionType` method, which returns | ||
* the following possible values: | ||
* - `touch` | ||
* - `mouse` | ||
* - `keyboard` | ||
* | ||
* Here is an example markup for using the interaction service. | ||
* ``` | ||
* var lastType = $mdInteraction.getLastInteractionType(); | ||
* if (lastType === 'keyboard') { | ||
* restoreFocus(); | ||
* }} | ||
* ``` | ||
* | ||
*/ | ||
function MdInteractionService($timeout) { | ||
var body = angular.element(document.body); | ||
var mouseEvent = window.MSPointerEvent ? 'MSPointerDown' : window.PointerEvent ? 'pointerdown' : 'mousedown'; | ||
var buffer = false; | ||
var timer; | ||
var lastInteractionType; | ||
|
||
// Type Mappings for the different events | ||
// There will be three three interaction types | ||
// `keyboard`, `mouse` and `touch` | ||
// type `pointer` will be evaluated in `pointerMap` for IE Browser events | ||
var inputMap = { | ||
'keydown': 'keyboard', | ||
'mousedown': 'mouse', | ||
'mouseenter': 'mouse', | ||
'touchstart': 'touch', | ||
'pointerdown': 'pointer', | ||
'MSPointerDown': 'pointer' | ||
}; | ||
|
||
// IE PointerDown events will be validated in `touch` or `mouse` | ||
// Index numbers referenced here: https://msdn.microsoft.com/library/windows/apps/hh466130.aspx | ||
var pointerMap = { | ||
2: 'touch', | ||
3: 'touch', | ||
4: 'mouse' | ||
}; | ||
|
||
function onInput(event) { | ||
if (buffer) return; | ||
var type = inputMap[event.type]; | ||
if (type === 'pointer') { | ||
type = (typeof event.pointerType === 'number') ? pointerMap[event.pointerType] : event.pointerType; | ||
} | ||
lastInteractionType = type; | ||
} | ||
|
||
function onBufferInput(event) { | ||
$timeout.cancel(timer); | ||
|
||
onInput(event); | ||
buffer = true; | ||
|
||
// The timeout of 650ms is needed to delay the touchstart, because otherwise the touch will call | ||
// the `onInput` function multiple times. | ||
timer = $timeout(function() { | ||
buffer = false; | ||
}, 650); | ||
} | ||
|
||
body.on('keydown', onInput); | ||
body.on(mouseEvent, onInput); | ||
body.on('mouseenter', onInput); | ||
if ('ontouchstart' in document.documentElement) { | ||
body.on('touchstart', onBufferInput); | ||
} | ||
|
||
/** | ||
* Gets the last interaction type triggered in body. | ||
* Possible return values are `mouse`, `keyboard` and `touch` | ||
* @returns {string} | ||
*/ | ||
this.getLastInteractionType = function() { | ||
return lastInteractionType; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
describe("$mdInteraction service", function() { | ||
var $mdInteraction; | ||
|
||
beforeEach(module('material.core')); | ||
|
||
beforeEach(inject(function(_$mdInteraction_) { | ||
$mdInteraction = _$mdInteraction_; | ||
})); | ||
|
||
describe("last interaction type", function() { | ||
|
||
it("imitates a basic keyboard interaction and checks it", function() { | ||
|
||
var event = document.createEvent('Event'); | ||
event.keyCode = 37; | ||
event.initEvent('keydown', false, true); | ||
document.body.dispatchEvent(event); | ||
|
||
expect($mdInteraction.getLastInteractionType()).toBe('keyboard'); | ||
}); | ||
|
||
it("dispatches a mousedown event on the document body and checks it", function() { | ||
|
||
var event = document.createEvent("MouseEvent"); | ||
event.initMouseEvent("mousedown", true, true, window, null, 0, 0, 0, 0, false, false, false, false, 0, null); | ||
document.body.dispatchEvent(event); | ||
|
||
expect($mdInteraction.getLastInteractionType()).toBe("mouse"); | ||
}); | ||
|
||
}); | ||
}); |