vuewrite 0.0.7 → 0.0.9
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/dist/vuewrite.d.ts +33 -0
- package/dist/vuewrite.js +157 -28
- package/package.json +1 -1
package/dist/vuewrite.d.ts
CHANGED
|
@@ -29,10 +29,17 @@ export declare type Block = {
|
|
|
29
29
|
text: string;
|
|
30
30
|
type?: string;
|
|
31
31
|
styles: Style[];
|
|
32
|
+
editable?: boolean;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export declare type Decorator = (style: Style) => HTMLAttributes | undefined;
|
|
35
36
|
|
|
37
|
+
declare type HistoryAction = {
|
|
38
|
+
type: "insertText" | "setText";
|
|
39
|
+
blocks: Block[];
|
|
40
|
+
selection: TextEditorSelection;
|
|
41
|
+
};
|
|
42
|
+
|
|
36
43
|
export declare type Style = {
|
|
37
44
|
start: number;
|
|
38
45
|
end: number;
|
|
@@ -48,9 +55,11 @@ text: string;
|
|
|
48
55
|
styles?: Style[] | undefined;
|
|
49
56
|
type?: string | undefined;
|
|
50
57
|
}[] | undefined;
|
|
58
|
+
parser?: TextParser | undefined;
|
|
51
59
|
styles?: Style[] | undefined;
|
|
52
60
|
autofocus?: boolean | undefined;
|
|
53
61
|
autoselect?: boolean | undefined;
|
|
62
|
+
preventMultiline?: boolean | undefined;
|
|
54
63
|
}>, {
|
|
55
64
|
currentStyles: ComputedRef<Map<string, Style>>;
|
|
56
65
|
currentBlock: ComputedRef< {
|
|
@@ -63,6 +72,7 @@ end: number;
|
|
|
63
72
|
style: string;
|
|
64
73
|
meta?: any;
|
|
65
74
|
}[];
|
|
75
|
+
editable?: boolean | undefined;
|
|
66
76
|
} | null>;
|
|
67
77
|
isCollapsed: ComputedRef<boolean>;
|
|
68
78
|
selection: {
|
|
@@ -84,6 +94,7 @@ insertBlock: (blockData: Partial<Block>) => void;
|
|
|
84
94
|
addNewLine: () => void;
|
|
85
95
|
removeNewLine: () => void;
|
|
86
96
|
selectAll: () => void;
|
|
97
|
+
pushHistory: (type: "insertText" | "setText") => void;
|
|
87
98
|
getClientRects: (selection: TextEditorSelection) => DOMRectList;
|
|
88
99
|
}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
89
100
|
keydown: (...args: any[]) => void;
|
|
@@ -97,9 +108,11 @@ text: string;
|
|
|
97
108
|
styles?: Style[] | undefined;
|
|
98
109
|
type?: string | undefined;
|
|
99
110
|
}[] | undefined;
|
|
111
|
+
parser?: TextParser | undefined;
|
|
100
112
|
styles?: Style[] | undefined;
|
|
101
113
|
autofocus?: boolean | undefined;
|
|
102
114
|
autoselect?: boolean | undefined;
|
|
115
|
+
preventMultiline?: boolean | undefined;
|
|
103
116
|
}>>> & {
|
|
104
117
|
onKeydown?: ((...args: any[]) => any) | undefined;
|
|
105
118
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
@@ -108,9 +121,22 @@ onKeydown?: ((...args: any[]) => any) | undefined;
|
|
|
108
121
|
placeholder?(_: {}): any;
|
|
109
122
|
}>;
|
|
110
123
|
|
|
124
|
+
declare class TextEditorHistory {
|
|
125
|
+
actions: HistoryAction[];
|
|
126
|
+
currentCursor: number;
|
|
127
|
+
private store;
|
|
128
|
+
constructor(store: TextEditorStore);
|
|
129
|
+
tickStarted: boolean;
|
|
130
|
+
push(type: HistoryAction["type"]): void;
|
|
131
|
+
private applyAction;
|
|
132
|
+
undo(): void;
|
|
133
|
+
redo(): void;
|
|
134
|
+
}
|
|
135
|
+
|
|
111
136
|
export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText" | "insertBlock" | "addNewLine" | "removeNewLine" | "selectAll"> & {
|
|
112
137
|
isFocused: boolean;
|
|
113
138
|
getClientRects: (selection: TextEditorSelection) => DOMRectList;
|
|
139
|
+
pushHistory: TextEditorHistory["push"];
|
|
114
140
|
};
|
|
115
141
|
|
|
116
142
|
declare type TextEditorSelection = {
|
|
@@ -125,6 +151,7 @@ declare type TextEditorSelection = {
|
|
|
125
151
|
};
|
|
126
152
|
|
|
127
153
|
declare class TextEditorStore {
|
|
154
|
+
history: TextEditorHistory;
|
|
128
155
|
blocks: {
|
|
129
156
|
id: string;
|
|
130
157
|
text: string;
|
|
@@ -135,6 +162,7 @@ declare class TextEditorStore {
|
|
|
135
162
|
style: string;
|
|
136
163
|
meta?: any;
|
|
137
164
|
}[];
|
|
165
|
+
editable?: boolean | undefined;
|
|
138
166
|
}[];
|
|
139
167
|
selection: {
|
|
140
168
|
anchor: {
|
|
@@ -159,6 +187,7 @@ declare class TextEditorStore {
|
|
|
159
187
|
style: string;
|
|
160
188
|
meta?: any;
|
|
161
189
|
}[];
|
|
190
|
+
editable?: boolean | undefined;
|
|
162
191
|
} | null>;
|
|
163
192
|
get currentBlock(): {
|
|
164
193
|
id: string;
|
|
@@ -170,10 +199,12 @@ declare class TextEditorStore {
|
|
|
170
199
|
style: string;
|
|
171
200
|
meta?: any;
|
|
172
201
|
}[];
|
|
202
|
+
editable?: boolean | undefined;
|
|
173
203
|
} | null;
|
|
174
204
|
_selectedText: ComputedRef<string>;
|
|
175
205
|
get selectedText(): string;
|
|
176
206
|
moveOffset(newOffset: number): void;
|
|
207
|
+
concatBlocks(start: Block, end: Block): void;
|
|
177
208
|
removeNewLine(): void;
|
|
178
209
|
onInput(_e: Event): void;
|
|
179
210
|
addNewLine(): void;
|
|
@@ -198,4 +229,6 @@ declare class TextEditorStore {
|
|
|
198
229
|
selectAll(): void;
|
|
199
230
|
}
|
|
200
231
|
|
|
232
|
+
declare type TextParser = (text: string) => Style[];
|
|
233
|
+
|
|
201
234
|
export { }
|
package/dist/vuewrite.js
CHANGED
|
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4
4
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
|
-
import { getCurrentScope, onScopeDispose, unref, watch, reactive, computed, ref, defineComponent, getCurrentInstance, openBlock, createBlock, resolveDynamicComponent, createElementBlock, normalizeProps, mergeProps, h,
|
|
7
|
+
import { getCurrentScope, onScopeDispose, unref, watch, nextTick, reactive, computed, ref, defineComponent, getCurrentInstance, openBlock, createBlock, resolveDynamicComponent, createElementBlock, normalizeProps, mergeProps, h, useSlots, onMounted, Fragment, renderList, renderSlot, createCommentVNode } from "vue";
|
|
8
8
|
function tryOnScopeDispose(fn) {
|
|
9
9
|
if (getCurrentScope()) {
|
|
10
10
|
onScopeDispose(fn);
|
|
@@ -140,8 +140,85 @@ const isEqual = (a, b) => {
|
|
|
140
140
|
}
|
|
141
141
|
return true;
|
|
142
142
|
};
|
|
143
|
+
class TextEditorHistory {
|
|
144
|
+
constructor(store) {
|
|
145
|
+
__publicField(this, "actions", []);
|
|
146
|
+
__publicField(this, "currentCursor", 0);
|
|
147
|
+
__publicField(this, "store");
|
|
148
|
+
__publicField(this, "tickStarted", false);
|
|
149
|
+
this.store = store;
|
|
150
|
+
window.showHistory = () => console.log(this.actions);
|
|
151
|
+
}
|
|
152
|
+
push(type) {
|
|
153
|
+
var _a;
|
|
154
|
+
if (this.currentCursor + 1 < this.actions.length) {
|
|
155
|
+
this.actions.length = this.currentCursor + 1;
|
|
156
|
+
}
|
|
157
|
+
const lastAction = this.actions.length > 0 && this.currentCursor === this.actions.length - 1 ? this.actions[this.actions.length - 1] : null;
|
|
158
|
+
const selection = JSON.parse(JSON.stringify(this.store.selection));
|
|
159
|
+
if (type === "insertText") {
|
|
160
|
+
const currentBlock = JSON.parse(JSON.stringify(this.store.currentBlock));
|
|
161
|
+
if (lastAction && lastAction.type === type && ((_a = lastAction.blocks[0]) == null ? void 0 : _a.id) === currentBlock.id) {
|
|
162
|
+
lastAction.blocks = [currentBlock];
|
|
163
|
+
lastAction.selection = selection;
|
|
164
|
+
} else {
|
|
165
|
+
this.actions.push({ type, blocks: [currentBlock], selection });
|
|
166
|
+
}
|
|
167
|
+
} else if (type === "setText") {
|
|
168
|
+
const blocks = JSON.parse(JSON.stringify(this.store.blocks));
|
|
169
|
+
if (this.tickStarted && lastAction) {
|
|
170
|
+
lastAction.blocks = blocks;
|
|
171
|
+
lastAction.selection = selection;
|
|
172
|
+
} else {
|
|
173
|
+
this.actions.push({ type: "setText", blocks, selection });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
this.currentCursor = this.actions.length - 1;
|
|
177
|
+
if (!this.tickStarted && type === "setText") {
|
|
178
|
+
this.tickStarted = true;
|
|
179
|
+
nextTick(() => {
|
|
180
|
+
this.tickStarted = false;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
applyAction(action) {
|
|
185
|
+
if (action.type === "setText") {
|
|
186
|
+
for (let i = 0; i < action.blocks.length; i++) {
|
|
187
|
+
if (i >= this.store.blocks.length) {
|
|
188
|
+
this.store.blocks.push({ ...action.blocks[i] });
|
|
189
|
+
} else {
|
|
190
|
+
Object.assign(this.store.blocks[i], action.blocks[i]);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (this.store.blocks.length > action.blocks.length) {
|
|
194
|
+
this.store.blocks.length = action.blocks.length;
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
for (let _block of action.blocks) {
|
|
198
|
+
const block = this.store.blocks.find((block2) => block2.id === _block.id);
|
|
199
|
+
if (block) {
|
|
200
|
+
block.text = _block.text;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
Object.assign(this.store.selection, action.selection);
|
|
205
|
+
}
|
|
206
|
+
undo() {
|
|
207
|
+
if (this.currentCursor === 0)
|
|
208
|
+
return;
|
|
209
|
+
this.currentCursor--;
|
|
210
|
+
this.applyAction(this.actions[this.currentCursor]);
|
|
211
|
+
}
|
|
212
|
+
redo() {
|
|
213
|
+
if (this.currentCursor >= this.actions.length - 1)
|
|
214
|
+
return;
|
|
215
|
+
this.currentCursor++;
|
|
216
|
+
this.applyAction(this.actions[this.currentCursor]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
143
219
|
class TextEditorStore {
|
|
144
220
|
constructor() {
|
|
221
|
+
__publicField(this, "history", new TextEditorHistory(this));
|
|
145
222
|
__publicField(this, "blocks", reactive([{ id: uid(), text: "", styles: [] }]));
|
|
146
223
|
__publicField(this, "selection", reactive({
|
|
147
224
|
anchor: { blockId: this.blocks[0].id, offset: 0 },
|
|
@@ -202,18 +279,34 @@ class TextEditorStore {
|
|
|
202
279
|
this.selection.anchor.offset = newOffset;
|
|
203
280
|
this.selection.focus.offset = newOffset;
|
|
204
281
|
}
|
|
282
|
+
concatBlocks(start, end) {
|
|
283
|
+
for (let style of end.styles) {
|
|
284
|
+
style.start += start.text.length;
|
|
285
|
+
style.end += start.text.length;
|
|
286
|
+
start.styles.push(style);
|
|
287
|
+
}
|
|
288
|
+
start.text = start.text + end.text;
|
|
289
|
+
}
|
|
205
290
|
removeNewLine() {
|
|
206
291
|
const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
|
|
207
292
|
if (blockIndex < 1)
|
|
208
293
|
return;
|
|
294
|
+
if (this.blocks[blockIndex - 1].editable === false) {
|
|
295
|
+
this.blocks.splice(blockIndex - 1, 1);
|
|
296
|
+
} else {
|
|
297
|
+
this.concatBlocks(this.blocks[blockIndex - 1], this.blocks[blockIndex]);
|
|
298
|
+
this.blocks.splice(blockIndex, 1);
|
|
299
|
+
}
|
|
209
300
|
this.selection.anchor.blockId = this.blocks[blockIndex - 1].id;
|
|
210
301
|
this.selection.focus.blockId = this.blocks[blockIndex - 1].id;
|
|
211
302
|
this.selection.anchor.offset = this.blocks[blockIndex - 1].text.length;
|
|
212
303
|
this.selection.focus.offset = this.blocks[blockIndex - 1].text.length;
|
|
213
|
-
this.
|
|
304
|
+
this.history.push("setText");
|
|
214
305
|
}
|
|
215
306
|
onInput(_e) {
|
|
216
307
|
const ev = _e;
|
|
308
|
+
if (ev.defaultPrevented)
|
|
309
|
+
return;
|
|
217
310
|
ev.preventDefault();
|
|
218
311
|
const collapsed = this.isCollapsed;
|
|
219
312
|
if (!collapsed)
|
|
@@ -224,7 +317,11 @@ class TextEditorStore {
|
|
|
224
317
|
if ((ev.inputType === "deleteContentBackward" || ev.inputType === "deleteContentForward") && collapsed) {
|
|
225
318
|
if (ev.inputType === "deleteContentBackward") {
|
|
226
319
|
if (this.selection.anchor.offset === 0) {
|
|
227
|
-
|
|
320
|
+
if (block.type) {
|
|
321
|
+
delete block.type;
|
|
322
|
+
} else {
|
|
323
|
+
this.removeNewLine();
|
|
324
|
+
}
|
|
228
325
|
} else {
|
|
229
326
|
const offset = Math.max(0, this.selection.focus.offset - 1);
|
|
230
327
|
block.text = block.text.slice(0, offset) + block.text.slice(this.selection.focus.offset);
|
|
@@ -234,7 +331,11 @@ class TextEditorStore {
|
|
|
234
331
|
if (ev.inputType === "deleteContentForward") {
|
|
235
332
|
const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
|
|
236
333
|
if (this.selection.anchor.offset === this.blocks[blockIndex].text.length) {
|
|
237
|
-
this.blocks
|
|
334
|
+
const nextBlock = this.blocks[blockIndex + 1];
|
|
335
|
+
if (nextBlock) {
|
|
336
|
+
this.blocks.splice(blockIndex + 1, 1);
|
|
337
|
+
this.concatBlocks(this.blocks[blockIndex - 1], this.blocks[blockIndex]);
|
|
338
|
+
}
|
|
238
339
|
} else {
|
|
239
340
|
block.text = block.text.slice(0, this.selection.focus.offset) + block.text.slice(this.selection.focus.offset + 1);
|
|
240
341
|
this.moveStyles(block, this.selection.focus.offset + 1, 1);
|
|
@@ -243,6 +344,7 @@ class TextEditorStore {
|
|
|
243
344
|
}
|
|
244
345
|
if (ev.inputType === "insertText") {
|
|
245
346
|
this.insertText(ev.data);
|
|
347
|
+
this.history.push("insertText");
|
|
246
348
|
}
|
|
247
349
|
}
|
|
248
350
|
addNewLine() {
|
|
@@ -256,13 +358,15 @@ class TextEditorStore {
|
|
|
256
358
|
this.blocks.splice(index + 1, 0, block);
|
|
257
359
|
this.selection.anchor = { blockId: block.id, offset: 0 };
|
|
258
360
|
this.selection.focus = { blockId: block.id, offset: 0 };
|
|
361
|
+
this.history.push("setText");
|
|
259
362
|
}
|
|
260
363
|
insertText(data) {
|
|
261
364
|
const block = this.currentBlock;
|
|
262
365
|
if (!block)
|
|
263
366
|
return;
|
|
264
|
-
|
|
265
|
-
|
|
367
|
+
const text = data.replace(/\r/g, "");
|
|
368
|
+
block.text = block.text.slice(0, this.selection.focus.offset) + text + block.text.slice(this.selection.focus.offset);
|
|
369
|
+
this.moveOffset(clamp(this.selection.focus.offset + text.length, 0, block.text.length));
|
|
266
370
|
}
|
|
267
371
|
insertBlock(blockData) {
|
|
268
372
|
if (!this.currentBlock)
|
|
@@ -277,6 +381,10 @@ class TextEditorStore {
|
|
|
277
381
|
Object.assign(this.selection, selection);
|
|
278
382
|
}
|
|
279
383
|
Object.assign(this.currentBlock, blockData);
|
|
384
|
+
if (blockData.editable === false && this.currentBlock === this.blocks[this.blocks.length - 1]) {
|
|
385
|
+
this.addNewLine();
|
|
386
|
+
}
|
|
387
|
+
this.history.push("setText");
|
|
280
388
|
}
|
|
281
389
|
get startAndEnd() {
|
|
282
390
|
const a = this.blocks.findIndex((block) => block.id === this.selection.anchor.blockId);
|
|
@@ -421,7 +529,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
421
529
|
props: {
|
|
422
530
|
block: {},
|
|
423
531
|
slots: {},
|
|
424
|
-
decorator: { type: Function }
|
|
532
|
+
decorator: { type: Function },
|
|
533
|
+
parser: {}
|
|
425
534
|
},
|
|
426
535
|
emits: ["postrender"],
|
|
427
536
|
setup(__props, { emit: __emit }) {
|
|
@@ -505,6 +614,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
505
614
|
};
|
|
506
615
|
const content = () => {
|
|
507
616
|
const block = props.block;
|
|
617
|
+
if (block.editable === false)
|
|
618
|
+
return null;
|
|
508
619
|
if (block.text.length === 0) {
|
|
509
620
|
cleanTree(1);
|
|
510
621
|
return [h("br")];
|
|
@@ -518,6 +629,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
518
629
|
markers.push([style.start, style]);
|
|
519
630
|
markers.push([style.end, style]);
|
|
520
631
|
}
|
|
632
|
+
if (props.parser) {
|
|
633
|
+
for (let style of props.parser(text)) {
|
|
634
|
+
markers.push([style.start, style]);
|
|
635
|
+
markers.push([style.end, style]);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
521
638
|
markers.sort((a, b) => a[0] - b[0]);
|
|
522
639
|
let currentIndex = 0;
|
|
523
640
|
const activeStyles = /* @__PURE__ */ new Set();
|
|
@@ -560,9 +677,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
560
677
|
decorator: { type: Function },
|
|
561
678
|
single: { type: Boolean },
|
|
562
679
|
modelValue: {},
|
|
680
|
+
parser: { type: Function },
|
|
563
681
|
styles: {},
|
|
564
682
|
autofocus: { type: Boolean },
|
|
565
|
-
autoselect: { type: Boolean }
|
|
683
|
+
autoselect: { type: Boolean },
|
|
684
|
+
preventMultiline: { type: Boolean }
|
|
566
685
|
},
|
|
567
686
|
emits: ["keydown", "update:modelValue", "update:styles"],
|
|
568
687
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
@@ -621,46 +740,47 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
621
740
|
return;
|
|
622
741
|
if (e.code === "Enter") {
|
|
623
742
|
e.preventDefault();
|
|
624
|
-
if (e.shiftKey || props.single) {
|
|
743
|
+
if (!props.preventMultiline && (e.shiftKey || props.single)) {
|
|
625
744
|
store.insertText("\n");
|
|
626
745
|
} else {
|
|
627
746
|
store.addNewLine();
|
|
628
747
|
}
|
|
629
748
|
}
|
|
630
|
-
if (e.code === "Backspace") {
|
|
631
|
-
if (store.isCollapsed && store.selection.anchor.offset === 0) {
|
|
632
|
-
e.preventDefault();
|
|
633
|
-
if (store.currentBlock && store.currentBlock.type) {
|
|
634
|
-
delete store.currentBlock.type;
|
|
635
|
-
} else {
|
|
636
|
-
store.removeNewLine();
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
749
|
if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
|
|
641
750
|
if (e.code === "KeyB" || e.code === "KeyI" || e.code === "KeyU") {
|
|
642
751
|
e.preventDefault();
|
|
643
752
|
}
|
|
644
753
|
}
|
|
754
|
+
if ((e.ctrlKey || e.metaKey) && e.code === "KeyZ" && !e.shiftKey) {
|
|
755
|
+
e.preventDefault();
|
|
756
|
+
store.history.undo();
|
|
757
|
+
}
|
|
758
|
+
if ((e.ctrlKey || e.metaKey) && (e.code === "KeyY" || e.shiftKey && e.code === "KeyZ")) {
|
|
759
|
+
e.preventDefault();
|
|
760
|
+
store.history.redo();
|
|
761
|
+
}
|
|
645
762
|
};
|
|
646
763
|
let cachedSelection = {};
|
|
647
764
|
useEventListener(document, "selectionchange", () => {
|
|
648
765
|
const sel = window.getSelection();
|
|
649
|
-
const anchor = findParent(sel.anchorNode, (el) => el.hasAttribute("data-vw-block-id"));
|
|
766
|
+
const anchor = findParent(sel.anchorNode, (el) => el.hasAttribute("data-vw-block-id") && el.parentElement === textEditorRef.value);
|
|
650
767
|
if (anchor) {
|
|
651
|
-
const
|
|
768
|
+
const isNonEditable = anchor.getAttribute("contenteditable") === "false";
|
|
769
|
+
const offset = isNonEditable || anchor === sel.focusNode ? 0 : calcOffsetToNode(anchor, sel.anchorNode) + sel.anchorOffset;
|
|
652
770
|
store.selection.anchor = { blockId: anchor.getAttribute("data-vw-block-id"), offset };
|
|
653
771
|
}
|
|
654
|
-
const focus = findParent(sel.focusNode, (el) => el.hasAttribute("data-vw-block-id"));
|
|
772
|
+
const focus = findParent(sel.focusNode, (el) => el.hasAttribute("data-vw-block-id") && el.parentElement === textEditorRef.value);
|
|
655
773
|
if (focus) {
|
|
656
|
-
const
|
|
774
|
+
const isNonEditable = focus.getAttribute("contenteditable") === "false";
|
|
775
|
+
const offset = isNonEditable || focus === sel.focusNode ? 0 : calcOffsetToNode(focus, sel.focusNode) + sel.focusOffset;
|
|
657
776
|
store.selection.focus = { blockId: focus.getAttribute("data-vw-block-id"), offset };
|
|
658
777
|
}
|
|
659
|
-
if (store.isFocused.value !== !!focus || !!anchor) {
|
|
778
|
+
if (store.isFocused.value !== (!!focus || !!anchor)) {
|
|
660
779
|
store.isFocused.value = !!focus || !!anchor;
|
|
661
780
|
}
|
|
662
|
-
if (
|
|
781
|
+
if (anchor && focus) {
|
|
663
782
|
cachedSelection = JSON.parse(JSON.stringify(store.selection));
|
|
783
|
+
}
|
|
664
784
|
});
|
|
665
785
|
let postRendered = false;
|
|
666
786
|
const onPostRender = () => {
|
|
@@ -688,6 +808,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
688
808
|
}
|
|
689
809
|
if (isEqual(store.selection, cachedSelection))
|
|
690
810
|
return;
|
|
811
|
+
if (store.selection.anchor.blockId === store.selection.focus.blockId && store.currentBlock && store.currentBlock.editable === false) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
691
814
|
const anchor = getNode(store.selection.anchor.blockId);
|
|
692
815
|
const focus = getNode(store.selection.focus.blockId);
|
|
693
816
|
const nativeSelection = window.getSelection();
|
|
@@ -710,15 +833,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
710
833
|
(_b = textEditorRef.value) == null ? void 0 : _b.focus();
|
|
711
834
|
store.selectAll();
|
|
712
835
|
}
|
|
836
|
+
store.history.push("setText");
|
|
713
837
|
});
|
|
714
838
|
const onCopy = (e) => {
|
|
715
839
|
e.preventDefault();
|
|
716
840
|
navigator.clipboard.writeText(store.selectedText);
|
|
841
|
+
store.history.push("setText");
|
|
717
842
|
};
|
|
718
843
|
const onCut = (e) => {
|
|
719
844
|
e.preventDefault();
|
|
720
845
|
navigator.clipboard.writeText(store.selectedText);
|
|
721
846
|
store.deleteSelected();
|
|
847
|
+
store.history.push("setText");
|
|
722
848
|
};
|
|
723
849
|
const onPaste = (e) => {
|
|
724
850
|
var _a;
|
|
@@ -727,6 +853,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
727
853
|
if (!text)
|
|
728
854
|
return;
|
|
729
855
|
store.insertText(text);
|
|
856
|
+
store.history.push("setText");
|
|
730
857
|
};
|
|
731
858
|
const getClientRects = (selection) => {
|
|
732
859
|
const anchor = getNode(selection.anchor.blockId);
|
|
@@ -753,6 +880,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
753
880
|
addNewLine: store.addNewLine.bind(store),
|
|
754
881
|
removeNewLine: store.removeNewLine.bind(store),
|
|
755
882
|
selectAll: store.selectAll.bind(store),
|
|
883
|
+
pushHistory: store.history.push.bind(store.history),
|
|
756
884
|
getClientRects
|
|
757
885
|
});
|
|
758
886
|
return (_ctx, _cache) => {
|
|
@@ -760,7 +888,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
760
888
|
ref_key: "textEditorRef",
|
|
761
889
|
ref: textEditorRef,
|
|
762
890
|
contenteditable: "",
|
|
763
|
-
|
|
891
|
+
onBeforeinput: _cache[0] || (_cache[0] = //@ts-ignore
|
|
764
892
|
(...args) => unref(store).onInput && unref(store).onInput(...args)),
|
|
765
893
|
onKeydown: onKeyDown,
|
|
766
894
|
onCopy,
|
|
@@ -773,10 +901,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
773
901
|
block,
|
|
774
902
|
slots: unref(slots),
|
|
775
903
|
decorator: props.decorator,
|
|
904
|
+
parser: props.parser,
|
|
776
905
|
onPostrender: onPostRender
|
|
777
|
-
}, null, 8, ["block", "slots", "decorator"]);
|
|
906
|
+
}, null, 8, ["block", "slots", "decorator", "parser"]);
|
|
778
907
|
}), 128)),
|
|
779
|
-
unref(store).blocks.length === 1 && unref(store).blocks[0].text === "" ? renderSlot(_ctx.$slots, "placeholder", { key: 0 }) : createCommentVNode("", true)
|
|
908
|
+
unref(store).blocks.length === 1 && unref(store).blocks[0].text === "" && !unref(store).blocks[0].type ? renderSlot(_ctx.$slots, "placeholder", { key: 0 }) : createCommentVNode("", true)
|
|
780
909
|
], 544);
|
|
781
910
|
};
|
|
782
911
|
}
|