vuewrite 0.0.2 → 0.0.4
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 +12 -1
- package/dist/vuewrite.js +64 -5
- package/package.json +1 -1
package/dist/vuewrite.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ExtractPropTypes } from 'vue';
|
|
|
5
5
|
import { HTMLAttributes } from 'vue';
|
|
6
6
|
import { PropType } from 'vue';
|
|
7
7
|
import { PublicProps } from 'vue';
|
|
8
|
+
import { Ref } from 'vue';
|
|
8
9
|
|
|
9
10
|
declare type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
10
11
|
|
|
@@ -44,6 +45,7 @@ decorator?: Decorator | undefined;
|
|
|
44
45
|
single?: boolean | undefined;
|
|
45
46
|
modelValue?: string | string[] | undefined;
|
|
46
47
|
styles?: Style[] | Style[][] | undefined;
|
|
48
|
+
autofocus?: boolean | undefined;
|
|
47
49
|
}>, {
|
|
48
50
|
currentStyles: ComputedRef<Map<string, Style>>;
|
|
49
51
|
currentBlock: ComputedRef< {
|
|
@@ -68,10 +70,12 @@ blockId: string;
|
|
|
68
70
|
offset: number;
|
|
69
71
|
};
|
|
70
72
|
};
|
|
73
|
+
isFocused: Ref<boolean>;
|
|
71
74
|
toggleStyle: (style: string) => void;
|
|
72
75
|
applyStyle: (_style: string, meta?: any) => void;
|
|
73
76
|
removeStyle: (_style: string) => void;
|
|
74
77
|
insertText: (data: string) => void;
|
|
78
|
+
selectAll: () => void;
|
|
75
79
|
}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
76
80
|
keydown: (...args: any[]) => void;
|
|
77
81
|
"update:modelValue": (...args: any[]) => void;
|
|
@@ -81,6 +85,7 @@ decorator?: Decorator | undefined;
|
|
|
81
85
|
single?: boolean | undefined;
|
|
82
86
|
modelValue?: string | string[] | undefined;
|
|
83
87
|
styles?: Style[] | Style[][] | undefined;
|
|
88
|
+
autofocus?: boolean | undefined;
|
|
84
89
|
}>>> & {
|
|
85
90
|
onKeydown?: ((...args: any[]) => any) | undefined;
|
|
86
91
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
@@ -89,7 +94,9 @@ onKeydown?: ((...args: any[]) => any) | undefined;
|
|
|
89
94
|
placeholder?(_: {}): any;
|
|
90
95
|
}>;
|
|
91
96
|
|
|
92
|
-
export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText"
|
|
97
|
+
export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText" | "selectAll"> & {
|
|
98
|
+
isFocused: boolean;
|
|
99
|
+
};
|
|
93
100
|
|
|
94
101
|
declare class TextEditorStore {
|
|
95
102
|
blocks: {
|
|
@@ -115,6 +122,7 @@ declare class TextEditorStore {
|
|
|
115
122
|
};
|
|
116
123
|
_isCollapsed: ComputedRef<boolean>;
|
|
117
124
|
get isCollapsed(): boolean;
|
|
125
|
+
isFocused: Ref<boolean>;
|
|
118
126
|
_currentBlock: ComputedRef< {
|
|
119
127
|
id: string;
|
|
120
128
|
text: string;
|
|
@@ -137,6 +145,8 @@ declare class TextEditorStore {
|
|
|
137
145
|
meta?: any;
|
|
138
146
|
}[];
|
|
139
147
|
} | null;
|
|
148
|
+
_selectedText: ComputedRef<string>;
|
|
149
|
+
get selectedText(): string;
|
|
140
150
|
moveOffset(newOffset: number): void;
|
|
141
151
|
onInput(_e: Event): void;
|
|
142
152
|
addNewLine(): void;
|
|
@@ -157,6 +167,7 @@ declare class TextEditorStore {
|
|
|
157
167
|
removeStyle(_style: string): void;
|
|
158
168
|
removeAllStyles(): void;
|
|
159
169
|
toggleStyle(style: string): void;
|
|
170
|
+
selectAll(): void;
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
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, defineComponent, getCurrentInstance, openBlock, createBlock, resolveDynamicComponent, createElementBlock, normalizeProps, mergeProps, h, nextTick, useSlots,
|
|
7
|
+
import { getCurrentScope, onScopeDispose, unref, watch, reactive, computed, ref, defineComponent, getCurrentInstance, openBlock, createBlock, resolveDynamicComponent, createElementBlock, normalizeProps, mergeProps, h, nextTick, useSlots, onMounted, Fragment, renderList, renderSlot, createCommentVNode } from "vue";
|
|
8
8
|
function tryOnScopeDispose(fn) {
|
|
9
9
|
if (getCurrentScope()) {
|
|
10
10
|
onScopeDispose(fn);
|
|
@@ -150,11 +150,24 @@ class TextEditorStore {
|
|
|
150
150
|
__publicField(this, "_isCollapsed", computed(() => {
|
|
151
151
|
return this.selection.anchor.blockId === this.selection.focus.blockId && this.selection.anchor.offset === this.selection.focus.offset;
|
|
152
152
|
}));
|
|
153
|
+
__publicField(this, "isFocused", ref(false));
|
|
153
154
|
__publicField(this, "_currentBlock", computed(() => {
|
|
154
155
|
if (this.selection.anchor.blockId !== this.selection.focus.blockId)
|
|
155
156
|
return null;
|
|
156
157
|
return this.blocks.find((item) => item.id === this.selection.anchor.blockId) ?? null;
|
|
157
158
|
}));
|
|
159
|
+
__publicField(this, "_selectedText", computed(() => {
|
|
160
|
+
if (this.isCollapsed)
|
|
161
|
+
return "";
|
|
162
|
+
const [start, end, startIndex, endIndex] = this.startAndEnd;
|
|
163
|
+
if (startIndex === endIndex) {
|
|
164
|
+
return this.blocks[startIndex].text.slice(start.offset, end.offset);
|
|
165
|
+
}
|
|
166
|
+
const startText = this.blocks[startIndex].text.slice(start.offset);
|
|
167
|
+
const endText = this.blocks[endIndex].text.slice(0, end.offset);
|
|
168
|
+
const arr = [startText, ...this.blocks.slice(startIndex + 1, endIndex).map((block) => block.text), endText];
|
|
169
|
+
return arr.join("\n");
|
|
170
|
+
}));
|
|
158
171
|
__publicField(this, "_currentStyles", computed(() => {
|
|
159
172
|
const [start, end, startIndex, endIndex] = this.startAndEnd;
|
|
160
173
|
const styles = /* @__PURE__ */ new Map();
|
|
@@ -178,6 +191,9 @@ class TextEditorStore {
|
|
|
178
191
|
get currentBlock() {
|
|
179
192
|
return this._currentBlock.value;
|
|
180
193
|
}
|
|
194
|
+
get selectedText() {
|
|
195
|
+
return this._selectedText.value;
|
|
196
|
+
}
|
|
181
197
|
moveOffset(newOffset) {
|
|
182
198
|
const delta = newOffset - this.selection.anchor.offset;
|
|
183
199
|
if (delta === 0)
|
|
@@ -374,6 +390,11 @@ class TextEditorStore {
|
|
|
374
390
|
this.applyStyle(style);
|
|
375
391
|
}
|
|
376
392
|
}
|
|
393
|
+
selectAll() {
|
|
394
|
+
this.selection.anchor = { blockId: this.blocks[0].id, offset: 0 };
|
|
395
|
+
const lastBlock = this.blocks[this.blocks.length - 1];
|
|
396
|
+
this.selection.focus = { blockId: lastBlock.id, offset: lastBlock.text.length };
|
|
397
|
+
}
|
|
377
398
|
}
|
|
378
399
|
let uidCounter = 0;
|
|
379
400
|
const uid = () => (uidCounter++).toString();
|
|
@@ -521,7 +542,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
521
542
|
decorator: { type: Function },
|
|
522
543
|
single: { type: Boolean },
|
|
523
544
|
modelValue: {},
|
|
524
|
-
styles: {}
|
|
545
|
+
styles: {},
|
|
546
|
+
autofocus: { type: Boolean }
|
|
525
547
|
},
|
|
526
548
|
emits: ["keydown", "update:modelValue", "update:styles"],
|
|
527
549
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
@@ -605,7 +627,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
605
627
|
const offset = anchor === sel.focusNode ? 0 : calcOffsetToNode(focus, sel.focusNode) + sel.focusOffset;
|
|
606
628
|
store.selection.focus = { blockId: focus.getAttribute("data-block-id"), offset };
|
|
607
629
|
}
|
|
608
|
-
|
|
630
|
+
if (store.isFocused.value !== !!focus || !!anchor) {
|
|
631
|
+
store.isFocused.value = !!focus || !!anchor;
|
|
632
|
+
}
|
|
633
|
+
if (!anchor && !focus)
|
|
634
|
+
cachedSelection = JSON.parse(JSON.stringify(store.selection));
|
|
609
635
|
});
|
|
610
636
|
let postRendered = false;
|
|
611
637
|
const onPostRender = () => {
|
|
@@ -619,6 +645,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
619
645
|
});
|
|
620
646
|
};
|
|
621
647
|
const applySelection = () => {
|
|
648
|
+
if (!store.isFocused.value) {
|
|
649
|
+
cachedSelection = JSON.parse(JSON.stringify(store.selection));
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
622
652
|
if (isEqual(store.selection, cachedSelection))
|
|
623
653
|
return;
|
|
624
654
|
const nativeSelection = window.getSelection();
|
|
@@ -641,15 +671,41 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
641
671
|
cachedSelection = JSON.parse(JSON.stringify(store.selection));
|
|
642
672
|
};
|
|
643
673
|
watch(() => store.selection, applySelection, { deep: true, flush: "post" });
|
|
674
|
+
onMounted(() => {
|
|
675
|
+
var _a;
|
|
676
|
+
if (props.autofocus) {
|
|
677
|
+
(_a = textEditorRef.value) == null ? void 0 : _a.focus();
|
|
678
|
+
applySelection();
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
const onCopy = (e) => {
|
|
682
|
+
e.preventDefault();
|
|
683
|
+
navigator.clipboard.writeText(store.selectedText);
|
|
684
|
+
};
|
|
685
|
+
const onCut = (e) => {
|
|
686
|
+
e.preventDefault();
|
|
687
|
+
navigator.clipboard.writeText(store.selectedText);
|
|
688
|
+
store.deleteSelected();
|
|
689
|
+
};
|
|
690
|
+
const onPaste = (e) => {
|
|
691
|
+
var _a;
|
|
692
|
+
e.preventDefault();
|
|
693
|
+
const text = (_a = e.clipboardData) == null ? void 0 : _a.getData("Text");
|
|
694
|
+
if (!text)
|
|
695
|
+
return;
|
|
696
|
+
store.insertText(text);
|
|
697
|
+
};
|
|
644
698
|
__expose({
|
|
645
699
|
currentStyles: store._currentStyles,
|
|
646
700
|
currentBlock: store._currentBlock,
|
|
647
701
|
isCollapsed: store._isCollapsed,
|
|
648
702
|
selection: store.selection,
|
|
703
|
+
isFocused: store.isFocused,
|
|
649
704
|
toggleStyle: store.toggleStyle.bind(store),
|
|
650
705
|
applyStyle: store.applyStyle.bind(store),
|
|
651
706
|
removeStyle: store.removeStyle.bind(store),
|
|
652
|
-
insertText: store.insertText.bind(store)
|
|
707
|
+
insertText: store.insertText.bind(store),
|
|
708
|
+
selectAll: store.selectAll.bind(store)
|
|
653
709
|
});
|
|
654
710
|
return (_ctx, _cache) => {
|
|
655
711
|
return openBlock(), createElementBlock("div", {
|
|
@@ -658,7 +714,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
658
714
|
contenteditable: "",
|
|
659
715
|
onInput: _cache[0] || (_cache[0] = //@ts-ignore
|
|
660
716
|
(...args) => unref(store).onInput && unref(store).onInput(...args)),
|
|
661
|
-
onKeydown: onKeyDown
|
|
717
|
+
onKeydown: onKeyDown,
|
|
718
|
+
onCopy,
|
|
719
|
+
onPaste,
|
|
720
|
+
onCut
|
|
662
721
|
}, [
|
|
663
722
|
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(store).blocks, (block) => {
|
|
664
723
|
return openBlock(), createBlock(_sfc_main$1, {
|