Commit 1874d9f5 authored by Robert Knight's avatar Robert Knight

Focus Annotation / Notes tabs on tap or mouse down

Focus the Annotation and Notes tabs on touch or mouse down rather than
click.

This makes the tabs act more like tabs in native apps and feel more
responsive.

Since Angular does not provide a built-in attribute directive for
handling touch events, implement a custom one.
parent ff2ae2ba
...@@ -135,6 +135,7 @@ module.exports = angular.module('h', [ ...@@ -135,6 +135,7 @@ module.exports = angular.module('h', [
.directive('helpLink', require('./directive/help-link')) .directive('helpLink', require('./directive/help-link'))
.directive('helpPanel', require('./directive/help-panel')) .directive('helpPanel', require('./directive/help-panel'))
.directive('hAutofocus', require('./directive/h-autofocus')) .directive('hAutofocus', require('./directive/h-autofocus'))
.directive('hOnTouch', require('./directive/h-on-touch'))
.directive('hTooltip', require('./directive/h-tooltip')) .directive('hTooltip', require('./directive/h-tooltip'))
.directive('loggedoutMessage', require('./directive/loggedout-message')) .directive('loggedoutMessage', require('./directive/loggedout-message'))
.directive('loginControl', require('./directive/login-control')) .directive('loginControl', require('./directive/login-control'))
......
'use strict';
/**
* Install an event handler on an element.
*
* The event handler follows the same behavior as the ng-<event name>
* directives that Angular includes. This means:
*
* - The handler function is passed an object with an $event property
* - The handler function is executed in the context of `$scope.$apply()`
*
* @param {Element} element
* @param {Array<string>} events
* @param {Function} handler
*/
function addEventHandler($scope, element, events, handler) {
var callback = function (event) {
$scope.$apply(function () {
handler($scope, {$event: event});
});
};
events.forEach(function (name) {
element.addEventListener(name, callback);
});
}
/**
* A directive which adds an event handler for mouse press or touch to
* a directive. This is similar to `ng-click` etc. but reacts either on
* mouse press OR touch.
*/
// @ngInject
module.exports = function ($parse) {
return {
restrict: 'A',
link: function ($scope, $element, $attrs) {
var fn = $parse($attrs.hOnTouch, null /* interceptor */);
addEventHandler(
$scope,
$element[0],
['click', 'mousedown', 'touchstart'],
fn
);
},
};
};
...@@ -7,7 +7,7 @@ module.exports = function () { ...@@ -7,7 +7,7 @@ module.exports = function () {
bindToController: true, bindToController: true,
controllerAs: 'vm', controllerAs: 'vm',
//@ngInject //@ngInject
controller: function (annotationUI) { controller: function ($element, annotationUI) {
this.TAB_ANNOTATIONS = uiConstants.TAB_ANNOTATIONS; this.TAB_ANNOTATIONS = uiConstants.TAB_ANNOTATIONS;
this.TAB_NOTES = uiConstants.TAB_NOTES; this.TAB_NOTES = uiConstants.TAB_NOTES;
......
'use strict';
var angular = require('angular');
var unroll = require('../../test/util').unroll;
var util = require('./util');
function testComponent() {
return {
bindToController: true,
controllerAs: 'vm',
controller: function () {
this.tapCount = 0;
this.tap = function () {
++this.tapCount;
};
},
restrict: 'E',
template: '<div h-on-touch="vm.tap()">Tap me</div>',
};
}
describe('hOnTouch', function () {
var testEl;
before(function () {
angular.module('app', [])
.directive('hOnTouch', require('../h-on-touch'))
.directive('test', testComponent);
});
beforeEach(function () {
angular.mock.module('app');
testEl = util.createDirective(document, 'test', {});
});
unroll('calls the handler when activated with a "#event" event', function (testCase) {
util.sendEvent(testEl[0].querySelector('div'), testCase.event);
assert.equal(testEl.ctrl.tapCount, 1);
},[{
event: 'touchstart',
},{
event: 'mousedown',
},{
event: 'click',
}]);
});
<!-- Tabbed display of annotations and notes. --> <!-- Tabbed display of annotations and notes. -->
<ul class="selection-tabs"> <ul class="selection-tabs">
<li class="selection-tabs__type" ng-class="{'selection-tabs--selected': vm.selectedTab === vm.TAB_ANNOTATIONS}" ng-click="vm.selectTab('annotation')"> <li class="selection-tabs__type"
ng-class="{'selection-tabs--selected': vm.selectedTab === vm.TAB_ANNOTATIONS}"
h-on-touch="vm.selectTab('annotation')">
Annotations Annotations
<span class="selection-tabs__count" ng-if="vm.totalAnnotations > 0">{{ vm.totalAnnotations }}</sup> <span class="selection-tabs__count" ng-if="vm.totalAnnotations > 0">{{ vm.totalAnnotations }}</sup>
</li> </li>
<li class="selection-tabs__type" ng-class="{'selection-tabs--selected': vm.selectedTab === vm.TAB_NOTES}" ng-click="vm.selectTab('note')"> <li class="selection-tabs__type"
ng-class="{'selection-tabs--selected': vm.selectedTab === vm.TAB_NOTES}"
h-on-touch="vm.selectTab('note')">
Notes Notes
<span class="selection-tabs__count" ng-if="vm.totalNotes > 0">{{ vm.totalNotes }}</sup> <span class="selection-tabs__count" ng-if="vm.totalNotes > 0">{{ vm.totalNotes }}</sup>
</li> </li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment