// 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; /** @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 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);