hi-mention
Advanced tools
Comparing version 2.0.1 to 2.1.0
{ | ||
"name": "hi-mention", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"main": "index", | ||
@@ -5,0 +5,0 @@ "types": "index.d.ts", |
@@ -133,13 +133,16 @@ # Mention 提及 | ||
## 自定义用户列表 | ||
## 自定义 | ||
- 如果内置用户列表无法满足需求,可以通过继承 HiMention 组件,以下方法来实现自定义用户列表 | ||
- 如果内置功能如无法满足需求,可以通过继承 HiMention 组件,以下方法来实现自定义用户列表 | ||
### HiMention 接口 | ||
| 接口名 | 说明 | 类型 | 备注 | | ||
| ------------------- | ---------------------- | -------------------- | ----------------------------------------- | | ||
| `initUserSelector` | 方法:初始化用户选择器 | `()=>void` | - | | ||
| `closeUserSelector` | 方法:关闭用户选择器 | `()=>void` | - | | ||
| `openUserSelector` | 方法:打开用户列表 | `(query:User)=>void` | `query`:为用户输入`@`时后面跟的查询字符串 | | ||
| 接口名 | 说明 | 类型 | 备注 | | ||
| ------------------- | ---------------------- | ------------------------------ | ----------------------------------------- | | ||
| `initUserSelector` | 方法:初始化用户选择器 | `()=>void` | - | | ||
| `closeUserSelector` | 方法:关闭用户选择器 | `()=>void` | - | | ||
| `openUserSelector` | 方法:打开用户列表 | `(query:User)=>void` | `query`:为用户输入`@`时后面跟的查询字符串 | | ||
| `onWordDelete` | 方法:删除/退格 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | ||
| `onMoveCursor` | 方法:光标移动 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | ||
| `onWordWrap` | 方法:换行 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | ||
@@ -225,14 +228,4 @@ ### HiUserSelector 接口 | ||
## 自定义换行 | ||
### 自定义换行示例 | ||
- 如果内置换行功能无法满足需求,可以通过继承 HiMention 组件,以下方法来实现自定义换行 | ||
### HiMention 接口 | ||
| 接口名 | 说明 | 类型 | 备注 | | ||
| ------------ | -------------------------- | ----------------------------- | ---- | | ||
| `onWordWrap` | 方法:监听用户按下换行按键 | `(e: KeyboardEvent): boolean` | - | | ||
- 继承示例 | ||
```javascript | ||
@@ -253,5 +246,6 @@ // 引入插件 | ||
if (["Enter", "NumpadEnter"].includes(e.code)) { | ||
// 可重新设置快捷键 | ||
// 调用内置换行方法 | ||
this.wordWrap(); | ||
// 如果换行完成请返回true | ||
this.wordWrap(); // 可重新设置换行逻辑 | ||
// 返回true阻止默认事件和触发其他事件 | ||
return true; | ||
@@ -263,1 +257,18 @@ } | ||
``` | ||
# 更新日志 | ||
```html | ||
v2.1.0 2024-10-26 | ||
- 修复剪切、复制、粘贴 BUG | ||
- 修复移动光标 BUG | ||
- 修复换行 BUG | ||
- 修复删除 BUG | ||
- 修复焦点 BUG | ||
- 修复占位符展示异常 BUG | ||
- 针对火狐浏览器做兼容处理 | ||
v2.0.1 2024-10-25 | ||
- 修复默认用户选择器切换用户异常 | ||
v2.0.0 2024-10-25 | ||
- 初始版本 | ||
``` |
import { MentionOptions, UserSelectorOptions } from "./types"; | ||
export declare const BROWSER: () => { | ||
isIE: boolean; | ||
isEdge: boolean; | ||
isFirefox: boolean; | ||
isChrome: boolean; | ||
isSafari: boolean; | ||
isOpera: boolean; | ||
}; | ||
export declare const EDITOR_CLASS = "hi-mention-editor"; | ||
@@ -6,4 +14,4 @@ export declare const ROW_TAG_CLASS = "hi-mention-row"; | ||
export declare const PLACEHOLDER_TEXT = "\uFEFF"; | ||
export declare const NEW_LINE = "<br/>"; | ||
export declare const NEW_LINE: string; | ||
export declare const defaultUserSelectorOptions: () => UserSelectorOptions; | ||
export declare const defaultMentionOptions: () => MentionOptions; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defaultMentionOptions = exports.defaultUserSelectorOptions = exports.NEW_LINE = exports.PLACEHOLDER_TEXT = exports.TEXT_TAG_CLASS = exports.ROW_TAG_CLASS = exports.EDITOR_CLASS = void 0; | ||
exports.defaultMentionOptions = exports.defaultUserSelectorOptions = exports.NEW_LINE = exports.PLACEHOLDER_TEXT = exports.TEXT_TAG_CLASS = exports.ROW_TAG_CLASS = exports.EDITOR_CLASS = exports.BROWSER = void 0; | ||
// 浏览器类型 | ||
var BROWSER = function () { | ||
var ua = navigator.userAgent.toLowerCase(); | ||
return { | ||
isIE: ua.indexOf("msie") > -1 || ua.indexOf("trident") > -1, | ||
isEdge: ua.indexOf("edge") > -1, | ||
isFirefox: ua.indexOf("firefox") > -1, | ||
isChrome: ua.indexOf("chrome") > -1, | ||
isSafari: ua.indexOf("safari") > -1, | ||
isOpera: ua.indexOf("opr") > -1, | ||
}; | ||
}; | ||
exports.BROWSER = BROWSER; | ||
// 编辑器类名 | ||
@@ -13,3 +26,3 @@ exports.EDITOR_CLASS = "hi-mention-editor"; | ||
// 换行符 | ||
exports.NEW_LINE = "<br/>"; | ||
exports.NEW_LINE = (0, exports.BROWSER)().isFirefox ? "<br/>" : exports.PLACEHOLDER_TEXT; | ||
var defaultUserSelectorOptions = function () { return ({ | ||
@@ -26,8 +39,10 @@ users: [], | ||
exports.defaultUserSelectorOptions = defaultUserSelectorOptions; | ||
var defaultMentionOptions = function () { return Object.assign({ | ||
trigger: "@", | ||
placeholder: "请输入", | ||
placeholderColor: "#aaa", | ||
mentionColor: "#0090FF", | ||
}, (0, exports.defaultUserSelectorOptions)()); }; | ||
var defaultMentionOptions = function () { | ||
return Object.assign({ | ||
trigger: "@", | ||
placeholder: "请输入", | ||
placeholderColor: "#aaa", | ||
mentionColor: "#0090FF", | ||
}, (0, exports.defaultUserSelectorOptions)()); | ||
}; | ||
exports.defaultMentionOptions = defaultMentionOptions; |
@@ -8,2 +8,6 @@ import UserSelector from "./UserSelector"; | ||
constructor(el: Element | HTMLElement | string, option?: Partial<MentionOptions>); | ||
protected addHistory(): void; | ||
protected undoHistory(e: KeyboardEvent): boolean; | ||
protected moveCursor(direction: "ArrowLeft" | "ArrowRight"): void; | ||
protected onMoveCursor(e: KeyboardEvent): boolean; | ||
protected wordDelete(e: KeyboardEvent): boolean; | ||
@@ -10,0 +14,0 @@ protected onWordDelete(e: KeyboardEvent): boolean; |
@@ -23,2 +23,3 @@ "use strict"; | ||
var wordDelete_1 = __importDefault(require("./utils/wordDelete")); | ||
var moveCursor_1 = __importDefault(require("./utils/moveCursor")); | ||
var Mention = /** @class */ (function () { | ||
@@ -41,2 +42,4 @@ function Mention(el, option) { | ||
this._queryStr = ""; | ||
// 历史记录 | ||
this._history = []; | ||
if (!el) { | ||
@@ -120,2 +123,12 @@ throw new Error("Mention: no element provided"); | ||
} | ||
bool = this.undoHistory(e); | ||
if (bool) { | ||
e.preventDefault(); | ||
return; | ||
} | ||
bool = this.onMoveCursor(e); | ||
if (bool) { | ||
e.preventDefault(); | ||
return; | ||
} | ||
this._events["keydowns"].forEach(function (fn) { return fn(e); }); | ||
@@ -141,5 +154,11 @@ }; | ||
return; | ||
var reg = new RegExp("".concat(const_1.PLACEHOLDER_TEXT), "ig"); | ||
text = text.replace(reg, ""); | ||
var range = (0, range_1.getRangeAt)(); | ||
if (!range) | ||
return; | ||
var els = (0, range_1.rangeEls)(range); | ||
if (!els) | ||
return; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
range.deleteContents(); | ||
@@ -149,3 +168,5 @@ range.insertNode(document.createTextNode(text)); | ||
range.setStart(range.endContainer, range.endOffset); | ||
range.setEnd(range.endContainer, range.endOffset); | ||
range.collapse(true); | ||
// 修正行元素 | ||
(0, index_1.fixRowContent)(els.rowEl); | ||
this._inputEvent(); | ||
@@ -156,5 +177,5 @@ this._onchange(); | ||
var _this = this; | ||
var text = this._editorEl.innerText; | ||
var reg = new RegExp("^".concat(const_1.PLACEHOLDER_TEXT, "*$")); | ||
if (!text || /^\n*$/.test(text) || reg.test(text)) { | ||
var text = this._editorEl.textContent; | ||
var reg = new RegExp("^[\n".concat(const_1.PLACEHOLDER_TEXT, "\r]*$")); | ||
if (!text || reg.test(text)) { | ||
this._placeholderEl.style.display = "block"; | ||
@@ -167,3 +188,5 @@ } | ||
this._changetimeout = setTimeout(function () { | ||
_this._events["changes"].forEach(function (fn) { return fn({ text: _this._editorEl.innerText, html: _this._editorEl.innerHTML }); }); | ||
var html = _this._editorEl.innerHTML; | ||
_this._events["changes"].forEach(function (fn) { return fn({ text: _this._editorEl.textContent || "", html: html }); }); | ||
_this.addHistory(); | ||
}, 300); | ||
@@ -204,2 +227,22 @@ }; | ||
}; | ||
Mention.prototype.addHistory = function () { | ||
// 记录内容变化:待开发 | ||
}; | ||
Mention.prototype.undoHistory = function (e) { | ||
if (e.ctrlKey && ["Z", "z"].includes(e.key)) { | ||
console.log("撤销:开发中!!!"); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
Mention.prototype.moveCursor = function (direction) { | ||
return (0, moveCursor_1.default)(direction); | ||
}; | ||
Mention.prototype.onMoveCursor = function (e) { | ||
if (e.code === "ArrowLeft" || e.code === "ArrowRight") { | ||
this.moveCursor(e.code); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
Mention.prototype.wordDelete = function (e) { | ||
@@ -206,0 +249,0 @@ return (0, wordDelete_1.default)(e, this._editorEl); |
@@ -0,0 +0,0 @@ import { UserInfo, UserSelectorOptions } from "./types"; |
@@ -27,10 +27,28 @@ export declare const createElement: <K extends keyof HTMLElementTagNameMap>(type: K, { className, style, content }?: { | ||
*/ | ||
export declare const fixRowContent: (rowEl: HTMLElement) => void; | ||
export declare const fixRowContent: (rowEl: HTMLElement, rangeTextEl?: HTMLElement) => void; | ||
export declare const createTextNode: (text?: string) => Text; | ||
/** | ||
* 修正文本内容 | ||
* 创建一个空节点用来装载子元素 | ||
* @returns | ||
*/ | ||
export declare const fixTextContent: (textEl: HTMLElement) => void; | ||
export declare const createTextNode: (text?: string) => Text; | ||
export declare const createDocumentFragment: (el?: HTMLElement | DocumentFragment) => DocumentFragment; | ||
export declare const createDocumentFragment: () => DocumentFragment; | ||
/** | ||
* 插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
export declare const insertText: (text: string, range: Range) => boolean; | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
export declare const insertElement: (el: HTMLElement, range: Range) => boolean; | ||
/** | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
*/ | ||
export declare const transferElement: (el: Element | Node, target: HTMLElement | Node) => void; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.insertElement = exports.insertText = exports.createDocumentFragment = exports.createTextNode = exports.fixTextContent = exports.fixRowContent = exports.fixEditorContent = exports.createRowTag = exports.createTextTag = exports.isEmptyElement = exports.createElement = void 0; | ||
exports.transferElement = exports.insertElement = exports.insertText = exports.createDocumentFragment = exports.createTextNode = exports.fixRowContent = exports.fixEditorContent = exports.createRowTag = exports.createTextTag = exports.isEmptyElement = exports.createElement = void 0; | ||
var const_1 = require("../const"); | ||
@@ -25,3 +25,9 @@ var range_1 = require("./range"); | ||
var isEmptyElement = function (el) { | ||
return Boolean(!el.textContent || el.textContent === "\n" || el.textContent === const_1.PLACEHOLDER_TEXT); | ||
var text = el.innerText; | ||
if (!text) | ||
text = el.textContent || ""; | ||
var notContext = !text; | ||
var newLine = text === "\n"; | ||
var isEmpty = text === const_1.PLACEHOLDER_TEXT; | ||
return Boolean(notContext || newLine || isEmpty); | ||
}; | ||
@@ -48,6 +54,5 @@ exports.isEmptyElement = isEmptyElement; | ||
var fixEditorContent = function (editor) { | ||
if (!editor.innerText || editor.innerText === "\n" || editor.innerText === const_1.PLACEHOLDER_TEXT) { | ||
if ((0, exports.isEmptyElement)(editor)) { | ||
editor.innerHTML = ""; | ||
var textTag = (0, exports.createTextTag)(const_1.NEW_LINE); | ||
editor.appendChild((0, exports.createElement)("p", { className: const_1.ROW_TAG_CLASS, content: textTag })); | ||
editor.appendChild((0, exports.createElement)("p", { className: const_1.ROW_TAG_CLASS, content: (0, exports.createTextTag)(const_1.NEW_LINE) })); | ||
return true; | ||
@@ -61,26 +66,33 @@ } | ||
*/ | ||
var fixRowContent = function (rowEl) { | ||
var _a; | ||
if (rowEl.childNodes.length > 1) { | ||
var brs = rowEl.querySelectorAll("br"); | ||
brs.forEach(function (br) { return br.remove(); }); | ||
} | ||
var fixRowContent = function (rowEl, rangeTextEl) { | ||
var _a, _b; | ||
if ((0, exports.isEmptyElement)(rowEl)) { | ||
rowEl.innerHTML = (0, exports.createTextTag)(const_1.NEW_LINE).outerHTML; | ||
return; | ||
} | ||
else if (((_a = rowEl.children[rowEl.children.length - 1]) === null || _a === void 0 ? void 0 : _a.className) !== const_1.TEXT_TAG_CLASS) { | ||
rowEl.appendChild((0, exports.createTextTag)()); | ||
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); | ||
} | ||
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)); | ||
} | ||
// 将相邻的空节点合并 | ||
for (var i = rowEl.childNodes.length - 1; i > 0; i--) { | ||
var prev = rowEl.childNodes[i - 1]; | ||
var next = rowEl.childNodes[i]; | ||
if ((0, exports.isEmptyElement)(prev) && (0, exports.isEmptyElement)(next)) { | ||
// 不改变光标标签 | ||
if (rangeTextEl && next === rangeTextEl) { | ||
prev.remove(); | ||
} | ||
else { | ||
next.remove(); | ||
} | ||
} | ||
} | ||
// 删除br标签 | ||
var brs = rowEl.querySelectorAll("br"); | ||
brs.forEach(function (br) { return br.remove(); }); | ||
}; | ||
exports.fixRowContent = fixRowContent; | ||
/** | ||
* 修正文本内容 | ||
*/ | ||
var fixTextContent = function (textEl) { | ||
// 修正文本内容,如果内容长度>1则删除所有的0宽占位符 | ||
if (textEl.textContent && textEl.textContent.length > 1) { | ||
textEl.textContent = textEl.textContent.replace(const_1.PLACEHOLDER_TEXT, ""); | ||
} | ||
}; | ||
exports.fixTextContent = fixTextContent; | ||
var createTextNode = function (text) { | ||
@@ -91,12 +103,17 @@ if (text === void 0) { text = ""; } | ||
exports.createTextNode = createTextNode; | ||
// 创建一个空节点用来装载子元素 | ||
var createDocumentFragment = function (el) { | ||
/** | ||
* 创建一个空节点用来装载子元素 | ||
* @returns | ||
*/ | ||
var createDocumentFragment = function () { | ||
var fr = document.createDocumentFragment(); | ||
if (el) { | ||
fr.appendChild(el); | ||
} | ||
return fr; | ||
}; | ||
exports.createDocumentFragment = createDocumentFragment; | ||
// 插入文本 | ||
/** | ||
* 插入文本 | ||
* @param text 文本内容 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
var insertText = function (text, range) { | ||
@@ -110,2 +127,3 @@ var commonEl = range.commonAncestorContainer; | ||
return false; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
els.textEl.removeChild(range.commonAncestorContainer); | ||
@@ -121,3 +139,8 @@ els.textEl.innerHTML = text; | ||
exports.insertText = insertText; | ||
// 在文本内容中插入元素 | ||
/** | ||
* 在文本内容中插入元素 | ||
* @param el 需要插入的元素 | ||
* @param range 光标位置 | ||
* @returns | ||
*/ | ||
var insertElement = function (el, range) { | ||
@@ -131,7 +154,3 @@ var _a, _b, _c; | ||
return false; | ||
// 如果光标在BR标签上 | ||
var brs = els.textEl.querySelectorAll("br"); | ||
if (brs.length) { | ||
brs.forEach(function (br) { return br.remove(); }); | ||
} | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
// 如果当前文本元素是个空元素 | ||
@@ -143,3 +162,3 @@ if (!els.textEl.textContent) { | ||
range.setStart(t, 0); | ||
range.setEnd(t, 0); | ||
range.collapse(true); | ||
} | ||
@@ -167,3 +186,3 @@ el.setAttribute("contenteditable", "false"); | ||
range.setStart(nextEl, 0); | ||
range.setEnd(nextEl, 0); | ||
range.collapse(true); | ||
return true; | ||
@@ -180,5 +199,18 @@ } | ||
range.setStart(textEl2.childNodes[0], 0); | ||
range.setEnd(textEl2.childNodes[0], 0); | ||
range.collapse(true); | ||
return true; | ||
}; | ||
exports.insertElement = insertElement; | ||
/** | ||
* 将一个元素的内容转移到另外一个元素下面 | ||
* @param el 需要移动的元素 | ||
* @param target 目标元素 | ||
*/ | ||
var transferElement = function (el, target) { | ||
var fr = (0, exports.createDocumentFragment)(); | ||
while (el.firstChild) { | ||
fr.appendChild(el.firstChild); | ||
} | ||
target.appendChild(fr); | ||
}; | ||
exports.transferElement = transferElement; |
@@ -44,1 +44,5 @@ export declare function getSelection(): Selection | null; | ||
export declare function isRangeAtTextStart(range: Range): boolean; | ||
/** | ||
* 修正文本标签光标 | ||
*/ | ||
export declare function fixTextRange(range: Range, textEl: HTMLElement): void; |
@@ -13,2 +13,3 @@ "use strict"; | ||
exports.isRangeAtTextStart = isRangeAtTextStart; | ||
exports.fixTextRange = fixTextRange; | ||
var _1 = require("."); | ||
@@ -31,3 +32,10 @@ var const_1 = require("../const"); | ||
try { | ||
var range = selection ? selection.getRangeAt(index) : document.createRange(); | ||
var range = selection === null || selection === void 0 ? void 0 : selection.getRangeAt(index); | ||
if (!range) { | ||
range = document.createRange(); | ||
range.selectNodeContents(document.body); | ||
range.collapse(false); | ||
selection === null || selection === void 0 ? void 0 : selection.removeAllRanges(); | ||
selection === null || selection === void 0 ? void 0 : selection.addRange(range); | ||
} | ||
// 如果光标没有选中内容,修正光标位置 | ||
@@ -73,7 +81,7 @@ if (range.collapsed) { | ||
// 获取最后一个文本标签的长度 | ||
var textNode = lastText.childNodes[lastText.childNodes.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; | ||
// 设置光标位置 | ||
range.setStart(textNode ? textNode : lastText, lastTextLength); | ||
range.setEnd(textNode ? textNode : lastText, lastTextLength); | ||
range.collapse(true); | ||
} | ||
@@ -93,4 +101,5 @@ /** | ||
// 设置光标位置 | ||
range.setStart(firstText, 0); | ||
range.setEnd(firstText, 0); | ||
var textNode = firstText.firstChild; | ||
range.setStart(textNode ? textNode : firstText, 0); | ||
range.collapse(true); | ||
} | ||
@@ -101,3 +110,2 @@ /** | ||
function rangeEls(range, which) { | ||
var _a, _b; | ||
if (which === void 0) { which = "common"; } | ||
@@ -157,7 +165,8 @@ // 光标所在的编辑器 | ||
} | ||
// 如果光标位置在行或者编辑器中,修正光标位置 | ||
if (range.commonAncestorContainer === editorEl || range.commonAncestorContainer === rowEl) { | ||
// 如果光标位置不在TEXT节点上,修正光标位置 | ||
if (range.commonAncestorContainer.nodeName !== "#text") { | ||
var tNode = textEl.firstChild; | ||
// 设置光标位置 | ||
range.setStart(textEl, ((_a = textEl.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0); | ||
range.setEnd(textEl, ((_b = textEl.textContent) === null || _b === void 0 ? void 0 : _b.length) || 0); | ||
range.setStart(tNode ? tNode : textEl, 0); | ||
range.collapse(true); | ||
} | ||
@@ -219,1 +228,54 @@ return { editorEl: editorEl, rowEl: rowEl, textEl: textEl }; | ||
} | ||
/** | ||
* 修正文本标签光标 | ||
*/ | ||
function fixTextRange(range, textEl) { | ||
var _a, _b; | ||
if (range.startContainer.nodeName === "BR") { | ||
var text_1 = (0, _1.createTextNode)(); | ||
textEl.appendChild(text_1); | ||
range.setStart(text_1, 0); | ||
range.collapse(true); | ||
return; | ||
} | ||
if (textEl.childNodes.length <= 1) | ||
return; | ||
if (range.startContainer.nodeName !== "#text" && range.startContainer !== textEl) | ||
return; | ||
var rangeEl = range.startContainer; | ||
var rangeIndex = range.startOffset; | ||
if (rangeEl === textEl) { | ||
rangeEl = textEl.childNodes[range.startOffset - 1]; | ||
rangeIndex = ((_a = rangeEl.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0; | ||
} | ||
for (var i = 0; i < textEl.childNodes.length; i++) { | ||
if (rangeEl === textEl.childNodes[i]) { | ||
break; | ||
} | ||
else { | ||
rangeIndex += ((_b = textEl.childNodes[i].textContent) === null || _b === void 0 ? void 0 : _b.length) || 0; | ||
} | ||
} | ||
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; | ||
} | ||
} | ||
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; | ||
} | ||
textEl.innerHTML = ""; | ||
var textNode = (0, _1.createTextNode)(text); | ||
textEl.appendChild(textNode); | ||
range.setStart(textNode, rangeIndex <= text.length ? rangeIndex : text.length); | ||
range.collapse(true); | ||
} |
@@ -8,6 +8,6 @@ "use strict"; | ||
function onDelete(range, _a) { | ||
var _b, _c, _d, _e, _f; | ||
var _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
var rowEl = _a.rowEl, textEl = _a.textEl; | ||
var rangeNode = range.commonAncestorContainer; | ||
// 删除文本内容使用默认行为 | ||
// 删除文本内容 | ||
var isText = rangeNode.nodeName === "#text"; | ||
@@ -26,7 +26,27 @@ var textLength = ((_b = rangeNode.textContent) === null || _b === void 0 ? void 0 : _b.length) || 0; | ||
var text = (_c = rangeNode.textContent) === null || _c === void 0 ? void 0 : _c[index]; | ||
var text1 = ((_d = rangeNode.textContent) === null || _d === void 0 ? void 0 : _d.slice(0, text === const_1.PLACEHOLDER_TEXT ? index + 1 : index)) || ""; | ||
var text2 = ((_e = rangeNode.textContent) === null || _e === void 0 ? void 0 : _e.slice(text === const_1.PLACEHOLDER_TEXT ? index + 2 : index + 1)) || ""; | ||
var sIndex = index; | ||
var eIndex = index + 1; | ||
if (text === const_1.PLACEHOLDER_TEXT) { | ||
index += 1; | ||
sIndex = index; | ||
eIndex = index + 1; | ||
text = (_d = rangeNode.textContent) === null || _d === void 0 ? void 0 : _d[index + 1]; | ||
} | ||
// 如果要删除的是\r,则将连续的\r都删除 | ||
if (text === "\r" && index < Number((_e = rangeNode.textContent) === null || _e === void 0 ? void 0 : _e.length)) { | ||
for (var i = index; i < Number((_f = rangeNode.textContent) === null || _f === void 0 ? void 0 : _f.length); i++) { | ||
if (((_g = rangeNode.textContent) === null || _g === void 0 ? void 0 : _g[i]) === "\r") { | ||
index += 1; | ||
eIndex = index + 1; | ||
} | ||
else | ||
break; | ||
} | ||
} | ||
var text1 = ((_h = rangeNode.textContent) === null || _h === void 0 ? void 0 : _h.slice(0, sIndex)) || ""; | ||
var text2 = ((_j = rangeNode.textContent) === null || _j === void 0 ? void 0 : _j.slice(eIndex)) || ""; | ||
rangeNode.textContent = text1 + text2; | ||
index = Math.min(index, rangeNode.textContent.length); | ||
range.setStart(rangeNode, index); | ||
range.setEnd(rangeNode, index); | ||
range.collapse(true); | ||
return true; | ||
@@ -36,6 +56,2 @@ } | ||
var nextRow = rowEl.nextElementSibling; | ||
// 没有下一个节点并且在当前行的末尾 | ||
if (!nextRow && (0, range_1.isRangeAtRowEnd)(range, rowEl)) { | ||
return true; | ||
} | ||
// 如果当前节点是空标签 | ||
@@ -51,2 +67,6 @@ if ((0, _1.isEmptyElement)(rowEl)) { | ||
} | ||
// 没有下一个节点并且在当前行的末尾 | ||
if (!nextRow && (0, range_1.isRangeAtRowEnd)(range, rowEl)) { | ||
return true; | ||
} | ||
// 如果光标在当前行的末尾并且有下一个兄弟节点 | ||
@@ -59,9 +79,4 @@ if ((0, range_1.isRangeAtRowEnd)(range, rowEl) && nextRow) { | ||
} | ||
// 将下一个兄弟节点的内容复制到当前节点 | ||
var fr_1 = (0, _1.createDocumentFragment)(); | ||
nextRow.remove(); | ||
nextRow.childNodes.forEach(function (node) { | ||
fr_1.appendChild(node.cloneNode(true)); | ||
}); | ||
rowEl.appendChild(fr_1); | ||
// 将下一个兄弟节点的内容转移到当前节点 | ||
(0, _1.transferElement)(nextRow, rowEl); | ||
return true; | ||
@@ -96,3 +111,3 @@ } | ||
if (delEl.className === const_1.TEXT_TAG_CLASS) { | ||
delEl.textContent = ((_f = delEl.textContent) === null || _f === void 0 ? void 0 : _f.slice(1)) || ""; | ||
delEl.textContent = ((_k = delEl.textContent) === null || _k === void 0 ? void 0 : _k.slice(1)) || ""; | ||
// 如果还有剩余内容,将光标移动到节点开头 | ||
@@ -102,3 +117,3 @@ if (!(0, _1.isEmptyElement)(delEl)) { | ||
range.setStart(textNode ? textNode : delEl, 0); | ||
range.setEnd(textNode ? textNode : delEl, 0); | ||
range.collapse(true); | ||
return true; | ||
@@ -118,3 +133,3 @@ } | ||
range.setStart(textNode ? textNode : nextNode, 0); | ||
range.setEnd(textNode ? textNode : nextNode, 0); | ||
range.collapse(true); | ||
} | ||
@@ -124,6 +139,6 @@ return true; | ||
function onBackspace(range, _a) { | ||
var _b, _c, _d, _e, _f, _g; | ||
var _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
var rowEl = _a.rowEl, textEl = _a.textEl; | ||
var rangeNode = range.commonAncestorContainer; | ||
// 删除文本内容使用默认行为 | ||
// 删除文本内容 | ||
var isText = rangeNode.nodeName === "#text"; | ||
@@ -133,15 +148,36 @@ var isEmpty = rangeNode.textContent === const_1.PLACEHOLDER_TEXT; | ||
// 如果只有一个字符,则将节点内容设置为0宽占位符 | ||
if (range.startOffset === 1) { | ||
if (((_b = range.startContainer.textContent) === null || _b === void 0 ? void 0 : _b.length) === 1) { | ||
rangeNode.textContent = const_1.PLACEHOLDER_TEXT; | ||
return true; | ||
} | ||
// 否则删除光标位置之后的第一个文本内容 | ||
// 否则删除光标位置之前的第一个文本内容 | ||
var index = range.startOffset; | ||
// 找到要删除的内容 | ||
var text = (_b = rangeNode.textContent) === null || _b === void 0 ? void 0 : _b[index - 1]; | ||
var text1 = ((_c = rangeNode.textContent) === null || _c === void 0 ? void 0 : _c.slice(0, text === const_1.PLACEHOLDER_TEXT ? index - 2 : index - 1)) || ""; | ||
var text2 = ((_d = rangeNode.textContent) === null || _d === void 0 ? void 0 : _d.slice(text === const_1.PLACEHOLDER_TEXT ? index - 1 : index)) || ""; | ||
var text = (_c = rangeNode.textContent) === null || _c === void 0 ? void 0 : _c[index - 1]; | ||
var sIndex = index - 1; | ||
var eIndex = index; | ||
if (text === const_1.PLACEHOLDER_TEXT) { | ||
index -= 1; | ||
sIndex = index - 1; | ||
eIndex = index; | ||
text = (_d = rangeNode.textContent) === null || _d === void 0 ? void 0 : _d[index - 1]; | ||
} | ||
// 如果要删除的是\r,则将连续的\r都删除 | ||
if (text === "\r" && index > 1) { | ||
for (var i = index - 1; i >= 0; i--) { | ||
if (((_e = rangeNode.textContent) === null || _e === void 0 ? void 0 : _e[i]) === "\r") { | ||
index -= 1; | ||
sIndex = index - 1; | ||
} | ||
else | ||
break; | ||
} | ||
} | ||
var text1 = ((_f = rangeNode.textContent) === null || _f === void 0 ? void 0 : _f.slice(0, sIndex)) || ""; | ||
var text2 = ((_g = rangeNode.textContent) === null || _g === void 0 ? void 0 : _g.slice(eIndex)) || ""; | ||
rangeNode.textContent = text1 + text2; | ||
range.setStart(rangeNode, index - 1); | ||
range.setEnd(rangeNode, index - 1); | ||
index = Math.max(0, index - 1); | ||
index = Math.min(index, rangeNode.textContent.length); | ||
range.setStart(rangeNode, index); | ||
range.collapse(true); | ||
return true; | ||
@@ -151,6 +187,2 @@ } | ||
var upRow = rowEl.previousElementSibling; | ||
// 如果没有上级兄弟,并且光标在当前行开头,不执行操作 | ||
if (!upRow && (0, range_1.isRangeAtRowStart)(range, rowEl)) { | ||
return true; | ||
} | ||
// 如果当前节点是空标签 | ||
@@ -167,2 +199,6 @@ if ((0, _1.isEmptyElement)(rowEl)) { | ||
} | ||
// 如果没有上级兄弟,并且光标在当前行开头,不执行操作 | ||
if (!upRow && (0, range_1.isRangeAtRowStart)(range, rowEl)) { | ||
return true; | ||
} | ||
// 如果光标在当前行开头,并且有上一个兄弟节点 | ||
@@ -175,13 +211,7 @@ if ((0, range_1.isRangeAtRowStart)(range, rowEl) && upRow) { | ||
} | ||
// 将当前行中的所有内容转入到上一行 | ||
var fr_2 = (0, _1.createDocumentFragment)(); | ||
rowEl.remove(); | ||
// 将当前行中的所有内容复制到文档片段中 | ||
rowEl.childNodes.forEach(function (node) { | ||
fr_2.appendChild(node.cloneNode(true)); | ||
}); | ||
// 将光标移动到上一个P标签的末尾 | ||
(0, range_1.moveRangeAtRowEnd)(range, upRow); | ||
// 将当前P标签的内容添加到上一个P标签中 | ||
upRow.appendChild(fr_2); | ||
rowEl.remove(); | ||
// 将当前行的内容添加到上一行中 | ||
(0, _1.transferElement)(rowEl, upRow); | ||
return true; | ||
@@ -208,9 +238,9 @@ } | ||
if (delEl.className === const_1.TEXT_TAG_CLASS) { | ||
delEl.textContent = ((_e = delEl.textContent) === null || _e === void 0 ? void 0 : _e.slice(0, -1)) || ""; | ||
delEl.textContent = ((_h = delEl.textContent) === null || _h === void 0 ? void 0 : _h.slice(0, -1)) || ""; | ||
// 如果还有内容,将光标移动到文本末尾 | ||
if (!(0, _1.isEmptyElement)(delEl)) { | ||
var textNode = delEl.lastChild; | ||
var textLength = ((_f = delEl.textContent) === null || _f === void 0 ? void 0 : _f.length) || 0; | ||
var textLength = ((_j = delEl.textContent) === null || _j === void 0 ? void 0 : _j.length) || 0; | ||
range.setStart(textNode ? textNode : delEl, textNode ? textLength : delEl.childNodes.length); | ||
range.setEnd(textNode ? textNode : delEl, textNode ? textLength : delEl.childNodes.length); | ||
range.collapse(true); | ||
return true; | ||
@@ -230,5 +260,5 @@ } | ||
var nextChild = upNode.childNodes[childLength - 1]; | ||
var index = (0, _1.isEmptyElement)(upNode) ? 0 : ((_g = nextChild.textContent) === null || _g === void 0 ? void 0 : _g.length) || 0; | ||
var index = (0, _1.isEmptyElement)(upNode) ? 0 : ((_k = nextChild.textContent) === null || _k === void 0 ? void 0 : _k.length) || 0; | ||
range.setStart(nextChild, index); | ||
range.setEnd(nextChild, index); | ||
range.collapse(true); | ||
} | ||
@@ -260,12 +290,8 @@ return true; | ||
if (startP !== endP) { | ||
var fr_3 = (0, _1.createDocumentFragment)(); | ||
endP.remove(); | ||
endP.childNodes.forEach(function (node) { | ||
fr_3.appendChild(node.cloneNode(true)); | ||
}); | ||
startP.appendChild(fr_3); | ||
(0, _1.transferElement)(endP, startP); | ||
} | ||
// 修正光标位置 | ||
range.setStart(startContainer, startOffset); | ||
range.setEnd(startContainer, startOffset); | ||
range.collapse(true); | ||
return true; | ||
@@ -277,9 +303,15 @@ } | ||
return true; | ||
var bool = false; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
if (e.code === "Backspace") { | ||
return onBackspace(range, els); | ||
bool = onBackspace(range, els); | ||
} | ||
if (e.code === "Delete") { | ||
return onDelete(range, els); | ||
bool = onDelete(range, els); | ||
} | ||
return false; | ||
if (bool) { | ||
// 修正当前行标签 | ||
(0, _1.fixRowContent)(els.rowEl); | ||
} | ||
return bool; | ||
} |
@@ -35,4 +35,5 @@ "use strict"; | ||
return; | ||
(0, range_1.fixTextRange)(range, els.textEl); | ||
// 如果光标在当前行末尾 | ||
if ((0, range_1.isRangeAtRowEnd)(range, els.rowEl)) { | ||
if ((0, _1.isEmptyElement)(els.rowEl) || (0, range_1.isRangeAtRowEnd)(range, els.rowEl)) { | ||
// 在当前行后创建一个新行 | ||
@@ -67,16 +68,5 @@ var newRow_1 = (0, _1.createRowTag)(); | ||
emptyEls.forEach(function (el) { var _a; return (_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(el); }); | ||
var newRow = (0, _1.createElement)("p", { className: const_1.ROW_TAG_CLASS }); | ||
// 将内容插入到新创建的行中 | ||
var newRow = (0, _1.createElement)("p", { className: const_1.ROW_TAG_CLASS }); | ||
var fr = (0, _1.createDocumentFragment)(); | ||
selectedContent.childNodes.forEach(function (node) { | ||
if (node.nodeName === "#text") { | ||
if (!node.textContent) | ||
return; | ||
fr.appendChild((0, _1.createTextTag)(node.textContent)); | ||
} | ||
else { | ||
fr.appendChild(node.cloneNode(true)); | ||
} | ||
}); | ||
newRow.appendChild(fr); | ||
(0, _1.transferElement)(selectedContent, newRow); | ||
// 修正新的行 | ||
@@ -83,0 +73,0 @@ (0, _1.fixRowContent)(newRow); |
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
91702
24
2113
271