vuewrite 0.0.25 → 0.0.27

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.
@@ -0,0 +1,14 @@
1
+ import { Block } from 'vuewrite-markdown';
2
+ import { blocksToMarkdown } from 'vuewrite-markdown';
3
+ import { markdownToBlocks } from 'vuewrite-markdown';
4
+ import { Style } from 'vuewrite-markdown';
5
+
6
+ export { Block }
7
+
8
+ export { blocksToMarkdown }
9
+
10
+ export { markdownToBlocks }
11
+
12
+ export { Style }
13
+
14
+ export { }
@@ -0,0 +1,358 @@
1
+ let _counter = 0;
2
+ const uid = () => (++_counter).toString();
3
+ function blockContentKey(block) {
4
+ const { id: _id, ...rest } = block;
5
+ return JSON.stringify(rest);
6
+ }
7
+ function lcsIndices(oldKeys, newKeys) {
8
+ const m = oldKeys.length;
9
+ const n = newKeys.length;
10
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
11
+ for (let i2 = 1; i2 <= m; i2++) {
12
+ for (let j2 = 1; j2 <= n; j2++) {
13
+ dp[i2][j2] = oldKeys[i2 - 1] === newKeys[j2 - 1] ? dp[i2 - 1][j2 - 1] + 1 : Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
14
+ }
15
+ }
16
+ const pairs = [];
17
+ let i = m;
18
+ let j = n;
19
+ while (i > 0 && j > 0) {
20
+ if (oldKeys[i - 1] === newKeys[j - 1]) {
21
+ pairs.unshift([i - 1, j - 1]);
22
+ i--;
23
+ j--;
24
+ } else if (dp[i - 1][j] >= dp[i][j - 1]) {
25
+ i--;
26
+ } else {
27
+ j--;
28
+ }
29
+ }
30
+ return pairs;
31
+ }
32
+ function markdownToBlocks(markdown, previousBlocks = []) {
33
+ const lines = markdown.split("\n");
34
+ const blocks = [];
35
+ let i = 0;
36
+ while (i < lines.length) {
37
+ const line = lines[i];
38
+ const customFenceMatch = line.match(/^:::\s*(\S+)/);
39
+ if (customFenceMatch) {
40
+ const type = customFenceMatch[1];
41
+ const bodyLines = [];
42
+ i++;
43
+ while (i < lines.length && lines[i].trim() !== ":::") {
44
+ bodyLines.push(lines[i]);
45
+ i++;
46
+ }
47
+ const { text: text2, styles: styles2 } = parseInline(bodyLines.join("\n"));
48
+ const block2 = { id: uid(), text: text2, type };
49
+ if (styles2.length > 0) block2.styles = styles2;
50
+ blocks.push(block2);
51
+ i++;
52
+ continue;
53
+ }
54
+ const xmlPairedMatch = line.match(/^<(\w[\w-]*)(\s[^>]*)?>(.+)<\/\1>$/);
55
+ if (xmlPairedMatch) {
56
+ const attrs = parseAttributes(xmlPairedMatch[2] ?? "");
57
+ const { text: text2, styles: styles2 } = parseInline(xmlPairedMatch[3]);
58
+ const block2 = { id: uid(), text: text2, type: xmlPairedMatch[1], ...attrs };
59
+ if (styles2.length > 0) block2.styles = styles2;
60
+ blocks.push(block2);
61
+ i++;
62
+ continue;
63
+ }
64
+ const xmlSelfMatch = line.match(/^<(\w[\w-]*)(\s[^>]*)?\s*\/?>$/);
65
+ if (xmlSelfMatch) {
66
+ const attrs = parseAttributes(xmlSelfMatch[2] ?? "");
67
+ const block2 = { id: uid(), text: "", type: xmlSelfMatch[1], editable: false, ...attrs };
68
+ blocks.push(block2);
69
+ i++;
70
+ continue;
71
+ }
72
+ if (line.startsWith("```")) {
73
+ const codeLines = [];
74
+ i++;
75
+ while (i < lines.length && !lines[i].startsWith("```")) {
76
+ codeLines.push(lines[i]);
77
+ i++;
78
+ }
79
+ blocks.push({ id: uid(), text: codeLines.join("\n"), type: "code", editable: false });
80
+ i++;
81
+ continue;
82
+ }
83
+ const headingMatch = line.match(/^(#{1,3}) (.+)$/);
84
+ if (headingMatch) {
85
+ const level = headingMatch[1].length;
86
+ const type = level === 1 ? "h1" : level === 2 ? "h2" : "h3";
87
+ const { text: text2, styles: styles2 } = parseInline(headingMatch[2]);
88
+ const block2 = { id: uid(), text: text2, type };
89
+ if (styles2.length > 0) block2.styles = styles2;
90
+ blocks.push(block2);
91
+ i++;
92
+ continue;
93
+ }
94
+ const ulMatch = line.match(/^[-*] (.+)$/);
95
+ if (ulMatch) {
96
+ const { text: text2, styles: styles2 } = parseInline(ulMatch[1]);
97
+ const block2 = { id: uid(), text: text2, type: "li" };
98
+ if (styles2.length > 0) block2.styles = styles2;
99
+ blocks.push(block2);
100
+ i++;
101
+ continue;
102
+ }
103
+ const olMatch = line.match(/^\d+\. (.+)$/);
104
+ if (olMatch) {
105
+ const { text: text2, styles: styles2 } = parseInline(olMatch[1]);
106
+ const block2 = { id: uid(), text: text2, type: "ol" };
107
+ if (styles2.length > 0) block2.styles = styles2;
108
+ blocks.push(block2);
109
+ i++;
110
+ continue;
111
+ }
112
+ if (line === "") {
113
+ if (blocks.length > 0 && i < lines.length - 1) {
114
+ blocks.push({ id: uid(), text: "" });
115
+ }
116
+ i++;
117
+ continue;
118
+ }
119
+ const { text, styles } = parseInline(line);
120
+ const block = { id: uid(), text };
121
+ if (styles.length > 0) block.styles = styles;
122
+ blocks.push(block);
123
+ i++;
124
+ }
125
+ if (blocks.length === 0) {
126
+ blocks.push({ id: uid(), text: "" });
127
+ }
128
+ if (previousBlocks.length === 0) return blocks;
129
+ const oldKeys = previousBlocks.map(blockContentKey);
130
+ const newKeys = blocks.map(blockContentKey);
131
+ const pairs = lcsIndices(oldKeys, newKeys);
132
+ const oldIdByNewIndex = new Map(pairs.map(([i2, j]) => [j, previousBlocks[i2].id]));
133
+ return blocks.map((block, j) => {
134
+ const oldId = oldIdByNewIndex.get(j);
135
+ return oldId !== void 0 ? { ...block, id: oldId } : block;
136
+ });
137
+ }
138
+ function parseAttributes(attrStr) {
139
+ const result = {};
140
+ const re = /(\w[\w-]*)(?:=(?:"([^"]*)"|'([^']*)'|(\S+)))?/g;
141
+ let m;
142
+ while ((m = re.exec(attrStr)) !== null) {
143
+ result[m[1]] = m[2] ?? m[3] ?? m[4] ?? true;
144
+ }
145
+ return result;
146
+ }
147
+ function parseInline(md) {
148
+ let plainText = "";
149
+ const styles = [];
150
+ function recurse(inner, extraStyles, linkMeta) {
151
+ const start = plainText.length;
152
+ const result = parseInline(inner);
153
+ plainText += result.text;
154
+ const end = plainText.length;
155
+ for (const styleName of extraStyles) {
156
+ styles.push({ start, end, style: styleName, ...linkMeta ? { meta: linkMeta } : {} });
157
+ }
158
+ for (const s of result.styles) {
159
+ styles.push({ ...s, start: start + s.start, end: start + s.end });
160
+ }
161
+ }
162
+ let i = 0;
163
+ while (i < md.length) {
164
+ const rest = md.slice(i);
165
+ const boldItalicM = rest.match(/^\*\*\*([\s\S]*?)\*\*\*/);
166
+ if (boldItalicM) {
167
+ recurse(boldItalicM[1], ["bold", "italic"]);
168
+ i += boldItalicM[0].length;
169
+ continue;
170
+ }
171
+ const boldM = rest.match(/^\*\*([\s\S]*?)\*\*/);
172
+ if (boldM) {
173
+ recurse(boldM[1], ["bold"]);
174
+ i += boldM[0].length;
175
+ continue;
176
+ }
177
+ const underlineM = rest.match(/^__([\s\S]*?)__/);
178
+ if (underlineM) {
179
+ recurse(underlineM[1], ["underline"]);
180
+ i += underlineM[0].length;
181
+ continue;
182
+ }
183
+ const italicAsteriskM = rest.match(/^\*([\s\S]*?)\*/);
184
+ if (italicAsteriskM) {
185
+ recurse(italicAsteriskM[1], ["italic"]);
186
+ i += italicAsteriskM[0].length;
187
+ continue;
188
+ }
189
+ const italicUnderscoreM = rest.match(/^_([\s\S]*?)_/);
190
+ if (italicUnderscoreM) {
191
+ recurse(italicUnderscoreM[1], ["italic"]);
192
+ i += italicUnderscoreM[0].length;
193
+ continue;
194
+ }
195
+ const codeM = rest.match(/^`([\s\S]*?)`/);
196
+ if (codeM) {
197
+ const start = plainText.length;
198
+ plainText += codeM[1];
199
+ styles.push({ start, end: plainText.length, style: "code" });
200
+ i += codeM[0].length;
201
+ continue;
202
+ }
203
+ const linkM = rest.match(/^\[([\s\S]*?)\]\(([\s\S]*?)\)/);
204
+ if (linkM) {
205
+ recurse(linkM[1], ["link"], { href: linkM[2] });
206
+ i += linkM[0].length;
207
+ continue;
208
+ }
209
+ if (md[i] === "\\" && i + 1 < md.length) {
210
+ plainText += md[i + 1];
211
+ i += 2;
212
+ continue;
213
+ }
214
+ plainText += md[i];
215
+ i++;
216
+ }
217
+ return { text: plainText, styles };
218
+ }
219
+ const MARKERS = {
220
+ bold: { open: "**", close: "**" },
221
+ italic: { open: "*", close: "*" },
222
+ underline: { open: "__", close: "__" },
223
+ code: { open: "`", close: "`" }
224
+ };
225
+ const STANDARD_FIELDS = /* @__PURE__ */ new Set(["id", "text", "type", "styles", "editable"]);
226
+ function blocksToMarkdown(blocks) {
227
+ const lines = [];
228
+ let olCounter = 0;
229
+ for (const block of blocks) {
230
+ if (block.type === "code") {
231
+ lines.push("```");
232
+ lines.push(block.text);
233
+ lines.push("```");
234
+ olCounter = 0;
235
+ continue;
236
+ }
237
+ const extraKeys = Object.keys(block).filter((k) => !STANDARD_FIELDS.has(k));
238
+ if (block.type && extraKeys.length > 0) {
239
+ const attrStr = extraKeys.map((k) => {
240
+ const v = block[k];
241
+ return v === true ? k : `${k}="${v}"`;
242
+ }).join(" ");
243
+ const prefix = attrStr ? ` ${attrStr}` : "";
244
+ if (block.editable === false || !block.text) {
245
+ lines.push(`<${block.type}${prefix}/>`);
246
+ } else {
247
+ lines.push(`<${block.type}${prefix}>${renderInline(block.text, block.styles ?? [])}</${block.type}>`);
248
+ }
249
+ olCounter = 0;
250
+ continue;
251
+ }
252
+ const inline = renderInline(block.text, block.styles ?? []);
253
+ switch (block.type) {
254
+ case "h1":
255
+ lines.push(`# ${inline}`);
256
+ olCounter = 0;
257
+ break;
258
+ case "h2":
259
+ lines.push(`## ${inline}`);
260
+ olCounter = 0;
261
+ break;
262
+ case "h3":
263
+ lines.push(`### ${inline}`);
264
+ olCounter = 0;
265
+ break;
266
+ case "li":
267
+ lines.push(`- ${inline}`);
268
+ olCounter = 0;
269
+ break;
270
+ case "ol":
271
+ lines.push(`${++olCounter}. ${inline}`);
272
+ break;
273
+ default:
274
+ if (block.type) {
275
+ lines.push(`:::${block.type}`);
276
+ lines.push(inline);
277
+ lines.push(":::");
278
+ } else {
279
+ lines.push(inline);
280
+ }
281
+ olCounter = 0;
282
+ break;
283
+ }
284
+ }
285
+ return lines.join("\n");
286
+ }
287
+ function escapeMarkdown(text) {
288
+ return text.replace(/[\\*_`\[\]]/g, "\\$&");
289
+ }
290
+ function buildSegments(text, styles) {
291
+ var _a;
292
+ const linkStyles = styles.filter((s) => s.style === "link");
293
+ const formatStyles = styles.filter((s) => s.style in MARKERS);
294
+ const bpSet = /* @__PURE__ */ new Set([0, text.length]);
295
+ for (const s of [...linkStyles, ...formatStyles]) {
296
+ bpSet.add(s.start);
297
+ bpSet.add(s.end);
298
+ }
299
+ const breakpoints = [...bpSet].sort((a, b) => a - b);
300
+ const segments = [];
301
+ for (let i = 0; i < breakpoints.length - 1; i++) {
302
+ const start = breakpoints[i];
303
+ const end = breakpoints[i + 1];
304
+ const formats = formatStyles.filter((s) => s.start <= start && s.end >= end).map((s) => s.style).sort((a, b) => MARKERS[b].open.length - MARKERS[a].open.length);
305
+ const link = linkStyles.find((l) => l.start <= start && l.end >= end);
306
+ segments.push({ start, end, formats, linkHref: (_a = link == null ? void 0 : link.meta) == null ? void 0 : _a.href });
307
+ }
308
+ return segments;
309
+ }
310
+ function renderSegments(text, segments) {
311
+ let result = "";
312
+ let activeFormats = [];
313
+ for (const seg of segments) {
314
+ const toClose = activeFormats.filter((f) => !seg.formats.includes(f));
315
+ if (toClose.length > 0) {
316
+ for (const f of [...activeFormats].reverse()) result += MARKERS[f].close;
317
+ for (const f of seg.formats) result += MARKERS[f].open;
318
+ } else {
319
+ for (const f of seg.formats) {
320
+ if (!activeFormats.includes(f)) result += MARKERS[f].open;
321
+ }
322
+ }
323
+ activeFormats = seg.formats;
324
+ result += seg.formats.includes("code") ? text.slice(seg.start, seg.end) : escapeMarkdown(text.slice(seg.start, seg.end));
325
+ }
326
+ for (const f of [...activeFormats].reverse()) result += MARKERS[f].close;
327
+ return result;
328
+ }
329
+ function renderInline(text, styles) {
330
+ if (styles.length === 0) return escapeMarkdown(text);
331
+ const segments = buildSegments(text, styles);
332
+ let result = "";
333
+ let i = 0;
334
+ while (i < segments.length) {
335
+ const seg = segments[i];
336
+ if (seg.linkHref !== void 0) {
337
+ const href = seg.linkHref;
338
+ const linkSegs = [];
339
+ while (i < segments.length && segments[i].linkHref === href) {
340
+ linkSegs.push(segments[i]);
341
+ i++;
342
+ }
343
+ result += `[${renderSegments(text, linkSegs)}](${href})`;
344
+ } else {
345
+ const plainSegs = [];
346
+ while (i < segments.length && segments[i].linkHref === void 0) {
347
+ plainSegs.push(segments[i]);
348
+ i++;
349
+ }
350
+ result += renderSegments(text, plainSegs);
351
+ }
352
+ }
353
+ return result;
354
+ }
355
+ export {
356
+ blocksToMarkdown,
357
+ markdownToBlocks
358
+ };
@@ -1,10 +1,12 @@
1
1
  import { ComponentOptionsMixin } from 'vue';
2
+ import { ComponentProvideOptions } from 'vue';
2
3
  import { ComputedRef } from 'vue';
3
4
  import { DefineComponent } from 'vue';
4
5
  import { ExtractPropTypes } from 'vue';
5
6
  import { HTMLAttributes } from 'vue';
6
7
  import { PropType } from 'vue';
7
8
  import { PublicProps } from 'vue';
9
+ import { Reactive } from 'vue';
8
10
  import { Ref } from 'vue';
9
11
  import { RendererElement } from 'vue';
10
12
  import { RendererNode } from 'vue';
@@ -57,22 +59,23 @@ export declare type Style = {
57
59
  meta?: any;
58
60
  };
59
61
 
60
- export declare const TextEditor: __VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<{
61
- decorator?: Decorator | undefined;
62
- renderer?: Renderer | undefined;
63
- single?: boolean | undefined;
64
- modelValue?: string | {
62
+ export declare const TextEditor: __VLS_WithTemplateSlots<DefineComponent<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
63
+ decorator?: Decorator;
64
+ renderer?: Renderer;
65
+ single?: boolean;
66
+ modelValue?: {
67
+ id?: string;
65
68
  text: string;
66
- styles?: Style[] | undefined;
67
- type?: string | undefined;
68
- }[] | undefined;
69
- parser?: TextParser | undefined;
70
- styles?: Style[] | undefined;
71
- autofocus?: boolean | undefined;
72
- autoselect?: boolean | undefined;
73
- preventMultiline?: boolean | undefined;
74
- htmlParser?: ((el: Element) => string | null | void) | undefined;
75
- }>, {
69
+ styles?: Style[];
70
+ type?: string;
71
+ }[] | string;
72
+ parser?: TextParser;
73
+ styles?: Style[];
74
+ autofocus?: boolean;
75
+ autoselect?: boolean;
76
+ preventMultiline?: boolean;
77
+ htmlParser?: (el: Element) => string | null | void;
78
+ }>>, {
76
79
  currentStyles: ComputedRef<Map<string, Style>>;
77
80
  currentBlock: ComputedRef< {
78
81
  id: string;
@@ -97,8 +100,8 @@ blockId: string;
97
100
  offset: number;
98
101
  };
99
102
  };
100
- isFocused: Ref<boolean>;
101
- getCurrentBlocks: () => Generator<Block, any, unknown>;
103
+ isFocused: Ref<boolean, boolean>;
104
+ getCurrentBlocks: () => Generator<Block>;
102
105
  toggleStyle: (style: string) => void;
103
106
  applyStyle: (_style: string, meta?: any) => void;
104
107
  removeStyle: (_style: string) => void;
@@ -110,30 +113,31 @@ removeCurrentBlock: () => void;
110
113
  selectAll: () => void;
111
114
  pushHistory: (type: string) => void;
112
115
  getClientRects: (selection: TextEditorSelection) => DOMRectList;
113
- }, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
116
+ }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
114
117
  keydown: (...args: any[]) => void;
115
118
  "update:modelValue": (...args: any[]) => void;
116
119
  "update:styles": (...args: any[]) => void;
117
120
  }, string, PublicProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
118
- decorator?: Decorator | undefined;
119
- renderer?: Renderer | undefined;
120
- single?: boolean | undefined;
121
- modelValue?: string | {
121
+ decorator?: Decorator;
122
+ renderer?: Renderer;
123
+ single?: boolean;
124
+ modelValue?: {
125
+ id?: string;
122
126
  text: string;
123
- styles?: Style[] | undefined;
124
- type?: string | undefined;
125
- }[] | undefined;
126
- parser?: TextParser | undefined;
127
- styles?: Style[] | undefined;
128
- autofocus?: boolean | undefined;
129
- autoselect?: boolean | undefined;
130
- preventMultiline?: boolean | undefined;
131
- htmlParser?: ((el: Element) => string | null | void) | undefined;
132
- }>>> & {
127
+ styles?: Style[];
128
+ type?: string;
129
+ }[] | string;
130
+ parser?: TextParser;
131
+ styles?: Style[];
132
+ autofocus?: boolean;
133
+ autoselect?: boolean;
134
+ preventMultiline?: boolean;
135
+ htmlParser?: (el: Element) => string | null | void;
136
+ }>>> & Readonly<{
133
137
  onKeydown?: ((...args: any[]) => any) | undefined;
134
138
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
135
139
  "onUpdate:styles"?: ((...args: any[]) => any) | undefined;
136
- }, {}, {}>, {
140
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>, {
137
141
  placeholder?(_: {}): any;
138
142
  }>;
139
143
 
@@ -172,18 +176,7 @@ declare type TextEditorSelection = {
172
176
 
173
177
  declare class TextEditorStore {
174
178
  history: TextEditorHistory;
175
- blocks: {
176
- id: string;
177
- text: string;
178
- type?: string | undefined;
179
- styles?: {
180
- start: number;
181
- end: number;
182
- style: string;
183
- meta?: any;
184
- }[] | undefined;
185
- editable?: boolean | undefined;
186
- }[];
179
+ blocks: Reactive<Block[]>;
187
180
  selection: {
188
181
  anchor: {
189
182
  blockId: string;
@@ -196,7 +189,7 @@ declare class TextEditorStore {
196
189
  };
197
190
  _isCollapsed: ComputedRef<boolean>;
198
191
  get isCollapsed(): boolean;
199
- isFocused: Ref<boolean>;
192
+ isFocused: Ref<boolean, boolean>;
200
193
  _currentBlock: ComputedRef< {
201
194
  id: string;
202
195
  text: string;
@@ -257,31 +250,26 @@ declare class TextEditorStore {
257
250
  selectAll(): void;
258
251
  }
259
252
 
260
- export declare const TextEditorView: DefineComponent<Readonly<{
261
- styles?: any;
262
- decorator?: any;
263
- renderer?: any;
264
- parser?: any;
265
- modelValue?: any;
266
- listParser?: any;
267
- }>, () => VNode<RendererNode, RendererElement, {
253
+ export declare const TextEditorView: DefineComponent< {
254
+ modelValue: Block[] | string;
255
+ decorator?: Decorator | undefined;
256
+ renderer?: Renderer | undefined;
257
+ parser?: TextParser | undefined;
258
+ styles?: Style[] | undefined;
259
+ listParser?: ((block: Block) => string | undefined | void) | undefined;
260
+ }, () => VNode<RendererNode, RendererElement, {
268
261
  [key: string]: any;
269
- }>, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes<Readonly<{
270
- styles?: any;
271
- decorator?: any;
272
- renderer?: any;
273
- parser?: any;
274
- modelValue?: any;
275
- listParser?: any;
276
- }>>>, {
277
- readonly styles?: any;
278
- readonly decorator?: any;
279
- readonly renderer?: any;
280
- readonly parser?: any;
281
- readonly modelValue?: any;
282
- readonly listParser?: any;
283
- }, {}>;
262
+ }>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<{
263
+ modelValue: Block[] | string;
264
+ decorator?: Decorator | undefined;
265
+ renderer?: Renderer | undefined;
266
+ parser?: TextParser | undefined;
267
+ styles?: Style[] | undefined;
268
+ listParser?: ((block: Block) => string | undefined | void) | undefined;
269
+ }> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
284
270
 
285
271
  declare type TextParser = (text: string) => Style[];
286
272
 
273
+ export declare const uid: () => string;
274
+
287
275
  export { }
package/dist/vuewrite.js CHANGED
@@ -1,110 +1,30 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
- import { getCurrentScope, onScopeDispose, unref, watch, reactive, computed, ref, defineComponent, getCurrentInstance, h, nextTick, useSlots, isProxy, toRaw, onMounted, openBlock, createElementBlock, Fragment, renderList, createBlock, renderSlot, createCommentVNode } from "vue";
8
- function tryOnScopeDispose(fn) {
9
- if (getCurrentScope()) {
10
- onScopeDispose(fn);
11
- return true;
12
- }
13
- return false;
14
- }
15
- function toValue(r) {
16
- return typeof r === "function" ? r() : unref(r);
17
- }
18
- const isClient = typeof window !== "undefined" && typeof document !== "undefined";
19
- typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
20
- const toString = Object.prototype.toString;
21
- const isObject = (val) => toString.call(val) === "[object Object]";
22
- const noop = () => {
23
- };
24
- function unrefElement(elRef) {
25
- var _a;
26
- const plain = toValue(elRef);
27
- return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;
28
- }
29
- const defaultWindow = isClient ? window : void 0;
30
- function useEventListener(...args) {
31
- let target;
32
- let events;
33
- let listeners;
34
- let options;
35
- if (typeof args[0] === "string" || Array.isArray(args[0])) {
36
- [events, listeners, options] = args;
37
- target = defaultWindow;
38
- } else {
39
- [target, events, listeners, options] = args;
40
- }
41
- if (!target)
42
- return noop;
43
- if (!Array.isArray(events))
44
- events = [events];
45
- if (!Array.isArray(listeners))
46
- listeners = [listeners];
47
- const cleanups = [];
48
- const cleanup = () => {
49
- cleanups.forEach((fn) => fn());
50
- cleanups.length = 0;
51
- };
52
- const register = (el, event, listener, options2) => {
53
- el.addEventListener(event, listener, options2);
54
- return () => el.removeEventListener(event, listener, options2);
55
- };
56
- const stopWatch = watch(
57
- () => [unrefElement(target), toValue(options)],
58
- ([el, options2]) => {
59
- cleanup();
60
- if (!el)
61
- return;
62
- const optionsClone = isObject(options2) ? { ...options2 } : options2;
63
- cleanups.push(
64
- ...events.flatMap((event) => {
65
- return listeners.map((listener) => register(el, event, listener, optionsClone));
66
- })
67
- );
68
- },
69
- { immediate: true, flush: "post" }
70
- );
71
- const stop = () => {
72
- stopWatch();
73
- cleanup();
74
- };
75
- tryOnScopeDispose(stop);
76
- return stop;
77
- }
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { reactive, computed, ref, defineComponent, getCurrentInstance, h, nextTick, useSlots, watch, isProxy, toRaw, onMounted, onUnmounted, openBlock, createElementBlock, unref, Fragment, renderList, createBlock, renderSlot, createCommentVNode } from "vue";
78
5
  const findParent = (el, callback) => {
79
- if (!el)
80
- return null;
6
+ if (!el) return null;
81
7
  if (el.nodeType === Node.ELEMENT_NODE) {
82
- if (callback(el))
83
- return el;
8
+ if (callback(el)) return el;
84
9
  }
85
- if (!el.parentElement)
86
- return null;
10
+ if (!el.parentElement) return null;
87
11
  return findParent(el.parentElement, callback);
88
12
  };
89
13
  const calcOffsetToNode = (parent, target) => {
90
14
  let offset = 0;
91
15
  for (let child of parent.childNodes) {
92
- if (child.nodeName === "BR")
93
- continue;
16
+ if (child.nodeName === "BR") continue;
94
17
  const ch = child.nodeType === Node.TEXT_NODE ? child : child.childNodes[0];
95
- if (ch === target)
96
- return offset;
18
+ if (ch === target) return offset;
97
19
  offset += ch.length;
98
20
  }
99
21
  return offset;
100
22
  };
101
23
  const calcNodeByOffset = (parent, offset) => {
102
24
  let currentOffset = offset;
103
- if (offset === 0)
104
- return [parent, 0];
25
+ if (offset === 0) return [parent, 0];
105
26
  for (let child of parent.childNodes) {
106
- if (child.nodeName === "BR")
107
- continue;
27
+ if (child.nodeName === "BR") continue;
108
28
  const ch = child.nodeType === Node.TEXT_NODE ? child : child.childNodes[0];
109
29
  if (currentOffset - ch.length <= 0) {
110
30
  return [ch, currentOffset];
@@ -114,29 +34,22 @@ const calcNodeByOffset = (parent, offset) => {
114
34
  return [parent, 0];
115
35
  };
116
36
  const clamp = (val, min, max) => {
117
- if (val > max)
118
- return max;
119
- if (val < min)
120
- return min;
37
+ if (val > max) return max;
38
+ if (val < min) return min;
121
39
  return val;
122
40
  };
123
41
  const isEqual = (a, b) => {
124
- if (a === b)
125
- return true;
126
- if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
127
- return false;
42
+ if (a === b) return true;
43
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
128
44
  if (Array.isArray(a)) {
129
- if (!Array.isArray(b) || a.length !== b.length)
130
- return false;
45
+ if (!Array.isArray(b) || a.length !== b.length) return false;
131
46
  for (let i = 0; i < a.length; i++) {
132
- if (!isEqual(a[i], b[i]))
133
- return false;
47
+ if (!isEqual(a[i], b[i])) return false;
134
48
  }
135
49
  return true;
136
50
  }
137
51
  for (let key in a) {
138
- if (!isEqual(a[key], b[key]))
139
- return false;
52
+ if (!isEqual(a[key], b[key])) return false;
140
53
  }
141
54
  return true;
142
55
  };
@@ -214,14 +127,12 @@ class TextEditorHistory {
214
127
  this.cacheBlockIds();
215
128
  }
216
129
  undo() {
217
- if (this.currentCursor === 0)
218
- return;
130
+ if (this.currentCursor === 0) return;
219
131
  this.currentCursor--;
220
132
  this.applyAction(this.actions[this.currentCursor]);
221
133
  }
222
134
  redo() {
223
- if (this.currentCursor >= this.actions.length - 1)
224
- return;
135
+ if (this.currentCursor >= this.actions.length - 1) return;
225
136
  this.currentCursor++;
226
137
  this.applyAction(this.actions[this.currentCursor]);
227
138
  }
@@ -239,13 +150,11 @@ class TextEditorStore {
239
150
  }));
240
151
  __publicField(this, "isFocused", ref(false));
241
152
  __publicField(this, "_currentBlock", computed(() => {
242
- if (this.selection.anchor.blockId !== this.selection.focus.blockId)
243
- return null;
153
+ if (this.selection.anchor.blockId !== this.selection.focus.blockId) return null;
244
154
  return this.blocks.find((item) => item.id === this.selection.anchor.blockId) ?? null;
245
155
  }));
246
156
  __publicField(this, "_selectedText", computed(() => {
247
- if (this.isCollapsed)
248
- return "";
157
+ if (this.isCollapsed) return "";
249
158
  const [start, end, startIndex, endIndex] = this.startAndEnd;
250
159
  if (startIndex === endIndex) {
251
160
  return this.blocks[startIndex].text.slice(start.offset, end.offset);
@@ -258,17 +167,13 @@ class TextEditorStore {
258
167
  __publicField(this, "_currentStyles", computed(() => {
259
168
  const [start, end, startIndex, endIndex] = this.startAndEnd;
260
169
  const styles = /* @__PURE__ */ new Map();
261
- if (startIndex < 0)
262
- return styles;
170
+ if (startIndex < 0) return styles;
263
171
  for (let i = startIndex; i <= endIndex; i++) {
264
172
  const blockStyles = this.blocks[i].styles;
265
- if (!blockStyles)
266
- continue;
173
+ if (!blockStyles) continue;
267
174
  for (let style of blockStyles) {
268
- if (i === startIndex && start.offset < style.start)
269
- continue;
270
- if (i === endIndex && end.offset > style.end)
271
- continue;
175
+ if (i === startIndex && start.offset < style.start) continue;
176
+ if (i === endIndex && end.offset > style.end) continue;
272
177
  styles.set(style.style, style);
273
178
  }
274
179
  }
@@ -284,8 +189,7 @@ class TextEditorStore {
284
189
  *getCurrentBlocks() {
285
190
  const blockAnchorIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
286
191
  const focusAnchorIndex = this.blocks.findIndex((item) => item.id === this.selection.focus.blockId);
287
- if (blockAnchorIndex === -1 || focusAnchorIndex === -1)
288
- return;
192
+ if (blockAnchorIndex === -1 || focusAnchorIndex === -1) return;
289
193
  const start = Math.min(blockAnchorIndex, focusAnchorIndex);
290
194
  const end = Math.max(blockAnchorIndex, focusAnchorIndex);
291
195
  for (let i = start; i <= end; i++) {
@@ -297,8 +201,7 @@ class TextEditorStore {
297
201
  }
298
202
  moveOffset(newOffset) {
299
203
  const delta = newOffset - this.selection.anchor.offset;
300
- if (delta === 0)
301
- return;
204
+ if (delta === 0) return;
302
205
  this.moveStyles(this.currentBlock, this.selection.focus.offset, -delta);
303
206
  this.selection.anchor.offset = newOffset;
304
207
  this.selection.focus.offset = newOffset;
@@ -323,8 +226,7 @@ class TextEditorStore {
323
226
  }
324
227
  removeCurrentBlock() {
325
228
  const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
326
- if (blockIndex < 0)
327
- return;
229
+ if (blockIndex < 0) return;
328
230
  this.blocks.splice(blockIndex, 1);
329
231
  if (this.blocks.length === 0) {
330
232
  this.blocks.push({ id: uid(), text: "" });
@@ -338,8 +240,7 @@ class TextEditorStore {
338
240
  }
339
241
  removeNewLine() {
340
242
  const blockIndex = this.blocks.findIndex((item) => item.id === this.selection.anchor.blockId);
341
- if (blockIndex < 1)
342
- return;
243
+ if (blockIndex < 1) return;
343
244
  if (this.blocks[blockIndex - 1].editable === false) {
344
245
  if (this.blocks[blockIndex].text === "") {
345
246
  this.blocks.splice(blockIndex, 1);
@@ -359,15 +260,12 @@ class TextEditorStore {
359
260
  }
360
261
  onInput(_e) {
361
262
  const ev = _e;
362
- if (ev.defaultPrevented)
363
- return;
263
+ if (ev.defaultPrevented) return;
364
264
  ev.preventDefault();
365
265
  const collapsed = this.isCollapsed;
366
- if (!collapsed)
367
- this.deleteSelected();
266
+ if (!collapsed) this.deleteSelected();
368
267
  const block = this.currentBlock;
369
- if (!block)
370
- return;
268
+ if (!block) return;
371
269
  if ((ev.inputType === "deleteContentBackward" || ev.inputType === "deleteContentForward") && collapsed) {
372
270
  if (ev.inputType === "deleteContentBackward") {
373
271
  if (this.selection.anchor.offset === 0) {
@@ -416,8 +314,7 @@ class TextEditorStore {
416
314
  return;
417
315
  }
418
316
  this.deleteSelected();
419
- if (!this.currentBlock)
420
- return;
317
+ if (!this.currentBlock) return;
421
318
  const endText = this.currentBlock.editable === false ? "" : this.currentBlock.text.slice(this.selection.anchor.offset);
422
319
  this.currentBlock.text = this.currentBlock.text.slice(0, this.selection.anchor.offset);
423
320
  const block = { id: uid(), text: endText || "" };
@@ -435,15 +332,13 @@ class TextEditorStore {
435
332
  }
436
333
  insertText(data) {
437
334
  const block = this.currentBlock;
438
- if (!block)
439
- return;
335
+ if (!block) return;
440
336
  const text = data.replace(/\r/g, "");
441
337
  block.text = block.text.slice(0, this.selection.focus.offset) + text + block.text.slice(this.selection.focus.offset);
442
338
  this.moveOffset(clamp(this.selection.focus.offset + text.length, 0, block.text.length));
443
339
  }
444
340
  insertBlock(blockData) {
445
- if (!this.currentBlock)
446
- return;
341
+ if (!this.currentBlock) return;
447
342
  this.deleteSelected();
448
343
  if (this.currentBlock.text !== "") {
449
344
  this.addNewLine();
@@ -473,14 +368,11 @@ class TextEditorStore {
473
368
  }
474
369
  }
475
370
  moveStyles(block, offset, delta) {
476
- if (!block.styles)
477
- return;
371
+ if (!block.styles) return;
478
372
  for (let i = 0; i < block.styles.length; i++) {
479
373
  const style = block.styles[i];
480
- if (style.start >= offset)
481
- style.start -= delta;
482
- if (style.end >= offset)
483
- style.end -= delta;
374
+ if (style.start >= offset) style.start -= delta;
375
+ if (style.end >= offset) style.end -= delta;
484
376
  if (style.end <= style.start) {
485
377
  block.styles.splice(i, 1);
486
378
  i--;
@@ -488,8 +380,7 @@ class TextEditorStore {
488
380
  }
489
381
  }
490
382
  deleteSelected() {
491
- if (this.isCollapsed)
492
- return;
383
+ if (this.isCollapsed) return;
493
384
  const [start, end, startIndex, endIndex] = this.startAndEnd;
494
385
  const startText = this.blocks[startIndex].text.slice(0, start.offset);
495
386
  const endText = this.blocks[endIndex].text.slice(end.offset);
@@ -511,8 +402,7 @@ class TextEditorStore {
511
402
  return this._currentStyles.value;
512
403
  }
513
404
  applyStyle(_style, meta) {
514
- if (this.isCollapsed)
515
- return;
405
+ if (this.isCollapsed) return;
516
406
  const [start, end, startIndex, endIndex] = this.startAndEnd;
517
407
  for (let i = startIndex; i <= endIndex; i++) {
518
408
  const block = this.blocks[i];
@@ -521,13 +411,10 @@ class TextEditorStore {
521
411
  let createNewStyle = true;
522
412
  if (block.styles) {
523
413
  for (let style of block.styles) {
524
- if (style.style !== _style)
525
- continue;
526
- if (style.start > _end || style.end < _start)
527
- continue;
414
+ if (style.style !== _style) continue;
415
+ if (style.start > _end || style.end < _start) continue;
528
416
  if (meta && !isEqual(meta, style.meta) && (style.start !== _start || style.end !== _end)) {
529
- if (_start === style.end || _end === style.start)
530
- continue;
417
+ if (_start === style.end || _end === style.start) continue;
531
418
  this.removeStyleAt(block, _start, _end, _style);
532
419
  } else {
533
420
  style.start = Math.min(style.start, _start);
@@ -551,14 +438,11 @@ class TextEditorStore {
551
438
  }
552
439
  removeStyleAt(block, _start, _end, _style) {
553
440
  const removeAll = typeof _style !== "string";
554
- if (!block.styles)
555
- return;
441
+ if (!block.styles) return;
556
442
  for (let i = 0; i < block.styles.length; i++) {
557
443
  const style = block.styles[i];
558
- if (!removeAll && style.style !== _style)
559
- continue;
560
- if (style.start > _end || style.end < _start)
561
- continue;
444
+ if (!removeAll && style.style !== _style) continue;
445
+ if (style.start > _end || style.end < _start) continue;
562
446
  if (style.start >= _start && style.end <= _end) {
563
447
  block.styles.splice(i, 1);
564
448
  i--;
@@ -618,17 +502,14 @@ const _sfc_main$2 = defineComponent({
618
502
  emits: ["postrender"],
619
503
  setup(props, { emit }) {
620
504
  const slot = computed(() => {
621
- if (!props.block.type)
622
- return props.slots["default"] ?? null;
505
+ if (!props.block.type) return props.slots["default"] ?? null;
623
506
  return props.slots[props.block.type] ?? null;
624
507
  });
625
508
  const instance = getCurrentInstance();
626
509
  const getRef = () => {
627
- if (!instance)
628
- return null;
510
+ if (!instance) return null;
629
511
  const el = instance.vnode.el;
630
- if (!el)
631
- return null;
512
+ if (!el) return null;
632
513
  if (el.nodeType === Node.TEXT_NODE && el.nextSibling !== null) {
633
514
  return el.nextSibling;
634
515
  }
@@ -637,11 +518,9 @@ const _sfc_main$2 = defineComponent({
637
518
  const cacheNodes = [];
638
519
  let cacheEl = null;
639
520
  const cleanTree = (count) => {
640
- if (props.static === true)
641
- return;
521
+ if (props.static === true) return;
642
522
  const el = getRef();
643
- if (!el)
644
- return;
523
+ if (!el) return;
645
524
  if (el === cacheEl && cacheNodes.length > 0) {
646
525
  el.prepend(cacheNodes[0]);
647
526
  el.append(cacheNodes[1]);
@@ -653,12 +532,9 @@ const _sfc_main$2 = defineComponent({
653
532
  if (el.childNodes.length > count + 2) {
654
533
  for (let i = 0; i < el.childNodes.length; i++) {
655
534
  const child = el.childNodes[i];
656
- if (i === 0 && child.nodeType === Node.TEXT_NODE && child.textContent === "")
657
- continue;
658
- if ("__vnode" in child)
659
- continue;
660
- if (child.nodeType === Node.TEXT_NODE && ((_a = child.textContent) == null ? void 0 : _a.endsWith("\n")))
661
- continue;
535
+ if (i === 0 && child.nodeType === Node.TEXT_NODE && child.textContent === "") continue;
536
+ if ("__vnode" in child) continue;
537
+ if (child.nodeType === Node.TEXT_NODE && ((_a = child.textContent) == null ? void 0 : _a.endsWith("\n"))) continue;
662
538
  el.removeChild(child);
663
539
  break;
664
540
  }
@@ -673,8 +549,7 @@ const _sfc_main$2 = defineComponent({
673
549
  };
674
550
  const content = () => {
675
551
  const block = props.block;
676
- if (block.editable === false)
677
- return [];
552
+ if (block.editable === false) return [];
678
553
  if (block.text.length === 0) {
679
554
  cleanTree(1);
680
555
  return [h("br")];
@@ -686,16 +561,14 @@ const _sfc_main$2 = defineComponent({
686
561
  const markers = [];
687
562
  if (block.styles) {
688
563
  for (let style of block.styles) {
689
- if (style.end <= style.start)
690
- continue;
564
+ if (style.end <= style.start) continue;
691
565
  markers.push([style.start, style]);
692
566
  markers.push([style.end, style]);
693
567
  }
694
568
  }
695
569
  if (props.parser) {
696
570
  for (let style of props.parser(text)) {
697
- if (style.end <= style.start)
698
- continue;
571
+ if (style.end <= style.start) continue;
699
572
  markers.push([style.start, style]);
700
573
  markers.push([style.end, style]);
701
574
  }
@@ -725,14 +598,12 @@ const _sfc_main$2 = defineComponent({
725
598
  return blocks;
726
599
  };
727
600
  const renderBlockPart = (text, styles) => {
728
- if (!props.decorator)
729
- return text;
601
+ if (!props.decorator) return text;
730
602
  let elementTag = "span";
731
603
  const attrs = {};
732
604
  for (let style of styles) {
733
605
  const partProps = props.decorator(style);
734
- if (!partProps)
735
- continue;
606
+ if (!partProps) continue;
736
607
  const { class: _class, style: _style, tag, ...otherProps } = partProps;
737
608
  Object.assign(attrs, otherProps);
738
609
  if (_class) {
@@ -745,8 +616,7 @@ const _sfc_main$2 = defineComponent({
745
616
  elementTag = tag;
746
617
  }
747
618
  }
748
- if (Object.keys(attrs).length === 0 && elementTag === "span")
749
- return text;
619
+ if (Object.keys(attrs).length === 0 && elementTag === "span") return text;
750
620
  return h(elementTag, attrs, text);
751
621
  };
752
622
  return () => {
@@ -764,8 +634,7 @@ const _sfc_main$2 = defineComponent({
764
634
  }
765
635
  if (slot.value) {
766
636
  const component = slot.value({ content, props: blockProps, block: props.block });
767
- if (Array.isArray(component) && component.length === 1)
768
- return component[0];
637
+ if (Array.isArray(component) && component.length === 1) return component[0];
769
638
  return component;
770
639
  }
771
640
  return h(elementTag, blockProps, content());
@@ -800,15 +669,13 @@ const createClipboardEvents = (store, props) => {
800
669
  ];
801
670
  };
802
671
  const onCopy = (e) => {
803
- if (e.defaultPrevented)
804
- return;
672
+ if (e.defaultPrevented) return;
805
673
  e.preventDefault();
806
674
  navigator.clipboard.write(getSelected());
807
675
  store.history.push("setText");
808
676
  };
809
677
  const onCut = (e) => {
810
- if (e.defaultPrevented)
811
- return;
678
+ if (e.defaultPrevented) return;
812
679
  e.preventDefault();
813
680
  navigator.clipboard.write(getSelected());
814
681
  store.deleteSelected();
@@ -840,8 +707,7 @@ const createClipboardEvents = (store, props) => {
840
707
  }
841
708
  if (isTextNode) {
842
709
  const text = node.textContent;
843
- if (!text)
844
- return;
710
+ if (!text) return;
845
711
  insertText(text, type ?? ((_b = props.htmlParser) == null ? void 0 : _b.call(props, node)) ?? void 0);
846
712
  store.addNewLine();
847
713
  return;
@@ -849,7 +715,7 @@ const createClipboardEvents = (store, props) => {
849
715
  for (let child of node.children) {
850
716
  if (child.tagName === "DIV") {
851
717
  parseHtml(child, type);
852
- } else if (child.tagName === "UL") {
718
+ } else if (child.tagName === "UL" || child.tagName === "OL") {
853
719
  for (let li of child.children) {
854
720
  parseHtml(li, ((_c = props.htmlParser) == null ? void 0 : _c.call(props, li)) ?? void 0);
855
721
  }
@@ -862,8 +728,7 @@ const createClipboardEvents = (store, props) => {
862
728
  const parser = new DOMParser();
863
729
  const onPaste = (e) => {
864
730
  var _a, _b;
865
- if (e.defaultPrevented)
866
- return;
731
+ if (e.defaultPrevented) return;
867
732
  e.preventDefault();
868
733
  const html = (_a = e.clipboardData) == null ? void 0 : _a.getData("text/html");
869
734
  if (html) {
@@ -872,8 +737,7 @@ const createClipboardEvents = (store, props) => {
872
737
  parseHtml(dom.body);
873
738
  } else {
874
739
  const text = (_b = e.clipboardData) == null ? void 0 : _b.getData("text");
875
- if (!text)
876
- return;
740
+ if (!text) return;
877
741
  store.deleteSelected();
878
742
  insertText(text);
879
743
  }
@@ -908,10 +772,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
908
772
  const store = new TextEditorStore();
909
773
  let modelValue = "";
910
774
  watch(() => props.modelValue, (newValue) => {
911
- if (isProxy(newValue) && toRaw(newValue) === modelValue)
912
- return;
913
- if (newValue === void 0 || newValue === null || newValue === modelValue)
914
- return;
775
+ if (isProxy(newValue) && toRaw(newValue) === modelValue) return;
776
+ if (newValue === void 0 || newValue === null || newValue === modelValue) return;
915
777
  if (!Array.isArray(newValue)) {
916
778
  store.blocks[0].text = newValue;
917
779
  return;
@@ -921,17 +783,15 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
921
783
  }
922
784
  store.blocks.length = newValue.length;
923
785
  for (let i = 0; i < newValue.length; i++) {
924
- store.blocks[i] = { ...newValue[i], id: uid() };
786
+ store.blocks[i] = { ...newValue[i], id: newValue[i].id ?? uid() };
925
787
  }
926
788
  }
927
789
  }, { immediate: true });
928
790
  let styles;
929
791
  watch(() => props.styles, (newStyles) => {
930
- if (!newStyles || newStyles.length === 0 || newStyles === styles)
931
- return;
792
+ if (!newStyles || newStyles.length === 0 || newStyles === styles) return;
932
793
  for (let i = 0; i < store.blocks.length; i++) {
933
- if (newStyles.length <= i)
934
- break;
794
+ if (newStyles.length <= i) break;
935
795
  store.blocks[i].styles = newStyles;
936
796
  }
937
797
  }, { immediate: true });
@@ -948,8 +808,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
948
808
  }, { deep: true });
949
809
  const onKeyDown = (e) => {
950
810
  emit("keydown", e);
951
- if (e.defaultPrevented)
952
- return;
811
+ if (e.defaultPrevented) return;
953
812
  if (e.code === "Enter") {
954
813
  e.preventDefault();
955
814
  if (!props.preventMultiline && (e.shiftKey || props.single)) {
@@ -973,7 +832,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
973
832
  }
974
833
  };
975
834
  let cachedSelection = {};
976
- useEventListener(document, "selectionchange", () => {
835
+ const onSelectionChange = () => {
977
836
  const sel = window.getSelection();
978
837
  const anchor = findParent(sel.anchorNode, (el) => el.hasAttribute("data-vw-block-id") && el.parentElement === textEditorRef.value);
979
838
  if (anchor) {
@@ -993,11 +852,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
993
852
  if (anchor && focus) {
994
853
  cachedSelection = JSON.parse(JSON.stringify(store.selection));
995
854
  }
996
- });
855
+ };
856
+ onMounted(() => document.addEventListener("selectionchange", onSelectionChange));
857
+ onUnmounted(() => document.removeEventListener("selectionchange", onSelectionChange));
997
858
  let postRendered = false;
998
859
  const onPostRender = () => {
999
- if (postRendered)
1000
- return;
860
+ if (postRendered) return;
1001
861
  cachedSelection = {};
1002
862
  postRendered = true;
1003
863
  applySelection();
@@ -1019,8 +879,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1019
879
  cachedSelection = JSON.parse(JSON.stringify(store.selection));
1020
880
  return;
1021
881
  }
1022
- if (isEqual(store.selection, cachedSelection))
1023
- return;
882
+ if (isEqual(store.selection, cachedSelection)) return;
1024
883
  const anchor = getNode(store.selection.anchor.blockId);
1025
884
  const focus = getNode(store.selection.focus.blockId);
1026
885
  const nativeSelection = window.getSelection();
@@ -1172,5 +1031,6 @@ const _sfc_main = defineComponent({
1172
1031
  });
1173
1032
  export {
1174
1033
  _sfc_main$1 as TextEditor,
1175
- _sfc_main as TextEditorView
1034
+ _sfc_main as TextEditorView,
1035
+ uid
1176
1036
  };
package/package.json CHANGED
@@ -1,38 +1,42 @@
1
- {
2
- "name": "vuewrite",
3
- "description": "Rich Text Editor based on Vue3 reactivity",
4
- "private": false,
5
- "version": "0.0.25",
6
- "type": "module",
7
- "license": "MIT",
8
- "author": "den59k",
9
- "repository": {
10
- "type": "git",
11
- "url": "https://github.com/den59k/vuewrite.git"
12
- },
13
- "main": "dist/vuewrite.js",
14
- "types": "dist/vuewrite.d.ts",
15
- "scripts": {
16
- "dev": "vite",
17
- "build": "vue-tsc && vite build",
18
- "build:app": "vue-tsc && vite build -c vite-app.config.ts",
19
- "preview": "vite preview"
20
- },
21
- "dependencies": {
22
- "vue": "^3"
23
- },
24
- "devDependencies": {
25
- "@vitejs/plugin-vue": "^5.0.4",
26
- "@vueuse/core": "^10.10.0",
27
- "color2k": "^2.0.3",
28
- "sass": "^1.77.2",
29
- "typescript": "^5.2.2",
30
- "vite": "^5.2.0",
31
- "vite-plugin-dts": "^3.9.1",
32
- "vue-tsc": "^2.0.6",
33
- "vuesix": "^1.0.12"
34
- },
35
- "files": [
36
- "dist"
37
- ]
38
- }
1
+ {
2
+ "name": "vuewrite",
3
+ "description": "Rich Text Editor based on Vue3 reactivity",
4
+ "private": false,
5
+ "version": "0.0.27",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "author": "den59k",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/den59k/vuewrite.git"
12
+ },
13
+ "main": "dist/vuewrite.js",
14
+ "types": "dist/vuewrite.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/vuewrite.js",
18
+ "types": "./dist/vuewrite.d.ts"
19
+ },
20
+ "./markdown": {
21
+ "import": "./dist/markdown.js",
22
+ "types": "./dist/markdown.d.ts"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "build": "vue-tsc && vite build",
27
+ "dev": "vite build --watch"
28
+ },
29
+ "dependencies": {
30
+ "vue": "^3",
31
+ "vuewrite-markdown": "0.0.1"
32
+ },
33
+ "devDependencies": {
34
+ "@vitejs/plugin-vue": "^5.0.4",
35
+ "typescript": "^5.2.2",
36
+ "vite": "^5.2.0",
37
+ "vite-plugin-dts": "^3.9.1",
38
+ "vuesix": "^1.0.12",
39
+ "vue-tsc": "^2.0.6"
40
+ },
41
+ "files": ["dist"]
42
+ }
package/README.md DELETED
@@ -1,68 +0,0 @@
1
- # VueWrite
2
-
3
- VueWrite is another text editor that takes full advantage of Vue3's features.
4
- It contains no pre-made styles and blocks as its main goal is complete customization and extension
5
-
6
- ## Demo
7
-
8
- You can watch the demo [here](https://vuewrite.easix.ru)
9
-
10
- ## Quickstart
11
-
12
- ```vue
13
- <template>
14
- <TextEditor
15
- ref="textEditorRef"
16
- v-model="modelValue"
17
- single
18
- class="text-editor"
19
- :decorator="decorator"
20
- @keydown="onKeyDown"
21
- />
22
- </template>
23
-
24
- <script lang="ts">
25
- import { TextEditor, TextEditorRef } from 'vuewrite'
26
-
27
- const textEditorRef = shallowRef<TextEditorRef>()
28
- const modelValue = shallowRef("")
29
-
30
- const onKeyDown = (e: KeyboardEvent) => {
31
- if (!textEditorRef.value) return
32
- if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {
33
- if (e.code === "KeyB") {
34
- textEditorRef.value.toggleStyle("bold")
35
- }
36
- if (e.code === "KeyI") {
37
- textEditorRef.value.toggleStyle("italic")
38
- }
39
- if (e.code === "KeyU") {
40
- textEditorRef.value.toggleStyle("underline")
41
- }
42
- }
43
- }
44
-
45
- const decorator = (style: Style) => {
46
- if (style.style === 'bold' || style.style === "underline" || style.style === "italic") {
47
- return { class: style.style }
48
- }
49
- }
50
-
51
- </script>
52
-
53
- <style lang="css">
54
- .text-editor {
55
- white-space: pre-wrap;
56
- }
57
- .text-editor .bold {
58
- font-weight: 700
59
- }
60
- .text-editor .italic {
61
- font-style: italic
62
- }
63
- .text-editor .underline {
64
- text-decoration: underline
65
- }
66
- </style>
67
-
68
- ```