hi-mention
Version:
纯JS聊天框,兼容原生HTML/React/Vue等各种框架;支持@提及功能、插入富文本等多功能编辑器;内置H5和PC的交互样式
167 lines (166 loc) • 5.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createElement = createElement;
exports.isEmptyElement = isEmptyElement;
exports.createTextTag = createTextTag;
exports.createRowTag = createRowTag;
exports.fixEditorContent = fixEditorContent;
exports.fixRowContent = fixRowContent;
exports.createTextNode = createTextNode;
exports.createDocumentFragment = createDocumentFragment;
exports.transferElement = transferElement;
exports.isNeedFix = isNeedFix;
exports.formatString = formatString;
var const_1 = require("../const");
function createElement(type, _a) {
var _b = _a === void 0 ? {} : _a, className = _b.className, style = _b.style, content = _b.content;
var element = document.createElement(type);
if (className)
element.className = className;
if (style) {
Object.keys(style).forEach(function (key) { return (element.style[key] = style[key]); });
}
if (content) {
if (typeof content === "string")
element.innerHTML = content;
else
element.appendChild(content);
}
return element;
}
/**
* 判断一个标签是否为空标签
*/
function isEmptyElement(el) {
var text = el.innerText;
if (!text)
text = el.textContent || "";
var notContext = !text;
var newLine = text === "\n";
var isEmpty = new RegExp("^".concat(const_1.PLACEHOLDER_TEXT, "+$")).test(text);
return Boolean(notContext || newLine || isEmpty);
}
/**
* 创建一个文本标签
*/
function createTextTag(content) {
if (content === void 0) { content = const_1.PLACEHOLDER_TEXT; }
return createElement("span", { className: const_1.TEXT_TAG_CLASS, content: content });
}
/**
* 创建一个行标签
*/
function createRowTag() {
return createElement("p", { className: const_1.ROW_TAG_CLASS, content: createTextTag(const_1.NEW_LINE) });
}
/**
* 修正编辑器内容
*/
function fixEditorContent(editor) {
if (isEmptyElement(editor)) {
editor.innerHTML = "";
editor.appendChild(createElement("p", { className: const_1.ROW_TAG_CLASS, content: createTextTag(const_1.NEW_LINE) }));
return true;
}
return false;
}
/**
* 修正行内容
*/
function fixRowContent(rowEl, rangeTextEl) {
var _a, _b;
if (isEmptyElement(rowEl)) {
rowEl.innerHTML = createTextTag(const_1.NEW_LINE).outerHTML;
return;
}
if (((_a = rowEl.children[0]) === null || _a === void 0 ? void 0 : _a.className) !== const_1.TEXT_TAG_CLASS) {
rowEl.insertBefore(createTextTag(), rowEl.firstChild);
}
if (((_b = rowEl.children[rowEl.children.length - 1]) === null || _b === void 0 ? void 0 : _b.className) !== const_1.TEXT_TAG_CLASS) {
rowEl.appendChild(createTextTag(const_1.NEW_LINE));
}
// 将相邻的空节点合并
for (var i = rowEl.childNodes.length - 1; i > 0; i--) {
var prev = rowEl.childNodes[i - 1];
var next = rowEl.childNodes[i];
if (isEmptyElement(prev) && isEmptyElement(next)) {
// 不改变光标标签
if (rangeTextEl && next === rangeTextEl) {
prev.remove();
}
else {
next.remove();
}
}
}
}
function createTextNode(text) {
if (text === void 0) { text = ""; }
return document.createTextNode(text);
}
/**
* 创建一个空节点用来装载子元素
* @returns
*/
function createDocumentFragment() {
var fr = document.createDocumentFragment();
return fr;
}
/**
* 将一个元素的内容转移到另外一个元素下面
* @param el 需要移动的元素
* @param target 目标元素
*/
function transferElement(el, target) {
// 先合并紧挨着的相同的元素(text元素和text文本)
var children = [];
for (var i = el.childNodes.length - 1; i >= 0; i--) {
var child = el.childNodes[i];
if (child.nodeName === "#text" || child.className === const_1.TEXT_TAG_CLASS) {
var content = child.textContent || "";
var prevChild = el.childNodes[i - 1];
if (prevChild && (prevChild.nodeName === "#text" || prevChild.className === const_1.TEXT_TAG_CLASS)) {
content = (child.textContent || "") + (prevChild.textContent || "");
el.removeChild(prevChild);
i--;
}
content = formatString(content, true);
child.textContent = content;
}
children.unshift(child);
}
var fr = createDocumentFragment();
var targetIsRow = target.className === const_1.ROW_TAG_CLASS;
children.forEach(function (node) {
var el = targetIsRow && node.nodeName === "#text" ? createTextTag(node.textContent || const_1.PLACEHOLDER_TEXT) : node;
fr.appendChild(el);
});
target.appendChild(fr);
}
/**
* 判断文本内容是否需要修正
*/
function isNeedFix(textEl) {
var text = textEl.textContent || "";
if (!text)
return false;
var textNodeNum = 0;
for (var i = 0; i < textEl.childNodes.length; i++) {
if (textEl.childNodes[i].textContent)
textNodeNum++;
if (textNodeNum > 1)
return true;
}
var br = textEl.querySelector("br");
return Boolean(br || new RegExp("\n|".concat(const_1.PLACEHOLDER_TEXT, "|\r")).test(text));
}
/**
* 格式化字符串,删除字符串中的\n和连续的\r
*/
function formatString(str, isPlaceholder) {
if (isPlaceholder === void 0) { isPlaceholder = false; }
if (!str)
return isPlaceholder ? const_1.PLACEHOLDER_TEXT : "";
var result = str.replace(/\r+/g, "\r").replace(/\n+/g, "").replace(new RegExp(const_1.PLACEHOLDER_TEXT, "g"), "");
return result ? result : isPlaceholder ? const_1.PLACEHOLDER_TEXT : "";
}