Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 6fc9212

Browse files
SplaktarThomasBurleson
authored andcommitted
fix(mdTooltip): fix regression that broke tooltips on Firefox
Remove check for pointer-events not equal to none to resolve non-visible tooltips on Firefox. Add Chrome & Firefox as default test runners in karma task to avoid regressions like this in the future. Improve and automate use of ngAnimateMock Fixes #3047. Fixes #3250. Fixes #3430. Closes #3467.
1 parent ee60441 commit 6fc9212

File tree

14 files changed

+41
-33
lines changed

14 files changed

+41
-33
lines changed

config/karma.conf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ module.exports = function(config) {
6565
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
6666
// - PhantomJS
6767
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
68-
browsers: ['PhantomJS'],
68+
browsers: ['PhantomJS','Firefox'],
6969

7070
// you can define custom flags
7171
customLaunchers: {

gulp/tasks/karma-fast.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var util = require('../util');
44
var ROOT = require('../const').ROOT;
55
var args = util.args;
66

7-
// NOTE: `karma-fas` does NOT pre-make a full build of JS and CSS
7+
// NOTE: `karma-fast` does NOT pre-make a full build of JS and CSS
88
// exports.dependencies = ['build'];
99

1010
exports.task = function (done) {
@@ -19,6 +19,7 @@ exports.task = function (done) {
1919
if ( args.browsers ) {
2020
karmaConfig.browsers = args.browsers.trim().split(',');
2121
}
22+
// NOTE: `karma-fast` does NOT test Firefox by default.
2223

2324
gutil.log('Running unit tests on unminified source.');
2425
karma.start(karmaConfig, captureError(clearEnv,clearEnv));

gulp/tasks/karma.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ exports.task = function (done) {
3939

4040
if ( args.browsers ) {
4141
karmaConfig.browsers = args.browsers.trim().split(',');
42+
} else {
43+
karmaConfig.browsers = ['Firefox', 'PhantomJS'];
4244
}
4345

4446
gutil.log('Running unit tests on unminified source.');

src/components/bottomSheet/bottomSheet.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe('$mdBottomSheet service', function() {
2-
beforeEach(module('material.components.bottomSheet', 'ngAnimateMock'));
2+
beforeEach(module('material.components.bottomSheet'));
33

44
describe('#build()', function() {
55
it('should escapeToClose == true', inject(function($mdBottomSheet, $rootScope, $rootElement, $timeout, $animate, $mdConstant) {

src/components/dialog/dialog.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
describe('$mdDialog', function() {
22

3-
beforeEach(module('material.components.dialog', 'ngAnimateMock'));
3+
beforeEach(module('material.components.dialog'));
44

55
beforeEach(inject(function spyOnMdEffects($$q, $animate) {
66
spyOn($animate, 'leave').and.callFake(function(element) {
@@ -576,7 +576,7 @@ describe('$mdDialog', function() {
576576
});
577577

578578
describe('$mdDialog with custom interpolation symbols', function() {
579-
beforeEach(module('material.components.dialog', 'ngAnimateMock'));
579+
beforeEach(module('material.components.dialog'));
580580

581581
beforeEach(module(function($interpolateProvider) {
582582
$interpolateProvider.startSymbol('[[').endSymbol(']]');

src/components/menu/menu.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
describe('md-menu directive', function () {
22
var $mdMenu, $timeout, something;
33

4-
beforeEach(module('material.components.menu', 'ngAnimateMock'));
4+
beforeEach(module('material.components.menu'));
55
beforeEach(inject(function ($mdUtil, $$q, $document, _$mdMenu_, _$timeout_) {
66
$mdMenu = _$mdMenu_;
77
$timeout = _$timeout_;

src/components/select/select.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
describe('<md-select>', function() {
22

33
beforeEach(module('material.components.input'));
4-
beforeEach(module('material.components.select', 'ngAnimateMock'));
4+
beforeEach(module('material.components.select'));
55

66
beforeEach(inject(function($mdUtil, $$q) {
77
$mdUtil.transitionEndPromise = function() {

src/components/sidenav/sidenav.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe('mdSidenav', function() {
2-
beforeEach(module('material.components.sidenav', 'ngAnimateMock'));
2+
beforeEach(module('material.components.sidenav'));
33

44
function setup(attrs) {
55
var el;

src/components/toast/toast.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe('$mdToast service', function() {
2-
beforeEach(module('material.components.toast', 'ngAnimateMock', function($provide) {
2+
beforeEach(module('material.components.toast', function($provide) {
33
}));
44

55
function setup(options) {

src/components/tooltip/tooltip.js

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ angular
2929
*
3030
* @param {expression=} md-visible Boolean bound to whether the tooltip is
3131
* currently visible.
32-
* @param {number=} md-delay How many milliseconds to wait to show the tooltip after the user focuses, hovers, or touches the parent. Defaults to 400ms.
32+
* @param {number=} md-delay How many milliseconds to wait to show the tooltip after the user focuses, hovers, or touches the parent. Defaults to 300ms.
3333
* @param {string=} md-direction Which direction would you like the tooltip to go? Supports left, right, top, and bottom. Defaults to bottom.
3434
* @param {boolean=} md-autohide If present or provided with a boolean value, the tooltip will hide on mouse leave, regardless of focus
3535
*/
@@ -66,15 +66,14 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
6666
tooltipParent = angular.element(current || document.body),
6767
debouncedOnResize = $$rAF.throttle(function () { if (scope.visible) positionTooltip(); });
6868

69-
return init();
69+
// Initialize element
70+
71+
setDefaults();
72+
manipulateElement();
73+
bindEvents();
74+
configureWatchers();
75+
addAriaLabel();
7076

71-
function init () {
72-
setDefaults();
73-
manipulateElement();
74-
bindEvents();
75-
configureWatchers();
76-
addAriaLabel();
77-
}
7877

7978
function setDefaults () {
8079
if (!angular.isDefined(attr.mdDelay)) scope.delay = TOOLTIP_SHOW_DELAY;
@@ -103,9 +102,12 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
103102
element.attr('role', 'tooltip');
104103
}
105104

105+
/**
106+
* Scan up dom hierarchy for enabled parent;
107+
*/
106108
function getParentWithPointerEvents () {
107109
var parent = element.parent();
108-
while (parent && $window.getComputedStyle(parent[0])['pointer-events'] == 'none') {
110+
while (parent && hasComputedStyleValue('pointer-events','none', parent[0])) {
109111
parent = parent.parent();
110112
}
111113
return parent;
@@ -120,22 +122,26 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
120122
return current;
121123
}
122124

123-
function hasComputedStyleValue(key, value) {
124-
// Check if we should show it or not...
125-
var computedStyles = $window.getComputedStyle(element[0]);
126-
return angular.isDefined(computedStyles[key]) && (computedStyles[key] == value);
125+
126+
function hasComputedStyleValue(key, value, target) {
127+
key = attr.$normalize(key);
128+
target = target || element[0];
129+
130+
var computedStyles = $window.getComputedStyle(target);
131+
132+
return angular.isDefined(computedStyles[key]) && (computedStyles[key] == value);
127133
}
128134

129135
function bindEvents () {
130136
var mouseActive = false;
131137
var enterHandler = function() {
132-
if (!hasComputedStyleValue('pointer-events','none')) {
133-
setVisible(true);
134-
}
138+
parent.on('blur mouseleave touchend touchcancel', leaveHandler );
139+
setVisible(true);
135140
};
136141
var leaveHandler = function () {
137142
var autohide = scope.hasOwnProperty('autohide') ? scope.autohide : attr.hasOwnProperty('mdAutohide');
138143
if (autohide || mouseActive || ($document[0].activeElement !== parent[0]) ) {
144+
parent.off('blur mouseleave touchend touchcancel', leaveHandler );
139145
setVisible(false);
140146
}
141147
mouseActive = false;
@@ -144,7 +150,6 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
144150
// to avoid `synthetic clicks` we listen to mousedown instead of `click`
145151
parent.on('mousedown', function() { mouseActive = true; });
146152
parent.on('focus mouseenter touchstart', enterHandler );
147-
parent.on('blur mouseleave touchend touchcancel', leaveHandler );
148153

149154

150155
angular.element($window).on('resize', debouncedOnResize);

src/components/tooltip/tooltip.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ describe('<md-tooltip> directive', function() {
22
var $compile, $rootScope, $animate, $timeout;
33
var element;
44

5-
beforeEach(module('material.components.tooltip', 'ngAnimateMock'));
5+
beforeEach(module('material.components.tooltip'));
66
beforeEach(inject(function(_$compile_, _$rootScope_, _$animate_, _$timeout_){
77
$compile = _$compile_;
88
$rootScope = _$rootScope_;
@@ -75,7 +75,7 @@ describe('<md-tooltip> directive', function() {
7575
$timeout.flush(98);
7676
expect($rootScope.isVisible).toBeFalsy();
7777

78-
// Total 99 == tooltipDelay
78+
// Total 300 == tooltipDelay
7979
$timeout.flush(1);
8080
expect($rootScope.isVisible).toBe(true);
8181

@@ -170,7 +170,7 @@ describe('<md-tooltip> directive', function() {
170170
'Tooltip' +
171171
'</md-tooltip>' +
172172
'</md-button>'
173-
)
173+
);
174174

175175
// this focus is needed to set `$document.activeElement`
176176
// and wouldn't be required if `document.activeElement` was settable.

src/components/virtualRepeat/virtualRepeater.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe('<md-virtual-repeat>', function() {
2-
beforeEach(module('ngMaterial-mock', 'material.components.virtualRepeat'));
2+
beforeEach(module('material.components.virtualRepeat'));
33

44
var VirtualRepeatController = { NUM_EXTRA : 3 };
55

src/core/services/interimElement/interimElement.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ describe('$$interimElement service', function() {
33
var $compilerSpy, $themingSpy, resolvingPromise;
44

55
function setup() {
6-
module('material.core', 'ngAnimateMock', function($provide) {
6+
module('material.core', function($provide) {
77
var $mdCompiler = { compile: angular.noop };
88
$compilerSpy = spyOn($mdCompiler, 'compile');
99
$themingSpy = jasmine.createSpy('$mdTheming');

test/angular-material-spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* Before each test, require that the 'ngMaterial-mock' module is ready for injection
3535
* NOTE: assumes that angular-material-mocks.js has been loaded.
3636
*/
37-
module('ngMaterial-mock')
37+
module('ngAnimateMock','ngMaterial-mock');
3838

3939
/**
4040
* Mocks angular.element#focus ONLY for the duration of a particular test.

0 commit comments

Comments
 (0)