重构:引用输入区的选区兜底收敛成一个 helper
抽出 $selectionOrRootEnd():选区缺失或指向已被重建掉的节点时统一回落到草稿末尾 insertReferences / insertText / $insertContentAtSelection 三处重复的兜底判断改为调用它 行为不变:插件插入与粘贴插入仍走同一套「插到草稿末尾」的策略,只是不再各写一份
This commit is contained in:
+34
-48
@@ -300,6 +300,22 @@ function applyContentToRoot(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取当前可用的选区:选区缺失、或指向已被重建掉的节点时(跨会话恢复草稿后就是这种),
|
||||
* 统一回落到草稿末尾,避免把内容插到一个已经不存在的位置。取不到时返回 `null`。
|
||||
*/
|
||||
function $selectionOrRootEnd() {
|
||||
let selection = $getSelection();
|
||||
if (
|
||||
!$isRangeSelection(selection) ||
|
||||
!selection.anchor.getNode().isAttached()
|
||||
) {
|
||||
$getRoot().selectEnd();
|
||||
selection = $getSelection();
|
||||
}
|
||||
return $isRangeSelection(selection) ? selection : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 粘贴插入:在光标处就地插入 content 对应的节点,正文其余部分逐字不动。
|
||||
*
|
||||
@@ -311,31 +327,19 @@ function $insertContentAtSelection(
|
||||
content: readonly DirectCodexUserContentPart[],
|
||||
providers: readonly ReferenceProvider[],
|
||||
) {
|
||||
// 与 insertReferences 同一处置:选区可能指向已被重建掉的节点,统一回落到草稿末尾。
|
||||
// 每插一段都重新取一次选区:插入会移动光标,缓存下来的那个 RangeSelection 会过期。
|
||||
const currentSelection = () => {
|
||||
let selection = $getSelection();
|
||||
if (
|
||||
!$isRangeSelection(selection) ||
|
||||
!selection.anchor.getNode().isAttached()
|
||||
) {
|
||||
$getRoot().selectEnd();
|
||||
selection = $getSelection();
|
||||
}
|
||||
return $isRangeSelection(selection) ? selection : null;
|
||||
};
|
||||
if (!currentSelection()) return;
|
||||
// 每插一段都重新取一次选区:插入会移动光标,上一轮拿到的那个 RangeSelection 会过期。
|
||||
if (!$selectionOrRootEnd()) return;
|
||||
content.forEach((part) => {
|
||||
if (part.type === 'input_text') {
|
||||
part.text.split('\n').forEach((line, index) => {
|
||||
if (index > 0) currentSelection()?.insertParagraph();
|
||||
if (line) currentSelection()?.insertText(line);
|
||||
if (index > 0) $selectionOrRootEnd()?.insertParagraph();
|
||||
if (line) $selectionOrRootEnd()?.insertText(line);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const reference = referenceFromPart(providers, part);
|
||||
if (reference) {
|
||||
currentSelection()?.insertNodes([
|
||||
$selectionOrRootEnd()?.insertNodes([
|
||||
$createResourceReferenceNode(reference),
|
||||
]);
|
||||
}
|
||||
@@ -413,24 +417,14 @@ function ResourceReferenceEditor({
|
||||
(nextReferences: ChatReference[]) => {
|
||||
if (nextReferences.length === 0) return;
|
||||
editor.update(() => {
|
||||
let selection = $getSelection();
|
||||
// 跨会话恢复草稿后选区可能仍指向已被重建掉的节点,这里统一回落到草稿末尾,
|
||||
// 避免把引用插到一个已经不存在的位置。
|
||||
if (
|
||||
!$isRangeSelection(selection) ||
|
||||
!selection.anchor.getNode().isAttached()
|
||||
) {
|
||||
$getRoot().selectEnd();
|
||||
selection = $getSelection();
|
||||
}
|
||||
if ($isRangeSelection(selection)) {
|
||||
selection.insertNodes(
|
||||
nextReferences.flatMap((reference) => [
|
||||
$createResourceReferenceNode(reference),
|
||||
$createTextNode(' '),
|
||||
]),
|
||||
);
|
||||
}
|
||||
const selection = $selectionOrRootEnd();
|
||||
if (!selection) return;
|
||||
selection.insertNodes(
|
||||
nextReferences.flatMap((reference) => [
|
||||
$createResourceReferenceNode(reference),
|
||||
$createTextNode(' '),
|
||||
]),
|
||||
);
|
||||
});
|
||||
editor.focus();
|
||||
},
|
||||
@@ -442,19 +436,11 @@ function ResourceReferenceEditor({
|
||||
const insert = text.replace(/\s+$/u, '');
|
||||
if (!insert.trim()) return;
|
||||
editor.update(() => {
|
||||
let selection = $getSelection();
|
||||
if (
|
||||
!$isRangeSelection(selection) ||
|
||||
!selection.anchor.getNode().isAttached()
|
||||
) {
|
||||
$getRoot().selectEnd();
|
||||
selection = $getSelection();
|
||||
}
|
||||
if ($isRangeSelection(selection)) {
|
||||
const rootText = $getRoot().getTextContent();
|
||||
if (rootText && !/\s$/u.test(rootText)) selection.insertText(' ');
|
||||
selection.insertText(insert);
|
||||
}
|
||||
const selection = $selectionOrRootEnd();
|
||||
if (!selection) return;
|
||||
const rootText = $getRoot().getTextContent();
|
||||
if (rootText && !/\s$/u.test(rootText)) selection.insertText(' ');
|
||||
selection.insertText(insert);
|
||||
});
|
||||
editor.focus();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user