@syncfusion/ej2-richtexteditor
Version:
Essential JS 2 RichTextEditor component
443 lines (440 loc) • 21.2 kB
JavaScript
import { IsFormatted } from './isformatted';
import * as CONSTANT from './../base/constant';
import { NodeSelection } from './../../selection/index';
import { getDefaultHtmlTbStatus } from './../../common/util';
import { closest, isNullOrUndefined } from '@syncfusion/ej2-base';
/**
* Update Toolbar Status
*
* @hidden
*/
export var statusCollection = getDefaultHtmlTbStatus();
var ToolbarStatus = /** @class */ (function () {
function ToolbarStatus() {
}
/**
* get method
*
* @param {Document} docElement - specifies the document element
* @param {Node} rootNode - specifies the content editable element
* @param {string[]} formatNode - specifies the format node
* @param {string[]} fontSize - specifies the font size
* @param {string[]} fontName - specifies the font name.
* @param {Node} documentNode - specifies the document node.
* @returns {IToolbarStatus} - returns the toolbar status
* @hidden
*/
ToolbarStatus.get = function (docElement, rootNode, formatNode, fontSize, fontName, documentNode) {
var formatCollection = JSON.parse(JSON.stringify(statusCollection));
var nodeCollection = JSON.parse(JSON.stringify(statusCollection));
var nodeSelection = new NodeSelection(rootNode);
var range = nodeSelection.getRange(docElement);
var nodes = documentNode ? [documentNode] : range.collapsed ? nodeSelection.getNodeCollection(range) :
nodeSelection.getSelectionNodeCollectionBr(range);
var nodesLength = nodes.length;
var isNodeChanged = false;
for (var index = 0; index < nodes.length; index++) {
while (nodes[index] && nodes[index].nodeType === 3 && range.startContainer.nodeType === 3 &&
nodes[index].parentNode && nodes[index].parentNode.lastElementChild && nodes[index].parentNode.lastElementChild.nodeName !== 'BR' &&
(this.getImmediateBlockNode(nodes[index].parentNode)) &&
(this.getImmediateBlockNode(nodes[index].parentNode)).textContent.replace(/\u200B/g, '').length === 0 &&
range.startContainer.textContent.replace(/\u200B/g, '').length === 0 &&
nodeSelection.get(docElement).toString().replace(/\u200B/g, '').length === 0) {
nodes[index] = nodes[index].parentNode.lastElementChild.firstChild;
isNodeChanged = true;
}
if (isNodeChanged && nodes[index]) {
nodeSelection.setCursorPoint(docElement, nodes[index], nodes[index].textContent.length);
isNodeChanged = false;
}
if (nodes[index] && ((nodes[index].nodeName !== 'BR' && nodes[index].nodeType !== 3) ||
(nodesLength > 1 && nodes[index].nodeType === 3 && nodes[index].textContent.trim() === ''))) {
nodes.splice(index, 1);
index--;
}
}
for (var index = 0; index < nodes.length; index++) {
var closestColOrColgroup = closest(nodes[index], 'col, colgroup');
if (isNullOrUndefined(closestColOrColgroup)) {
// eslint-disable-next-line max-len
formatCollection = this.getFormatParent(docElement, formatCollection, nodes[index], rootNode, formatNode, fontSize, fontName);
if ((index === 0 && formatCollection.bold) || !formatCollection.bold) {
nodeCollection.bold = formatCollection.bold;
}
if ((index === 0 && formatCollection.insertcode) || !formatCollection.insertcode) {
nodeCollection.insertcode = formatCollection.insertcode;
}
if ((index === 0 && formatCollection.isCodeBlock) || !formatCollection.isCodeBlock) {
nodeCollection.isCodeBlock = formatCollection.isCodeBlock;
}
if ((index === 0 && formatCollection.blockquote) || !formatCollection.blockquote) {
nodeCollection.blockquote = formatCollection.blockquote;
}
if ((index === 0 && formatCollection.italic) || !formatCollection.italic) {
nodeCollection.italic = formatCollection.italic;
}
if ((index === 0 && formatCollection.underline) || !formatCollection.underline) {
nodeCollection.underline = formatCollection.underline;
}
if ((index === 0 && formatCollection.strikethrough) || !formatCollection.strikethrough) {
nodeCollection.strikethrough = formatCollection.strikethrough;
}
if ((index === 0 && formatCollection.superscript) || !formatCollection.superscript) {
nodeCollection.superscript = formatCollection.superscript;
}
if ((index === 0 && formatCollection.subscript) || !formatCollection.subscript) {
nodeCollection.subscript = formatCollection.subscript;
}
if ((index === 0 && formatCollection.fontcolor) || !formatCollection.fontcolor) {
nodeCollection.fontcolor = formatCollection.fontcolor;
}
if (index === 0 && formatCollection.fontname) {
nodeCollection.fontname = formatCollection.fontname;
}
else {
nodeCollection.fontname = formatCollection.fontname === nodeCollection.fontname ? formatCollection.fontname : 'empty';
}
if (index === 0 && formatCollection.fontsize) {
nodeCollection.fontsize = formatCollection.fontsize;
}
else {
nodeCollection.fontsize = formatCollection.fontsize === nodeCollection.fontsize ? formatCollection.fontsize : 'empty';
}
if ((index === 0 && formatCollection.backgroundcolor) || !formatCollection.backgroundcolor) {
nodeCollection.backgroundcolor = formatCollection.backgroundcolor;
}
if ((index === 0 && formatCollection.orderedlist) || !formatCollection.orderedlist) {
nodeCollection.orderedlist = formatCollection.orderedlist;
}
if ((index === 0 && formatCollection.unorderedlist) || !formatCollection.unorderedlist) {
nodeCollection.unorderedlist = formatCollection.unorderedlist;
}
if ((index === 0 && formatCollection.alignments) || !formatCollection.alignments) {
nodeCollection.alignments = formatCollection.alignments;
}
if (index === 0 && formatCollection.formats) {
nodeCollection.formats = formatCollection.formats;
}
else {
nodeCollection.formats = formatCollection.formats === nodeCollection.formats ? formatCollection.formats : 'empty';
}
if ((index === 0 && formatCollection.createlink) || !formatCollection.createlink) {
nodeCollection.createlink = formatCollection.createlink;
}
if ((index === 0 && formatCollection.numberFormatList) || !formatCollection.numberFormatList) {
nodeCollection.numberFormatList = formatCollection.numberFormatList;
}
if ((index === 0 && formatCollection.bulletFormatList) || !formatCollection.bulletFormatList) {
nodeCollection.bulletFormatList = formatCollection.bulletFormatList;
}
if ((index === 0 && formatCollection.inlinecode) || !formatCollection.inlinecode) {
nodeCollection.inlinecode = formatCollection.inlinecode;
}
formatCollection = JSON.parse(JSON.stringify(statusCollection));
}
}
return nodeCollection;
};
ToolbarStatus.getImmediateBlockNode = function (node) {
do {
node = node.parentNode;
} while (node && CONSTANT.BLOCK_TAGS.indexOf(node.nodeName.toLocaleLowerCase()) < 0);
return node;
};
ToolbarStatus.getFormatParent = function (docElement, formatCollection, node, targetNode, formatNode, fontSize, fontName) {
var isListUpdated = false;
var isComplexListUpdated = false;
if (targetNode.contains(node) ||
(node && node.nodeType === 3 && targetNode.nodeType !== 3 && targetNode.contains(node.parentNode))) {
formatCollection = this.isFormattedNode(docElement, formatCollection, node, isListUpdated, isComplexListUpdated, formatNode, fontSize, fontName, targetNode);
}
return formatCollection;
};
ToolbarStatus.checkCodeBlock = function (element) {
return (element.nodeName === 'CODE' && element.parentElement && element.parentElement.nodeName === 'PRE' && element.parentElement.hasAttribute('data-language'));
};
ToolbarStatus.isFormattedNode = function (docElement, formatCollection, node, isListUpdated, isComplexListUpdated, formatNode, fontSize, fontName, targetNode) {
var BLOCK_TAGS = CONSTANT.BLOCK_TAGS;
var currentNode = node;
var collectedTags = [];
var collectedStyles = {};
//Traverse and collect tags and styles for inline nodes
while (currentNode && (!(BLOCK_TAGS.indexOf(currentNode.nodeName.toLowerCase()) > -1)) &&
(!targetNode || currentNode.nodeName !== targetNode.nodeName)) {
if (currentNode.nodeType === 1) {
var element = currentNode;
if (!this.checkCodeBlock(element)) {
collectedTags.push(element.nodeName.toLowerCase());
}
this.collectStyles(currentNode, collectedStyles, docElement, fontName, fontSize);
}
currentNode = currentNode.parentNode;
}
// Keep traversing up until document root
while (currentNode && currentNode !== targetNode) {
var nodeName = currentNode.nodeName.toLowerCase();
if (!formatCollection.unorderedlist && nodeName === 'ul' && !isListUpdated && !isComplexListUpdated) {
formatCollection.unorderedlist = true;
isListUpdated = true;
formatCollection.bulletFormatList = this.isBulletFormatList(currentNode);
isComplexListUpdated = formatCollection.bulletFormatList !== null ? true : false;
}
if (!formatCollection.orderedlist && nodeName === 'ol' && !isListUpdated && !isComplexListUpdated) {
formatCollection.orderedlist = true;
isListUpdated = true;
formatCollection.numberFormatList = this.isNumberFormatList(currentNode);
isComplexListUpdated = formatCollection.numberFormatList !== null ? true : false;
}
if (!formatCollection.blockquote && nodeName === 'blockquote') {
formatCollection.blockquote = true;
}
if (!formatCollection.formats) {
formatCollection.formats = this.isFormats(currentNode, formatNode);
if (formatCollection.formats === 'pre' && nodeName === 'pre' && currentNode.firstChild.nodeName !== 'CODE' && !currentNode.hasAttribute('data-language')) {
formatCollection.insertcode = true;
}
}
if (!formatCollection.isCodeBlock && currentNode.nodeName.toLocaleLowerCase() === 'pre' && currentNode.hasAttribute('data-language')) {
formatCollection.isCodeBlock = true;
}
this.collectStyles(currentNode, collectedStyles, docElement, fontName, fontSize);
currentNode = currentNode.parentNode;
}
if (collectedTags.indexOf('b') > -1 || collectedTags.indexOf('strong') > -1) {
formatCollection.bold = true;
}
if (collectedTags.indexOf('i') > -1 || collectedTags.indexOf('em') > -1) {
formatCollection.italic = true;
}
if (collectedTags.indexOf('u') > -1 || (collectedStyles['underLine'])) {
formatCollection.underline = true;
}
if (collectedTags.indexOf('s') > -1 || collectedTags.indexOf('del') > -1 || (collectedStyles['strikeThrough'])) {
formatCollection.strikethrough = true;
}
if (collectedTags.indexOf('sup') > -1) {
formatCollection.superscript = true;
}
if (collectedTags.indexOf('sub') > -1) {
formatCollection.subscript = true;
}
if (collectedStyles['color']) {
formatCollection.fontcolor = collectedStyles['color'];
}
if (collectedStyles['backgroundColor']) {
formatCollection.backgroundcolor = collectedStyles['backgroundColor'];
}
if (collectedStyles['fontFamily']) {
formatCollection.fontname = collectedStyles['fontFamily'];
}
if (collectedStyles['fontSize']) {
formatCollection.fontsize = collectedStyles['fontSize'];
}
if (collectedStyles['textAlign']) {
formatCollection.alignments = collectedStyles['textAlign'];
}
if (collectedTags.indexOf('a') > -1) {
formatCollection.createlink = true;
}
if (collectedTags.indexOf('code') > -1) {
formatCollection.inlinecode = true;
}
return formatCollection;
};
ToolbarStatus.isFontColor = function (docElement, node) {
var color = node.style && node.style.color;
if ((color === null || color === undefined || color === '') && node.nodeType !== 3) {
color = this.getComputedStyle(docElement, node, 'color');
}
if (color !== null && color !== '' && color !== undefined) {
return color;
}
else {
return null;
}
};
ToolbarStatus.isBackgroundColor = function (node) {
var backColor = node.style && node.style.backgroundColor;
if (backColor !== null && backColor !== '' && backColor !== undefined) {
return backColor;
}
else {
return null;
}
};
ToolbarStatus.isFontSize = function (docElement, node, fontSize) {
var size = node.style && node.style.fontSize;
var isInlineTags = IsFormatted.inlineTags.indexOf(node.nodeName.toLowerCase()) > -1;
if (size && node.nodeType === 1 && !isInlineTags) {
size = null;
}
if ((size === null || size === undefined || size === '') && node.nodeType !== 3 &&
node.parentElement.classList.contains('e-content')) {
size = this.getComputedStyle(docElement, node, 'font-size');
}
if ((size !== null && size !== '' && size !== undefined)
&& (fontSize === null || fontSize === undefined || (fontSize.indexOf(size) > -1))) {
return size;
}
else {
return null;
}
};
ToolbarStatus.isFontName = function (docElement, node, fontName) {
var name = node.style && node.style.fontFamily;
var isInlineTags = IsFormatted.inlineTags.indexOf(node.nodeName.toLowerCase()) > -1;
if (name && node.nodeType === 1 && !isInlineTags) {
name = null;
}
if ((name === null || name === undefined || name === '') && node.nodeType !== 3 && isInlineTags) {
name = this.getComputedStyle(docElement, node, 'font-family');
}
var index = null;
if ((name !== null && name !== '' && name !== undefined)
&& (fontName === null || fontName === undefined || (fontName.filter(function (value, pos) {
var regExp = RegExp;
var pattern = new regExp(name, 'i');
if ((value.replace(/"/g, '').replace(/ /g, '').toLowerCase() === name.replace(/"/g, '').replace(/ /g, '').toLowerCase()) ||
(value.split(',')[0] && !isNullOrUndefined(value.split(',')[0].trim().match(pattern)) &&
value.split(',')[0].trim() === value.split(',')[0].trim().match(pattern)[0])) {
index = pos;
}
}) && (index !== null)))) {
return (index !== null) ? fontName[index] : name.replace(/"/g, '');
}
else {
return null;
}
};
ToolbarStatus.isAlignment = function (node) {
var align = node.style && node.style.textAlign;
if (align === 'left') {
return 'justifyleft';
}
else if (align === 'center') {
return 'justifycenter';
}
else if (align === 'right') {
return 'justifyright';
}
else if (align === 'justify') {
return 'justifyfull';
}
else {
return null;
}
};
ToolbarStatus.isFormats = function (node, formatNode) {
var tags = ['tbody', 'tfoot', 'thead', 'ol', 'ul', 'table', 'li', 'td', 'th'];
if (((formatNode === undefined || formatNode === null)
&& CONSTANT.BLOCK_TAGS.indexOf(node.nodeName.toLocaleLowerCase()) > -1)
|| (formatNode !== null && formatNode !== undefined
&& formatNode.indexOf(node.nodeName.toLocaleLowerCase()) > -1)) {
return node.nodeName.toLocaleLowerCase();
}
else if (tags.indexOf(node.nodeName.toLocaleLowerCase()) > -1) {
return 'p';
}
else {
return null;
}
};
ToolbarStatus.getComputedStyle = function (docElement, node, prop) {
return docElement.defaultView.getComputedStyle(node, null).getPropertyValue(prop);
};
ToolbarStatus.isNumberFormatList = function (node) {
var list = node.style && node.style.listStyleType;
if (list === 'lower-alpha') {
return 'Lower Alpha';
}
else if (list === 'number') {
return 'Number';
}
else if (list === 'upper-alpha') {
return 'Upper Alpha';
}
else if (list === 'lower-roman') {
return 'Lower Roman';
}
else if (list === 'upper-roman') {
return 'Upper Roman';
}
else if (list === 'lower-greek') {
return 'Lower Greek';
}
else if (list === 'none' && node.nodeName === 'OL') {
return 'None';
}
else if (node.nodeName === 'OL') {
return true;
}
else {
return null;
}
};
ToolbarStatus.isBulletFormatList = function (node) {
var list = node.style && node.style.listStyleType;
if (list === 'circle') {
return 'Circle';
}
else if (list === 'square') {
return 'Square';
}
else if (list === 'none' && node.nodeName === 'UL') {
return 'None';
}
else if (list === 'disc') {
return 'Disc';
}
else if (node.nodeName === 'UL') {
return true;
}
else {
return null;
}
};
// collecting styles of the current node
ToolbarStatus.collectStyles = function (currentNode, collectedStyles, docElement, fontName, fontSize) {
if (!collectedStyles['color']) {
collectedStyles['color'] = this.isFontColor(docElement, currentNode);
}
if (!collectedStyles['backgroundColor']) {
collectedStyles['backgroundColor'] = this.isBackgroundColor(currentNode);
}
if (!collectedStyles['fontFamily']) {
var font = this.isFontName(docElement, currentNode, fontName);
if (font) {
collectedStyles['fontFamily'] = font;
}
}
if (!collectedStyles['fontSize']) {
var size = this.isFontSize(docElement, currentNode, fontSize);
if (size) {
collectedStyles['fontSize'] = size;
}
}
if (!collectedStyles['textAlign']) {
collectedStyles['textAlign'] = this.isAlignment(currentNode);
}
var textDecoration = null;
if (currentNode.style && currentNode.style.textDecoration) {
textDecoration = currentNode.style.textDecoration;
}
else {
textDecoration = this.getComputedStyle(docElement, currentNode, 'text-decoration');
if (currentNode.nodeName === 'A' && textDecoration.includes('underline')) {
textDecoration = null;
}
}
if (textDecoration) {
if (!collectedStyles['underLine']) {
collectedStyles['underLine'] = textDecoration.includes('underline') ? 'underline' : null;
}
if (!collectedStyles['strikeThrough']) {
collectedStyles['strikeThrough'] = textDecoration.includes('line-through') ? 'line-through' : null;
}
}
};
return ToolbarStatus;
}());
export { ToolbarStatus };