jodit
Version:
Jodit is an awesome and useful wysiwyg editor with filebrowser
211 lines (210 loc) • 7.18 kB
JavaScript
/*!
* 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 };