Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngClick): subract processing time of the click action #13447

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/ngTouch/directive/ngClick.js
Expand Up @@ -57,6 +57,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',

var ACTIVE_CLASS_NAME = 'ng-click-active';
var lastPreventedTime;
var processingTime;
var touchCoordinates;
var lastLabelClickCoordinates;

Expand Down Expand Up @@ -121,7 +122,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
// Global click handler that prevents the click if it's in a bustable zone and preventGhostClick
// was called recently.
function onClick(event) {
if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
if (Date.now() - lastPreventedTime - processingTime > PREVENT_DURATION) {
return; // Too old.
}

Expand Down Expand Up @@ -197,6 +198,14 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
checkAllowableRegions(touchCoordinates, x, y);
}

function calculateProcessingTime() {
//use the now - last prevented time on a timeout
processingTime = 0;
$timeout(function() {
processingTime = Date.now() - lastPreventedTime;
}, 0);
}

// Actual linking function.
return function(scope, element, attr) {
var clickHandler = $parse(attr.ngClick),
Expand Down Expand Up @@ -251,6 +260,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
// Call preventGhostClick so the clickbuster will catch the corresponding click.
preventGhostClick(x, y);
calculateProcessingTime();

// Blur the focused element (the button, probably) before firing the callback.
// This doesn't work perfectly on Android Chrome, but seems to work elsewhere.
Expand Down
79 changes: 79 additions & 0 deletions test/ngTouch/directive/ngClickSpec.js
Expand Up @@ -233,6 +233,85 @@ describe('ngClick (touch)', function() {
}));


it('should cancel the following click event with long running processes', inject(function($rootScope, $compile, $rootElement, $timeout) {
//we need the real date now function for really getting the time... to really test the timeout...
Date.now = orig_now;
var count = 0;
var done = false;

$rootScope.slowCount = function() {
var start = Date.now();
var now = Date.now();
//must wait longer than the PREVENT_DURATION
while (now - start < 3000) {
now = Date.now();
}
count++;
};

element = $compile('<div ng-click="slowCount()"></div>')($rootScope);
$rootElement.append(element);

$rootScope.$digest();

expect(count).toBe(0);

// Fire touchstart at 10ms, touchend at 50ms, the click at 300ms.
runs(function() {
setTimeout(function() {
browserTrigger(element, 'touchstart', {
keys: [],
x: 10,
y: 10
});
try {
$timeout.verifyNoPendingTasks();
} catch (e) {
$timeout.flush();
}
}, 10);

setTimeout(function() {
browserTrigger(element, 'touchend', {
keys: [],
x: 10,
y: 10
});
try {
$timeout.verifyNoPendingTasks();
} catch (e) {
$timeout.flush();
}

expect(count).toBe(1);
}, 50);

setTimeout(function() {
browserTrigger(element, 'click', {
keys: [],
x: 10,
y: 10
});
try {
$timeout.verifyNoPendingTasks();
} catch (e) {
$timeout.flush();
}
done = true;
}, 300);

});

waitsFor(function() {
return done;
}, "click event to fire", 500);

runs(function() {
expect(count).toEqual(1);
});
}));


it('should cancel the following click event even when the element has changed', inject(
function($rootScope, $compile, $rootElement) {
$rootElement.append(
Expand Down