blob: 2da68469b8780196b1caa7597e0458329f03110a [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 = 10;
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._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 ||
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 offset = this._getOffset(this);
var top = offset.top;
var left = offset.left;
top -= this.offsetHeight + BOTTOM_OFFSET;
left -= (tooltip.offsetWidth / 2) - (this.offsetWidth / 2);
left = Math.max(0, left);
top = Math.max(0, top);
tooltip.style.left = left + 'px';
tooltip.style.top = top + 'px';
},
_getOffset: function(el) {
var top = 0;
var left = 0;
for (var node = el; node; node = node.offsetParent) {
if (node.offsetTop) { top += node.offsetTop; }
if (node.offsetLeft) { left += node.offsetLeft; }
}
top += window.scrollY;
left += window.scrollX;
return {top: top, left: left};
},
};
window.Gerrit = window.Gerrit || {};
window.Gerrit.TooltipBehavior = TooltipBehavior;
})(window);