hi-mention
Advanced tools
Comparing version 2.1.0 to 2.2.0
{ | ||
"name": "hi-mention", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"main": "index", | ||
@@ -5,0 +5,0 @@ "types": "index.d.ts", |
@@ -256,9 +256,12 @@ # Mention 提及 | ||
```html | ||
v2.2.0 2024-10-27 | ||
- 对v2.1.0版本BUG继续修复 | ||
v2.1.0 2024-10-26 | ||
- 修复剪切、复制、粘贴 BUG | ||
- 修复移动光标 BUG | ||
- 修复换行 BUG | ||
- 修复删除 BUG | ||
- 修复焦点 BUG | ||
- 修复占位符展示异常 BUG | ||
- 修复剪切、复制、粘贴 | ||
- 修复移动光标 | ||
- 修复换行 | ||
- 修复删除 | ||
- 修复焦点 | ||
- 修复占位符展示异常 | ||
- 针对火狐浏览器做兼容处理 | ||
@@ -265,0 +268,0 @@ |
@@ -8,4 +8,7 @@ import UserSelector from "./UserSelector"; | ||
constructor(el: Element | HTMLElement | string, option?: Partial<MentionOptions>); | ||
protected addHistory(): void; | ||
protected undoHistory(e: KeyboardEvent): boolean; | ||
protected onUndoHistory(e: KeyboardEvent): boolean; | ||
protected selectAll(): void; | ||
protected onSelectAll(e: KeyboardEvent): boolean; | ||
protected shearContent(): true | undefined; | ||
protected onShearContent(e: KeyboardEvent): boolean; | ||
protected moveCursor(direction: "ArrowLeft" | "ArrowRight"): void; | ||
@@ -12,0 +15,0 @@ protected onMoveCursor(e: KeyboardEvent): boolean; |
@@ -13,2 +13,38 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); | ||
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (g && (g = 0, op[0] && (_ = 0)), _) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -111,4 +147,4 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
e.preventDefault(); | ||
this._onchange(); // 不触发默认行为,需要手动触发change事件 | ||
this._inputEvent(); | ||
this._onchange(); // 不触发默认行为,需要手动触发change事件 | ||
return; | ||
@@ -119,7 +155,7 @@ } | ||
e.preventDefault(); | ||
this._onchange(); // 不触发默认行为,需要手动触发change事件 | ||
this._inputEvent(); | ||
this._onchange(); // 不触发默认行为,需要手动触发change事件 | ||
return; | ||
} | ||
bool = this.undoHistory(e); | ||
bool = this.onMoveCursor(e); | ||
if (bool) { | ||
@@ -129,3 +165,3 @@ e.preventDefault(); | ||
} | ||
bool = this.onMoveCursor(e); | ||
bool = this.onUndoHistory(e); | ||
if (bool) { | ||
@@ -135,2 +171,12 @@ e.preventDefault(); | ||
} | ||
bool = this.onSelectAll(e); | ||
if (bool) { | ||
e.preventDefault(); | ||
return; | ||
} | ||
bool = this.onShearContent(e); | ||
if (bool) { | ||
e.preventDefault(); | ||
return; | ||
} | ||
this._events["keydowns"].forEach(function (fn) { return fn(e); }); | ||
@@ -147,4 +193,4 @@ }; | ||
Mention.prototype._oncut = function (e) { | ||
this._onchange(); | ||
this._inputEvent(); | ||
this._onchange(); | ||
}; | ||
@@ -165,15 +211,19 @@ Mention.prototype._onpaste = function (e) { | ||
return; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
range.deleteContents(); | ||
range.insertNode(document.createTextNode(text)); | ||
// 修正光标位置 | ||
range.setStart(range.endContainer, range.endOffset); | ||
range.collapse(true); | ||
if (!range.collapsed) { | ||
(0, range_1.removeRangeContent)(range, { startEls: els, endEls: els }); | ||
} | ||
else { | ||
(0, range_1.fixTextContent)(range, els); | ||
} | ||
range.insertNode((0, index_1.createTextNode)(text)); | ||
// 修正行元素 | ||
(0, index_1.fixRowContent)(els.rowEl); | ||
this._onchange(); | ||
this._inputEvent(); | ||
this._onchange(); | ||
}; | ||
Mention.prototype._onchange = function () { | ||
var _this = this; | ||
if ((0, index_1.fixEditorContent)(this._editorEl)) { | ||
this.focus(); | ||
} | ||
var text = this._editorEl.textContent; | ||
@@ -191,3 +241,2 @@ var reg = new RegExp("^[\n".concat(const_1.PLACEHOLDER_TEXT, "\r]*$")); | ||
_this._events["changes"].forEach(function (fn) { return fn({ text: _this._editorEl.textContent || "", html: html }); }); | ||
_this.addHistory(); | ||
}, 300); | ||
@@ -197,5 +246,2 @@ }; | ||
var _a, _b, _c; | ||
if ((0, index_1.fixEditorContent)(this._editorEl)) { | ||
this.focus(); | ||
} | ||
var selection = (0, range_1.getSelection)(); | ||
@@ -229,7 +275,4 @@ if (!((_a = selection === null || selection === void 0 ? void 0 : selection.anchorNode) === null || _a === void 0 ? void 0 : _a.textContent)) | ||
}; | ||
Mention.prototype.addHistory = function () { | ||
// 记录内容变化:待开发 | ||
}; | ||
Mention.prototype.undoHistory = function (e) { | ||
if (e.ctrlKey && ["Z", "z"].includes(e.key)) { | ||
Mention.prototype.onUndoHistory = function (e) { | ||
if (e.ctrlKey && e.code === "KeyZ") { | ||
console.log("撤销:开发中!!!"); | ||
@@ -240,2 +283,65 @@ return true; | ||
}; | ||
Mention.prototype.selectAll = function () { | ||
if ((0, index_1.isEmptyElement)(this._editorEl)) | ||
return; | ||
var range = (0, range_1.getRangeAt)(); | ||
if (!range) | ||
return; | ||
var tRow = this._editorEl.children[0]; | ||
var tfow = this._editorEl.children[this._editorEl.children.length - 1]; | ||
if (tRow) | ||
(0, range_1.moveRangeAtRowStart)(range, tRow, false); | ||
if (tfow) | ||
(0, range_1.moveRangeAtRowEnd)(range, tfow, false); | ||
}; | ||
Mention.prototype.onSelectAll = function (e) { | ||
if (e.ctrlKey && e.code === "KeyA") { | ||
this.selectAll(); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
Mention.prototype.shearContent = function () { | ||
var _this = this; | ||
var range = (0, range_1.getRangeAt)(); | ||
if (!range) | ||
return; | ||
if (!range.collapsed) { | ||
var content_1 = (0, range_1.removeRangeContent)(range); | ||
this._onchange(); | ||
this._inputEvent(); | ||
// 将内容写入剪切板 | ||
if (content_1) { | ||
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () { | ||
var err_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 3]); | ||
// 将文本写入剪贴板 | ||
return [4 /*yield*/, navigator.clipboard.writeText(content_1)]; | ||
case 1: | ||
// 将文本写入剪贴板 | ||
_a.sent(); | ||
console.info("剪切板写入内容:", content_1); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
err_1 = _a.sent(); | ||
console.error("内容写入剪切板失败: ", err_1); | ||
return [3 /*break*/, 3]; | ||
case 3: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }); | ||
} | ||
} | ||
return true; | ||
}; | ||
Mention.prototype.onShearContent = function (e) { | ||
if (e.ctrlKey && e.code === "KeyX") { | ||
this.shearContent(); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
Mention.prototype.moveCursor = function (direction) { | ||
@@ -347,3 +453,3 @@ return (0, moveCursor_1.default)(direction); | ||
// 插入span元素 | ||
(0, index_1.insertElement)(span, range); | ||
(0, range_1.insertElement)(span, range); | ||
this._events["mention-users"].forEach(function (fn) { return fn(user); }); | ||
@@ -377,3 +483,3 @@ this._onchange(); | ||
return this; | ||
(0, index_1.insertText)(text, range); | ||
(0, range_1.insertText)(text, range); | ||
this._onchange(); | ||
@@ -397,3 +503,3 @@ range.collapse(false); | ||
return this; | ||
(0, index_1.insertElement)(html, range); | ||
(0, range_1.insertElement)(html, range); | ||
this._onchange(); | ||
@@ -400,0 +506,0 @@ range.collapse(false); |
@@ -53,1 +53,6 @@ export interface UserInfo { | ||
} | ||
export interface RangeElsType { | ||
editorEl: HTMLElement; | ||
rowEl: HTMLElement; | ||
textEl: HTMLElement; | ||
} |
@@ -0,0 +0,0 @@ import { UserInfo, UserSelectorOptions } from "./types"; |
@@ -1,2 +0,2 @@ | ||
export declare const createElement: <K extends keyof HTMLElementTagNameMap>(type: K, { className, style, content }?: { | ||
export declare function createElement<K extends keyof HTMLElementTagNameMap>(type: K, { className, style, content }?: { | ||
className?: string; | ||
@@ -6,25 +6,25 @@ style?: { | ||
}; | ||
content?: string | HTMLElement; | ||
}) => HTMLElementTagNameMap[K]; | ||
content?: string | HTMLElement | Text | Node | Element; | ||
}): HTMLElementTagNameMap[K]; | ||
/** | ||
* 判断一个标签是否为空标签 | ||
*/ | ||
export declare const isEmptyElement: (el: HTMLElement | Node) => boolean; | ||
export declare function isEmptyElement(el: HTMLElement | Node): boolean; | ||
/** | ||
* 创建一个文本标签 | ||
*/ | ||
export declare const createTextTag: (content?: string) => HTMLElement; | ||
export declare function createTextTag(content?: string | Text): HTMLElement; | ||
/** | ||
* 创建一个行标签 | ||
*/ | ||
export declare const createRowTag: () => HTMLElement; | ||
export declare function createRowTag(): HTMLElement; | ||
/** | ||
* 修正编辑器内容 | ||
*/ | ||
export declare const fixEditorContent: (editor: HTMLElement) => boolean; | ||
export declare function fixEditorContent(editor: HTMLElement): boolean; | ||
/** | ||
* 修正行内容 | ||
*/ | ||
export declare const fixRowContent: (rowEl: HTMLElement, rangeTextEl?: HTMLElement) => void; | ||
export declare const createTextNode: (text?: string) => Text; | ||
export declare function fixRowContent(rowEl: HTMLElement, rangeTextEl?: HTMLElement): void; | ||
export declare function createTextNode(text?: string): Text; | ||
/** | ||
@@ -34,22 +34,16 @@ * 创建一个空节点用来装载子元素 | ||
*/ | ||
export declare const createDocumentFragment: () => DocumentFragment; | ||
export declare function createDocumentFragment(): DocumentFragment; | ||
/** | ||
* 插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
*/ | ||
export declare const insertText: (text: string, range: Range) => boolean; | ||
export declare function transferElement(el: Element | Node, target: HTMLElement | Node): void; | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
* 判断文本内容是否需要修正 | ||
*/ | ||
export declare const insertElement: (el: HTMLElement, range: Range) => boolean; | ||
export declare function isNeedFix(textEl: HTMLElement): boolean; | ||
/** | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
* 格式化字符串,删除字符串中的\n和连续的\r | ||
*/ | ||
export declare const transferElement: (el: Element | Node, target: HTMLElement | Node) => void; | ||
export declare function formatString(str?: string, isPlaceholder?: boolean): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.transferElement = exports.insertElement = exports.insertText = exports.createDocumentFragment = exports.createTextNode = exports.fixRowContent = exports.fixEditorContent = exports.createRowTag = exports.createTextTag = exports.isEmptyElement = exports.createElement = void 0; | ||
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"); | ||
var range_1 = require("./range"); | ||
var createElement = function (type, _a) { | ||
function createElement(type, _a) { | ||
var _b = _a === void 0 ? {} : _a, className = _b.className, style = _b.style, content = _b.content; | ||
@@ -14,13 +23,14 @@ var element = document.createElement(type); | ||
} | ||
if (content && typeof content === "string") | ||
element.innerHTML = content; | ||
else if (content && typeof content === "object") | ||
element.appendChild(content); | ||
if (content) { | ||
if (typeof content === "string") | ||
element.innerHTML = content; | ||
else | ||
element.appendChild(content); | ||
} | ||
return element; | ||
}; | ||
exports.createElement = createElement; | ||
} | ||
/** | ||
* 判断一个标签是否为空标签 | ||
*/ | ||
var isEmptyElement = function (el) { | ||
function isEmptyElement(el) { | ||
var text = el.innerText; | ||
@@ -31,47 +41,43 @@ if (!text) | ||
var newLine = text === "\n"; | ||
var isEmpty = text === const_1.PLACEHOLDER_TEXT; | ||
var isEmpty = new RegExp("^".concat(const_1.PLACEHOLDER_TEXT, "+$")).test(text); | ||
return Boolean(notContext || newLine || isEmpty); | ||
}; | ||
exports.isEmptyElement = isEmptyElement; | ||
} | ||
/** | ||
* 创建一个文本标签 | ||
*/ | ||
var createTextTag = function (content) { | ||
function createTextTag(content) { | ||
if (content === void 0) { content = const_1.PLACEHOLDER_TEXT; } | ||
return (0, exports.createElement)("span", { className: const_1.TEXT_TAG_CLASS, content: content }); | ||
}; | ||
exports.createTextTag = createTextTag; | ||
return createElement("span", { className: const_1.TEXT_TAG_CLASS, content: content }); | ||
} | ||
/** | ||
* 创建一个行标签 | ||
*/ | ||
var createRowTag = function () { | ||
return (0, exports.createElement)("p", { className: const_1.ROW_TAG_CLASS, content: (0, exports.createTextTag)(const_1.NEW_LINE) }); | ||
}; | ||
exports.createRowTag = createRowTag; | ||
function createRowTag() { | ||
return createElement("p", { className: const_1.ROW_TAG_CLASS, content: createTextTag(const_1.NEW_LINE) }); | ||
} | ||
/** | ||
* 修正编辑器内容 | ||
*/ | ||
var fixEditorContent = function (editor) { | ||
if ((0, exports.isEmptyElement)(editor)) { | ||
function fixEditorContent(editor) { | ||
if (isEmptyElement(editor)) { | ||
editor.innerHTML = ""; | ||
editor.appendChild((0, exports.createElement)("p", { className: const_1.ROW_TAG_CLASS, content: (0, exports.createTextTag)(const_1.NEW_LINE) })); | ||
editor.appendChild(createElement("p", { className: const_1.ROW_TAG_CLASS, content: createTextTag(const_1.NEW_LINE) })); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
exports.fixEditorContent = fixEditorContent; | ||
} | ||
/** | ||
* 修正行内容 | ||
*/ | ||
var fixRowContent = function (rowEl, rangeTextEl) { | ||
function fixRowContent(rowEl, rangeTextEl) { | ||
var _a, _b; | ||
if ((0, exports.isEmptyElement)(rowEl)) { | ||
rowEl.innerHTML = (0, exports.createTextTag)(const_1.NEW_LINE).outerHTML; | ||
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((0, exports.createTextTag)(), rowEl.firstChild); | ||
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((0, exports.createTextTag)(const_1.NEW_LINE)); | ||
rowEl.appendChild(createTextTag(const_1.NEW_LINE)); | ||
} | ||
@@ -82,3 +88,3 @@ // 将相邻的空节点合并 | ||
var next = rowEl.childNodes[i]; | ||
if ((0, exports.isEmptyElement)(prev) && (0, exports.isEmptyElement)(next)) { | ||
if (isEmptyElement(prev) && isEmptyElement(next)) { | ||
// 不改变光标标签 | ||
@@ -93,12 +99,7 @@ if (rangeTextEl && next === rangeTextEl) { | ||
} | ||
// 删除br标签 | ||
var brs = rowEl.querySelectorAll("br"); | ||
brs.forEach(function (br) { return br.remove(); }); | ||
}; | ||
exports.fixRowContent = fixRowContent; | ||
var createTextNode = function (text) { | ||
} | ||
function createTextNode(text) { | ||
if (text === void 0) { text = ""; } | ||
return document.createTextNode(text); | ||
}; | ||
exports.createTextNode = createTextNode; | ||
} | ||
/** | ||
@@ -108,104 +109,63 @@ * 创建一个空节点用来装载子元素 | ||
*/ | ||
var createDocumentFragment = function () { | ||
function createDocumentFragment() { | ||
var fr = document.createDocumentFragment(); | ||
return fr; | ||
}; | ||
exports.createDocumentFragment = createDocumentFragment; | ||
} | ||
/** | ||
* 插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
*/ | ||
var insertText = function (text, range) { | ||
var commonEl = range.commonAncestorContainer; | ||
if (!["BR", "#text"].includes(commonEl === null || commonEl === void 0 ? void 0 : commonEl.nodeName) && commonEl.className !== const_1.TEXT_TAG_CLASS) | ||
return false; | ||
if (commonEl.nodeName === "BR") { | ||
var els = (0, range_1.rangeEls)(range); | ||
if (!els) | ||
return false; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
els.textEl.removeChild(range.commonAncestorContainer); | ||
els.textEl.innerHTML = text; | ||
// 修正光标位置 | ||
(0, range_1.moveRangeAtRowEnd)(range, els.rowEl); | ||
return true; | ||
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); | ||
} | ||
range.insertNode((0, exports.createTextNode)(text)); | ||
return true; | ||
}; | ||
exports.insertText = insertText; | ||
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); | ||
} | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
* 判断文本内容是否需要修正 | ||
*/ | ||
var insertElement = function (el, range) { | ||
var _a, _b, _c; | ||
var commonEl = range.commonAncestorContainer; | ||
if (!["BR", "#text"].includes(commonEl === null || commonEl === void 0 ? void 0 : commonEl.nodeName) && commonEl.className !== const_1.TEXT_TAG_CLASS) | ||
function isNeedFix(textEl) { | ||
var text = textEl.textContent || ""; | ||
if (!text) | ||
return false; | ||
var els = (0, range_1.rangeEls)(range); | ||
if (!els) | ||
return false; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
// 如果当前文本元素是个空元素 | ||
if (!els.textEl.textContent) { | ||
var t = (0, exports.createTextNode)(const_1.PLACEHOLDER_TEXT); | ||
els.textEl.appendChild(t); | ||
// 修正光标位置 | ||
range.setStart(t, 0); | ||
range.collapse(true); | ||
var textNodeNum = 0; | ||
for (var i = 0; i < textEl.childNodes.length; i++) { | ||
if (textEl.childNodes[i].textContent) | ||
textNodeNum++; | ||
if (textNodeNum > 1) | ||
return true; | ||
} | ||
el.setAttribute("contenteditable", "false"); | ||
// 如果当前光标在文本节点开头,则将元素插入到文本节点之前 | ||
if (range.startOffset === 0) { | ||
// 获取当前textEL的前一个兄弟节点 | ||
var prevEl = els.textEl.previousElementSibling; | ||
if (!prevEl || prevEl.className !== const_1.TEXT_TAG_CLASS) { | ||
els.textEl.insertAdjacentElement("beforebegin", (0, exports.createTextTag)()); | ||
} | ||
els.textEl.insertAdjacentElement("beforebegin", el); | ||
return true; | ||
} | ||
else if (range.endOffset === ((_a = range.endContainer.textContent) === null || _a === void 0 ? void 0 : _a.length)) { | ||
// 获取当前textEL的下一个兄弟节点 | ||
var nextEl = els.textEl.nextElementSibling; | ||
if (!nextEl || nextEl.className !== const_1.TEXT_TAG_CLASS) { | ||
nextEl = (0, exports.createTextTag)(); | ||
els.textEl.insertAdjacentElement("afterend", nextEl); | ||
} | ||
els.textEl.insertAdjacentElement("afterend", el); | ||
// 更新光标位置 | ||
range.setStart(nextEl, 0); | ||
range.collapse(true); | ||
return true; | ||
} | ||
// 如果当前光标在文本节点中间,则将文本节点分割为两个,并将元素插入到中间 | ||
var text1 = ((_b = range.endContainer.textContent) === null || _b === void 0 ? void 0 : _b.slice(0, range.endOffset)) || const_1.PLACEHOLDER_TEXT; | ||
var text2 = ((_c = range.endContainer.textContent) === null || _c === void 0 ? void 0 : _c.slice(range.endOffset)) || const_1.PLACEHOLDER_TEXT; | ||
range.endContainer.textContent = text1; | ||
var textEl2 = (0, exports.createTextTag)(text2); | ||
els.textEl.insertAdjacentElement("afterend", textEl2); | ||
els.textEl.insertAdjacentElement("afterend", el); | ||
// 更新光标位置 | ||
range.setStart(textEl2.childNodes[0], 0); | ||
range.collapse(true); | ||
return true; | ||
}; | ||
exports.insertElement = insertElement; | ||
var br = textEl.querySelector("br"); | ||
return Boolean(br || new RegExp("\n|".concat(const_1.PLACEHOLDER_TEXT, "|\r")).test(text)); | ||
} | ||
/** | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
* 格式化字符串,删除字符串中的\n和连续的\r | ||
*/ | ||
var transferElement = function (el, target) { | ||
var fr = (0, exports.createDocumentFragment)(); | ||
while (el.firstChild) { | ||
fr.appendChild(el.firstChild); | ||
} | ||
target.appendChild(fr); | ||
}; | ||
exports.transferElement = transferElement; | ||
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 : ""; | ||
} |
@@ -15,3 +15,3 @@ "use strict"; | ||
return; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
(0, range_1.fixTextContent)(range, els); | ||
// 判断是否需要换行 | ||
@@ -18,0 +18,0 @@ if (type === "ArrowLeft" && (0, range_1.isRangeAtRowStart)(range, els.rowEl)) { |
@@ -0,1 +1,2 @@ | ||
import { RangeElsType } from "../types"; | ||
export declare function getSelection(): Selection | null; | ||
@@ -15,15 +16,11 @@ /** | ||
*/ | ||
export declare function moveRangeAtRowEnd(range: Range, rowEl: HTMLElement): void; | ||
export declare function moveRangeAtRowEnd(range: Range, rowEl: HTMLElement, merge?: boolean): void; | ||
/** | ||
* 将光标位置移动到当前行的开头 | ||
*/ | ||
export declare function moveRangeAtRowStart(range: Range, rowEl: HTMLElement): void; | ||
export declare function moveRangeAtRowStart(range: Range, rowEl: HTMLElement, merge?: boolean): void; | ||
/** | ||
* 修正光标位置,并获取当前光标所在的编辑器/行/文本 | ||
*/ | ||
export declare function rangeEls(range: Range, which?: "end" | "start" | "common"): { | ||
editorEl: HTMLElement; | ||
rowEl: HTMLElement; | ||
textEl: HTMLElement; | ||
} | null; | ||
export declare function rangeEls(range: Range, which?: "end" | "start" | "common"): RangeElsType | null; | ||
/** | ||
@@ -46,4 +43,26 @@ * 判断光标是否在当前行的末尾 | ||
/** | ||
* 修正文本标签光标 | ||
* 修正文本标签内容 | ||
*/ | ||
export declare function fixTextRange(range: Range, textEl: HTMLElement): void; | ||
export declare function fixTextContent(range: Range, els?: RangeElsType): void; | ||
/** | ||
* 删除选中区域内的所有元素 | ||
*/ | ||
export declare function removeRangeContent(range: Range, { startEls, endEls, mergeRow }?: { | ||
startEls?: RangeElsType; | ||
endEls?: RangeElsType; | ||
mergeRow?: boolean; | ||
}): string; | ||
/** | ||
* 在光标位置插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
export declare function insertText(text: string, range: Range): boolean; | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
export declare function insertElement(el: HTMLElement, range: Range): boolean; |
@@ -13,3 +13,6 @@ "use strict"; | ||
exports.isRangeAtTextStart = isRangeAtTextStart; | ||
exports.fixTextRange = fixTextRange; | ||
exports.fixTextContent = fixTextContent; | ||
exports.removeRangeContent = removeRangeContent; | ||
exports.insertText = insertText; | ||
exports.insertElement = insertElement; | ||
var _1 = require("."); | ||
@@ -69,4 +72,5 @@ var const_1 = require("../const"); | ||
*/ | ||
function moveRangeAtRowEnd(range, rowEl) { | ||
var _a, _b; | ||
function moveRangeAtRowEnd(range, rowEl, merge) { | ||
var _a; | ||
if (merge === void 0) { merge = true; } | ||
// 获取最后一个文本标签 | ||
@@ -82,6 +86,7 @@ var lastText = rowEl.children[rowEl.children.length - 1]; | ||
var textNode = lastText.lastChild; | ||
var lastTextLength = (textNode ? (_a = textNode.textContent) === null || _a === void 0 ? void 0 : _a.length : (_b = lastText.textContent) === null || _b === void 0 ? void 0 : _b.length) || 0; | ||
var lastTextLength = (textNode ? (_a = textNode.textContent) === null || _a === void 0 ? void 0 : _a.length : lastText.childNodes.length) || 0; | ||
// 设置光标位置 | ||
range.setStart(textNode ? textNode : lastText, lastTextLength); | ||
range.collapse(true); | ||
range.setEnd(textNode ? textNode : lastText, lastTextLength); | ||
if (merge) | ||
range.collapse(); | ||
} | ||
@@ -91,3 +96,4 @@ /** | ||
*/ | ||
function moveRangeAtRowStart(range, rowEl) { | ||
function moveRangeAtRowStart(range, rowEl, merge) { | ||
if (merge === void 0) { merge = true; } | ||
// 获取第一个文本标签 | ||
@@ -104,3 +110,4 @@ var firstText = rowEl.children[0]; | ||
range.setStart(textNode ? textNode : firstText, 0); | ||
range.collapse(true); | ||
if (merge) | ||
range.collapse(true); | ||
} | ||
@@ -111,2 +118,3 @@ /** | ||
function rangeEls(range, which) { | ||
var _a, _b, _c; | ||
if (which === void 0) { which = "common"; } | ||
@@ -119,17 +127,18 @@ // 光标所在的编辑器 | ||
var textEl = null; | ||
var el; | ||
var rangeEl; | ||
var rangeIndex = which === "start" ? range.startOffset : range.endOffset; | ||
if (which === "end") { | ||
el = range.endContainer; | ||
rangeEl = range.endContainer; | ||
} | ||
else if (which === "start") { | ||
el = range.startContainer; | ||
rangeEl = range.startContainer; | ||
} | ||
else { | ||
el = range.commonAncestorContainer; | ||
rangeEl = range.commonAncestorContainer; | ||
} | ||
if (!el) | ||
if (!rangeEl) | ||
return null; | ||
// 向上找节点,最多找10层 | ||
for (var i = 0; i < 10 && !editorEl; i++) { | ||
if (el.className === const_1.TEXT_TAG_CLASS) { | ||
for (var i = 0, el = rangeEl; i < 10 && !editorEl; i++) { | ||
if (el.className === const_1.TEXT_TAG_CLASS || ((_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.className) === const_1.ROW_TAG_CLASS) { | ||
textEl = el; | ||
@@ -148,28 +157,72 @@ } | ||
return null; | ||
if (textEl && rowEl) | ||
return { editorEl: editorEl, rowEl: rowEl, textEl: textEl }; | ||
if (which !== "common") | ||
return null; | ||
// 查找当前光标,如果光标不在文本标签中,修正光标位置 | ||
if (!rowEl) { | ||
var index = range.startOffset > editorEl.childNodes.length - 1 ? editorEl.childNodes.length - 1 : range.startOffset; | ||
rowEl = editorEl.childNodes[index]; | ||
if (!rowEl || rowEl.className !== const_1.ROW_TAG_CLASS) { | ||
// 如果不在行内,则将当前光标所在的内容全部转移到新的一行 | ||
var textContent = rangeEl.textContent; | ||
rangeEl.remove(); | ||
var index_1 = rangeIndex > editorEl.childNodes.length - 1 ? editorEl.childNodes.length - 1 : rangeIndex; | ||
rowEl = editorEl.childNodes[index_1]; | ||
if (!rowEl || rowEl.className !== const_1.ROW_TAG_CLASS) { | ||
textEl = (0, _1.createTextTag)(const_1.NEW_LINE); | ||
rowEl = (0, _1.createElement)("p", { className: const_1.ROW_TAG_CLASS, content: textEl }); | ||
textEl = (0, _1.createTextTag)(textContent ? textContent : const_1.NEW_LINE); | ||
rowEl = (0, _1.createElement)("p", { className: const_1.ROW_TAG_CLASS }); | ||
rowEl.appendChild(textEl); | ||
editorEl.appendChild(rowEl); | ||
} | ||
if (!textEl) { | ||
textEl = rowEl.children[rowEl.children.length - 1]; | ||
if (textEl.className !== const_1.TEXT_TAG_CLASS) { | ||
textEl = (0, _1.createTextTag)(textContent ? textContent : const_1.NEW_LINE); | ||
rowEl.appendChild(textEl); | ||
} | ||
} | ||
rangeIndex = which === "start" ? 0 : rowEl.childNodes.length; | ||
} | ||
textEl = rowEl.children[rowEl.children.length - 1]; | ||
if (!textEl || textEl.className !== const_1.TEXT_TAG_CLASS) { | ||
textEl = (0, _1.createTextTag)(rowEl.children.length > 0 ? const_1.PLACEHOLDER_TEXT : const_1.NEW_LINE); | ||
if (!textEl || textEl.nodeName === "#text") { | ||
// 如果不在行内,则将当前光标所在的内容全部转移到新的一行 | ||
var textContent = rangeEl.textContent; | ||
rangeEl.remove(); | ||
textEl = (0, _1.createTextTag)(textContent ? textContent : rowEl.children.length > 0 ? const_1.PLACEHOLDER_TEXT : const_1.NEW_LINE); | ||
rowEl.appendChild(textEl); | ||
rangeIndex = which === "start" ? 0 : rowEl.childNodes.length; | ||
} | ||
// 如果光标位置不在TEXT节点上,修正光标位置 | ||
if (range.commonAncestorContainer.nodeName !== "#text") { | ||
var tNode = textEl.firstChild; | ||
// 设置光标位置 | ||
range.setStart(tNode ? tNode : textEl, 0); | ||
range.collapse(true); | ||
var _while = 0; // 防止死循环 | ||
while (textEl.className !== const_1.TEXT_TAG_CLASS && _while < 10) { | ||
if (which === "start") { | ||
textEl = textEl.previousElementSibling; | ||
var textNode_1 = textEl.lastChild; | ||
range.setStart(textNode_1 ? textNode_1 : textEl, (textNode_1 ? (_b = textNode_1.textContent) === null || _b === void 0 ? void 0 : _b.length : textEl.childNodes.length) || 0); | ||
} | ||
else { | ||
textEl = textEl.nextElementSibling; | ||
var textNode_2 = textEl.firstChild; | ||
range.setEnd(textNode_2 ? textNode_2 : textEl, 0); | ||
} | ||
_while++; | ||
} | ||
if (_while) { | ||
rangeIndex = which === "start" ? 0 : rowEl.childNodes.length; | ||
} | ||
// 查找当前光标,如果光标不在文本标签中,修正光标位置 | ||
var textNode = null; | ||
var index = 0; | ||
if (rangeEl === rowEl) { | ||
var _textEl = (which === "start" ? rowEl.childNodes[0] : rowEl.childNodes[rangeIndex - 1]); | ||
if ((_textEl === null || _textEl === void 0 ? void 0 : _textEl.className) !== const_1.TEXT_TAG_CLASS) { | ||
_textEl = (which === "start" ? rowEl.firstElementChild : rowEl.lastElementChild); | ||
} | ||
textNode = (which === "start" ? _textEl.firstElementChild : _textEl.lastElementChild); | ||
} | ||
else if (rangeEl === textEl) { | ||
textNode = (which === "start" ? textEl.firstElementChild : textEl.lastElementChild); | ||
} | ||
if (textNode) { | ||
index = which === "start" ? 0 : ((_c = textNode.textContent) === null || _c === void 0 ? void 0 : _c.length) || 0; | ||
if (which === "start") { | ||
range.setStart(textNode, index); | ||
} | ||
else { | ||
range.setEnd(textNode, index); | ||
} | ||
if (which === "common") | ||
range.collapse(false); | ||
} | ||
return { editorEl: editorEl, rowEl: rowEl, textEl: textEl }; | ||
@@ -181,2 +234,4 @@ } | ||
function isRangeAtRowEnd(range, rowEl) { | ||
if (range.startContainer === rowEl && range.startOffset === rowEl.childNodes.length) | ||
return true; | ||
var els = rangeEls(range); | ||
@@ -189,4 +244,2 @@ if (!els) | ||
return false; | ||
if (range.endContainer === rowEl && range.endOffset === rowEl.childNodes.length) | ||
return true; | ||
return isRangeAtTextEnd(range); | ||
@@ -198,7 +251,31 @@ } | ||
function isRangeAtTextEnd(range) { | ||
var _a, _b, _c, _d; | ||
var textEl = range.endContainer; | ||
if (((_a = textEl.textContent) === null || _a === void 0 ? void 0 : _a[((_b = textEl.textContent) === null || _b === void 0 ? void 0 : _b.length) - 1]) === const_1.PLACEHOLDER_TEXT && range.endOffset === ((_c = textEl.textContent) === null || _c === void 0 ? void 0 : _c.length) - 1) | ||
var _a, _b, _c, _d, _e; | ||
var rangeEl = range.endContainer; | ||
var textEl = rangeEl; | ||
if (textEl.className !== const_1.TEXT_TAG_CLASS && textEl.parentElement) { | ||
textEl = textEl.parentElement; | ||
} | ||
if (rangeEl.className === const_1.TEXT_TAG_CLASS && range.endOffset === rangeEl.childNodes.length) | ||
return true; | ||
return range.endOffset === ((_d = textEl.textContent) === null || _d === void 0 ? void 0 : _d.length); | ||
if (Number((_a = textEl.textContent) === null || _a === void 0 ? void 0 : _a.length) === 0) | ||
return true; | ||
if (Number((_b = textEl.textContent) === null || _b === void 0 ? void 0 : _b.length) === 1) { | ||
if (textEl.textContent === const_1.PLACEHOLDER_TEXT) | ||
return true; | ||
if (textEl.textContent === "\n") | ||
return true; | ||
if (rangeEl.nodeName === "BR") | ||
return true; | ||
} | ||
if (rangeEl.nodeName === "#text") { | ||
if (range.endOffset < Number((_c = rangeEl.textContent) === null || _c === void 0 ? void 0 : _c.length)) | ||
return false; | ||
var nodeIndex = Array.from(((_d = rangeEl.parentElement) === null || _d === void 0 ? void 0 : _d.childNodes) || []).indexOf(rangeEl); | ||
for (var i = nodeIndex + 1; i < textEl.childNodes.length; i++) { | ||
if ((_e = textEl.childNodes[i].textContent) === null || _e === void 0 ? void 0 : _e.trim()) | ||
return false; | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
@@ -210,2 +287,4 @@ /** | ||
// 如果不是0宽占位符就必须是0 | ||
if (range.startContainer === rowEl && range.startOffset === 0) | ||
return true; | ||
if (range.commonAncestorContainer.textContent !== const_1.PLACEHOLDER_TEXT && range.startOffset !== 0) | ||
@@ -220,4 +299,2 @@ return false; | ||
return false; | ||
if (range.startContainer === rowEl && range.startOffset === 0) | ||
return true; | ||
return isRangeAtTextStart(range); | ||
@@ -229,60 +306,285 @@ } | ||
function isRangeAtTextStart(range) { | ||
var _a; | ||
var textEl = range.startContainer; | ||
if (((_a = textEl.textContent) === null || _a === void 0 ? void 0 : _a[0]) === const_1.PLACEHOLDER_TEXT && range.startOffset === 1) | ||
var _a, _b, _c, _d; | ||
var rangeEl = range.startContainer; | ||
var textEl = rangeEl; | ||
if (textEl.className !== const_1.TEXT_TAG_CLASS && textEl.parentElement) { | ||
textEl = textEl.parentElement; | ||
} | ||
if (rangeEl.className === const_1.TEXT_TAG_CLASS && range.endOffset === 0) | ||
return true; | ||
return range.startOffset === 0; | ||
if (Number((_a = textEl.textContent) === null || _a === void 0 ? void 0 : _a.length) === 0) | ||
return true; | ||
if (Number((_b = textEl.textContent) === null || _b === void 0 ? void 0 : _b.length) === 1) { | ||
if (textEl.textContent === const_1.PLACEHOLDER_TEXT) | ||
return true; | ||
if (textEl.textContent === "\n") | ||
return true; | ||
if (rangeEl.nodeName === "BR") | ||
return true; | ||
} | ||
if (range.startOffset > 0) | ||
return false; | ||
if (rangeEl.nodeName === "#text") { | ||
var nodeIndex = Array.from(((_c = rangeEl.parentElement) === null || _c === void 0 ? void 0 : _c.childNodes) || []).indexOf(rangeEl); | ||
for (var i = 0; i < nodeIndex; i++) { | ||
if ((_d = textEl.childNodes[i].textContent) === null || _d === void 0 ? void 0 : _d.trim()) | ||
return false; | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
* 修正文本标签光标 | ||
* 修正文本标签内容 | ||
*/ | ||
function fixTextRange(range, textEl) { | ||
var _a, _b; | ||
function fixTextContent(range, els) { | ||
var _a, _b, _c, _d; | ||
var _els = els || rangeEls(range); | ||
if (!_els) | ||
return; | ||
var rowEl = _els.rowEl, textEl = _els.textEl; | ||
if (range.startContainer.nodeName === "BR") { | ||
var text_1 = (0, _1.createTextNode)(); | ||
textEl.appendChild(text_1); | ||
range.setStart(text_1, 0); | ||
var br_1 = range.startContainer; | ||
var text = (0, _1.createTextNode)(); | ||
// 将text内容插入到range.startContainer标签之前 | ||
(_a = br_1.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(text, br_1); | ||
range.setStart(text, 0); | ||
range.collapse(true); | ||
var content = textEl.textContent || ""; | ||
if (content && content !== "\n") { | ||
(_b = br_1.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(br_1); | ||
} | ||
return; | ||
} | ||
if (textEl.childNodes.length <= 1) | ||
var br = rowEl.querySelector("br"); | ||
while (Number((_c = rowEl.textContent) === null || _c === void 0 ? void 0 : _c.trim().length) > 1 && br) { | ||
br.remove(); | ||
br = rowEl.querySelector("br"); | ||
} | ||
if (!(0, _1.isNeedFix)(textEl)) | ||
return; | ||
if (range.startContainer.nodeName !== "#text" && range.startContainer !== textEl) | ||
if (textEl.className !== const_1.TEXT_TAG_CLASS) | ||
return; | ||
if (Number((_d = textEl.textContent) === null || _d === void 0 ? void 0 : _d.length) <= 1) | ||
return; | ||
var rangeEl = range.startContainer; | ||
var rangeIndex = range.startOffset; | ||
var nodeIndex = 0; | ||
if (rangeEl === textEl) { | ||
rangeEl = textEl.childNodes[range.startOffset - 1]; | ||
rangeIndex = ((_a = rangeEl.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0; | ||
nodeIndex = rangeIndex - 1; | ||
rangeIndex = 0; | ||
} | ||
for (var i = 0; i < textEl.childNodes.length; i++) { | ||
if (rangeEl === textEl.childNodes[i]) { | ||
break; | ||
else if (rangeEl.nodeName === "#text") { | ||
nodeIndex = Array.from(textEl.childNodes).indexOf(rangeEl); | ||
} | ||
// 获取光标两边的内容 | ||
var prevText = ""; | ||
var nextText = ""; | ||
textEl.childNodes.forEach(function (node, index) { | ||
var _a, _b; | ||
if (index < nodeIndex) { | ||
prevText += node.textContent || ""; | ||
} | ||
else if (index > nodeIndex) { | ||
nextText += node.textContent || ""; | ||
} | ||
else { | ||
rangeIndex += ((_b = textEl.childNodes[i].textContent) === null || _b === void 0 ? void 0 : _b.length) || 0; | ||
prevText += ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.slice(0, rangeIndex)) || ""; | ||
nextText += ((_b = node.textContent) === null || _b === void 0 ? void 0 : _b.slice(rangeIndex)) || ""; | ||
} | ||
}); | ||
prevText = (0, _1.formatString)(prevText); | ||
nextText = (0, _1.formatString)(nextText); | ||
var textNode = (0, _1.createTextNode)(prevText + nextText); | ||
textEl.innerHTML = ""; | ||
textEl.appendChild(textNode); | ||
range.setStart(textNode, prevText.length); | ||
range.collapse(true); | ||
} | ||
/** | ||
* 删除选中区域内的所有元素 | ||
*/ | ||
function removeRangeContent(range, _a) { | ||
var _b, _c, _d, _e; | ||
var _f = _a === void 0 ? {} : _a, startEls = _f.startEls, endEls = _f.endEls, mergeRow = _f.mergeRow; | ||
if (range.collapsed) | ||
return ""; // 没有选中内容 | ||
var sEls = startEls ? startEls : rangeEls(range, "start"); | ||
var eEls = endEls ? endEls : rangeEls(range, "end"); | ||
if (!sEls || !eEls) | ||
return ""; | ||
// 不在同一个编辑器内 | ||
if (sEls.editorEl !== eEls.editorEl) | ||
return ""; | ||
// 如果是同一个文本标签 | ||
if (sEls.textEl === eEls.textEl) { | ||
// 是标准文本标签 | ||
if (sEls.textEl.className === const_1.TEXT_TAG_CLASS) { | ||
var rangeEl = range.startContainer; | ||
var rangeIndex = range.startOffset; | ||
// 获取选中内容 | ||
var content_1 = range.extractContents().textContent || ""; | ||
// 删除选中内容 | ||
range.deleteContents(); | ||
range.setStart(rangeEl, rangeIndex); | ||
range.collapse(true); | ||
return content_1; | ||
} | ||
var content = sEls.textEl.textContent || ""; | ||
// 删除标签 | ||
sEls.textEl.remove(); | ||
return content; | ||
} | ||
var text = textEl.textContent || ""; | ||
// 清除所有的占位符和换行符 | ||
for (var i = 0; i < text.length; i++) { | ||
if (i > rangeIndex) | ||
break; | ||
var t = text[i]; | ||
if (t === const_1.PLACEHOLDER_TEXT || t === "\n") { | ||
rangeIndex -= 1; | ||
var startContent = ""; // 前面删除的内容 | ||
// 获取开始标签下标 | ||
var sIndex = Array.from(sEls.rowEl.children).indexOf(sEls.textEl); | ||
// 如果开始标签是标准文本标签 | ||
if (sEls.textEl.className === const_1.TEXT_TAG_CLASS) { | ||
startContent += ((_b = sEls.textEl.textContent) === null || _b === void 0 ? void 0 : _b.slice(range.startOffset)) || ""; | ||
// 保留光标之前的内容 | ||
var context = (_c = sEls.textEl.textContent) === null || _c === void 0 ? void 0 : _c.slice(0, range.startOffset); | ||
context = (0, _1.formatString)(context); | ||
if (context) { | ||
sIndex += 1; // 如果还有内容,要删除的开始标签往后移一位 | ||
sEls.textEl.textContent = context; | ||
var textNode = sEls.textEl.lastChild; | ||
range.setStart(textNode ? textNode : sEls.textEl, textNode ? context.length : sEls.textEl.childNodes.length); | ||
} | ||
} | ||
rangeIndex = Math.max(rangeIndex, 0); | ||
text = text.replace(new RegExp(const_1.PLACEHOLDER_TEXT, "g"), ""); | ||
text = text.replace(/\n/g, ""); | ||
if (!text) { | ||
text = const_1.PLACEHOLDER_TEXT; | ||
rangeIndex = 1; | ||
// 获取结束标签下标 | ||
var eIndex = Array.from(eEls.rowEl.children).indexOf(eEls.textEl); | ||
// 如果结束标签是标准文本标签 | ||
var endContent = ""; // 后面的内容 | ||
if (eEls.textEl.className === const_1.TEXT_TAG_CLASS) { | ||
endContent += ((_d = eEls.textEl.textContent) === null || _d === void 0 ? void 0 : _d.slice(0, range.endOffset)) || ""; | ||
// 保留光标之后的内容 | ||
var context = (_e = eEls.textEl.textContent) === null || _e === void 0 ? void 0 : _e.slice(range.endOffset); | ||
context = (0, _1.formatString)(context); | ||
if (context) { | ||
eIndex -= 1; // 如果还有内容,要删除的结束标签往前移一位 | ||
eEls.textEl.textContent = context; | ||
range.setEnd(eEls.textEl, 0); | ||
} | ||
} | ||
textEl.innerHTML = ""; | ||
var textNode = (0, _1.createTextNode)(text); | ||
textEl.appendChild(textNode); | ||
range.setStart(textNode, rangeIndex <= text.length ? rangeIndex : text.length); | ||
// 如果是同一行 | ||
if (sEls.rowEl === eEls.rowEl) { | ||
// 删除包括开始和结束的所有内容 | ||
for (var i = eIndex; i >= sIndex; i--) { | ||
endContent = (sEls.rowEl.children[i].textContent || "") + endContent; | ||
sEls.rowEl.children[i].remove(); | ||
} | ||
range.collapse(true); | ||
return startContent + endContent; | ||
} | ||
// 删除开始行和结束行之间的所有行 | ||
var swIndex = Array.from(sEls.editorEl.children).indexOf(sEls.rowEl); | ||
var ewIndex = Array.from(eEls.editorEl.children).indexOf(eEls.rowEl); | ||
var centerContent = ""; // 中间的内容 | ||
for (var i = ewIndex - 1; i > swIndex; i--) { | ||
centerContent = (sEls.editorEl.children[i].textContent || "") + centerContent; | ||
sEls.editorEl.children[i].remove(); | ||
} | ||
// 从开始文本标签开始删除开始行的所有内容 | ||
for (var i = sEls.rowEl.children.length - 1; i >= sIndex; i--) { | ||
centerContent = (sEls.rowEl.children[i].textContent || "") + centerContent; | ||
sEls.rowEl.children[i].remove(); | ||
} | ||
// 删除结束行的从头到结束标签之前的内容 | ||
for (var i = eIndex; i >= 0; i--) { | ||
endContent = (eEls.rowEl.children[i].textContent || "") + endContent; | ||
eEls.rowEl.children[i].remove(); | ||
} | ||
if (mergeRow) { | ||
// 将光标移动到开始标签的末尾 | ||
moveRangeAtRowEnd(range, sEls.rowEl); | ||
// 将结束行的所有内容添加到开始行的末尾 | ||
(0, _1.transferElement)(eEls.rowEl, sEls.rowEl); | ||
// 删除结束标签 | ||
eEls.rowEl.remove(); | ||
} | ||
range.collapse(true); | ||
return startContent + centerContent + endContent; | ||
} | ||
/** | ||
* 在光标位置插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
function insertText(text, range) { | ||
var _a; | ||
var commonEl = range.commonAncestorContainer; | ||
if (!["BR", "#text"].includes(commonEl === null || commonEl === void 0 ? void 0 : commonEl.nodeName) && commonEl.className !== const_1.TEXT_TAG_CLASS) | ||
return false; | ||
if (commonEl.nodeName === "BR") { | ||
var els = rangeEls(range); | ||
if (!els) | ||
return false; | ||
(_a = commonEl.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(commonEl); | ||
els.textEl.innerHTML = text; | ||
fixTextContent(range, els); | ||
return true; | ||
} | ||
range.insertNode((0, _1.createTextNode)(text)); | ||
return true; | ||
} | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
function insertElement(el, range) { | ||
var _a, _b; | ||
var commonEl = range.commonAncestorContainer; | ||
if (!["BR", "#text"].includes(commonEl === null || commonEl === void 0 ? void 0 : commonEl.nodeName) && commonEl.className !== const_1.TEXT_TAG_CLASS) | ||
return false; | ||
var els = rangeEls(range); | ||
if (!els) | ||
return false; | ||
fixTextContent(range, els); | ||
// 如果当前文本元素是个空元素 | ||
if (!els.textEl.textContent) { | ||
var t = (0, _1.createTextNode)(const_1.PLACEHOLDER_TEXT); | ||
els.textEl.innerHTML = ""; | ||
els.textEl.appendChild(t); | ||
// 修正光标位置 | ||
range.setStart(t, 0); | ||
range.collapse(true); | ||
} | ||
el.setAttribute("contenteditable", "false"); | ||
// 如果当前光标在文本节点开头,则将元素插入到文本节点之前 | ||
if (isRangeAtTextStart(range)) { | ||
// 获取当前textEL的前一个兄弟节点 | ||
var prevEl = els.textEl.previousElementSibling; | ||
if (!prevEl || prevEl.className !== const_1.TEXT_TAG_CLASS) { | ||
els.textEl.insertAdjacentElement("beforebegin", (0, _1.createTextTag)()); | ||
} | ||
els.textEl.insertAdjacentElement("beforebegin", el); | ||
return true; | ||
} | ||
else if (isRangeAtTextEnd(range)) { | ||
// 获取当前textEL的下一个兄弟节点 | ||
var nextEl = els.textEl.nextElementSibling; | ||
if (!nextEl || nextEl.className !== const_1.TEXT_TAG_CLASS) { | ||
nextEl = (0, _1.createTextTag)(); | ||
els.textEl.insertAdjacentElement("afterend", nextEl); | ||
} | ||
els.textEl.insertAdjacentElement("afterend", el); | ||
// 更新光标位置 | ||
range.setStart(nextEl, 0); | ||
range.collapse(true); | ||
return true; | ||
} | ||
// 如果当前光标在文本节点中间,则将文本节点分割为两个,并将元素插入到中间 | ||
var text1 = ((_a = range.endContainer.textContent) === null || _a === void 0 ? void 0 : _a.slice(0, range.endOffset)) || const_1.PLACEHOLDER_TEXT; | ||
var text2 = ((_b = range.endContainer.textContent) === null || _b === void 0 ? void 0 : _b.slice(range.endOffset)) || const_1.PLACEHOLDER_TEXT; | ||
range.endContainer.textContent = text1; | ||
var textEl2 = (0, _1.createTextTag)(text2); | ||
els.textEl.insertAdjacentElement("afterend", textEl2); | ||
els.textEl.insertAdjacentElement("afterend", el); | ||
// 更新光标位置 | ||
range.setStart(textEl2.childNodes[0], 0); | ||
range.collapse(true); | ||
return true; | ||
} |
@@ -268,15 +268,3 @@ "use strict"; | ||
return false; | ||
var _a = [sEls.rowEl, eEls.rowEl], startP = _a[0], endP = _a[1]; | ||
var startContainer = range.startContainer; | ||
var startOffset = range.startOffset; | ||
// 如果存在选中内容,删除选中内容 | ||
range.deleteContents(); | ||
// 如果开始和结束P标签不一致,将结束标签中的剩余内容复制到开始标签中,并删除结束标签 | ||
if (startP !== endP) { | ||
endP.remove(); | ||
(0, _1.transferElement)(endP, startP); | ||
} | ||
// 修正光标位置 | ||
range.setStart(startContainer, startOffset); | ||
range.collapse(true); | ||
(0, range_1.removeRangeContent)(range, { startEls: sEls, endEls: eEls, mergeRow: true }); | ||
return true; | ||
@@ -289,3 +277,3 @@ } | ||
var bool = false; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
(0, range_1.fixTextContent)(range, els); | ||
if (e.code === "Backspace") { | ||
@@ -292,0 +280,0 @@ bool = onBackspace(range, els); |
@@ -13,4 +13,2 @@ "use strict"; | ||
if (!range.collapsed) { | ||
// 删除选中的内容 | ||
range.deleteContents(); | ||
// 获取开始位置所在的P标签 | ||
@@ -21,9 +19,6 @@ var sEls = (0, range_1.rangeEls)(range, "start"); | ||
return; | ||
// 修正开始行标签 | ||
(0, _1.fixRowContent)(sEls.rowEl); | ||
// 如果开始位置和结束位置不在同一行 | ||
// 删除选中内容 | ||
(0, range_1.removeRangeContent)(range, { startEls: sEls, endEls: eEls }); | ||
// 如果不是同一行,将光标移动到结束行的开头位置 | ||
if (sEls.rowEl !== eEls.rowEl) { | ||
// 修正结束行标签 | ||
(0, _1.fixRowContent)(eEls.rowEl); | ||
// 将光标移动到结束P标签的开头 | ||
(0, range_1.moveRangeAtRowStart)(range, eEls.rowEl); | ||
@@ -33,7 +28,7 @@ return; | ||
} | ||
// 获取当前所在的标签 | ||
// 获取光标当前所在的标签 | ||
var els = (0, range_1.rangeEls)(range); | ||
if (!els) | ||
return; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
(0, range_1.fixTextContent)(range, els); | ||
// 如果光标在当前行末尾 | ||
@@ -40,0 +35,0 @@ if ((0, _1.isEmptyElement)(els.rowEl) || (0, range_1.isRangeAtRowEnd)(range, els.rowEl)) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
107994
2484
274