UNPKG

jodit

Version:

Jodit is awesome and usefully wysiwyg editor with filebrowser

420 lines (400 loc) 7.96 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Licensed under GNU General Public License version 2 or later or a commercial license or MIT; * For GPL see LICENSE-GPL.txt in the project root for license information. * For MIT see LICENSE-MIT.txt in the project root for license information. * For commercial licenses see https://xdsoft.net/jodit/commercial/ * Copyright (c) 2013-2019 Valeriy Chupurnov. All rights reserved. https://xdsoft.net */ import { Config } from '../Config'; import { KEY_DOWN, KEY_ENTER, KEY_LEFT, KEY_RIGHT, KEY_UP } from '../constants'; import { Alert, Dialog } from '../modules/dialog/'; import { IControlType } from '../types/toolbar'; import { IJodit } from '../types'; declare module '../Config' { interface Config { specialCharacters: string[]; usePopupForSpecialCharacters: boolean; } } Config.prototype.usePopupForSpecialCharacters = false; Config.prototype.specialCharacters = [ '!', '&quot;', '#', '$', '%', '&amp;', "'", '(', ')', '*', '+', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '&lt;', '=', '&gt;', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '&euro;', '&lsquo;', '&rsquo;', '&ldquo;', '&rdquo;', '&ndash;', '&mdash;', '&iexcl;', '&cent;', '&pound;', '&curren;', '&yen;', '&brvbar;', '&sect;', '&uml;', '&copy;', '&ordf;', '&laquo;', '&raquo;', '&not;', '&reg;', '&macr;', '&deg;', '&sup2;', '&sup3;', '&acute;', '&micro;', '&para;', '&middot;', '&cedil;', '&sup1;', '&ordm;', '&frac14;', '&frac12;', '&frac34;', '&iquest;', '&Agrave;', '&Aacute;', '&Acirc;', '&Atilde;', '&Auml;', '&Aring;', '&AElig;', '&Ccedil;', '&Egrave;', '&Eacute;', '&Ecirc;', '&Euml;', '&Igrave;', '&Iacute;', '&Icirc;', '&Iuml;', '&ETH;', '&Ntilde;', '&Ograve;', '&Oacute;', '&Ocirc;', '&Otilde;', '&Ouml;', '&times;', '&Oslash;', '&Ugrave;', '&Uacute;', '&Ucirc;', '&Uuml;', '&Yacute;', '&THORN;', '&szlig;', '&agrave;', '&aacute;', '&acirc;', '&atilde;', '&auml;', '&aring;', '&aelig;', '&ccedil;', '&egrave;', '&eacute;', '&ecirc;', '&euml;', '&igrave;', '&iacute;', '&icirc;', '&iuml;', '&eth;', '&ntilde;', '&ograve;', '&oacute;', '&ocirc;', '&otilde;', '&ouml;', '&divide;', '&oslash;', '&ugrave;', '&uacute;', '&ucirc;', '&uuml;', '&yacute;', '&thorn;', '&yuml;', '&OElig;', '&oelig;', '&#372;', '&#374', '&#373', '&#375;', '&sbquo;', '&#8219;', '&bdquo;', '&hellip;', '&trade;', '&#9658;', '&bull;', '&rarr;', '&rArr;', '&hArr;', '&diams;', '&asymp;' ]; Config.prototype.controls.symbol = { icon: 'omega', hotkeys: ['ctrl+shift+i', 'cmd+shift+i'], tooltip: 'Insert Special Character', popup: (editor: IJodit, current, control, close): any => { const container: HTMLElement | undefined = editor.events.fire( 'generateSpecialCharactersTable.symbols' ); if (container) { if (editor.options.usePopupForSpecialCharacters) { const box: HTMLDivElement = editor.ownerDocument.createElement( 'div' ); box.classList.add('jodit_symbols'); box.appendChild(container); editor.events.on(container, 'close_dialog', close); return box; } else { const dialog: Dialog = Alert( container, editor.i18n('Select Special Character'), void 0, 'jodit_symbols' ); const a: HTMLAnchorElement | null = container.querySelector( 'a' ); a && a.focus(); editor.events.on('beforeDestruct', () => { dialog && dialog.close(); }); } } } } as IControlType; /** * The plugin inserts characters that are not part of the standard keyboard. */ export class symbols { private countInRow: number = 17; constructor(editor: IJodit) { editor.events.on('generateSpecialCharactersTable.symbols', () => { const container: HTMLDivElement = editor.create.fromHTML( '<div class="jodit_symbols-container">' + '<div class="jodit_symbols-container_table"><table><tbody></tbody></table></div>' + '<div class="jodit_symbols-container_preview"><div class="jodit_symbols-preview"></div></div>' + '</div>' ) as HTMLDivElement, preview: HTMLDivElement = container.querySelector( '.jodit_symbols-preview' ) as HTMLDivElement, table: HTMLTableElement = container.querySelector( 'table' ) as HTMLTableElement, body: HTMLTableSectionElement = table.tBodies[0], chars: HTMLAnchorElement[] = []; for ( let i: number = 0; i < editor.options.specialCharacters.length; ) { const tr: HTMLTableRowElement = editor.create.element('tr'); for ( let j: number = 0; j < this.countInRow && i < editor.options.specialCharacters.length; j += 1, i += 1 ) { const td: HTMLTableCellElement = editor.create.element( 'td' ), a: HTMLAnchorElement = editor.create.fromHTML( `<a data-index="${i}" data-index-j="${j}" href="javascript:void(0)" role="option" tabindex="-1" >${editor.options.specialCharacters[i]}</a>` ) as HTMLAnchorElement; chars.push(a); td.appendChild(a); tr.appendChild(td); } body.appendChild(tr); } const self: symbols = this; editor.events .on(chars, 'focus', function(this: HTMLAnchorElement) { preview.innerHTML = this.innerHTML; }) .on(chars, 'mousedown', function( this: HTMLAnchorElement, e?: MouseEvent ) { if (this && this.nodeName === 'A') { editor.selection.focus(); editor.selection.insertHTML(this.innerHTML); editor.events.fire(this, 'close_dialog'); e && e.preventDefault(); e && e.stopImmediatePropagation(); } }) .on(chars, 'mouseenter', function(this: HTMLAnchorElement) { if (this && this.nodeName === 'A') { this.focus(); } }) .on(chars, 'keydown', (e: KeyboardEvent) => { const target: HTMLAnchorElement = e.target as HTMLAnchorElement; if (target && target.nodeName === 'A') { const index: number = parseInt( target.getAttribute('data-index') || '0', 10 ), jIndex: number = parseInt( target.getAttribute('data-index-j') || '0', 10 ); let newIndex: number; switch (e.which) { case KEY_UP: case KEY_DOWN: newIndex = e.which === KEY_UP ? index - self.countInRow : index + self.countInRow; if (chars[newIndex] === undefined) { newIndex = e.which === KEY_UP ? Math.floor( chars.length / self.countInRow ) * self.countInRow + jIndex : jIndex; if (newIndex > chars.length - 1) { newIndex -= self.countInRow; } } chars[newIndex] && chars[newIndex].focus(); break; case KEY_RIGHT: case KEY_LEFT: newIndex = e.which === KEY_LEFT ? index - 1 : index + 1; if (chars[newIndex] === undefined) { newIndex = e.which === KEY_LEFT ? chars.length - 1 : 0; } chars[newIndex] && chars[newIndex].focus(); break; case KEY_ENTER: editor.events.fire(target, 'mousedown'); e.stopImmediatePropagation(); e.preventDefault(); break; } } }); return container; }); } }