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

fix(tooltip): tooltip sometimes not hidden after element is disabled. #5912

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/components/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe

var ngWindow = angular.element($window);

// add an mutationObserver when there is support for it
// and the need for it in the form of viable host(parent[0])
if (parent[0] && 'MutationObserver' in $window) {
// use an mutationObserver to tackle #2602
var attributeObserver = new MutationObserver(function(mutations) {
mutations
.forEach(function (mutation) {
if (mutation.attributeName === 'disabled' && parent[0].disabled) {
setVisible(false);
scope.$digest(); // make sure the elements gets updated
}
});
});

attributeObserver.observe(parent[0], { attributes: true});
};

// Store whether the element was focused when the window loses focus.
var windowBlurHandler = function() {
elementFocusedOnWindowBlur = document.activeElement === parent[0];
Expand All @@ -133,6 +150,7 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
scope.$on('$destroy', function() {
ngWindow.off('blur', windowBlurHandler);
ngWindow.off('resize', debouncedOnResize);
attributeObserver && attributeObserver.disconnect();
});

var enterHandler = function(e) {
Expand Down
57 changes: 57 additions & 0 deletions src/components/tooltip/tooltip.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,63 @@ describe('<md-tooltip> directive', function() {
triggerEvent('focus');
expect($rootScope.testModel.isVisible).toBe(false);
}));

ddescribe('<md-tooltip> attributeObserver', function() {
if (window.MutationObserver === undefined) {
// PhantomJS doesn't support mo
it(' does not work without support for mutationObservers', function () {
expect(true).toBe(true);
})
return ;
}
var obs
beforeEach(function (mutationDone){
obs = new MutationObserver(function(mutations) {
mutations
.forEach(function (mutation) {
if (mutation.attributeName === 'disabled' && mutation.target.disabled) {
// allow a little time for the observer on the tooltip to finish
setTimeout(function() {
$timeout.flush();
$material.flushOutstandingAnimations();
mutationDone();
},50);
}
})
});

var el = buildTooltip(
'<md-button>' +
'Hello' +
'<md-tooltip md-visible="testModel.isVisible">' +
'Tooltip' +
'</md-tooltip>' +
'</md-button>'
);

showTooltip(true);
// check if the testsetup is ok
expect($rootScope.testModel.isVisible).toBe(true)
expect(findTooltip().length).toBe(1);
// attach the observer
obs.observe(el[0], { attributes: true});
// trigger the mutationObserver(s).
el.attr('disabled',true)
})

afterEach(function () {
// remove observer from dom.
obs.disconnect();
obs = null;
})

it('should be hidden after element gets disabled', function() {
expect($rootScope.testModel.isVisible).toBe(false)
expect(findTooltip().length).toBe(0);
})
});


});

// ******************************************************
Expand Down