// 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';

  const BOTTOM_OFFSET = 7.2; // Height of the arrow in tooltip.

  window.Gerrit = window.Gerrit || {};

  /** @polymerBehavior Gerrit.TooltipBehavior */
  Gerrit.TooltipBehavior = {

    properties: {
      hasTooltip: {
        type: Boolean,
        observer: '_setupTooltipListeners',
      },

      _isTouchDevice: {
        type: Boolean,
        value() {
          return 'ontouchstart' in document.documentElement;
        },
      },
      _tooltip: Object,
      _titleText: String,
      _hasSetupTooltipListeners: {
        type: Boolean,
        value: false,
      },
    },

    detached() {
      this._handleHideTooltip();
      this.unlisten(window, 'scroll', '_handleWindowScroll');
    },

    _setupTooltipListeners() {
      if (this._hasSetupTooltipListeners || !this.hasTooltip) { return; }
      this._hasSetupTooltipListeners = true;

      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');
    },

    _handleShowTooltip(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', '');

      const tooltip = document.createElement('gr-tooltip');
      tooltip.text = this._titleText;
      tooltip.maxWidth = this.getAttribute('max-width');

      // 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';
      Gerrit.getRootElement().appendChild(tooltip);
      this._positionTooltip(tooltip);
      tooltip.style.visibility = null;

      this._tooltip = tooltip;
    },

    _handleHideTooltip(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(e) {
      if (!this._tooltip) { return; }

      this._positionTooltip(this._tooltip);
    },

    _positionTooltip(tooltip) {
      const rect = this.getBoundingClientRect();
      const boxRect = tooltip.getBoundingClientRect();
      const parentRect = tooltip.parentElement.getBoundingClientRect();
      const top = rect.top - parentRect.top;
      const left =
          rect.left - parentRect.left + (rect.width - boxRect.width) / 2;
      const right = parentRect.width - left - boxRect.width;
      if (left < 0) {
        tooltip.updateStyles({
          '--gr-tooltip-arrow-center-offset': left + 'px',
        });
      } else if (right < 0) {
        tooltip.updateStyles({
          '--gr-tooltip-arrow-center-offset': (-0.5 * right) + 'px',
        });
      }
      tooltip.style.left = Math.max(0, left) + 'px';
      tooltip.style.top = Math.max(0, top) + 'px';
      tooltip.style.transform = 'translateY(calc(-100% - ' + BOTTOM_OFFSET +
          'px))';
    },
  };
})(window);

@@ -3253,24 +3253,153 @@
 (tooltip) %7B%0A
+      // This flush is needed for tooltips to be positioned correctly in Firefox%0A      // and Safari.%0A      Polymer.dom.flush();%0A
       const 

Fix tooltips on Safari and Firefox