UNPKG

jodit

Version:

Jodit is awesome and usefully wysiwyg editor with filebrowser

227 lines (183 loc) 5.02 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Licensed under GNU General Public License version 2 or later or a commercial license; * Copyright 2013-2019 Valeriy Chupurnov https://xdsoft.net */ import { IBound } from '../../types/types'; import { IViewBased } from '../../types/view'; import { Dom } from '../Dom'; import { css, offset, throttle } from '../helpers/'; import { Component } from '../Component'; import { IControlTypeStrong } from '../../types'; export class Popup extends Component { private calcPosition() { if (!this.isOpened || this.isDestructed) { return; } const popup: HTMLElement = this.container; const offsetContainer: IBound = offset( this.jodit.container as HTMLDivElement, this.jodit, this.jodit.ownerDocument, true ); const offsetPopup: IBound = offset( popup, this.jodit, this.jodit.ownerDocument, true ); const marginLeft: number = (css(popup, 'marginLeft') as number) || 0; offsetPopup.left -= marginLeft; let diffLeft: number = marginLeft; let width: number | string = 'auto'; if (offsetPopup.left < offsetContainer.left) { diffLeft = offsetContainer.left - offsetPopup.left; } else if ( offsetPopup.left + offsetPopup.width >= offsetContainer.left + offsetContainer.width ) { diffLeft = -( offsetPopup.left + offsetPopup.width - (offsetContainer.left + offsetContainer.width) ); } else { diffLeft = 0; } if (offsetPopup.width >= offsetContainer.width) { diffLeft = offsetContainer.left - offsetPopup.left; width = offsetContainer.width; } if (diffLeft !== marginLeft) { try { popup.style.setProperty( 'margin-left', diffLeft + 'px', 'important' ); } catch { popup.style.marginLeft = diffLeft + 'px'; // fallback for ie9 } } const triangle: HTMLSpanElement | null = popup.querySelector( '.jodit_popup_triangle' ); if (triangle) { triangle.style.marginLeft = -diffLeft + 'px'; } css(popup, 'width', width); } private throttleCalcPosition = throttle( this.calcPosition, this.jodit.defaultTimeout ); protected doOpen(content: string | HTMLElement | IControlTypeStrong) { if (!content) { return; } Dom.detach(this.container); this.container.innerHTML = '<span class="jodit_popup_triangle"></span>'; this.container.appendChild( Dom.isNode(content, this.jodit.ownerWindow) ? content : this.jodit.create.fromHTML(content.toString()) ); this.container.style.display = 'block'; this.container.style.marginLeft = null; } protected doClose() { // do nothing } isOpened: boolean = false; /** * @param {HTMLElement} content * @param {boolean} [rightAlign=false] Open popup on right side * @param {boolean} [noStandartActions=false] No call standarts action */ open( content: string | HTMLElement | IControlTypeStrong, rightAlign?: boolean, noStandartActions: boolean = false ) { Jodit.fireEach('beforeOpenPopup closeAllPopups', this, content); // close popups in another editors too noStandartActions || this.jodit.events.on('closeAllPopups', this.close); this.container.classList.add(this.className + '-open'); this.doOpen(content); this.target.appendChild(this.container); if (this.jodit.options.textIcons) { this.firstInFocus(); } if (rightAlign !== undefined) { this.container.classList.toggle('jodit_right', rightAlign); } if (!noStandartActions && this.container.parentNode) { this.jodit.events.fire( this.container.parentNode, 'afterOpenPopup', this.container ); } this.isOpened = true; !noStandartActions && this.calcPosition(); } close = (current?: HTMLElement | Popup) => { if (!this.isOpened && !this.isDestructed) { return; } if ( !current || !Dom.isOrContains( this.container, current instanceof Popup ? current.target : current ) ) { this.isOpened = false; this.jodit.events.off('closeAllPopups', this.close); this.doClose(); Dom.safeRemove(this.container); this.jodit.events.fire('removeMarkers'); this.jodit.events.fire(this, 'afterClose'); } }; public container: HTMLElement; constructor( jodit: IViewBased, readonly target: HTMLElement, readonly current?: HTMLElement, readonly className: string = 'jodit_toolbar_popup' ) { super(jodit); this.container = this.jodit.create.div(className, { 'data-editor_id': jodit.id }); this.jodit.events .on( this.container, 'mousedown touchstart touchend', (e: MouseEvent) => { e.stopPropagation(); } ) .on( [this.jodit.ownerWindow, this.jodit.events], 'resize', this.throttleCalcPosition ); } firstInFocus() {} destruct() { if (this.isDestructed) { return; } this.jodit.events.off( [this.jodit.ownerWindow, this.jodit.events], 'resize', this.throttleCalcPosition ); Dom.safeRemove(this.container); delete this.container; super.destruct(); } } import { Jodit } from '../../Jodit';