11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciimport {DOM, V8CustomElement} from './helper.mjs';
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciDOM.defineCustomElement(
81cb0ef41Sopenharmony_ci    'view/tool-tip', (templateText) => class Tooltip extends V8CustomElement {
91cb0ef41Sopenharmony_ci      _targetNode;
101cb0ef41Sopenharmony_ci      _content;
111cb0ef41Sopenharmony_ci      _isHidden = true;
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci      constructor() {
141cb0ef41Sopenharmony_ci        super(templateText);
151cb0ef41Sopenharmony_ci        this._intersectionObserver = new IntersectionObserver((entries) => {
161cb0ef41Sopenharmony_ci          if (entries[0].intersectionRatio <= 0) {
171cb0ef41Sopenharmony_ci            this.hide();
181cb0ef41Sopenharmony_ci          } else {
191cb0ef41Sopenharmony_ci            this.show();
201cb0ef41Sopenharmony_ci            this.requestUpdate(true);
211cb0ef41Sopenharmony_ci          }
221cb0ef41Sopenharmony_ci        });
231cb0ef41Sopenharmony_ci        document.addEventListener('click', (event) => {
241cb0ef41Sopenharmony_ci          // Only hide the tooltip if we click anywhere outside of it.
251cb0ef41Sopenharmony_ci          let target = event.target;
261cb0ef41Sopenharmony_ci          while (target) {
271cb0ef41Sopenharmony_ci            if (target == this) return;
281cb0ef41Sopenharmony_ci            target = target.parentNode;
291cb0ef41Sopenharmony_ci          }
301cb0ef41Sopenharmony_ci          this.hide()
311cb0ef41Sopenharmony_ci        });
321cb0ef41Sopenharmony_ci      }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci      _update() {
351cb0ef41Sopenharmony_ci        if (!this._targetNode || this._isHidden) return;
361cb0ef41Sopenharmony_ci        const rect = this._targetNode.getBoundingClientRect();
371cb0ef41Sopenharmony_ci        rect.x += rect.width / 2;
381cb0ef41Sopenharmony_ci        let atRight = this._useRight(rect.x);
391cb0ef41Sopenharmony_ci        let atBottom = this._useBottom(rect.y);
401cb0ef41Sopenharmony_ci        if (atBottom) rect.y += rect.height;
411cb0ef41Sopenharmony_ci        this._setPosition(rect, atRight, atBottom);
421cb0ef41Sopenharmony_ci        this.requestUpdate(true);
431cb0ef41Sopenharmony_ci      }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci      set positionOrTargetNode(positionOrTargetNode) {
461cb0ef41Sopenharmony_ci        if (positionOrTargetNode.nodeType === undefined) {
471cb0ef41Sopenharmony_ci          this.position = positionOrTargetNode;
481cb0ef41Sopenharmony_ci        } else {
491cb0ef41Sopenharmony_ci          this.targetNode = positionOrTargetNode;
501cb0ef41Sopenharmony_ci        }
511cb0ef41Sopenharmony_ci      }
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci      set targetNode(targetNode) {
541cb0ef41Sopenharmony_ci        this._intersectionObserver.disconnect();
551cb0ef41Sopenharmony_ci        this._targetNode = targetNode;
561cb0ef41Sopenharmony_ci        if (targetNode === undefined) return;
571cb0ef41Sopenharmony_ci        if (!(targetNode instanceof SVGElement)) {
581cb0ef41Sopenharmony_ci          this._intersectionObserver.observe(targetNode);
591cb0ef41Sopenharmony_ci        }
601cb0ef41Sopenharmony_ci        this.requestUpdate(true);
611cb0ef41Sopenharmony_ci      }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci      set position(position) {
641cb0ef41Sopenharmony_ci        this._targetNode = undefined;
651cb0ef41Sopenharmony_ci        this._setPosition(
661cb0ef41Sopenharmony_ci            position, this._useRight(position.x), this._useBottom(position.y));
671cb0ef41Sopenharmony_ci      }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci      _setPosition(viewportPosition, atRight, atBottom) {
701cb0ef41Sopenharmony_ci        const horizontalMode = atRight ? 'right' : 'left';
711cb0ef41Sopenharmony_ci        const verticalMode = atBottom ? 'bottom' : 'top';
721cb0ef41Sopenharmony_ci        this.bodyNode.className = horizontalMode + ' ' + verticalMode;
731cb0ef41Sopenharmony_ci        const pageX = viewportPosition.x + window.scrollX;
741cb0ef41Sopenharmony_ci        this.style.left = `${pageX}px`;
751cb0ef41Sopenharmony_ci        const pageY = viewportPosition.y + window.scrollY;
761cb0ef41Sopenharmony_ci        this.style.top = `${pageY}px`;
771cb0ef41Sopenharmony_ci      }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci      _useBottom(viewportY) {
801cb0ef41Sopenharmony_ci        return viewportY <= 400;
811cb0ef41Sopenharmony_ci      }
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci      _useRight(viewportX) {
841cb0ef41Sopenharmony_ci        return viewportX < document.documentElement.clientWidth / 2;
851cb0ef41Sopenharmony_ci      }
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci      set content(content) {
881cb0ef41Sopenharmony_ci        if (!content) return this.hide();
891cb0ef41Sopenharmony_ci        this.show();
901cb0ef41Sopenharmony_ci        if (this._content === content) return;
911cb0ef41Sopenharmony_ci        this._content = content;
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci        if (typeof content === 'string') {
941cb0ef41Sopenharmony_ci          this.contentNode.innerHTML = content;
951cb0ef41Sopenharmony_ci          this.contentNode.className = 'textContent';
961cb0ef41Sopenharmony_ci        } else if (content?.nodeType && content?.nodeName) {
971cb0ef41Sopenharmony_ci          this._setContentNode(content);
981cb0ef41Sopenharmony_ci        } else {
991cb0ef41Sopenharmony_ci          if (this.contentNode.firstChild?.localName == 'property-link-table') {
1001cb0ef41Sopenharmony_ci            this.contentNode.firstChild.propertyDict = content;
1011cb0ef41Sopenharmony_ci          } else {
1021cb0ef41Sopenharmony_ci            const node = DOM.element('property-link-table');
1031cb0ef41Sopenharmony_ci            node.instanceLinkButtons = true;
1041cb0ef41Sopenharmony_ci            node.propertyDict = content;
1051cb0ef41Sopenharmony_ci            this._setContentNode(node);
1061cb0ef41Sopenharmony_ci          }
1071cb0ef41Sopenharmony_ci        }
1081cb0ef41Sopenharmony_ci      }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci      _setContentNode(content) {
1111cb0ef41Sopenharmony_ci        const newContent = DOM.div();
1121cb0ef41Sopenharmony_ci        newContent.appendChild(content);
1131cb0ef41Sopenharmony_ci        this.contentNode.replaceWith(newContent);
1141cb0ef41Sopenharmony_ci        newContent.id = 'content';
1151cb0ef41Sopenharmony_ci      }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci      hide() {
1181cb0ef41Sopenharmony_ci        this._content = undefined;
1191cb0ef41Sopenharmony_ci        if (this._isHidden) return;
1201cb0ef41Sopenharmony_ci        this._isHidden = true;
1211cb0ef41Sopenharmony_ci        this.bodyNode.style.display = 'none';
1221cb0ef41Sopenharmony_ci        this.targetNode = undefined;
1231cb0ef41Sopenharmony_ci      }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci      show() {
1261cb0ef41Sopenharmony_ci        if (!this._isHidden) return;
1271cb0ef41Sopenharmony_ci        this.bodyNode.style.display = 'block';
1281cb0ef41Sopenharmony_ci        this._isHidden = false;
1291cb0ef41Sopenharmony_ci      }
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci      get bodyNode() {
1321cb0ef41Sopenharmony_ci        return this.$('#body');
1331cb0ef41Sopenharmony_ci      }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci      get contentNode() {
1361cb0ef41Sopenharmony_ci        return this.$('#content');
1371cb0ef41Sopenharmony_ci      }
1381cb0ef41Sopenharmony_ci    });
139