vuewrite 0.0.6 → 0.0.7

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.
@@ -80,7 +80,11 @@ toggleStyle: (style: string) => void;
80
80
  applyStyle: (_style: string, meta?: any) => void;
81
81
  removeStyle: (_style: string) => void;
82
82
  insertText: (data: string) => void;
83
+ insertBlock: (blockData: Partial<Block>) => void;
84
+ addNewLine: () => void;
85
+ removeNewLine: () => void;
83
86
  selectAll: () => void;
87
+ getClientRects: (selection: TextEditorSelection) => DOMRectList;
84
88
  }, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
85
89
  keydown: (...args: any[]) => void;
86
90
  "update:modelValue": (...args: any[]) => void;
@@ -104,8 +108,20 @@ onKeydown?: ((...args: any[]) => any) | undefined;
104
108
  placeholder?(_: {}): any;
105
109
  }>;
106
110
 
107
- export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText" | "selectAll"> & {
111
+ export declare type TextEditorRef = Pick<TextEditorStore, "currentStyles" | "currentBlock" | "isCollapsed" | "selection" | "toggleStyle" | "applyStyle" | "removeStyle" | "insertText" | "insertBlock" | "addNewLine" | "removeNewLine" | "selectAll"> & {
108
112
  isFocused: boolean;
113
+ getClientRects: (selection: TextEditorSelection) => DOMRectList;
114
+ };
115
+
116
+ declare type TextEditorSelection = {
117
+ anchor: {
118
+ blockId: string;
119
+ offset: number;
120
+ };
121
+ focus: {
122
+ blockId: string;
123
+ offset: number;
124
+ };
109
125
  };
110
126
 
