UNPKG

suneditor

Version:

Vanilla JavaScript based WYSIWYG web editor

156 lines (132 loc) 4.64 kB
import { PluginDropdown } from '../../interfaces'; import { dom } from '../../helper'; /** * @typedef {Object} FontPluginOptions * @property {Array<string>} [items] - Font list */ /** * @class * @description Text font plugin */ class Font extends PluginDropdown { static key = 'font'; static className = 'se-btn-select se-btn-tool-font'; #defaultValue; /** * @constructor * @param {SunEditor.Kernel} kernel - The Kernel instance * @param {FontPluginOptions} pluginOptions - plugin options */ constructor(kernel, pluginOptions) { super(kernel); // plugin basic properties this.title = this.$.lang.font; this.inner = '<span class="se-txt">' + this.$.lang.font + '</span>' + this.$.icons.arrow_down; // create HTML const fontList = pluginOptions.items || ['Arial', 'Comic Sans MS', 'Courier New', 'Impact', 'Georgia', 'tahoma', 'Trebuchet MS', 'Verdana']; const menu = CreateHTML(this.$, fontList); // members this.currentFont = ''; this.fontList = menu.querySelectorAll('ul li button'); this.fontArray = fontList; this.#defaultValue = /** @type {HTMLSpanElement} */ (menu.querySelector('.se-sub-list span')); // init this.$.menu.initDropdownTarget(Font, menu); } /** * @hook Editor.EventManager * @type {SunEditor.Hook.Event.Active} */ active(element, target) { const targetText = target.querySelector('.se-txt'); const tooltip = target.parentNode.querySelector('.se-tooltip-text'); let fontFamily = ''; if (!element) { const font = this.$.store.get('hasFocus') ? this.$.frameContext.get('wwComputedStyle').fontFamily : this.$.lang.font; dom.utils.changeTxt(targetText, font); dom.utils.changeTxt(tooltip, this.$.store.get('hasFocus') ? this.$.lang.font + (font ? ' (' + font + ')' : '') : font); } else if (this.$.format.isLine(element)) { return undefined; } else if ((fontFamily = dom.utils.getStyle(element, 'fontFamily'))) { const selectFont = fontFamily.replace(/["']/g, ''); dom.utils.changeTxt(targetText, selectFont); dom.utils.changeTxt(tooltip, this.$.lang.font + ' (' + selectFont + ')'); return true; } return false; } /** * @override * @type {PluginDropdown['on']} */ on(target) { const fontList = this.fontList; const currentFont = target.querySelector('.se-txt').textContent; if (currentFont !== this.currentFont) { let found = false; for (let i = 0, len = fontList.length; i < len; i++) { if (currentFont === (fontList[i].getAttribute('data-command') || '').replace(/'|"/g, '')) { dom.utils.addClass(fontList[i], 'active'); found = true; } else { dom.utils.removeClass(fontList[i], 'active'); } } this.currentFont = currentFont; if (!found) { this.#defaultValue.textContent = currentFont; this.#defaultValue.style.display = 'block'; } else { this.#defaultValue.style.display = 'none'; } } } /** * @override * @type {PluginDropdown['action']} */ async action(target) { let value = target.getAttribute('data-command'); if (value) { if (/[\s\d\W]/.test(value) && !/^['"].*['"]$/.test(value)) { value = `"${value}"`; } // before event if ((await this.$.eventManager.triggerEvent('onFontActionBefore', { value })) === false) return; const newNode = dom.utils.createElement('SPAN', { style: 'font-family: ' + value + ';' }); this.$.inline.apply(newNode, { stylesToModify: ['font-family'], nodesToRemove: null, strictRemove: null }); } else { this.$.inline.apply(null, { stylesToModify: ['font-family'], nodesToRemove: ['span'], strictRemove: true }); } this.$.menu.dropdownOff(); } } /** * @param {SunEditor.Deps} $ - Kernel dependencies * @param {string[]} fontList - Font name list * @returns {HTMLElement} */ function CreateHTML({ lang }, fontList) { let list = /*html*/ ` <div class="se-list-inner"> <ul class="se-list-basic"> <li> <button type="button" class="se-btn se-btn-list default_value" data-command="" title="${lang.default}" aria-label="${lang.default}"> ${lang.default} </button> </li> <li class="se-btn-list se-sub-list"><span></span></li>`; for (let i = 0, len = fontList.length, font, text; i < len; i++) { font = fontList[i]; text = font.split(',')[0]; list += /*html*/ ` <li> <button type="button" class="se-btn se-btn-list" data-command="${font}" data-txt="${text}" title="${text}" aria-label="${text}" style="font-family:${font};">${text}</button> </li>`; } list += /*html*/ ` </ul> </div>`; return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer se-list-font-family' }, list); } export default Font;