suneditor
Version:
Vanilla JavaScript WYSIWYG web editor (2.x legacy version, actively maintained)
124 lines (101 loc) • 4.33 kB
JavaScript
/*
* wysiwyg web editor
*
* suneditor.js
* Copyright 2017 JiHong Lee.
* MIT license.
*/
;
export default {
name: 'font',
display: 'submenu',
add: function (core, targetElement) {
const context = core.context;
context.font = {
targetText: targetElement.querySelector('.txt'),
targetTooltip: targetElement.parentNode.querySelector('.se-tooltip-text'),
_fontList: null,
currentFont: ''
};
/** set submenu */
let listDiv = this.setSubmenu(core);
/** add event listeners */
listDiv.querySelector('.se-list-inner').addEventListener('click', this.pickup.bind(core));
context.font._fontList = listDiv.querySelectorAll('ul li button');
/** append target button menu */
core.initMenuTarget(this.name, targetElement, listDiv);
/** empty memory */
listDiv = null;
},
setSubmenu: function (core) {
const lang = core.lang;
const listDiv = core.util.createElement('DIV');
listDiv.className = 'se-submenu se-list-layer se-list-font-family';
let font, text, i, len;
let fontList = core.options.font;
let list = '<div class="se-list-inner">' +
'<ul class="se-list-basic">' +
'<li><button type="button" class="default_value se-btn-list" title="' + lang.toolbar.default + '" aria-label="' + lang.toolbar.default + '">(' + lang.toolbar.default + ')</button></li>';
for (i = 0, len = fontList.length; i < len; i++) {
font = fontList[i];
text = font.split(',')[0];
list += '<li><button type="button" class="se-btn-list" data-value="' + font + '" data-txt="' + text + '" title="' + text + '" aria-label="' + text + '" style="font-family:' + font + ';">' + text + '</button></li>';
}
list += '</ul></div>';
listDiv.innerHTML = list;
return listDiv;
},
/**
* @Override core
*/
active: function (element) {
const target = this.context.font.targetText;
const tooltip = this.context.font.targetTooltip;
if (!element) {
const font = this.hasFocus ? this.wwComputedStyle.fontFamily : this.lang.toolbar.font;
this.util.changeTxt(target, font);
this.util.changeTxt(tooltip, this.hasFocus ? this.lang.toolbar.font + (font ? ' (' + font + ')' : '') : font);
} else if (element.style && element.style.fontFamily.length > 0) {
const selectFont = element.style.fontFamily.replace(/["']/g,'');
this.util.changeTxt(target, selectFont);
this.util.changeTxt(tooltip, this.lang.toolbar.font + ' (' + selectFont + ')');
return true;
}
return false;
},
/**
* @Override submenu
*/
on: function () {
const fontContext = this.context.font;
const fontList = fontContext._fontList;
const currentFont = fontContext.targetText.textContent;
if (currentFont !== fontContext.currentFont) {
for (let i = 0, len = fontList.length; i < len; i++) {
if (currentFont === (fontList[i].getAttribute('data-value') || '').replace(/'|"/g, '')) {
this.util.addClass(fontList[i], 'active');
} else {
this.util.removeClass(fontList[i], 'active');
}
}
fontContext.currentFont = currentFont;
}
},
pickup: function (e) {
if (!/^BUTTON$/i.test(e.target.tagName)) return false;
e.preventDefault();
e.stopPropagation();
let value = e.target.getAttribute('data-value');
if (value) {
const newNode = this.util.createElement('SPAN');
if (/[\s\d\W]/.test(value) && !/^['"].*['"]$/.test(value)) {
value = '"' + value + '"';
}
newNode.style.fontFamily = value;
this.nodeChange(newNode, ['font-family'], null, null);
} else {
this.nodeChange(null, ['font-family'], ['span'], true);
}
this.submenuOff();
}
};