blob: 3702c841d2e4ca90a730a7c62246ad2364035d60 [file] [log] [blame]
// 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,
_tooltip: Element,
_titleText: String,
},
attached: function() {
if (!this.hasTooltip) { return; }
this.addEventListener('mouseover', this._handleShowTooltip.bind(this));
this.addEventListener('mouseout', this._handleHideTooltip.bind(this));
this.addEventListener('focusin', this._handleShowTooltip.bind(this));
this.addEventListener('focusout', this._handleHideTooltip.bind(this));
this.listen(window, 'scroll', '_handleWindowScroll');
},
detached: function() {
this.unlisten(window, 'scroll', '_handleWindowScroll');
},
_handleShowTooltip: function(e) {
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 element’s 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.hasAttribute('title') ||
this._titleText == null ||
this === document.activeElement) { 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);