@haluo/biz 2.0.38 → 2.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/haluo-biz.js +1385 -66
- package/dist/haluo-biz.umd.cjs +1384 -76
- package/dist/{squire-raw-97946106.js → squire-raw-1aaeff0b.js} +0 -11
- package/dist/style.css +84 -4
- package/package.json +1 -1
package/dist/haluo-biz.js
CHANGED
|
@@ -317,7 +317,7 @@ const _export_sfc = (sfc, props) => {
|
|
|
317
317
|
}
|
|
318
318
|
return target;
|
|
319
319
|
};
|
|
320
|
-
const _sfc_main$
|
|
320
|
+
const _sfc_main$8 = {
|
|
321
321
|
components: {
|
|
322
322
|
ElTooltip,
|
|
323
323
|
ElDivider,
|
|
@@ -519,7 +519,7 @@ const _sfc_main$7 = {
|
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
521
|
};
|
|
522
|
-
const _hoisted_1$
|
|
522
|
+
const _hoisted_1$8 = {
|
|
523
523
|
key: 0,
|
|
524
524
|
class: "tools"
|
|
525
525
|
};
|
|
@@ -585,13 +585,13 @@ const _hoisted_42 = {
|
|
|
585
585
|
const _hoisted_43 = ["src"];
|
|
586
586
|
const _hoisted_44 = ["src"];
|
|
587
587
|
const _hoisted_45 = ["src"];
|
|
588
|
-
function _sfc_render$
|
|
588
|
+
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
589
589
|
const _component_el_tooltip = resolveComponent("el-tooltip");
|
|
590
590
|
const _component_el_divider = resolveComponent("el-divider");
|
|
591
591
|
const _component_el_popover = resolveComponent("el-popover");
|
|
592
592
|
const _component_colorPicker = resolveComponent("colorPicker");
|
|
593
593
|
const _directive_click_outside = resolveDirective("click-outside");
|
|
594
|
-
return $props.editor.fontInfo ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
594
|
+
return $props.editor.fontInfo ? (openBlock(), createElementBlock("div", _hoisted_1$8, [
|
|
595
595
|
createElementVNode("div", _hoisted_2$5, [
|
|
596
596
|
createVNode(_component_el_tooltip, {
|
|
597
597
|
class: "item",
|
|
@@ -1105,15 +1105,15 @@ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
1105
1105
|
])
|
|
1106
1106
|
])) : createCommentVNode("", true);
|
|
1107
1107
|
}
|
|
1108
|
-
const ToolBar = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
1108
|
+
const ToolBar = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$4], ["__scopeId", "data-v-50235bb8"]]);
|
|
1109
1109
|
const __vite_glob_0_0 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAmCAYAAAClI5npAAAA0UlEQVR42uWYwQnDMAxFfckAXkFDmGzgS1foDpnFS3gTb+IFtIDyA4UeBKUtNR8qwTvlkAdyfmSletySmRUwgIIJOijXs9VcLxegwNVDRFYLdHtdCg6wrRKY9l4NUFYIqH1WDeTfCXxXE9w5Ar4tQhBwh7SBjSDg2lJJAj47SAI+OwgC7pDuJAGfHQQBnx0kAZ8dBAF3SOtTgCchybjV2QLKFpihW6BAQn6GA0i4KG4g037H4QaSDiTWUMocyweQcFezBjLrer5TFxR/uaKhL6lOdeUQ8G6X1pQAAAAASUVORK5CYII=";
|
|
1110
|
-
const _hoisted_1$
|
|
1110
|
+
const _hoisted_1$7 = { key: 0 };
|
|
1111
1111
|
const _hoisted_2$4 = { class: "basic-dialog_title" };
|
|
1112
1112
|
const _hoisted_3$4 = {
|
|
1113
1113
|
key: 0,
|
|
1114
1114
|
class: "dialog-footer"
|
|
1115
1115
|
};
|
|
1116
|
-
const _sfc_main$
|
|
1116
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
1117
1117
|
__name: "index",
|
|
1118
1118
|
props: {
|
|
1119
1119
|
visible: { type: Boolean, default: false },
|
|
@@ -1154,7 +1154,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
1154
1154
|
class: normalizeClass(["basic-dialog", { "hide-title": !_ctx.showTitle }])
|
|
1155
1155
|
}, {
|
|
1156
1156
|
header: withCtx(() => [
|
|
1157
|
-
_ctx.showTitle ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
1157
|
+
_ctx.showTitle ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
|
|
1158
1158
|
createElementVNode("div", _hoisted_2$4, [
|
|
1159
1159
|
_cache[1] || (_cache[1] = createElementVNode("span", { class: "basic-dialog_divider" }, null, -1)),
|
|
1160
1160
|
renderSlot(_ctx.$slots, "title")
|
|
@@ -1195,7 +1195,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
1195
1195
|
};
|
|
1196
1196
|
}
|
|
1197
1197
|
});
|
|
1198
|
-
const index_vue_vue_type_style_index_0_lang$
|
|
1198
|
+
const index_vue_vue_type_style_index_0_lang$5 = "";
|
|
1199
1199
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
1200
1200
|
function getDefaultExportFromCjs(x) {
|
|
1201
1201
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
@@ -3485,7 +3485,7 @@ var ToolsClass = (
|
|
|
3485
3485
|
tools$2.exports = new ToolsClass();
|
|
3486
3486
|
var toolsExports = tools$2.exports;
|
|
3487
3487
|
const tools$1 = /* @__PURE__ */ getDefaultExportFromCjs(toolsExports);
|
|
3488
|
-
const _hoisted_1$
|
|
3488
|
+
const _hoisted_1$6 = { style: { "margin-left": "20px", "color": "#FF5A25" } };
|
|
3489
3489
|
const _hoisted_2$3 = { class: "insert-article" };
|
|
3490
3490
|
const _hoisted_3$3 = { class: "insert-article_input" };
|
|
3491
3491
|
const _hoisted_4$2 = {
|
|
@@ -3506,7 +3506,7 @@ const _hoisted_12$1 = {
|
|
|
3506
3506
|
key: 1,
|
|
3507
3507
|
style: { "display": "inline-flex", "flex-direction": "column" }
|
|
3508
3508
|
};
|
|
3509
|
-
const _sfc_main$
|
|
3509
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
3510
3510
|
__name: "index",
|
|
3511
3511
|
props: {
|
|
3512
3512
|
visible: { type: Boolean, default: false },
|
|
@@ -3582,6 +3582,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
3582
3582
|
data.busy = true;
|
|
3583
3583
|
const userInfo = JSON.parse(localStorage.getItem("user")) || JSON.parse(localStorage.getItem("userInfo"));
|
|
3584
3584
|
const userId = userInfo.uid || userInfo.userid;
|
|
3585
|
+
if (!getList.value)
|
|
3586
|
+
return;
|
|
3585
3587
|
const res = await getList.value({
|
|
3586
3588
|
uid: data.params.radio !== Radio_Type.ALL_ARITICLE ? userId : "",
|
|
3587
3589
|
autherid: data.params.radio !== Radio_Type.ALL_ARITICLE ? userId : "",
|
|
@@ -3601,14 +3603,14 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
3601
3603
|
data.busy = false;
|
|
3602
3604
|
}, 1e3);
|
|
3603
3605
|
return (_ctx, _cache) => {
|
|
3604
|
-
return openBlock(), createBlock(_sfc_main$
|
|
3606
|
+
return openBlock(), createBlock(_sfc_main$7, {
|
|
3605
3607
|
visible: unref(visible),
|
|
3606
3608
|
onSubmit: confirm
|
|
3607
3609
|
}, {
|
|
3608
3610
|
title: withCtx(() => [
|
|
3609
3611
|
createElementVNode("span", null, [
|
|
3610
3612
|
_cache[8] || (_cache[8] = createTextVNode("插入文章/视频")),
|
|
3611
|
-
createElementVNode("strong", _hoisted_1$
|
|
3613
|
+
createElementVNode("strong", _hoisted_1$6, "平台仅支持插入" + toDisplayString(`${isVideo.value ? "2年" : "18个月"}`) + "内的推荐内容", 1)
|
|
3612
3614
|
])
|
|
3613
3615
|
]),
|
|
3614
3616
|
default: withCtx(() => [
|
|
@@ -3718,7 +3720,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
3718
3720
|
};
|
|
3719
3721
|
}
|
|
3720
3722
|
});
|
|
3721
|
-
const index_vue_vue_type_style_index_0_lang$
|
|
3723
|
+
const index_vue_vue_type_style_index_0_lang$4 = "";
|
|
3722
3724
|
let getRandomValues;
|
|
3723
3725
|
const rnds8 = new Uint8Array(16);
|
|
3724
3726
|
function rng() {
|
|
@@ -3758,7 +3760,7 @@ function v4(options, buf, offset) {
|
|
|
3758
3760
|
}
|
|
3759
3761
|
return unsafeStringify(rnds);
|
|
3760
3762
|
}
|
|
3761
|
-
const _hoisted_1$
|
|
3763
|
+
const _hoisted_1$5 = { class: "img-upload-content" };
|
|
3762
3764
|
const _hoisted_2$2 = { class: "title-box" };
|
|
3763
3765
|
const _hoisted_3$2 = ["onClick"];
|
|
3764
3766
|
const _hoisted_4$1 = {
|
|
@@ -3820,7 +3822,7 @@ const _hoisted_28 = {
|
|
|
3820
3822
|
class: "protocol-box"
|
|
3821
3823
|
};
|
|
3822
3824
|
const _hoisted_29 = ["href"];
|
|
3823
|
-
const _sfc_main$
|
|
3825
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
3824
3826
|
__name: "index",
|
|
3825
3827
|
props: {
|
|
3826
3828
|
visible: { type: Boolean, default: false },
|
|
@@ -4102,12 +4104,12 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
4102
4104
|
emits("update:imgList", list);
|
|
4103
4105
|
};
|
|
4104
4106
|
return (_ctx, _cache) => {
|
|
4105
|
-
return openBlock(), createBlock(_sfc_main$
|
|
4107
|
+
return openBlock(), createBlock(_sfc_main$7, {
|
|
4106
4108
|
visible: props.visible,
|
|
4107
4109
|
showTitle: false
|
|
4108
4110
|
}, {
|
|
4109
4111
|
default: withCtx(() => [
|
|
4110
|
-
createElementVNode("div", _hoisted_1$
|
|
4112
|
+
createElementVNode("div", _hoisted_1$5, [
|
|
4111
4113
|
createElementVNode("div", _hoisted_2$2, [
|
|
4112
4114
|
(openBlock(true), createElementBlock(Fragment, null, renderList(titleList.value, (item, index) => {
|
|
4113
4115
|
return openBlock(), createElementBlock("div", {
|
|
@@ -4347,9 +4349,9 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
4347
4349
|
};
|
|
4348
4350
|
}
|
|
4349
4351
|
});
|
|
4350
|
-
const index_vue_vue_type_style_index_0_lang$
|
|
4351
|
-
const _hoisted_1$
|
|
4352
|
-
const _sfc_main$
|
|
4352
|
+
const index_vue_vue_type_style_index_0_lang$3 = "";
|
|
4353
|
+
const _hoisted_1$4 = { class: "insert-video" };
|
|
4354
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
4353
4355
|
__name: "index",
|
|
4354
4356
|
props: {
|
|
4355
4357
|
visible: { type: Boolean, default: false },
|
|
@@ -4371,7 +4373,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
4371
4373
|
ele[0].dispatchEvent(event);
|
|
4372
4374
|
};
|
|
4373
4375
|
return (_ctx, _cache) => {
|
|
4374
|
-
return openBlock(), createBlock(_sfc_main$
|
|
4376
|
+
return openBlock(), createBlock(_sfc_main$7, {
|
|
4375
4377
|
"show-btn": false,
|
|
4376
4378
|
visible: unref(visible),
|
|
4377
4379
|
width: "600px",
|
|
@@ -4381,7 +4383,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
4381
4383
|
createElementVNode("span", null, "插入视频", -1)
|
|
4382
4384
|
])),
|
|
4383
4385
|
default: withCtx(() => [
|
|
4384
|
-
createElementVNode("div", _hoisted_1$
|
|
4386
|
+
createElementVNode("div", _hoisted_1$4, [
|
|
4385
4387
|
createVNode(unref(ElButton), {
|
|
4386
4388
|
style: { "width": "120px" },
|
|
4387
4389
|
round: "",
|
|
@@ -4408,7 +4410,703 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
4408
4410
|
};
|
|
4409
4411
|
}
|
|
4410
4412
|
});
|
|
4413
|
+
const index_vue_vue_type_style_index_0_lang$2 = "";
|
|
4411
4414
|
const index_vue_vue_type_style_index_0_lang$1 = "";
|
|
4415
|
+
const _sfc_main$3 = {
|
|
4416
|
+
name: "TopicManager",
|
|
4417
|
+
props: {
|
|
4418
|
+
// 编辑器DOM引用
|
|
4419
|
+
editorDom: {
|
|
4420
|
+
type: Object,
|
|
4421
|
+
default: null
|
|
4422
|
+
},
|
|
4423
|
+
// 话题API请求方法
|
|
4424
|
+
request: {
|
|
4425
|
+
type: Object,
|
|
4426
|
+
default: null
|
|
4427
|
+
}
|
|
4428
|
+
},
|
|
4429
|
+
data() {
|
|
4430
|
+
return {
|
|
4431
|
+
// 话题弹框相关数据
|
|
4432
|
+
topicPopover: {
|
|
4433
|
+
visible: false,
|
|
4434
|
+
type: "hot",
|
|
4435
|
+
// 'hot' 热门话题, 'search' 搜索话题
|
|
4436
|
+
activeTab: "hot",
|
|
4437
|
+
// 'hot' 热门话题, 'recent' 最近使用
|
|
4438
|
+
position: { top: 0, left: 0 },
|
|
4439
|
+
searchKeyword: "",
|
|
4440
|
+
hotTopics: [],
|
|
4441
|
+
searchTopics: [],
|
|
4442
|
+
recentTopics: [],
|
|
4443
|
+
loading: false,
|
|
4444
|
+
page: 1,
|
|
4445
|
+
hasMore: true,
|
|
4446
|
+
searchPage: 1,
|
|
4447
|
+
searchHasMore: true,
|
|
4448
|
+
// 保存原始的selection和range信息
|
|
4449
|
+
originalRange: null,
|
|
4450
|
+
originalSelection: null,
|
|
4451
|
+
// 保存触发位置信息
|
|
4452
|
+
triggerInfo: {
|
|
4453
|
+
paragraph: null,
|
|
4454
|
+
hashIndex: -1,
|
|
4455
|
+
cursorPosition: 0
|
|
4456
|
+
},
|
|
4457
|
+
// 全局弹框DOM引用
|
|
4458
|
+
globalContainer: null,
|
|
4459
|
+
globalMask: null
|
|
4460
|
+
}
|
|
4461
|
+
};
|
|
4462
|
+
},
|
|
4463
|
+
methods: {
|
|
4464
|
+
// 初始化话题管理器
|
|
4465
|
+
init() {
|
|
4466
|
+
if (!this.editorDom) {
|
|
4467
|
+
console.warn("TopicManager: editorDom is required");
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
setTimeout(() => this.bindEditorEvents(), 0);
|
|
4471
|
+
},
|
|
4472
|
+
// 绑定编辑器事件
|
|
4473
|
+
bindEditorEvents() {
|
|
4474
|
+
if (!this.editorDom)
|
|
4475
|
+
return;
|
|
4476
|
+
this.editorDom.addEventListener("keydown", this.handleTopicInput.bind(this));
|
|
4477
|
+
},
|
|
4478
|
+
// 解绑编辑器事件
|
|
4479
|
+
unbindEditorEvents() {
|
|
4480
|
+
if (!this.editorDom)
|
|
4481
|
+
return;
|
|
4482
|
+
this.editorDom.removeEventListener("keydown", this.handleTopicInput.bind(this));
|
|
4483
|
+
},
|
|
4484
|
+
// 话题输入处理
|
|
4485
|
+
handleTopicInput(event) {
|
|
4486
|
+
var _a;
|
|
4487
|
+
const activeElement = document.activeElement;
|
|
4488
|
+
if (activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA")) {
|
|
4489
|
+
return;
|
|
4490
|
+
}
|
|
4491
|
+
const selection = window.getSelection();
|
|
4492
|
+
if (selection.rangeCount === 0)
|
|
4493
|
+
return;
|
|
4494
|
+
const range = selection.getRangeAt(0);
|
|
4495
|
+
const container = range.startContainer;
|
|
4496
|
+
if (!this.editorDom.contains(container))
|
|
4497
|
+
return;
|
|
4498
|
+
let currentNode = container;
|
|
4499
|
+
while (currentNode && currentNode !== this.editorDom) {
|
|
4500
|
+
if (currentNode.nodeType === Node.ELEMENT_NODE && currentNode.tagName === "MDD-TOPIC") {
|
|
4501
|
+
return;
|
|
4502
|
+
}
|
|
4503
|
+
currentNode = currentNode.parentNode;
|
|
4504
|
+
}
|
|
4505
|
+
let paragraph = container;
|
|
4506
|
+
while (paragraph && paragraph.nodeType !== Node.ELEMENT_NODE) {
|
|
4507
|
+
paragraph = paragraph.parentNode;
|
|
4508
|
+
}
|
|
4509
|
+
while (paragraph && !((_a = paragraph.classList) == null ? void 0 : _a.contains("halo-paragraph"))) {
|
|
4510
|
+
paragraph = paragraph.parentNode;
|
|
4511
|
+
}
|
|
4512
|
+
if (!paragraph)
|
|
4513
|
+
return;
|
|
4514
|
+
const { textContent: paragraphText, cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
4515
|
+
if (event.key === "#") {
|
|
4516
|
+
const afterCursor = paragraphText.substring(cursorPosition);
|
|
4517
|
+
if (afterCursor.length > 0 && (afterCursor[0] === "@" || afterCursor[0] === " ")) {
|
|
4518
|
+
return;
|
|
4519
|
+
}
|
|
4520
|
+
setTimeout(() => {
|
|
4521
|
+
const position = this.getCaretPosition();
|
|
4522
|
+
const triggerInfo = {
|
|
4523
|
+
paragraph,
|
|
4524
|
+
hashIndex: cursorPosition,
|
|
4525
|
+
// #号的位置
|
|
4526
|
+
cursorPosition: cursorPosition + 1
|
|
4527
|
+
// #号后的位置
|
|
4528
|
+
};
|
|
4529
|
+
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4530
|
+
}, 10);
|
|
4531
|
+
} else if (this.shouldTriggerSearch(event.key)) {
|
|
4532
|
+
setTimeout(() => {
|
|
4533
|
+
this.checkAndTriggerSearch(paragraph);
|
|
4534
|
+
}, 10);
|
|
4535
|
+
}
|
|
4536
|
+
},
|
|
4537
|
+
shouldTriggerSearch(key) {
|
|
4538
|
+
return key.length === 1 || key === "Backspace" || key === "Delete";
|
|
4539
|
+
},
|
|
4540
|
+
checkAndTriggerSearch(paragraph) {
|
|
4541
|
+
const selection = window.getSelection();
|
|
4542
|
+
if (selection.rangeCount === 0)
|
|
4543
|
+
return;
|
|
4544
|
+
const range = selection.getRangeAt(0);
|
|
4545
|
+
let currentNode = range.startContainer;
|
|
4546
|
+
while (currentNode && currentNode !== paragraph) {
|
|
4547
|
+
if (currentNode.nodeType === Node.ELEMENT_NODE && currentNode.tagName === "MDD-TOPIC") {
|
|
4548
|
+
this.hideTopicPopover();
|
|
4549
|
+
return;
|
|
4550
|
+
}
|
|
4551
|
+
currentNode = currentNode.parentNode;
|
|
4552
|
+
}
|
|
4553
|
+
const { textContent: paragraphText, cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
4554
|
+
const beforeCursor = paragraphText.substring(0, cursorPosition);
|
|
4555
|
+
const hashIndex = beforeCursor.lastIndexOf("#");
|
|
4556
|
+
if (hashIndex !== -1) {
|
|
4557
|
+
const afterHash = beforeCursor.substring(hashIndex + 1);
|
|
4558
|
+
if (afterHash.indexOf(" ") === -1 && afterHash.indexOf("@") === -1) {
|
|
4559
|
+
if (afterHash.length <= 15) {
|
|
4560
|
+
const position = this.getCaretPosition();
|
|
4561
|
+
const triggerInfo = {
|
|
4562
|
+
paragraph,
|
|
4563
|
+
hashIndex,
|
|
4564
|
+
cursorPosition
|
|
4565
|
+
};
|
|
4566
|
+
if (afterHash.length === 0) {
|
|
4567
|
+
this.showTopicPopover("hot", position, "", triggerInfo);
|
|
4568
|
+
} else {
|
|
4569
|
+
this.showTopicPopover("search", position, afterHash, triggerInfo);
|
|
4570
|
+
}
|
|
4571
|
+
} else if (afterHash.length > 15) {
|
|
4572
|
+
this.hideTopicPopover();
|
|
4573
|
+
}
|
|
4574
|
+
} else {
|
|
4575
|
+
this.hideTopicPopover();
|
|
4576
|
+
}
|
|
4577
|
+
} else {
|
|
4578
|
+
this.hideTopicPopover();
|
|
4579
|
+
}
|
|
4580
|
+
},
|
|
4581
|
+
getParagraphTextExcludingTopics(paragraph, range) {
|
|
4582
|
+
let textContent = "";
|
|
4583
|
+
let cursorPosition = 0;
|
|
4584
|
+
let foundCursor = false;
|
|
4585
|
+
const walker = document.createTreeWalker(
|
|
4586
|
+
paragraph,
|
|
4587
|
+
NodeFilter.SHOW_ALL,
|
|
4588
|
+
{
|
|
4589
|
+
acceptNode: function(node2) {
|
|
4590
|
+
if (node2.nodeType === Node.ELEMENT_NODE && node2.tagName === "MDD-TOPIC") {
|
|
4591
|
+
return NodeFilter.FILTER_REJECT;
|
|
4592
|
+
}
|
|
4593
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
4594
|
+
}
|
|
4595
|
+
},
|
|
4596
|
+
false
|
|
4597
|
+
);
|
|
4598
|
+
let node;
|
|
4599
|
+
while (node = walker.nextNode()) {
|
|
4600
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
4601
|
+
const nodeText = node.textContent;
|
|
4602
|
+
if (!foundCursor && node === range.startContainer) {
|
|
4603
|
+
cursorPosition = textContent.length + range.startOffset;
|
|
4604
|
+
foundCursor = true;
|
|
4605
|
+
}
|
|
4606
|
+
textContent += nodeText;
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
return { textContent, cursorPosition };
|
|
4610
|
+
},
|
|
4611
|
+
getCaretPosition() {
|
|
4612
|
+
const selection = window.getSelection();
|
|
4613
|
+
if (selection.rangeCount === 0)
|
|
4614
|
+
return { top: 0, left: 0 };
|
|
4615
|
+
const range = selection.getRangeAt(0);
|
|
4616
|
+
const rect = range.getBoundingClientRect();
|
|
4617
|
+
return {
|
|
4618
|
+
top: rect.bottom + window.scrollY,
|
|
4619
|
+
left: rect.left + window.scrollX
|
|
4620
|
+
};
|
|
4621
|
+
},
|
|
4622
|
+
// 话题弹框相关方法
|
|
4623
|
+
showTopicPopover(type, position, searchKeyword = "", triggerInfo = null) {
|
|
4624
|
+
if (!this.request || !this.request.getTopic) {
|
|
4625
|
+
console.warn("话题功能需要提供 request.getTopic 方法");
|
|
4626
|
+
return;
|
|
4627
|
+
}
|
|
4628
|
+
const selection = window.getSelection();
|
|
4629
|
+
if (selection.rangeCount > 0) {
|
|
4630
|
+
this.topicPopover.originalRange = selection.getRangeAt(0).cloneRange();
|
|
4631
|
+
this.topicPopover.originalSelection = selection;
|
|
4632
|
+
}
|
|
4633
|
+
if (triggerInfo) {
|
|
4634
|
+
this.topicPopover.triggerInfo = triggerInfo;
|
|
4635
|
+
}
|
|
4636
|
+
this.topicPopover.visible = true;
|
|
4637
|
+
this.topicPopover.type = type;
|
|
4638
|
+
this.topicPopover.position = position;
|
|
4639
|
+
this.topicPopover.searchKeyword = searchKeyword;
|
|
4640
|
+
if (type === "hot") {
|
|
4641
|
+
this.topicPopover.activeTab = "hot";
|
|
4642
|
+
this.loadHotTopics();
|
|
4643
|
+
this.loadRecentTopics();
|
|
4644
|
+
} else if (type === "search") {
|
|
4645
|
+
this.searchTopics(searchKeyword);
|
|
4646
|
+
}
|
|
4647
|
+
this.createGlobalTopicPopover();
|
|
4648
|
+
},
|
|
4649
|
+
hideTopicPopover() {
|
|
4650
|
+
this.topicPopover.visible = false;
|
|
4651
|
+
this.topicPopover.hotTopics = [];
|
|
4652
|
+
this.topicPopover.searchTopics = [];
|
|
4653
|
+
this.topicPopover.page = 1;
|
|
4654
|
+
this.topicPopover.searchPage = 1;
|
|
4655
|
+
this.topicPopover.hasMore = true;
|
|
4656
|
+
this.topicPopover.searchHasMore = true;
|
|
4657
|
+
this.topicPopover.originalRange = null;
|
|
4658
|
+
this.topicPopover.originalSelection = null;
|
|
4659
|
+
this.topicPopover.triggerInfo = {
|
|
4660
|
+
paragraph: null,
|
|
4661
|
+
hashIndex: -1,
|
|
4662
|
+
cursorPosition: 0
|
|
4663
|
+
};
|
|
4664
|
+
this.removeGlobalTopicPopover();
|
|
4665
|
+
},
|
|
4666
|
+
switchTopicTab(tab) {
|
|
4667
|
+
this.topicPopover.activeTab = tab;
|
|
4668
|
+
this.updateGlobalTopicPopover();
|
|
4669
|
+
},
|
|
4670
|
+
async loadHotTopics() {
|
|
4671
|
+
if (this.topicPopover.loading || !this.topicPopover.hasMore)
|
|
4672
|
+
return;
|
|
4673
|
+
this.topicPopover.loading = true;
|
|
4674
|
+
try {
|
|
4675
|
+
const response = await this.request.getTopic({
|
|
4676
|
+
action: "201023",
|
|
4677
|
+
page: this.topicPopover.page,
|
|
4678
|
+
limit: 50,
|
|
4679
|
+
hoopId: 0,
|
|
4680
|
+
type: 0,
|
|
4681
|
+
orderBy: "view"
|
|
4682
|
+
});
|
|
4683
|
+
if (response && response.data && response.data.code === 0) {
|
|
4684
|
+
const topics = response.data.data || [];
|
|
4685
|
+
if (topics.length === 0) {
|
|
4686
|
+
this.topicPopover.hasMore = false;
|
|
4687
|
+
} else {
|
|
4688
|
+
const existingIds = new Set(this.topicPopover.hotTopics.map((t) => t.id));
|
|
4689
|
+
const newTopics = topics.filter((t) => !existingIds.has(t.id));
|
|
4690
|
+
this.topicPopover.hotTopics = [...this.topicPopover.hotTopics, ...newTopics];
|
|
4691
|
+
this.topicPopover.page++;
|
|
4692
|
+
if (newTopics.length === 0) {
|
|
4693
|
+
this.topicPopover.hasMore = false;
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
} else {
|
|
4697
|
+
console.warn("加载热门话题失败:", response);
|
|
4698
|
+
this.topicPopover.hasMore = false;
|
|
4699
|
+
}
|
|
4700
|
+
} catch (error) {
|
|
4701
|
+
console.error("加载热门话题失败:", error);
|
|
4702
|
+
this.topicPopover.hasMore = false;
|
|
4703
|
+
} finally {
|
|
4704
|
+
this.topicPopover.loading = false;
|
|
4705
|
+
this.updateGlobalTopicPopover();
|
|
4706
|
+
}
|
|
4707
|
+
},
|
|
4708
|
+
async searchTopics(keyword) {
|
|
4709
|
+
this.topicPopover.searchKeyword = keyword;
|
|
4710
|
+
this.topicPopover.searchTopics = [];
|
|
4711
|
+
this.topicPopover.searchPage = 1;
|
|
4712
|
+
this.topicPopover.searchHasMore = true;
|
|
4713
|
+
if (this.topicPopover.loading) {
|
|
4714
|
+
this.topicPopover.loading = false;
|
|
4715
|
+
}
|
|
4716
|
+
this.topicPopover.loading = true;
|
|
4717
|
+
try {
|
|
4718
|
+
const response = await this.request.getTopic({
|
|
4719
|
+
action: "201023",
|
|
4720
|
+
title: keyword,
|
|
4721
|
+
highlightTitle: "title",
|
|
4722
|
+
page: this.topicPopover.searchPage,
|
|
4723
|
+
limit: 50
|
|
4724
|
+
});
|
|
4725
|
+
if (response && response.data && response.data.code === 0) {
|
|
4726
|
+
const topics = response.data.data || [];
|
|
4727
|
+
this.topicPopover.searchTopics = topics;
|
|
4728
|
+
this.topicPopover.searchPage++;
|
|
4729
|
+
if (topics.length === 0) {
|
|
4730
|
+
this.topicPopover.searchHasMore = false;
|
|
4731
|
+
} else {
|
|
4732
|
+
this.topicPopover.searchHasMore = topics.length >= 50;
|
|
4733
|
+
}
|
|
4734
|
+
} else {
|
|
4735
|
+
console.warn("搜索话题失败:", response);
|
|
4736
|
+
this.topicPopover.searchHasMore = false;
|
|
4737
|
+
}
|
|
4738
|
+
} catch (error) {
|
|
4739
|
+
console.error("搜索话题失败:", error);
|
|
4740
|
+
this.topicPopover.searchHasMore = false;
|
|
4741
|
+
} finally {
|
|
4742
|
+
this.topicPopover.loading = false;
|
|
4743
|
+
this.updateGlobalTopicPopover();
|
|
4744
|
+
}
|
|
4745
|
+
},
|
|
4746
|
+
loadRecentTopics() {
|
|
4747
|
+
try {
|
|
4748
|
+
const localTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
4749
|
+
this.topicPopover.recentTopics = localTopics;
|
|
4750
|
+
} catch (error) {
|
|
4751
|
+
console.error("加载最近使用话题失败:", error);
|
|
4752
|
+
this.topicPopover.recentTopics = [];
|
|
4753
|
+
}
|
|
4754
|
+
},
|
|
4755
|
+
selectTopic(topic) {
|
|
4756
|
+
this.saveToRecentTopics(topic);
|
|
4757
|
+
this.insertTopicToEditor(topic);
|
|
4758
|
+
this.hideTopicPopover();
|
|
4759
|
+
this.$emit("topic-inserted", topic);
|
|
4760
|
+
},
|
|
4761
|
+
saveToRecentTopics(topic) {
|
|
4762
|
+
try {
|
|
4763
|
+
let recentTopics = JSON.parse(localStorage.getItem("localTopic") || "[]");
|
|
4764
|
+
recentTopics = recentTopics.filter((item) => item.id !== topic.id);
|
|
4765
|
+
recentTopics.unshift(topic);
|
|
4766
|
+
if (recentTopics.length > 20) {
|
|
4767
|
+
recentTopics = recentTopics.slice(0, 20);
|
|
4768
|
+
}
|
|
4769
|
+
localStorage.setItem("localTopic", JSON.stringify(recentTopics));
|
|
4770
|
+
} catch (error) {
|
|
4771
|
+
console.error("保存最近使用话题失败:", error);
|
|
4772
|
+
}
|
|
4773
|
+
},
|
|
4774
|
+
// 创建全局话题弹框
|
|
4775
|
+
createGlobalTopicPopover() {
|
|
4776
|
+
this.removeGlobalTopicPopover();
|
|
4777
|
+
const mask = document.createElement("div");
|
|
4778
|
+
mask.className = "topic-popover-mask";
|
|
4779
|
+
mask.addEventListener("click", () => {
|
|
4780
|
+
this.hideTopicPopover();
|
|
4781
|
+
});
|
|
4782
|
+
const container = document.createElement("div");
|
|
4783
|
+
container.className = "topic-popover";
|
|
4784
|
+
container.style.position = "fixed";
|
|
4785
|
+
container.style.top = this.topicPopover.position.top + "px";
|
|
4786
|
+
container.style.left = this.topicPopover.position.left + "px";
|
|
4787
|
+
container.style.zIndex = "9999";
|
|
4788
|
+
container.addEventListener("click", (e) => {
|
|
4789
|
+
e.stopPropagation();
|
|
4790
|
+
});
|
|
4791
|
+
container.innerHTML = this.createTopicPopoverContent();
|
|
4792
|
+
document.body.appendChild(mask);
|
|
4793
|
+
document.body.appendChild(container);
|
|
4794
|
+
this.topicPopover.globalMask = mask;
|
|
4795
|
+
this.topicPopover.globalContainer = container;
|
|
4796
|
+
this.bindTopicPopoverEvents();
|
|
4797
|
+
},
|
|
4798
|
+
// 移除全局话题弹框
|
|
4799
|
+
removeGlobalTopicPopover() {
|
|
4800
|
+
if (this.topicPopover.globalMask) {
|
|
4801
|
+
document.body.removeChild(this.topicPopover.globalMask);
|
|
4802
|
+
this.topicPopover.globalMask = null;
|
|
4803
|
+
}
|
|
4804
|
+
if (this.topicPopover.globalContainer) {
|
|
4805
|
+
document.body.removeChild(this.topicPopover.globalContainer);
|
|
4806
|
+
this.topicPopover.globalContainer = null;
|
|
4807
|
+
}
|
|
4808
|
+
},
|
|
4809
|
+
// 更新全局话题弹框内容
|
|
4810
|
+
updateGlobalTopicPopover() {
|
|
4811
|
+
if (!this.topicPopover.globalContainer)
|
|
4812
|
+
return;
|
|
4813
|
+
this.topicPopover.globalContainer.innerHTML = this.createTopicPopoverContent();
|
|
4814
|
+
this.bindTopicPopoverEvents();
|
|
4815
|
+
},
|
|
4816
|
+
// 创建话题弹框内容
|
|
4817
|
+
createTopicPopoverContent() {
|
|
4818
|
+
if (this.topicPopover.type === "hot") {
|
|
4819
|
+
return this.getHotTopicPopoverHTML();
|
|
4820
|
+
} else if (this.topicPopover.type === "search") {
|
|
4821
|
+
return this.getSearchTopicPopoverHTML();
|
|
4822
|
+
}
|
|
4823
|
+
return "";
|
|
4824
|
+
},
|
|
4825
|
+
// 获取热门话题弹框HTML
|
|
4826
|
+
getHotTopicPopoverHTML() {
|
|
4827
|
+
const activeTab = this.topicPopover.activeTab;
|
|
4828
|
+
const hotTopics = this.topicPopover.hotTopics;
|
|
4829
|
+
const recentTopics = this.topicPopover.recentTopics;
|
|
4830
|
+
const loading = this.topicPopover.loading;
|
|
4831
|
+
const hasMore = this.topicPopover.hasMore;
|
|
4832
|
+
let topicListHTML = "";
|
|
4833
|
+
if (activeTab === "hot") {
|
|
4834
|
+
if (loading && hotTopics.length === 0) {
|
|
4835
|
+
topicListHTML = '<div class="topic-loading">加载中...</div>';
|
|
4836
|
+
} else if (hotTopics.length === 0) {
|
|
4837
|
+
topicListHTML = '<div class="topic-empty">暂无热门话题</div>';
|
|
4838
|
+
} else {
|
|
4839
|
+
topicListHTML = hotTopics.map(
|
|
4840
|
+
(topic) => `<div class="topic-item" data-topic-id="${topic.id}">#${topic.exactlyMatchTitle}</div>`
|
|
4841
|
+
).join("");
|
|
4842
|
+
if (loading) {
|
|
4843
|
+
topicListHTML += '<div class="topic-loading">加载更多...</div>';
|
|
4844
|
+
} else if (!hasMore) {
|
|
4845
|
+
topicListHTML += '<div class="topic-empty">没有更多了</div>';
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4848
|
+
} else {
|
|
4849
|
+
if (recentTopics.length === 0) {
|
|
4850
|
+
topicListHTML = '<div class="topic-empty">暂无最近使用记录</div>';
|
|
4851
|
+
} else {
|
|
4852
|
+
topicListHTML = recentTopics.map(
|
|
4853
|
+
(topic) => `<div class="topic-item" data-topic-id="${topic.id}">#${topic.exactlyMatchTitle}</div>`
|
|
4854
|
+
).join("");
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
return `
|
|
4858
|
+
<div class="topic-popover-content">
|
|
4859
|
+
<div class="topic-tabs">
|
|
4860
|
+
<div class="topic-tab ${activeTab === "hot" ? "active" : ""}" data-tab="hot">
|
|
4861
|
+
热门话题
|
|
4862
|
+
</div>
|
|
4863
|
+
<div class="topic-tab ${activeTab === "recent" ? "active" : ""}" data-tab="recent">
|
|
4864
|
+
最近使用
|
|
4865
|
+
</div>
|
|
4866
|
+
</div>
|
|
4867
|
+
<div class="topic-list-container">
|
|
4868
|
+
<div class="topic-list">
|
|
4869
|
+
${topicListHTML}
|
|
4870
|
+
</div>
|
|
4871
|
+
</div>
|
|
4872
|
+
</div>
|
|
4873
|
+
`;
|
|
4874
|
+
},
|
|
4875
|
+
// 获取搜索话题弹框HTML
|
|
4876
|
+
getSearchTopicPopoverHTML() {
|
|
4877
|
+
const searchKeyword = this.topicPopover.searchKeyword;
|
|
4878
|
+
const searchTopics = this.topicPopover.searchTopics;
|
|
4879
|
+
const loading = this.topicPopover.loading;
|
|
4880
|
+
const searchHasMore = this.topicPopover.searchHasMore;
|
|
4881
|
+
let topicListHTML = "";
|
|
4882
|
+
if (loading && searchTopics.length === 0) {
|
|
4883
|
+
topicListHTML = '<div class="topic-loading">搜索中...</div>';
|
|
4884
|
+
} else if (searchTopics.length === 0) {
|
|
4885
|
+
topicListHTML = '<div class="topic-empty">没有匹配到话题,请重新输入</div>';
|
|
4886
|
+
} else {
|
|
4887
|
+
topicListHTML = searchTopics.map(
|
|
4888
|
+
(topic) => `<div class="topic-item" data-topic-id="${topic.id}">#${topic.exactlyMatchTitle}</div>`
|
|
4889
|
+
).join("");
|
|
4890
|
+
if (loading) {
|
|
4891
|
+
topicListHTML += '<div class="topic-loading">加载更多...</div>';
|
|
4892
|
+
} else if (!searchHasMore) {
|
|
4893
|
+
topicListHTML += '<div class="topic-empty">没有更多了</div>';
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
return `
|
|
4897
|
+
<div class="topic-popover-content">
|
|
4898
|
+
<div class="topic-search-header">
|
|
4899
|
+
<span class="topic-search-title">#${searchKeyword}</span>
|
|
4900
|
+
</div>
|
|
4901
|
+
<div class="topic-list-container">
|
|
4902
|
+
<div class="topic-list">
|
|
4903
|
+
${topicListHTML}
|
|
4904
|
+
</div>
|
|
4905
|
+
</div>
|
|
4906
|
+
</div>
|
|
4907
|
+
`;
|
|
4908
|
+
},
|
|
4909
|
+
// 绑定话题弹框事件
|
|
4910
|
+
bindTopicPopoverEvents() {
|
|
4911
|
+
if (!this.topicPopover.globalContainer)
|
|
4912
|
+
return;
|
|
4913
|
+
const tabs = this.topicPopover.globalContainer.querySelectorAll(".topic-tab");
|
|
4914
|
+
tabs.forEach((tab) => {
|
|
4915
|
+
tab.addEventListener("click", (e) => {
|
|
4916
|
+
const tabType = e.target.getAttribute("data-tab");
|
|
4917
|
+
this.switchTopicTab(tabType);
|
|
4918
|
+
});
|
|
4919
|
+
});
|
|
4920
|
+
const topicItems = this.topicPopover.globalContainer.querySelectorAll(".topic-item");
|
|
4921
|
+
topicItems.forEach((item) => {
|
|
4922
|
+
item.addEventListener("click", (e) => {
|
|
4923
|
+
const topicId = parseInt(e.target.getAttribute("data-topic-id"));
|
|
4924
|
+
const topic = this.findTopicById(topicId);
|
|
4925
|
+
if (topic) {
|
|
4926
|
+
this.selectTopic(topic);
|
|
4927
|
+
}
|
|
4928
|
+
});
|
|
4929
|
+
});
|
|
4930
|
+
const listContainer = this.topicPopover.globalContainer.querySelector(".topic-list-container");
|
|
4931
|
+
if (listContainer) {
|
|
4932
|
+
listContainer.addEventListener("scroll", (e) => {
|
|
4933
|
+
if (this.topicPopover.type === "hot") {
|
|
4934
|
+
this.handleTopicScroll(e);
|
|
4935
|
+
} else if (this.topicPopover.type === "search") {
|
|
4936
|
+
this.handleSearchTopicScroll(e);
|
|
4937
|
+
}
|
|
4938
|
+
});
|
|
4939
|
+
}
|
|
4940
|
+
},
|
|
4941
|
+
// 根据ID查找话题
|
|
4942
|
+
findTopicById(topicId) {
|
|
4943
|
+
let topic = this.topicPopover.hotTopics.find((t) => t.id === topicId);
|
|
4944
|
+
if (topic)
|
|
4945
|
+
return topic;
|
|
4946
|
+
topic = this.topicPopover.searchTopics.find((t) => t.id === topicId);
|
|
4947
|
+
if (topic)
|
|
4948
|
+
return topic;
|
|
4949
|
+
topic = this.topicPopover.recentTopics.find((t) => t.id === topicId);
|
|
4950
|
+
if (topic)
|
|
4951
|
+
return topic;
|
|
4952
|
+
return null;
|
|
4953
|
+
},
|
|
4954
|
+
handleTopicScroll(event) {
|
|
4955
|
+
if (this.topicPopover.activeTab !== "hot")
|
|
4956
|
+
return;
|
|
4957
|
+
const container = event.target;
|
|
4958
|
+
const scrollTop = container.scrollTop;
|
|
4959
|
+
const scrollHeight = container.scrollHeight;
|
|
4960
|
+
const clientHeight = container.clientHeight;
|
|
4961
|
+
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4962
|
+
this.loadHotTopics();
|
|
4963
|
+
}
|
|
4964
|
+
},
|
|
4965
|
+
handleSearchTopicScroll(event) {
|
|
4966
|
+
const container = event.target;
|
|
4967
|
+
const scrollTop = container.scrollTop;
|
|
4968
|
+
const scrollHeight = container.scrollHeight;
|
|
4969
|
+
const clientHeight = container.clientHeight;
|
|
4970
|
+
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
4971
|
+
this.searchTopics(this.topicPopover.searchKeyword);
|
|
4972
|
+
}
|
|
4973
|
+
},
|
|
4974
|
+
insertTopicToEditor(topic) {
|
|
4975
|
+
const originalRange = this.topicPopover.originalRange;
|
|
4976
|
+
const triggerInfo = this.topicPopover.triggerInfo;
|
|
4977
|
+
const popoverType = this.topicPopover.type;
|
|
4978
|
+
this.hideTopicPopover();
|
|
4979
|
+
let range = originalRange;
|
|
4980
|
+
if (!range) {
|
|
4981
|
+
const selection2 = window.getSelection();
|
|
4982
|
+
if (selection2.rangeCount === 0)
|
|
4983
|
+
return;
|
|
4984
|
+
range = selection2.getRangeAt(0);
|
|
4985
|
+
}
|
|
4986
|
+
const topicText = `#${topic.exactlyMatchTitle}`;
|
|
4987
|
+
if (popoverType === "search" && triggerInfo && triggerInfo.paragraph) {
|
|
4988
|
+
const paragraph = triggerInfo.paragraph;
|
|
4989
|
+
const hashIndex = triggerInfo.hashIndex;
|
|
4990
|
+
const deleteRange = document.createRange();
|
|
4991
|
+
const walker = document.createTreeWalker(
|
|
4992
|
+
paragraph,
|
|
4993
|
+
NodeFilter.SHOW_TEXT,
|
|
4994
|
+
{
|
|
4995
|
+
acceptNode: function(node2) {
|
|
4996
|
+
let parent = node2.parentNode;
|
|
4997
|
+
while (parent && parent !== paragraph) {
|
|
4998
|
+
if (parent.tagName === "MDD-TOPIC") {
|
|
4999
|
+
return NodeFilter.FILTER_REJECT;
|
|
5000
|
+
}
|
|
5001
|
+
parent = parent.parentNode;
|
|
5002
|
+
}
|
|
5003
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
5004
|
+
}
|
|
5005
|
+
},
|
|
5006
|
+
false
|
|
5007
|
+
);
|
|
5008
|
+
let position = 0;
|
|
5009
|
+
let startNode = null;
|
|
5010
|
+
let startOffset = 0;
|
|
5011
|
+
let endNode = null;
|
|
5012
|
+
let endOffset = 0;
|
|
5013
|
+
let node;
|
|
5014
|
+
while (node = walker.nextNode()) {
|
|
5015
|
+
if (position + node.textContent.length > hashIndex) {
|
|
5016
|
+
startNode = node;
|
|
5017
|
+
startOffset = hashIndex - position;
|
|
5018
|
+
break;
|
|
5019
|
+
}
|
|
5020
|
+
position += node.textContent.length;
|
|
5021
|
+
}
|
|
5022
|
+
const currentCursorPosition = triggerInfo.cursorPosition;
|
|
5023
|
+
position = 0;
|
|
5024
|
+
walker.currentNode = paragraph;
|
|
5025
|
+
while (node = walker.nextNode()) {
|
|
5026
|
+
if (position + node.textContent.length >= currentCursorPosition) {
|
|
5027
|
+
endNode = node;
|
|
5028
|
+
endOffset = currentCursorPosition - position;
|
|
5029
|
+
break;
|
|
5030
|
+
}
|
|
5031
|
+
position += node.textContent.length;
|
|
5032
|
+
}
|
|
5033
|
+
if (startNode && endNode) {
|
|
5034
|
+
deleteRange.setStart(startNode, startOffset);
|
|
5035
|
+
deleteRange.setEnd(endNode, endOffset);
|
|
5036
|
+
deleteRange.deleteContents();
|
|
5037
|
+
range = document.createRange();
|
|
5038
|
+
range.setStart(startNode, startOffset);
|
|
5039
|
+
range.collapse(true);
|
|
5040
|
+
}
|
|
5041
|
+
} else if (popoverType === "hot") {
|
|
5042
|
+
const container = range.startContainer;
|
|
5043
|
+
if (container.nodeType === Node.TEXT_NODE && container.textContent) {
|
|
5044
|
+
const offset = range.startOffset;
|
|
5045
|
+
if (offset > 0 && container.textContent[offset - 1] === "#") {
|
|
5046
|
+
const deleteRange = document.createRange();
|
|
5047
|
+
deleteRange.setStart(container, offset - 1);
|
|
5048
|
+
deleteRange.setEnd(container, offset);
|
|
5049
|
+
deleteRange.deleteContents();
|
|
5050
|
+
range.setStart(container, offset - 1);
|
|
5051
|
+
range.collapse(true);
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
5055
|
+
const topicElement = document.createElement("mdd-topic");
|
|
5056
|
+
topicElement.setAttribute("data-topic", JSON.stringify({
|
|
5057
|
+
topicId: topic.id,
|
|
5058
|
+
topicType: 0,
|
|
5059
|
+
startIndex: 0,
|
|
5060
|
+
// 会在updateTopicPosition中更新
|
|
5061
|
+
endIndex: 0
|
|
5062
|
+
// 会在updateTopicPosition中更新
|
|
5063
|
+
}));
|
|
5064
|
+
topicElement.textContent = topicText;
|
|
5065
|
+
topicElement.setAttribute("contenteditable", "false");
|
|
5066
|
+
range.deleteContents();
|
|
5067
|
+
range.insertNode(topicElement);
|
|
5068
|
+
const spaceNode = document.createTextNode(" ");
|
|
5069
|
+
range.setStartAfter(topicElement);
|
|
5070
|
+
range.insertNode(spaceNode);
|
|
5071
|
+
const newRange = document.createRange();
|
|
5072
|
+
newRange.setStartAfter(spaceNode);
|
|
5073
|
+
newRange.collapse(true);
|
|
5074
|
+
const selection = window.getSelection();
|
|
5075
|
+
selection.removeAllRanges();
|
|
5076
|
+
selection.addRange(newRange);
|
|
5077
|
+
setTimeout(() => {
|
|
5078
|
+
const currentSelection = window.getSelection();
|
|
5079
|
+
if (currentSelection.rangeCount > 0) {
|
|
5080
|
+
const currentRange = currentSelection.getRangeAt(0);
|
|
5081
|
+
if (currentRange.startContainer !== spaceNode.nextSibling) {
|
|
5082
|
+
const correctRange = document.createRange();
|
|
5083
|
+
correctRange.setStartAfter(spaceNode);
|
|
5084
|
+
correctRange.collapse(true);
|
|
5085
|
+
currentSelection.removeAllRanges();
|
|
5086
|
+
currentSelection.addRange(correctRange);
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
}, 0);
|
|
5090
|
+
this.$emit("update-topic-position");
|
|
5091
|
+
},
|
|
5092
|
+
// 销毁话题管理器
|
|
5093
|
+
destroy() {
|
|
5094
|
+
this.unbindEditorEvents();
|
|
5095
|
+
this.hideTopicPopover();
|
|
5096
|
+
}
|
|
5097
|
+
},
|
|
5098
|
+
mounted() {
|
|
5099
|
+
this.init();
|
|
5100
|
+
},
|
|
5101
|
+
beforeUnmount() {
|
|
5102
|
+
this.destroy();
|
|
5103
|
+
}
|
|
5104
|
+
};
|
|
5105
|
+
const _hoisted_1$3 = { class: "topic-manager" };
|
|
5106
|
+
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5107
|
+
return openBlock(), createElementBlock("div", _hoisted_1$3);
|
|
5108
|
+
}
|
|
5109
|
+
const TopicManager = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
|
|
4412
5110
|
const index_vue_vue_type_style_index_0_lang = "";
|
|
4413
5111
|
const _sfc_main$2 = {
|
|
4414
5112
|
provide() {
|
|
@@ -4418,7 +5116,7 @@ const _sfc_main$2 = {
|
|
|
4418
5116
|
},
|
|
4419
5117
|
components: {
|
|
4420
5118
|
ElInput,
|
|
4421
|
-
BasicDialog: _sfc_main$
|
|
5119
|
+
BasicDialog: _sfc_main$7,
|
|
4422
5120
|
draggable
|
|
4423
5121
|
},
|
|
4424
5122
|
props: {
|
|
@@ -4589,14 +5287,15 @@ const _sfc_main = {
|
|
|
4589
5287
|
name: "Edit",
|
|
4590
5288
|
components: {
|
|
4591
5289
|
ElInput,
|
|
4592
|
-
InsertArticle: _sfc_main$
|
|
4593
|
-
ImgUpload: _sfc_main$
|
|
4594
|
-
VideoUpload: _sfc_main$
|
|
5290
|
+
InsertArticle: _sfc_main$6,
|
|
5291
|
+
ImgUpload: _sfc_main$5,
|
|
5292
|
+
VideoUpload: _sfc_main$4,
|
|
4595
5293
|
CollectArticle,
|
|
4596
5294
|
ElFormItem,
|
|
4597
5295
|
ElForm,
|
|
4598
5296
|
ElDialog,
|
|
4599
|
-
ElButton
|
|
5297
|
+
ElButton,
|
|
5298
|
+
TopicManager
|
|
4600
5299
|
},
|
|
4601
5300
|
props: [
|
|
4602
5301
|
"disabled",
|
|
@@ -4606,7 +5305,8 @@ const _sfc_main = {
|
|
|
4606
5305
|
"importEssay",
|
|
4607
5306
|
"uploadImageByOther",
|
|
4608
5307
|
"chartGallery",
|
|
4609
|
-
"request"
|
|
5308
|
+
"request",
|
|
5309
|
+
"placeholder"
|
|
4610
5310
|
],
|
|
4611
5311
|
data() {
|
|
4612
5312
|
return {
|
|
@@ -4743,7 +5443,7 @@ const _sfc_main = {
|
|
|
4743
5443
|
me2.editorDom = document.getElementById("editor-content");
|
|
4744
5444
|
me2.editorDom.addEventListener("blur", this.canSetAlign);
|
|
4745
5445
|
if (!window.Squire) {
|
|
4746
|
-
import("./squire-raw-
|
|
5446
|
+
import("./squire-raw-1aaeff0b.js").then(function() {
|
|
4747
5447
|
me2.initSquire();
|
|
4748
5448
|
});
|
|
4749
5449
|
} else {
|
|
@@ -4766,7 +5466,6 @@ const _sfc_main = {
|
|
|
4766
5466
|
},
|
|
4767
5467
|
setCursor() {
|
|
4768
5468
|
this.cursorStyle = this.cursorStyle === cursorImg ? "auto" : cursorImg;
|
|
4769
|
-
console.log(this.styleStatus, 999);
|
|
4770
5469
|
this.curStyle = { ...this.styleStatus };
|
|
4771
5470
|
this.editorDom.addEventListener("mouseup", this.handleCopyFormatUp);
|
|
4772
5471
|
},
|
|
@@ -4896,7 +5595,6 @@ const _sfc_main = {
|
|
|
4896
5595
|
this.updateData(true);
|
|
4897
5596
|
this.viewLinkDialog = false;
|
|
4898
5597
|
},
|
|
4899
|
-
// mark MDD-TOPIC
|
|
4900
5598
|
updateTopicPosition() {
|
|
4901
5599
|
const paragraphList = document.querySelectorAll("#editor-content .halo-paragraph") || [];
|
|
4902
5600
|
Array.from(paragraphList).forEach((paragraph) => {
|
|
@@ -4917,6 +5615,10 @@ const _sfc_main = {
|
|
|
4917
5615
|
});
|
|
4918
5616
|
});
|
|
4919
5617
|
},
|
|
5618
|
+
// TopicManager事件处理
|
|
5619
|
+
onTopicInserted(topic) {
|
|
5620
|
+
this.updateData(true);
|
|
5621
|
+
},
|
|
4920
5622
|
getHtml(type) {
|
|
4921
5623
|
this.updateTopicPosition();
|
|
4922
5624
|
const html = this.editor.getHTML();
|
|
@@ -5018,6 +5720,8 @@ const _sfc_main = {
|
|
|
5018
5720
|
const frag = document.createDocumentFragment();
|
|
5019
5721
|
frag.appendChild(this.editor.empty(div));
|
|
5020
5722
|
const nodes = [...frag.childNodes];
|
|
5723
|
+
const mddTopics = frag.querySelectorAll("mdd-topic");
|
|
5724
|
+
mddTopics.forEach((topic) => topic.setAttribute("contenteditable", "false"));
|
|
5021
5725
|
for (let i = 0; i < nodes.length; i++) {
|
|
5022
5726
|
const node = nodes[i];
|
|
5023
5727
|
if (node.nodeType === 1) {
|
|
@@ -5111,6 +5815,8 @@ const _sfc_main = {
|
|
|
5111
5815
|
},
|
|
5112
5816
|
async parseArticle(node) {
|
|
5113
5817
|
const data = JSON.parse(node.dataset.article);
|
|
5818
|
+
if (!this.getEassyDetail)
|
|
5819
|
+
return;
|
|
5114
5820
|
await this.getEassyDetail(data.id, (info) => {
|
|
5115
5821
|
const el = mountArticleDom(
|
|
5116
5822
|
{
|
|
@@ -5403,7 +6109,6 @@ const _sfc_main = {
|
|
|
5403
6109
|
}
|
|
5404
6110
|
});
|
|
5405
6111
|
var descInputWrap;
|
|
5406
|
-
console.log(data.seamlessFlag, "count<<<<<<");
|
|
5407
6112
|
var descInput = editor.createElement("textarea", {
|
|
5408
6113
|
class: "desc-input",
|
|
5409
6114
|
maxlength: "50",
|
|
@@ -5492,7 +6197,7 @@ const _sfc_main = {
|
|
|
5492
6197
|
}
|
|
5493
6198
|
}
|
|
5494
6199
|
},
|
|
5495
|
-
//
|
|
6200
|
+
// 初始化编辑器数据,数据是 html 格式(displayData)
|
|
5496
6201
|
initData(data = "", essayPicRelVOList) {
|
|
5497
6202
|
this.parseHtml(data, essayPicRelVOList).then((res) => {
|
|
5498
6203
|
this.editorDom.innerHTML = "";
|
|
@@ -5500,6 +6205,12 @@ const _sfc_main = {
|
|
|
5500
6205
|
this.updateData();
|
|
5501
6206
|
});
|
|
5502
6207
|
},
|
|
6208
|
+
// TODO jsonToHtml、htmlToJson 实现这 2 个方法里面的逻辑,数据结构参考方法里面的注释,出参入参都为字符串,注意:mdd-topic 里面的属性数据 和 json 中的topicPosition数据是一一对应的,startIndex、endIndex为mdd-topic的起止位置 从 content 里面进行分割处理
|
|
6209
|
+
// json、html 数据格式互转,暂时只支持文字、短话题
|
|
6210
|
+
jsonToHtml(json) {
|
|
6211
|
+
},
|
|
6212
|
+
htmlToJson(html) {
|
|
6213
|
+
},
|
|
5503
6214
|
// 设置富文本组件
|
|
5504
6215
|
initSquire() {
|
|
5505
6216
|
const me2 = this;
|
|
@@ -5588,7 +6299,8 @@ const _sfc_main = {
|
|
|
5588
6299
|
event.preventDefault();
|
|
5589
6300
|
});
|
|
5590
6301
|
me2.editor.addEventListener("keydown", function(event) {
|
|
5591
|
-
|
|
6302
|
+
var _a, _b, _c;
|
|
6303
|
+
if (["Backspace", "Delete"].includes(event.key)) {
|
|
5592
6304
|
try {
|
|
5593
6305
|
const selection2 = getSelection();
|
|
5594
6306
|
if (me2.selectDom && me2.moverClasses.includes(me2.selectDom.className)) {
|
|
@@ -5622,32 +6334,10 @@ const _sfc_main = {
|
|
|
5622
6334
|
} catch (error) {
|
|
5623
6335
|
console.log(error);
|
|
5624
6336
|
}
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
const startContainer = range.startContainer;
|
|
5630
|
-
let isInMddTopic = false;
|
|
5631
|
-
if (startContainer.nodeType === Node.ELEMENT_NODE && startContainer.tagName === "MDD-TOPIC") {
|
|
5632
|
-
isInMddTopic = true;
|
|
5633
|
-
} else if (startContainer.nodeType === Node.TEXT_NODE) {
|
|
5634
|
-
const parent = startContainer.parentNode;
|
|
5635
|
-
if (parent.tagName === "MDD-TOPIC") {
|
|
5636
|
-
isInMddTopic = true;
|
|
5637
|
-
}
|
|
5638
|
-
}
|
|
5639
|
-
if (isInMddTopic) {
|
|
5640
|
-
if (event.key === "Enter") {
|
|
5641
|
-
event.preventDefault();
|
|
5642
|
-
return;
|
|
5643
|
-
}
|
|
5644
|
-
const isPrintableKey = event.key.length === 1;
|
|
5645
|
-
if (isPrintableKey) {
|
|
5646
|
-
event.preventDefault();
|
|
5647
|
-
return;
|
|
5648
|
-
}
|
|
5649
|
-
}
|
|
5650
|
-
if ((event.key === "Backspace" || event.key === "Delete") && isInMddTopic) {
|
|
6337
|
+
const selection = window.getSelection();
|
|
6338
|
+
if (selection.rangeCount > 0) {
|
|
6339
|
+
const range = selection.getRangeAt(0);
|
|
6340
|
+
const startContainer = range.startContainer;
|
|
5651
6341
|
if (startContainer.nodeType === Node.ELEMENT_NODE && startContainer.tagName === "MDD-TOPIC") {
|
|
5652
6342
|
startContainer.remove();
|
|
5653
6343
|
event.preventDefault();
|
|
@@ -5660,6 +6350,228 @@ const _sfc_main = {
|
|
|
5660
6350
|
return;
|
|
5661
6351
|
}
|
|
5662
6352
|
}
|
|
6353
|
+
let currentParagraph = startContainer;
|
|
6354
|
+
while (currentParagraph && currentParagraph.nodeType !== Node.ELEMENT_NODE) {
|
|
6355
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6356
|
+
}
|
|
6357
|
+
while (currentParagraph && !((_a = currentParagraph.classList) == null ? void 0 : _a.contains("halo-paragraph"))) {
|
|
6358
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6359
|
+
}
|
|
6360
|
+
if (currentParagraph && event.key === "Backspace") {
|
|
6361
|
+
const container = range.startContainer;
|
|
6362
|
+
const offset = range.startOffset;
|
|
6363
|
+
let isAtParagraphStart = false;
|
|
6364
|
+
let cursorBeforeContent = null;
|
|
6365
|
+
if (container === currentParagraph && offset === 0) {
|
|
6366
|
+
isAtParagraphStart = true;
|
|
6367
|
+
cursorBeforeContent = currentParagraph.firstChild;
|
|
6368
|
+
} else if (container.nodeType === Node.TEXT_NODE && offset === 0) {
|
|
6369
|
+
let isFirstContent = true;
|
|
6370
|
+
let currentNode = currentParagraph.firstChild;
|
|
6371
|
+
while (currentNode && currentNode !== container) {
|
|
6372
|
+
if (currentNode.nodeType === Node.TEXT_NODE && currentNode.textContent.trim() !== "") {
|
|
6373
|
+
isFirstContent = false;
|
|
6374
|
+
break;
|
|
6375
|
+
} else if (currentNode.nodeType === Node.ELEMENT_NODE) {
|
|
6376
|
+
isFirstContent = false;
|
|
6377
|
+
break;
|
|
6378
|
+
}
|
|
6379
|
+
currentNode = currentNode.nextSibling;
|
|
6380
|
+
}
|
|
6381
|
+
if (isFirstContent) {
|
|
6382
|
+
isAtParagraphStart = true;
|
|
6383
|
+
cursorBeforeContent = container;
|
|
6384
|
+
}
|
|
6385
|
+
} else if (container === currentParagraph && offset > 0) {
|
|
6386
|
+
let hasContentBefore = false;
|
|
6387
|
+
for (let i = 0; i < offset; i++) {
|
|
6388
|
+
const node = currentParagraph.childNodes[i];
|
|
6389
|
+
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "") {
|
|
6390
|
+
hasContentBefore = true;
|
|
6391
|
+
break;
|
|
6392
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
6393
|
+
hasContentBefore = true;
|
|
6394
|
+
break;
|
|
6395
|
+
}
|
|
6396
|
+
}
|
|
6397
|
+
if (!hasContentBefore && offset < currentParagraph.childNodes.length) {
|
|
6398
|
+
isAtParagraphStart = true;
|
|
6399
|
+
cursorBeforeContent = currentParagraph.childNodes[offset];
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
if (isAtParagraphStart) {
|
|
6403
|
+
const prevParagraph = currentParagraph.previousElementSibling;
|
|
6404
|
+
if (prevParagraph && prevParagraph.classList.contains("halo-paragraph")) {
|
|
6405
|
+
const prevContent = prevParagraph.innerHTML.trim();
|
|
6406
|
+
if (prevContent === "<br>" || prevContent === "") {
|
|
6407
|
+
prevParagraph.remove();
|
|
6408
|
+
event.preventDefault();
|
|
6409
|
+
me2.updateData(true);
|
|
6410
|
+
return;
|
|
6411
|
+
} else {
|
|
6412
|
+
const mergePoint = prevParagraph.childNodes.length;
|
|
6413
|
+
if (prevParagraph.lastChild && prevParagraph.lastChild.tagName === "BR") {
|
|
6414
|
+
prevParagraph.removeChild(prevParagraph.lastChild);
|
|
6415
|
+
}
|
|
6416
|
+
const nodesToMove = Array.from(currentParagraph.childNodes);
|
|
6417
|
+
nodesToMove.forEach((node) => {
|
|
6418
|
+
prevParagraph.appendChild(node);
|
|
6419
|
+
});
|
|
6420
|
+
currentParagraph.remove();
|
|
6421
|
+
const newRange = document.createRange();
|
|
6422
|
+
if (cursorBeforeContent && prevParagraph.contains(cursorBeforeContent)) {
|
|
6423
|
+
newRange.setStartBefore(cursorBeforeContent);
|
|
6424
|
+
} else {
|
|
6425
|
+
if (mergePoint < prevParagraph.childNodes.length) {
|
|
6426
|
+
newRange.setStartBefore(prevParagraph.childNodes[mergePoint]);
|
|
6427
|
+
} else {
|
|
6428
|
+
newRange.setStart(prevParagraph, prevParagraph.childNodes.length);
|
|
6429
|
+
}
|
|
6430
|
+
}
|
|
6431
|
+
newRange.collapse(true);
|
|
6432
|
+
const selection2 = window.getSelection();
|
|
6433
|
+
selection2.removeAllRanges();
|
|
6434
|
+
selection2.addRange(newRange);
|
|
6435
|
+
event.preventDefault();
|
|
6436
|
+
me2.updateData(true);
|
|
6437
|
+
return;
|
|
6438
|
+
}
|
|
6439
|
+
}
|
|
6440
|
+
}
|
|
6441
|
+
}
|
|
6442
|
+
}
|
|
6443
|
+
}
|
|
6444
|
+
if (event.key === "Enter") {
|
|
6445
|
+
const selection = window.getSelection();
|
|
6446
|
+
if (selection.rangeCount > 0) {
|
|
6447
|
+
const range = selection.getRangeAt(0);
|
|
6448
|
+
const startContainer = range.startContainer;
|
|
6449
|
+
let currentParagraph = startContainer;
|
|
6450
|
+
while (currentParagraph && currentParagraph.nodeType !== Node.ELEMENT_NODE) {
|
|
6451
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6452
|
+
}
|
|
6453
|
+
while (currentParagraph && !((_b = currentParagraph.classList) == null ? void 0 : _b.contains("halo-paragraph"))) {
|
|
6454
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6455
|
+
}
|
|
6456
|
+
if (!(currentParagraph == null ? void 0 : currentParagraph.querySelector("mdd-topic"))) {
|
|
6457
|
+
return;
|
|
6458
|
+
}
|
|
6459
|
+
if (me2.isBetweenTwoTopics(range)) {
|
|
6460
|
+
event.preventDefault();
|
|
6461
|
+
me2.handleEnterBetweenTopics(range);
|
|
6462
|
+
return;
|
|
6463
|
+
}
|
|
6464
|
+
if (me2.wouldCreateNestedParagraph(range)) {
|
|
6465
|
+
event.preventDefault();
|
|
6466
|
+
me2.handleEnterKeyInParagraphWithTopic(range);
|
|
6467
|
+
return;
|
|
6468
|
+
}
|
|
6469
|
+
if (currentParagraph && currentParagraph.querySelector("mdd-topic")) {
|
|
6470
|
+
event.preventDefault();
|
|
6471
|
+
me2.handleEnterKeyInParagraphWithTopic(range);
|
|
6472
|
+
return;
|
|
6473
|
+
}
|
|
6474
|
+
}
|
|
6475
|
+
}
|
|
6476
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "ArrowLeft") {
|
|
6477
|
+
const selection = window.getSelection();
|
|
6478
|
+
if (selection.rangeCount > 0) {
|
|
6479
|
+
const range = selection.getRangeAt(0);
|
|
6480
|
+
const container = range.startContainer;
|
|
6481
|
+
let currentParagraph = container;
|
|
6482
|
+
while (currentParagraph && currentParagraph.nodeType !== Node.ELEMENT_NODE) {
|
|
6483
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6484
|
+
}
|
|
6485
|
+
while (currentParagraph && !((_c = currentParagraph.classList) == null ? void 0 : _c.contains("halo-paragraph"))) {
|
|
6486
|
+
currentParagraph = currentParagraph.parentNode;
|
|
6487
|
+
}
|
|
6488
|
+
if (currentParagraph) {
|
|
6489
|
+
const firstTopic = currentParagraph.querySelector("mdd-topic");
|
|
6490
|
+
if (firstTopic) {
|
|
6491
|
+
let hasTextBeforeTopic = false;
|
|
6492
|
+
let currentNode = currentParagraph.firstChild;
|
|
6493
|
+
while (currentNode && currentNode !== firstTopic) {
|
|
6494
|
+
if (currentNode.nodeType === Node.TEXT_NODE && currentNode.textContent.trim() !== "") {
|
|
6495
|
+
hasTextBeforeTopic = true;
|
|
6496
|
+
break;
|
|
6497
|
+
}
|
|
6498
|
+
currentNode = currentNode.nextSibling;
|
|
6499
|
+
}
|
|
6500
|
+
if (hasTextBeforeTopic) {
|
|
6501
|
+
if (container === currentParagraph && range.startOffset === 0) {
|
|
6502
|
+
return;
|
|
6503
|
+
}
|
|
6504
|
+
let shouldMoveToStart = false;
|
|
6505
|
+
const offset2 = range.startOffset;
|
|
6506
|
+
if (container.nodeType === Node.TEXT_NODE && container.parentNode === firstTopic) {
|
|
6507
|
+
shouldMoveToStart = true;
|
|
6508
|
+
} else if (container === firstTopic) {
|
|
6509
|
+
shouldMoveToStart = true;
|
|
6510
|
+
} else if (container.nodeType === Node.TEXT_NODE) {
|
|
6511
|
+
let prevSibling = container.previousSibling;
|
|
6512
|
+
while (prevSibling) {
|
|
6513
|
+
if (prevSibling === firstTopic) {
|
|
6514
|
+
shouldMoveToStart = true;
|
|
6515
|
+
break;
|
|
6516
|
+
}
|
|
6517
|
+
prevSibling = prevSibling.previousSibling;
|
|
6518
|
+
}
|
|
6519
|
+
} else if (container === currentParagraph) {
|
|
6520
|
+
const topicRange = document.createRange();
|
|
6521
|
+
topicRange.selectNode(firstTopic);
|
|
6522
|
+
const cursorRange = document.createRange();
|
|
6523
|
+
cursorRange.setStart(container, offset2);
|
|
6524
|
+
cursorRange.collapse(true);
|
|
6525
|
+
if (cursorRange.compareBoundaryPoints(Range.START_TO_END, topicRange) > 0) {
|
|
6526
|
+
shouldMoveToStart = true;
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
if (shouldMoveToStart) {
|
|
6530
|
+
event.preventDefault();
|
|
6531
|
+
event.stopPropagation();
|
|
6532
|
+
const newRange = document.createRange();
|
|
6533
|
+
newRange.setStart(currentParagraph, 0);
|
|
6534
|
+
newRange.collapse(true);
|
|
6535
|
+
const selection2 = window.getSelection();
|
|
6536
|
+
selection2.removeAllRanges();
|
|
6537
|
+
selection2.addRange(newRange);
|
|
6538
|
+
return false;
|
|
6539
|
+
}
|
|
6540
|
+
return;
|
|
6541
|
+
}
|
|
6542
|
+
let shouldMoveToTopicStart = false;
|
|
6543
|
+
const offset = range.startOffset;
|
|
6544
|
+
if (container.nodeType === Node.TEXT_NODE && container.parentNode === firstTopic) {
|
|
6545
|
+
shouldMoveToTopicStart = true;
|
|
6546
|
+
} else if (container === firstTopic) {
|
|
6547
|
+
shouldMoveToTopicStart = true;
|
|
6548
|
+
} else if (container.nodeType === Node.TEXT_NODE) {
|
|
6549
|
+
let prevSibling = container.previousSibling;
|
|
6550
|
+
while (prevSibling) {
|
|
6551
|
+
if (prevSibling === firstTopic) {
|
|
6552
|
+
shouldMoveToTopicStart = true;
|
|
6553
|
+
break;
|
|
6554
|
+
}
|
|
6555
|
+
prevSibling = prevSibling.previousSibling;
|
|
6556
|
+
}
|
|
6557
|
+
} else if (container === currentParagraph) {
|
|
6558
|
+
const topicRange = document.createRange();
|
|
6559
|
+
topicRange.selectNode(firstTopic);
|
|
6560
|
+
const cursorRange = document.createRange();
|
|
6561
|
+
cursorRange.setStart(container, offset);
|
|
6562
|
+
cursorRange.collapse(true);
|
|
6563
|
+
if (cursorRange.compareBoundaryPoints(Range.START_TO_END, topicRange) > 0) {
|
|
6564
|
+
shouldMoveToTopicStart = true;
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
if (shouldMoveToTopicStart) {
|
|
6568
|
+
event.preventDefault();
|
|
6569
|
+
event.stopPropagation();
|
|
6570
|
+
me2.setCursorBeforeElement(firstTopic);
|
|
6571
|
+
return false;
|
|
6572
|
+
}
|
|
6573
|
+
}
|
|
6574
|
+
}
|
|
5663
6575
|
}
|
|
5664
6576
|
}
|
|
5665
6577
|
});
|
|
@@ -5722,7 +6634,6 @@ const _sfc_main = {
|
|
|
5722
6634
|
this.insertElement(p);
|
|
5723
6635
|
};
|
|
5724
6636
|
window.Squire.prototype.makeHeader = function(content, config = { makeHeader: {} }) {
|
|
5725
|
-
console.log(content);
|
|
5726
6637
|
if (content) {
|
|
5727
6638
|
const h2 = this.createElement("h2", {
|
|
5728
6639
|
class: "halo-paragraph-title"
|
|
@@ -5756,7 +6667,6 @@ const _sfc_main = {
|
|
|
5756
6667
|
});
|
|
5757
6668
|
const selection = window.getSelection();
|
|
5758
6669
|
const range = document.createRange();
|
|
5759
|
-
console.log(container);
|
|
5760
6670
|
range.setStart(container, 1);
|
|
5761
6671
|
range.collapse(true);
|
|
5762
6672
|
selection.removeAllRanges();
|
|
@@ -5871,7 +6781,6 @@ const _sfc_main = {
|
|
|
5871
6781
|
e.stopPropagation();
|
|
5872
6782
|
}
|
|
5873
6783
|
});
|
|
5874
|
-
console.log(delBtn);
|
|
5875
6784
|
const posterBtn = me2.insertVideoBtns(this, video);
|
|
5876
6785
|
var p = this.createElement(
|
|
5877
6786
|
"DIV",
|
|
@@ -6419,6 +7328,408 @@ const _sfc_main = {
|
|
|
6419
7328
|
}).then(() => {
|
|
6420
7329
|
}).catch(() => {
|
|
6421
7330
|
});
|
|
7331
|
+
},
|
|
7332
|
+
// 检查是否会创建嵌套的halo-paragraph
|
|
7333
|
+
wouldCreateNestedParagraph(range) {
|
|
7334
|
+
let container = range.startContainer;
|
|
7335
|
+
while (container && container !== this.editorDom) {
|
|
7336
|
+
if (container.nodeType === Node.ELEMENT_NODE && container.classList && container.classList.contains("halo-paragraph")) {
|
|
7337
|
+
return true;
|
|
7338
|
+
}
|
|
7339
|
+
container = container.parentNode;
|
|
7340
|
+
}
|
|
7341
|
+
return false;
|
|
7342
|
+
},
|
|
7343
|
+
// 检查光标是否在两个连续的mdd-topic之间
|
|
7344
|
+
isBetweenTwoTopics(range) {
|
|
7345
|
+
const container = range.startContainer;
|
|
7346
|
+
const offset = range.startOffset;
|
|
7347
|
+
if (container.nodeType === Node.ELEMENT_NODE) {
|
|
7348
|
+
const prevElement = container.childNodes[offset - 1];
|
|
7349
|
+
const nextElement = container.childNodes[offset];
|
|
7350
|
+
return prevElement && prevElement.tagName === "MDD-TOPIC" && (nextElement && nextElement.tagName === "MDD-TOPIC");
|
|
7351
|
+
}
|
|
7352
|
+
if (container.nodeType === Node.TEXT_NODE && container.textContent.trim() === "") {
|
|
7353
|
+
const prevSibling = container.previousSibling;
|
|
7354
|
+
const nextSibling = container.nextSibling;
|
|
7355
|
+
return prevSibling && prevSibling.tagName === "MDD-TOPIC" && (nextSibling && nextSibling.tagName === "MDD-TOPIC");
|
|
7356
|
+
}
|
|
7357
|
+
return false;
|
|
7358
|
+
},
|
|
7359
|
+
// 处理两个话题之间的回车或话题前面的回车
|
|
7360
|
+
handleEnterBetweenTopics(range) {
|
|
7361
|
+
var _a;
|
|
7362
|
+
const me2 = this;
|
|
7363
|
+
let currentParagraph = range.startContainer;
|
|
7364
|
+
while (currentParagraph && currentParagraph.nodeType !== Node.ELEMENT_NODE) {
|
|
7365
|
+
currentParagraph = currentParagraph.parentNode;
|
|
7366
|
+
}
|
|
7367
|
+
while (currentParagraph && !((_a = currentParagraph.classList) == null ? void 0 : _a.contains("halo-paragraph"))) {
|
|
7368
|
+
currentParagraph = currentParagraph.parentNode;
|
|
7369
|
+
}
|
|
7370
|
+
if (!currentParagraph)
|
|
7371
|
+
return;
|
|
7372
|
+
const newParagraph = document.createElement("p");
|
|
7373
|
+
newParagraph.className = "halo-paragraph";
|
|
7374
|
+
const afterContent = me2.extractContentAfterCursorPrecise(range, currentParagraph);
|
|
7375
|
+
if (afterContent && afterContent.childNodes.length > 0) {
|
|
7376
|
+
while (afterContent.firstChild) {
|
|
7377
|
+
newParagraph.appendChild(afterContent.firstChild);
|
|
7378
|
+
}
|
|
7379
|
+
} else {
|
|
7380
|
+
newParagraph.innerHTML = "<br>";
|
|
7381
|
+
}
|
|
7382
|
+
currentParagraph.parentNode.insertBefore(newParagraph, currentParagraph.nextSibling);
|
|
7383
|
+
const newRange = document.createRange();
|
|
7384
|
+
if (newParagraph.firstChild && newParagraph.firstChild.nodeType === Node.TEXT_NODE) {
|
|
7385
|
+
newRange.setStart(newParagraph.firstChild, 0);
|
|
7386
|
+
} else if (newParagraph.firstChild && newParagraph.firstChild.nodeType === Node.ELEMENT_NODE) {
|
|
7387
|
+
newRange.setStart(newParagraph, 0);
|
|
7388
|
+
} else {
|
|
7389
|
+
newRange.setStart(newParagraph, 0);
|
|
7390
|
+
}
|
|
7391
|
+
newRange.collapse(true);
|
|
7392
|
+
const selection = window.getSelection();
|
|
7393
|
+
selection.removeAllRanges();
|
|
7394
|
+
selection.addRange(newRange);
|
|
7395
|
+
me2.updateData(true);
|
|
7396
|
+
},
|
|
7397
|
+
// 更精确地提取光标后的内容(专门用于话题分割)
|
|
7398
|
+
extractContentAfterCursorPrecise(range, paragraph) {
|
|
7399
|
+
const fragment = document.createDocumentFragment();
|
|
7400
|
+
const container = range.startContainer;
|
|
7401
|
+
const offset = range.startOffset;
|
|
7402
|
+
if (container.nodeType === Node.ELEMENT_NODE) {
|
|
7403
|
+
const childNodes = Array.from(container.childNodes);
|
|
7404
|
+
for (let i = offset; i < childNodes.length; i++) {
|
|
7405
|
+
fragment.appendChild(childNodes[i]);
|
|
7406
|
+
}
|
|
7407
|
+
} else if (container.nodeType === Node.TEXT_NODE) {
|
|
7408
|
+
if (offset < container.textContent.length) {
|
|
7409
|
+
const afterText = container.textContent.slice(offset);
|
|
7410
|
+
container.textContent = container.textContent.slice(0, offset);
|
|
7411
|
+
const textNode = document.createTextNode(afterText);
|
|
7412
|
+
fragment.appendChild(textNode);
|
|
7413
|
+
}
|
|
7414
|
+
let nextSibling = container.nextSibling;
|
|
7415
|
+
while (nextSibling) {
|
|
7416
|
+
const nodeToMove = nextSibling;
|
|
7417
|
+
nextSibling = nextSibling.nextSibling;
|
|
7418
|
+
fragment.appendChild(nodeToMove);
|
|
7419
|
+
}
|
|
7420
|
+
}
|
|
7421
|
+
return fragment;
|
|
7422
|
+
},
|
|
7423
|
+
// 处理包含话题的段落中的回车键
|
|
7424
|
+
handleEnterKeyInParagraphWithTopic(range) {
|
|
7425
|
+
var _a;
|
|
7426
|
+
const me2 = this;
|
|
7427
|
+
let currentParagraph = range.startContainer;
|
|
7428
|
+
while (currentParagraph && currentParagraph.nodeType !== Node.ELEMENT_NODE) {
|
|
7429
|
+
currentParagraph = currentParagraph.parentNode;
|
|
7430
|
+
}
|
|
7431
|
+
while (currentParagraph && !((_a = currentParagraph.classList) == null ? void 0 : _a.contains("halo-paragraph"))) {
|
|
7432
|
+
currentParagraph = currentParagraph.parentNode;
|
|
7433
|
+
}
|
|
7434
|
+
if (!currentParagraph)
|
|
7435
|
+
return;
|
|
7436
|
+
const newParagraph = document.createElement("p");
|
|
7437
|
+
newParagraph.className = "halo-paragraph";
|
|
7438
|
+
const isAtTopicStart = me2.isCursorBeforeFirstTopic(range, currentParagraph);
|
|
7439
|
+
const isAtEnd = me2.isCursorAtEndOfParagraph(range, currentParagraph);
|
|
7440
|
+
if (isAtTopicStart) {
|
|
7441
|
+
const afterContent = me2.extractContentAfterCursor(range, currentParagraph);
|
|
7442
|
+
if (afterContent && afterContent.childNodes.length > 0) {
|
|
7443
|
+
while (afterContent.firstChild) {
|
|
7444
|
+
newParagraph.appendChild(afterContent.firstChild);
|
|
7445
|
+
}
|
|
7446
|
+
} else {
|
|
7447
|
+
newParagraph.innerHTML = "<br>";
|
|
7448
|
+
}
|
|
7449
|
+
if (currentParagraph.innerHTML.trim() === "" || currentParagraph.childNodes.length === 0) {
|
|
7450
|
+
currentParagraph.innerHTML = "<br>";
|
|
7451
|
+
}
|
|
7452
|
+
currentParagraph.parentNode.insertBefore(newParagraph, currentParagraph.nextSibling);
|
|
7453
|
+
} else if (isAtEnd) {
|
|
7454
|
+
newParagraph.innerHTML = "<br>";
|
|
7455
|
+
currentParagraph.parentNode.insertBefore(newParagraph, currentParagraph.nextSibling);
|
|
7456
|
+
} else {
|
|
7457
|
+
const afterContent = me2.extractContentAfterCursor(range, currentParagraph);
|
|
7458
|
+
if (afterContent && afterContent.childNodes.length > 0) {
|
|
7459
|
+
let hasValidContent = false;
|
|
7460
|
+
for (let i = 0; i < afterContent.childNodes.length; i++) {
|
|
7461
|
+
const node = afterContent.childNodes[i];
|
|
7462
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
7463
|
+
if (node.textContent.trim() !== "") {
|
|
7464
|
+
hasValidContent = true;
|
|
7465
|
+
break;
|
|
7466
|
+
}
|
|
7467
|
+
} else {
|
|
7468
|
+
hasValidContent = true;
|
|
7469
|
+
break;
|
|
7470
|
+
}
|
|
7471
|
+
}
|
|
7472
|
+
if (hasValidContent) {
|
|
7473
|
+
while (afterContent.firstChild) {
|
|
7474
|
+
newParagraph.appendChild(afterContent.firstChild);
|
|
7475
|
+
}
|
|
7476
|
+
} else {
|
|
7477
|
+
newParagraph.innerHTML = "<br>";
|
|
7478
|
+
}
|
|
7479
|
+
} else {
|
|
7480
|
+
newParagraph.innerHTML = "<br>";
|
|
7481
|
+
}
|
|
7482
|
+
currentParagraph.parentNode.insertBefore(newParagraph, currentParagraph.nextSibling);
|
|
7483
|
+
}
|
|
7484
|
+
const newRange = document.createRange();
|
|
7485
|
+
if (newParagraph.firstChild && newParagraph.firstChild.nodeType === Node.TEXT_NODE) {
|
|
7486
|
+
newRange.setStart(newParagraph.firstChild, 0);
|
|
7487
|
+
} else if (newParagraph.firstChild) {
|
|
7488
|
+
newRange.setStart(newParagraph, 0);
|
|
7489
|
+
} else {
|
|
7490
|
+
newRange.setStart(newParagraph, 0);
|
|
7491
|
+
}
|
|
7492
|
+
newRange.collapse(true);
|
|
7493
|
+
const selection = window.getSelection();
|
|
7494
|
+
selection.removeAllRanges();
|
|
7495
|
+
selection.addRange(newRange);
|
|
7496
|
+
me2.updateData(true);
|
|
7497
|
+
},
|
|
7498
|
+
// 检查光标是否在第一个话题前面
|
|
7499
|
+
isCursorBeforeFirstTopic(range, paragraph) {
|
|
7500
|
+
const container = range.startContainer;
|
|
7501
|
+
const offset = range.startOffset;
|
|
7502
|
+
const firstTopic = paragraph.querySelector("mdd-topic");
|
|
7503
|
+
if (!firstTopic) {
|
|
7504
|
+
return false;
|
|
7505
|
+
}
|
|
7506
|
+
if (container === paragraph && offset === 0) {
|
|
7507
|
+
return true;
|
|
7508
|
+
}
|
|
7509
|
+
if (container === paragraph && offset > 0 && offset <= paragraph.childNodes.length) {
|
|
7510
|
+
if (offset < paragraph.childNodes.length) {
|
|
7511
|
+
const nodeAtOffset = paragraph.childNodes[offset];
|
|
7512
|
+
if (nodeAtOffset === firstTopic) {
|
|
7513
|
+
return true;
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
let nextNonEmptyNode = null;
|
|
7517
|
+
for (let i = offset; i < paragraph.childNodes.length; i++) {
|
|
7518
|
+
const node = paragraph.childNodes[i];
|
|
7519
|
+
if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "MDD-TOPIC") {
|
|
7520
|
+
nextNonEmptyNode = node;
|
|
7521
|
+
break;
|
|
7522
|
+
} else if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "") {
|
|
7523
|
+
break;
|
|
7524
|
+
}
|
|
7525
|
+
}
|
|
7526
|
+
if (nextNonEmptyNode === firstTopic) {
|
|
7527
|
+
return true;
|
|
7528
|
+
}
|
|
7529
|
+
}
|
|
7530
|
+
try {
|
|
7531
|
+
const topicRange = document.createRange();
|
|
7532
|
+
topicRange.setStartBefore(firstTopic);
|
|
7533
|
+
const comparison = topicRange.comparePoint(container, offset);
|
|
7534
|
+
if (comparison < 0) {
|
|
7535
|
+
return true;
|
|
7536
|
+
}
|
|
7537
|
+
} catch (e) {
|
|
7538
|
+
if (container.nodeType === Node.TEXT_NODE) {
|
|
7539
|
+
const tempRange = document.createRange();
|
|
7540
|
+
tempRange.setStart(container, offset);
|
|
7541
|
+
tempRange.collapse(true);
|
|
7542
|
+
const topicRange = document.createRange();
|
|
7543
|
+
topicRange.setStartBefore(firstTopic);
|
|
7544
|
+
if (tempRange.compareBoundaryPoints(Range.START_TO_START, topicRange) < 0) {
|
|
7545
|
+
return true;
|
|
7546
|
+
}
|
|
7547
|
+
}
|
|
7548
|
+
if (container === paragraph) {
|
|
7549
|
+
const testRange = document.createRange();
|
|
7550
|
+
testRange.setStart(paragraph, 0);
|
|
7551
|
+
testRange.setEnd(paragraph, offset);
|
|
7552
|
+
const containsTopic = testRange.intersectsNode(firstTopic);
|
|
7553
|
+
if (!containsTopic) {
|
|
7554
|
+
return true;
|
|
7555
|
+
}
|
|
7556
|
+
}
|
|
7557
|
+
}
|
|
7558
|
+
return false;
|
|
7559
|
+
},
|
|
7560
|
+
// 获取不包含mdd-topic内部文本的段落文本
|
|
7561
|
+
getParagraphTextExcludingTopics(paragraph, range) {
|
|
7562
|
+
let textContent = "";
|
|
7563
|
+
let cursorPosition = 0;
|
|
7564
|
+
let foundCursor = false;
|
|
7565
|
+
const walker = document.createTreeWalker(
|
|
7566
|
+
paragraph,
|
|
7567
|
+
NodeFilter.SHOW_ALL,
|
|
7568
|
+
{
|
|
7569
|
+
acceptNode: function(node2) {
|
|
7570
|
+
if (node2.nodeType === Node.ELEMENT_NODE && node2.tagName === "MDD-TOPIC") {
|
|
7571
|
+
return NodeFilter.FILTER_REJECT;
|
|
7572
|
+
}
|
|
7573
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
7574
|
+
}
|
|
7575
|
+
},
|
|
7576
|
+
false
|
|
7577
|
+
);
|
|
7578
|
+
let node;
|
|
7579
|
+
while (node = walker.nextNode()) {
|
|
7580
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
7581
|
+
const nodeText = node.textContent;
|
|
7582
|
+
if (!foundCursor && node === range.startContainer) {
|
|
7583
|
+
cursorPosition = textContent.length + range.startOffset;
|
|
7584
|
+
foundCursor = true;
|
|
7585
|
+
}
|
|
7586
|
+
textContent += nodeText;
|
|
7587
|
+
}
|
|
7588
|
+
}
|
|
7589
|
+
return { textContent, cursorPosition };
|
|
7590
|
+
},
|
|
7591
|
+
// 检查光标是否在段落开头
|
|
7592
|
+
isCursorAtStartOfParagraph(range, paragraph) {
|
|
7593
|
+
const { cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
7594
|
+
return cursorPosition === 0;
|
|
7595
|
+
},
|
|
7596
|
+
// 检查光标是否在段落末尾
|
|
7597
|
+
isCursorAtEndOfParagraph(range, paragraph) {
|
|
7598
|
+
const walker = document.createTreeWalker(
|
|
7599
|
+
paragraph,
|
|
7600
|
+
NodeFilter.SHOW_TEXT,
|
|
7601
|
+
{
|
|
7602
|
+
acceptNode: function(node2) {
|
|
7603
|
+
let parent = node2.parentNode;
|
|
7604
|
+
while (parent && parent !== paragraph) {
|
|
7605
|
+
if (parent.tagName === "MDD-TOPIC") {
|
|
7606
|
+
return NodeFilter.FILTER_REJECT;
|
|
7607
|
+
}
|
|
7608
|
+
parent = parent.parentNode;
|
|
7609
|
+
}
|
|
7610
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
7611
|
+
}
|
|
7612
|
+
},
|
|
7613
|
+
false
|
|
7614
|
+
);
|
|
7615
|
+
let totalLength = 0;
|
|
7616
|
+
let node;
|
|
7617
|
+
while (node = walker.nextNode()) {
|
|
7618
|
+
totalLength += node.textContent.length;
|
|
7619
|
+
}
|
|
7620
|
+
const { cursorPosition } = this.getParagraphTextExcludingTopics(paragraph, range);
|
|
7621
|
+
return cursorPosition >= totalLength;
|
|
7622
|
+
},
|
|
7623
|
+
// 获取当前段落
|
|
7624
|
+
getCurrentParagraph(range) {
|
|
7625
|
+
let container = range.startContainer;
|
|
7626
|
+
while (container && container !== this.editorDom) {
|
|
7627
|
+
if (container.nodeType === Node.ELEMENT_NODE && container.classList && container.classList.contains("halo-paragraph")) {
|
|
7628
|
+
return container;
|
|
7629
|
+
}
|
|
7630
|
+
container = container.parentNode;
|
|
7631
|
+
}
|
|
7632
|
+
return null;
|
|
7633
|
+
},
|
|
7634
|
+
// 提取光标后的内容
|
|
7635
|
+
extractContentAfterCursor(range, paragraph) {
|
|
7636
|
+
const fragment = document.createDocumentFragment();
|
|
7637
|
+
const container = range.startContainer;
|
|
7638
|
+
const offset = range.startOffset;
|
|
7639
|
+
let topicSpaceNode = null;
|
|
7640
|
+
if (container.nodeType === Node.TEXT_NODE && container.textContent === " " && container.previousSibling && container.previousSibling.tagName === "MDD-TOPIC") {
|
|
7641
|
+
topicSpaceNode = container;
|
|
7642
|
+
}
|
|
7643
|
+
const extractRange = document.createRange();
|
|
7644
|
+
let startNode = null;
|
|
7645
|
+
let hasContentToExtract = false;
|
|
7646
|
+
if (topicSpaceNode) {
|
|
7647
|
+
if (topicSpaceNode.nextSibling) {
|
|
7648
|
+
startNode = topicSpaceNode.nextSibling;
|
|
7649
|
+
hasContentToExtract = true;
|
|
7650
|
+
}
|
|
7651
|
+
} else if (container.nodeType === Node.TEXT_NODE) {
|
|
7652
|
+
if (container.textContent === "" && offset === 0) {
|
|
7653
|
+
if (container.nextSibling) {
|
|
7654
|
+
startNode = container.nextSibling;
|
|
7655
|
+
hasContentToExtract = true;
|
|
7656
|
+
}
|
|
7657
|
+
} else if (offset < container.textContent.length) {
|
|
7658
|
+
const afterText = container.textContent.slice(offset);
|
|
7659
|
+
container.textContent = container.textContent.slice(0, offset);
|
|
7660
|
+
if (afterText.trim()) {
|
|
7661
|
+
const newTextNode = document.createTextNode(afterText);
|
|
7662
|
+
container.parentNode.insertBefore(newTextNode, container.nextSibling);
|
|
7663
|
+
startNode = newTextNode;
|
|
7664
|
+
hasContentToExtract = true;
|
|
7665
|
+
} else if (container.nextSibling) {
|
|
7666
|
+
startNode = container.nextSibling;
|
|
7667
|
+
hasContentToExtract = true;
|
|
7668
|
+
}
|
|
7669
|
+
} else {
|
|
7670
|
+
if (container.nextSibling) {
|
|
7671
|
+
startNode = container.nextSibling;
|
|
7672
|
+
hasContentToExtract = true;
|
|
7673
|
+
}
|
|
7674
|
+
}
|
|
7675
|
+
} else if (container.nodeType === Node.ELEMENT_NODE) {
|
|
7676
|
+
if (offset < container.childNodes.length) {
|
|
7677
|
+
startNode = container.childNodes[offset];
|
|
7678
|
+
hasContentToExtract = true;
|
|
7679
|
+
} else if (offset === 0 && container === paragraph) {
|
|
7680
|
+
if (paragraph.firstChild) {
|
|
7681
|
+
startNode = paragraph.firstChild;
|
|
7682
|
+
hasContentToExtract = true;
|
|
7683
|
+
}
|
|
7684
|
+
}
|
|
7685
|
+
}
|
|
7686
|
+
if (!hasContentToExtract || !startNode) {
|
|
7687
|
+
return fragment;
|
|
7688
|
+
}
|
|
7689
|
+
if (!paragraph.contains(startNode)) {
|
|
7690
|
+
return fragment;
|
|
7691
|
+
}
|
|
7692
|
+
try {
|
|
7693
|
+
extractRange.setStartBefore(startNode);
|
|
7694
|
+
let lastNode = paragraph.lastChild;
|
|
7695
|
+
while (lastNode && lastNode.nodeType === Node.TEXT_NODE && lastNode.textContent === "" && // 只跳过完全空的文本节点
|
|
7696
|
+
lastNode !== startNode) {
|
|
7697
|
+
lastNode = lastNode.previousSibling;
|
|
7698
|
+
}
|
|
7699
|
+
if (lastNode) {
|
|
7700
|
+
extractRange.setEndAfter(lastNode);
|
|
7701
|
+
} else {
|
|
7702
|
+
extractRange.setEnd(paragraph, paragraph.childNodes.length);
|
|
7703
|
+
}
|
|
7704
|
+
const extractedContent = extractRange.extractContents();
|
|
7705
|
+
fragment.appendChild(extractedContent);
|
|
7706
|
+
} catch (e) {
|
|
7707
|
+
let currentNode = startNode;
|
|
7708
|
+
while (currentNode && currentNode.parentNode === paragraph) {
|
|
7709
|
+
const nextNode = currentNode.nextSibling;
|
|
7710
|
+
fragment.appendChild(currentNode);
|
|
7711
|
+
currentNode = nextNode;
|
|
7712
|
+
}
|
|
7713
|
+
}
|
|
7714
|
+
return fragment;
|
|
7715
|
+
},
|
|
7716
|
+
// 统一的光标设置方法 - 设置光标到元素后面
|
|
7717
|
+
setCursorAfterElement(element) {
|
|
7718
|
+
const newRange = document.createRange();
|
|
7719
|
+
newRange.setStartAfter(element);
|
|
7720
|
+
newRange.collapse(true);
|
|
7721
|
+
const selection = window.getSelection();
|
|
7722
|
+
selection.removeAllRanges();
|
|
7723
|
+
selection.addRange(newRange);
|
|
7724
|
+
},
|
|
7725
|
+
// 统一的光标设置方法 - 设置光标到元素前面
|
|
7726
|
+
setCursorBeforeElement(element) {
|
|
7727
|
+
const newRange = document.createRange();
|
|
7728
|
+
newRange.setStartBefore(element);
|
|
7729
|
+
newRange.collapse(true);
|
|
7730
|
+
const selection = window.getSelection();
|
|
7731
|
+
selection.removeAllRanges();
|
|
7732
|
+
selection.addRange(newRange);
|
|
6422
7733
|
}
|
|
6423
7734
|
},
|
|
6424
7735
|
beforeRouteLeave(to, from, next) {
|
|
@@ -6441,11 +7752,12 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6441
7752
|
const _component_ImgUpload = resolveComponent("ImgUpload");
|
|
6442
7753
|
const _component_VideoUpload = resolveComponent("VideoUpload");
|
|
6443
7754
|
const _component_CollectArticle = resolveComponent("CollectArticle");
|
|
7755
|
+
const _component_TopicManager = resolveComponent("TopicManager");
|
|
6444
7756
|
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
6445
7757
|
withDirectives(createElementVNode("div", {
|
|
6446
7758
|
style: normalizeStyle({ textAlign: $options.align }),
|
|
6447
7759
|
class: "placeholder"
|
|
6448
|
-
},
|
|
7760
|
+
}, toDisplayString($props.placeholder || "请输入正文"), 5), [
|
|
6449
7761
|
[vShow, !$options.isInputing && !$data.titleCount && !$data.hasArticleCard]
|
|
6450
7762
|
]),
|
|
6451
7763
|
$data.overLine ? (openBlock(), createElementBlock("div", {
|
|
@@ -6571,7 +7883,14 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6571
7883
|
class: "replace-poster hide",
|
|
6572
7884
|
accept: "image/*",
|
|
6573
7885
|
onChange: _cache[13] || (_cache[13] = (...args) => $options.replacePoster && $options.replacePoster(...args))
|
|
6574
|
-
}, null, 32)
|
|
7886
|
+
}, null, 32),
|
|
7887
|
+
createVNode(_component_TopicManager, {
|
|
7888
|
+
ref: "topicManager",
|
|
7889
|
+
"editor-dom": $data.editorDom,
|
|
7890
|
+
request: $props.request,
|
|
7891
|
+
onTopicInserted: $options.onTopicInserted,
|
|
7892
|
+
onUpdateTopicPosition: $options.updateTopicPosition
|
|
7893
|
+
}, null, 8, ["editor-dom", "request", "onTopicInserted", "onUpdateTopicPosition"])
|
|
6575
7894
|
]);
|
|
6576
7895
|
}
|
|
6577
7896
|
const Editor = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
|