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