gerrit/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.js
Becky Siegel 8bb09344ab Don't display tooltips on touch devices
Previously on iOS devices, tooltips in reply dialog did not always close
when clicking outside of the button. The focusOut event was not
triggered and thus _handleHideTooltip was not called. On other devices,
the tooltip remained open when clicking on it.

This change detects when a device triggers a touch event and sets a
boolean variable that it is a touch device. If touch, we do not open and
close tooltips. This was necessary because mouseenter and mouseleave
events are still triggered on touch devices with a touch.

Also, mouseover and mouseout events were replaced with mousenter and
mouseleave events because it seemed better practice since they don't
bubble to child elements & this is what is done in paper-tooltip.

Bug: Issue 4649
Change-Id: Ib3a4681e8da77a5cd7c140e3a899ceb0cf8400a8
2016-10-18 18:10:10 -07:00

116 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function(window) {
'use strict';
var BOTTOM_OFFSET = 7.2; // Height of the arrow in tooltip.
/** @polymerBehavior Gerrit.TooltipBehavior */
var TooltipBehavior = {
properties: {
hasTooltip: Boolean,
_isTouchDevice: {
type: Boolean,
value: function() {
return 'ontouchstart' in document.documentElement;
},
},
_tooltip: Element,
_titleText: String,
},
attached: function() {
if (!this.hasTooltip) { return; }
this.addEventListener('mouseenter', this._handleShowTooltip.bind(this));
this.addEventListener('mouseleave', this._handleHideTooltip.bind(this));
this.addEventListener('tap', this._handleHideTooltip.bind(this));
this.listen(window, 'scroll', '_handleWindowScroll');
},
detached: function() {
this.unlisten(window, 'scroll', '_handleWindowScroll');
},
_handleShowTooltip: function(e) {
if (this._isTouchDevice) { return; }
if (!this.hasAttribute('title') ||
this.getAttribute('title') === '' ||
this._tooltip) {
return;
}
// Store the title attribute text then set it to an empty string to
// prevent it from showing natively.
this._titleText = this.getAttribute('title');
this.setAttribute('title', '');
var tooltip = document.createElement('gr-tooltip');
tooltip.text = this._titleText;
// Set visibility to hidden before appending to the DOM so that
// calculations can be made based on the elements size.
tooltip.style.visibility = 'hidden';
Polymer.dom(document.body).appendChild(tooltip);
this._positionTooltip(tooltip);
tooltip.style.visibility = null;
this._tooltip = tooltip;
},
_handleHideTooltip: function(e) {
if (this._isTouchDevice) { return; }
if (!this.hasAttribute('title') ||
this._titleText == null) {
return;
}
this.setAttribute('title', this._titleText);
if (this._tooltip && this._tooltip.parentNode) {
this._tooltip.parentNode.removeChild(this._tooltip);
}
this._tooltip = null;
},
_handleWindowScroll: function(e) {
if (!this._tooltip) { return; }
this._positionTooltip(this._tooltip);
},
_positionTooltip: function(tooltip) {
var rect = this.getBoundingClientRect();
var boxRect = tooltip.getBoundingClientRect();
var parentRect = tooltip.parentElement.getBoundingClientRect();
var top = rect.top - parentRect.top - boxRect.height - BOTTOM_OFFSET;
var left =
rect.left - parentRect.left + (rect.width - boxRect.width) / 2;
if (left < 0) {
tooltip.updateStyles({
'--gr-tooltip-arrow-center-offset': left + 'px',
});
}
tooltip.style.left = Math.max(0, left) + 'px';
tooltip.style.top = Math.max(0, top) + 'px';
},
};
window.Gerrit = window.Gerrit || {};
window.Gerrit.TooltipBehavior = TooltipBehavior;
})(window);