
What it looks like: http://imgur.com/U37fSkk Will only trigger if the element has a title value and also has its hasTooltip property set. Add titles to the label buttons and turn tooltips on for those. Bug: Issue 3901 Change-Id: Id02f79bcf218419ab92d8100477ced093623f4d2
111 lines
3.4 KiB
JavaScript
111 lines
3.4 KiB
JavaScript
// 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);
|