111
127
  declare class TextEditorStore {
@@ -158,9 +174,11 @@ declare class TextEditorStore {
158
174
  _selectedText: ComputedRef<string>;
159
175
  get selectedText(): string;
160
176
  moveOffset(newOffset: number): void;
177
+ removeNewLine(): void;
161
178
  onInput(_e: Event): void;
162
179
  addNewLine(): void;
163
180
  insertText(data: string): void;
181
+ insertBlock(blockData: Partial<Block>): void;
164
182
  get startAndEnd(): [{
165
183
  blockId: string;
166
184
  offset: number;
package/dist/vuewrite.js CHANGED
@@ -202,6 +202,16 @@ class TextEditorStore {
202
202
  this.selection.anchor.offset = newOffset;
203
203
  this.selection.focus.offset = newOffset;
204
204
  }
205
+ removeNewLine() {
206
+ const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
207
+ if (blockIndex < 1)
208
+ return;
209
+ this.selection.anchor.blockId = this.blocks[blockIndex - 1].id;
210
+ this.selection.focus.blockId = this.blocks[blockIndex - 1].id;
211
+ this.selection.anchor.offset = this.blocks[blockIndex - 1].text.length;
212
+ this.selection.focus.offset = this.blocks[blockIndex - 1].text.length;
213
+ this.blocks.splice(blockIndex, 1);
214
+ }
205
215
  onInput(_e) {
206
216
  const ev = _e;
207
217
  ev.preventDefault();
@@ -212,16 +222,9 @@ class TextEditorStore {
212
222
  if (!block)
213
223
  return;
214
224
  if ((ev.inputType === "deleteContentBackward" || ev.inputType === "deleteContentForward") && collapsed) {
215
- const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
216
225
  if (ev.inputType === "deleteContentBackward") {
217
226
  if (this.selection.anchor.offset === 0) {
218
- if (blockIndex > 0) {
219
- this.selection.anchor.blockId = this.blocks[blockIndex - 1].id;
220
- this.selection.focus.blockId = this.blocks[blockIndex - 1].id;
221
- this.selection.anchor.offset = this.blocks[blockIndex - 1].text.length;
222
- this.selection.focus.offset = this.blocks[blockIndex - 1].text.length;
223
- this.blocks.splice(blockIndex, 1);
224
- }
227
+ this.removeNewLine();
225
228
  } else {
226
229
  const offset = Math.max(0, this.selection.focus.offset - 1);
227
230
  block.text = block.text.slice(0, offset) + block.text.slice(this.selection.focus.offset);
@@ -229,6 +232,7 @@ class TextEditorStore {
229
232
  }
230
233
  }
231
234
  if (ev.inputType === "deleteContentForward") {
235
+ const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
232
236
  if (this.selection.anchor.offset === this.blocks[blockIndex].text.length) {
233
237
  this.blocks.splice(blockIndex + 1, 1);
234
238
  } else {
@@ -260,6 +264,20 @@ class TextEditorStore {
260
264
  block.text = block.text.slice(0, this.selection.focus.offset) + data + block.text.slice(this.selection.focus.offset);
261
265
  this.moveOffset(clamp(this.selection.focus.offset + data.length, 0, block.text.length));
262
266
  }
267
+ insertBlock(blockData) {
268
+ if (!this.currentBlock)
269
+ return;
270
+ this.deleteSelected();
271
+ if (this.currentBlock.text !== "") {
272
+ this.addNewLine();
273
+ }
274
+ if (this.currentBlock.text !== "") {
275
+ const selection = JSON.parse(JSON.stringify(this.selection));
276
+ this.addNewLine();
277
+ Object.assign(this.selection, selection);
278
+ }
279
+ Object.assign(this.currentBlock, blockData);
280
+ }
263
281
  get startAndEnd() {
264
282
  const a = this.blocks.findIndex((block) => block.id === this.selection.anchor.blockId);
265
283
  const f = this.blocks.findIndex((block) => block.id === this.selection.focus.blockId);
@@ -610,8 +628,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
610
628
  }
611
629
  }
612
630
  if (e.code === "Backspace") {
613
- if (store.isCollapsed && store.currentBlock === store.blocks[0] && store.selection.anchor.offset === 0) {
631
+ if (store.isCollapsed && store.selection.anchor.offset === 0) {
614
632
  e.preventDefault();
633
+ if (store.currentBlock && store.currentBlock.type) {
634
+ delete store.currentBlock.type;
635
+ } else {
636
+ store.removeNewLine();
637
+ }
615
638
  }
616
639
  }
617
640
  if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
@@ -650,6 +673,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
650
673
  postRendered = false;
651
674
  });
652
675
  };
676
+ const getNode = (blockId) => {
677
+ for (let item of textEditorRef.value.children) {
678
+ if (item.getAttribute("data-vw-block-id") === blockId) {
679
+ return item;
680
+ }
681
+ }
682
+ return null;
683
+ };
653
684
  const applySelection = () => {
654
685
  if (!store.isFocused.value) {
655
686
  cachedSelection = JSON.parse(JSON.stringify(store.selection));
@@ -657,17 +688,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
657
688
  }
658
689
  if (isEqual(store.selection, cachedSelection))
659
690
  return;
691
+ const anchor = getNode(store.selection.anchor.blockId);
692
+ const focus = getNode(store.selection.focus.blockId);
660
693
  const nativeSelection = window.getSelection();
661
- let anchor = null;
662
- let focus = null;
663
- for (let item of textEditorRef.value.children) {
664
- if (item.getAttribute("data-vw-block-id") === store.selection.anchor.blockId) {
665
- anchor = item;
666
- }
667
- if (item.getAttribute("data-vw-block-id") === store.selection.focus.blockId) {
668
- focus = item;
669
- }
670
- }
671
694
  if (anchor && focus) {
672
695
  nativeSelection.setBaseAndExtent(
673
696
  ...calcNodeByOffset(anchor, store.selection.anchor.offset),
@@ -705,6 +728,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
705
728
  return;
706
729
  store.insertText(text);
707
730
  };
731
+ const getClientRects = (selection) => {
732
+ const anchor = getNode(selection.anchor.blockId);
733
+ const focus = getNode(selection.focus.blockId);
734
+ if (anchor && focus) {
735
+ const range = new Range();
736
+ range.setStart(...calcNodeByOffset(anchor, selection.anchor.offset));
737
+ range.setEnd(...calcNodeByOffset(focus, selection.focus.offset));
738
+ return range.getClientRects();
739
+ }
740
+ return new DOMRectList();
741
+ };
708
742
  __expose({
709
743
  currentStyles: store._currentStyles,
710
744
  currentBlock: store._currentBlock,
@@ -715,7 +749,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
715
749
  applyStyle: store.applyStyle.bind(store),
716
750
  removeStyle: store.removeStyle.bind(store),
717
751
  insertText: store.insertText.bind(store),
718
- selectAll: store.selectAll.bind(store)
752
+ insertBlock: store.insertBlock.bind(store),
753
+ addNewLine: store.addNewLine.bind(store),
754
+ removeNewLine: store.removeNewLine.bind(store),
755
+ selectAll: store.selectAll.bind(store),
756
+ getClientRects
719
757
  });
720
758
  return (_ctx, _cache) => {
721
759
  return openBlock(), createElementBlock("div", {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vuewrite",
3
3
  "description": "Rich Text Editor based on Vue3 reactivity",
4
4
  "private": false,
5
- "version": "0.0.6",
5
+ "version": "0.0.7",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "author": "den59k",