UNPKG

jodit

Version:

Jodit is an awesome and useful wysiwyg editor with filebrowser

211 lines (210 loc) 7.18 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Released under MIT see LICENSE.txt in the project root for license information. * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var UITooltip_1; import { STATUSES } from "../../../component/index.js"; import { autobind, component } from "../../../decorators/index.js"; import { Dom } from "../../../dom/index.js"; import { getContainer } from "../../../global.js"; import { position } from "../../../helpers/size/position.js"; import { attr, css } from "../../../helpers/utils/index.js"; import { UIElement } from "../../element.js"; const WINDOW_EVENTS_ON_HIDE = [ 'scroll.tooltip', 'joditCloseDialog', 'mouseleave.tooltip' ]; const JODIT_EVENTS_ON_HIDE = [ 'escape.tooltip', 'change.tooltip', 'changePlace.tooltip', 'afterOpenPopup.tooltip', 'hidePopup.tooltip', 'beforePopupClose.tooltip', 'closeAllPopups.tooltip' ]; let UITooltip = UITooltip_1 = class UITooltip extends UIElement { className() { return 'UITooltip'; } render() { return '<div><div class="&__content"></div></div>'; } constructor(view) { super(view); this.__isOpened = false; this.__attachedContainers = new Set(); this.__listenClose = false; this.__currentTarget = null; this.__delayShowTimeout = 0; this.__hideTimeout = 0; if (!view.o.textIcons && view.o.showTooltip && !view.o.useNativeTooltip) { this.j.e.on('getContainer', (box) => { this.__onAttach(box); }); view.hookStatus(STATUSES.ready, () => { this.__onAttach(this.j.container); }); } } __onAttach(container) { // TODO Move it inside __show method. Now it is here because testcase failed with capturing getContainer(this.j, UITooltip_1).appendChild(this.container); this.__attachedContainers.add(container); this.__attachedContainers.add(this.j.container); this.j.e .on(container, 'mouseenter.tooltip', this.__onMouseEnter, { capture: true }) .on(container, 'mouseleave.tooltip', this.__onMouseLeave, { capture: true }) .on(this.j.container, 'mouseleave.tooltip', this.__onMouseLeave, { capture: true }); } __addListenersOnEnter() { if (this.__listenClose) { return; } this.__listenClose = true; const view = this.j; view.e .on(view.ow, WINDOW_EVENTS_ON_HIDE, this.__hide) .on(JODIT_EVENTS_ON_HIDE, this.__hide); } __removeListenersOnLeave() { if (!this.__listenClose) { return; } this.__listenClose = false; const view = this.j; view.e .off(view.ow, WINDOW_EVENTS_ON_HIDE, this.__hide) .off(JODIT_EVENTS_ON_HIDE, this.__hide); } __onMouseLeave(e) { if (this.__currentTarget === e.target) { this.__hideDelay(); this.__currentTarget = null; } } __onMouseEnter(e) { if (!Dom.isHTMLElement(e.target)) { return; } const tooltip = attr(e.target, 'aria-label'); if (!tooltip) { return; } const disabled = Boolean(attr(e.target, 'disabled')); if (disabled) { return; } const isOwn = e.target.className.includes('jodit'); if (!isOwn) { return; } this.__currentTarget = e.target; const target = e.target; this.__open(() => { const pos = position(target); return { x: pos.left + pos.width / 2, y: pos.top + pos.height }; }, tooltip); } __open(getPoint, content) { this.__addListenersOnEnter(); this.__isOpened = true; this.j.async.clearTimeout(this.__hideTimeout); this.j.async.clearTimeout(this.__delayShowTimeout); const to = this.j.o.showTooltipDelay || this.j.defaultTimeout; if (!to) { this.__show(getPoint, content); return; } this.__delayShowTimeout = this.j.async.setTimeout(() => this.__show(getPoint, content), to); } __show(getPoint, content) { this.setMod('visible', true); this.setMod('above', false); this.getElm('content').innerHTML = content; const point = getPoint(); css(this.container, { left: point.x, top: point.y }); const tooltipPos = position(this.container); const viewHeight = this.j.ow.innerHeight; // If tooltip overflows below viewport, show it above the target if (tooltipPos.top + tooltipPos.height > viewHeight) { const targetPos = position(this.__currentTarget); this.setMod('above', true); css(this.container, { top: targetPos.top - tooltipPos.height }); } } __hide() { this.j.async.clearTimeout(this.__delayShowTimeout); this.j.async.clearTimeout(this.__hideTimeout); this.__removeListenersOnLeave(); if (this.__isOpened) { this.__isOpened = false; this.setMod('visible', false); this.getElm('content').innerHTML = ''; css(this.container, { left: -5000 }); } } __hideDelay() { this.j.async.clearTimeout(this.__delayShowTimeout); this.j.async.clearTimeout(this.__hideTimeout); if (!this.__isOpened) { return; } this.__hideTimeout = this.async.setTimeout(this.__hide, this.j.defaultTimeout); } destruct() { this.__attachedContainers.forEach(container => { this.j.e .off(container, 'mouseenter.tooltip', this.__onMouseEnter) .off(container, 'mouseleave.tooltip', this.__onMouseLeave); }); this.__hide(); super.destruct(); } }; __decorate([ autobind ], UITooltip.prototype, "__onMouseLeave", null); __decorate([ autobind ], UITooltip.prototype, "__onMouseEnter", null); __decorate([ autobind ], UITooltip.prototype, "__hide", null); __decorate([ autobind ], UITooltip.prototype, "__hideDelay", null); UITooltip = UITooltip_1 = __decorate([ component ], UITooltip); export { UITooltip };