UNPKG

@syncfusion/ej2-richtexteditor

Version:
443 lines (440 loc) 21.2 kB
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 };