@coze-editor/preset-chat 0.1.0-alpha.687604 → 0.1.0-alpha.a96b6d

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/esm/index.js CHANGED
@@ -24,14 +24,14 @@ function extractElementData(node, text) {
24
24
  const valueNode = isNode == null ? void 0 : isNode.nextSibling;
25
25
  if ((nameNode == null ? void 0 : nameNode.name) === "AttributeName" && (isNode == null ? void 0 : isNode.name) === "Is" && ((valueNode == null ? void 0 : valueNode.name) === "AttributeValue" || (valueNode == null ? void 0 : valueNode.name) === "UnquotedAttributeValue")) {
26
26
  const name = text.slice(nameNode.from, nameNode.to);
27
- const value = text.slice(valueNode.from, valueNode.to);
27
+ const fullValue = text.slice(valueNode.from, valueNode.to);
28
+ let value = fullValue;
28
29
  if (valueNode.name === "AttributeValue") {
29
- attributes[name] = decodeURIComponent(value.slice(1, -1));
30
- } else {
31
- try {
32
- attributes[name] = JSON.parse(decodeURIComponent(value));
33
- } catch (e) {
34
- }
30
+ value = fullValue.slice(1, -1);
31
+ }
32
+ try {
33
+ attributes[name] = JSON.parse(decodeURIComponent(value));
34
+ } catch (e) {
35
35
  }
36
36
  } else if ((nameNode == null ? void 0 : nameNode.name) === "AttributeName" && !isNode && !valueNode) {
37
37
  const name = text.slice(nameNode.from, nameNode.to);
@@ -63,18 +63,31 @@ var htmlLanguage = LRLanguage.define({
63
63
  });
64
64
 
65
65
  // src/schema.ts
66
+ function isElementRegistered(tagName, validTagNames) {
67
+ if (!Array.isArray(validTagNames)) {
68
+ return false;
69
+ }
70
+ if (validTagNames.includes(tagName)) {
71
+ return true;
72
+ }
73
+ return false;
74
+ }
66
75
  var schemaUtils = {
67
- toJSON(text) {
76
+ toJSON(text, options) {
77
+ if (text === "") {
78
+ return [];
79
+ }
68
80
  const tree = parse(text);
69
81
  const tags = [];
70
82
  tree.iterate({
71
83
  enter(node) {
72
- if (node.name === "Element" && node.matchContext(["Document"])) {
84
+ if (node.name === "Element") {
73
85
  const data = extractElementData(node.node, text);
74
- if (data) {
86
+ if (data && isElementRegistered(data.tagName, options == null ? void 0 : options.validTagNames)) {
75
87
  tags.push({
76
88
  from: node.from,
77
89
  to: node.to,
90
+ raw: text.slice(node.from, node.to),
78
91
  ...data
79
92
  });
80
93
  }
@@ -84,7 +97,8 @@ var schemaUtils = {
84
97
  let pos = 0;
85
98
  const elements = [];
86
99
  for (const tag of tags) {
87
- const { from, to, tagName, attributes } = tag;
100
+ const { from, to, tagName, attributes, raw } = tag;
101
+ const { cmid, ...restAttributes } = attributes ?? {};
88
102
  if (from < pos) {
89
103
  continue;
90
104
  }
@@ -97,7 +111,8 @@ var schemaUtils = {
97
111
  elements.push({
98
112
  type: "element",
99
113
  tagName,
100
- attributes
114
+ attributes: restAttributes,
115
+ raw
101
116
  });
102
117
  pos = to;
103
118
  }
@@ -138,12 +153,14 @@ function attributesToString(attributes) {
138
153
  const value = attributes[key];
139
154
  if (value === true) {
140
155
  array.push(key);
141
- } else {
142
- array.push(`${key}=${JSON.stringify(encodeURIComponent(value))}`);
156
+ } else if (typeof value !== "undefined") {
157
+ array.push(`${key}="${encodeURIComponent(JSON.stringify(value))}"`);
143
158
  }
144
159
  });
145
160
  if (!hasId) {
146
- array.unshift(`${INTERNAL_ID}="${uniqueId()}"`);
161
+ array.unshift(
162
+ `${INTERNAL_ID}="${encodeURIComponent(JSON.stringify(uniqueId()))}"`
163
+ );
147
164
  }
148
165
  return array.join(" ");
149
166
  }
@@ -151,7 +168,7 @@ function attributesToString(attributes) {
151
168
  // src/plugins.ts
152
169
  import { api, extension, option } from "@coze-editor/core";
153
170
  import { EditorView as EditorView2 } from "@codemirror/view";
154
- import { EditorSelection, StateEffect, StateField as StateField2 } from "@codemirror/state";
171
+ import { EditorSelection as EditorSelection2, StateEffect, StateField as StateField2 } from "@codemirror/state";
155
172
 
156
173
  // src/extension.ts
157
174
  import { createPortal, flushSync } from "react-dom";
@@ -165,11 +182,12 @@ import {
165
182
  WidgetType
166
183
  } from "@codemirror/view";
167
184
  import {
185
+ EditorSelection,
168
186
  Facet,
169
187
  RangeSetBuilder,
170
188
  StateField
171
189
  } from "@codemirror/state";
172
- import { syntaxTree } from "@codemirror/language";
190
+ import { ensureSyntaxTree, syntaxTree } from "@codemirror/language";
173
191
 
174
192
  // src/context.tsx
175
193
  import React, { createContext, useContext } from "react";
@@ -251,24 +269,30 @@ var field = StateField.define({
251
269
  }
252
270
  });
253
271
  function build(state) {
254
- const tree = syntaxTree(state);
272
+ const allElements = state.facet(elementsFacet);
273
+ if (!allElements) {
274
+ return Decoration.none;
275
+ }
276
+ const tree = ensureSyntaxTree(state, state.doc.length) ?? syntaxTree(state);
255
277
  const builder = new RangeSetBuilder();
256
278
  tree.iterate({
257
279
  enter(node) {
258
280
  const data = extract(node.node, state);
259
281
  if (data) {
260
- const allElements = state.facet(elementsFacet);
261
282
  const definition = allElements[data.tagName];
262
- builder.add(
263
- node.from,
264
- node.to,
265
- Decoration.replace({
266
- widget: new ElementWidget(definition, data.internalId, data.props)
267
- })
268
- );
269
- }
270
- if (node.matchContext(["Document"])) {
271
- return false;
283
+ if (definition) {
284
+ builder.add(
285
+ node.from,
286
+ node.to,
287
+ Decoration.replace({
288
+ widget: new ElementWidget(
289
+ definition,
290
+ data.internalId,
291
+ data.props
292
+ )
293
+ })
294
+ );
295
+ }
272
296
  }
273
297
  return true;
274
298
  }
@@ -290,9 +314,95 @@ function extract(node, state) {
290
314
  }
291
315
  }
292
316
  }
317
+ var CUSTOM_CLIPBOARD_MIMETYPE = "application/x-with-elements";
318
+ var copyPasteHandler = EditorView.domEventHandlers({
319
+ paste(event, view) {
320
+ var _a;
321
+ try {
322
+ let text = (_a = event.clipboardData) == null ? void 0 : _a.getData(CUSTOM_CLIPBOARD_MIMETYPE);
323
+ if (!text) {
324
+ return false;
325
+ }
326
+ text = text.replace(/\r\n/g, "\n");
327
+ const definitions = view.state.facet(elementsFacet);
328
+ const nodes = schemaUtils.toJSON(text, {
329
+ validTagNames: definitions ? Object.keys(definitions) : void 0
330
+ });
331
+ const newText = schemaUtils.fromJSON(
332
+ nodes.map((node) => {
333
+ if (node.type === "text") {
334
+ return node;
335
+ }
336
+ if (node.type === "element") {
337
+ return {
338
+ ...node,
339
+ attributes: {
340
+ ...node.attributes ?? {},
341
+ cmid: `e${Math.random()}`
342
+ }
343
+ };
344
+ }
345
+ }).filter((v) => isEditorNode(v))
346
+ );
347
+ view.dispatch({
348
+ changes: {
349
+ from: view.state.selection.main.from,
350
+ to: view.state.selection.main.to,
351
+ insert: newText
352
+ },
353
+ selection: EditorSelection.cursor(
354
+ view.state.selection.main.from + newText.length
355
+ )
356
+ });
357
+ return true;
358
+ } catch (e) {
359
+ return false;
360
+ }
361
+ },
362
+ copy(event, view) {
363
+ var _a, _b;
364
+ const definitions = view.state.facet(elementsFacet);
365
+ if (!definitions) {
366
+ return false;
367
+ }
368
+ try {
369
+ const { from, to } = view.state.selection.main;
370
+ const slice = view.state.doc.sliceString(from, to);
371
+ const nodes = schemaUtils.toJSON(slice, {
372
+ validTagNames: definitions ? Object.keys(definitions) : void 0
373
+ });
374
+ const plainText = nodes.map((node) => {
375
+ if (node.type === "text") {
376
+ return node.value;
377
+ }
378
+ if (node.type === "element") {
379
+ const definition = definitions[node.tagName];
380
+ const toString = definition == null ? void 0 : definition.toString;
381
+ if (!definition) {
382
+ return node.raw ?? "";
383
+ }
384
+ if (Object.prototype.hasOwnProperty.call(definition, "toString") && typeof toString === "function") {
385
+ return toString(node);
386
+ }
387
+ return `[${node.tagName}]`;
388
+ }
389
+ return "";
390
+ }).join("");
391
+ (_a = event.clipboardData) == null ? void 0 : _a.setData("text/plain", plainText);
392
+ (_b = event.clipboardData) == null ? void 0 : _b.setData(CUSTOM_CLIPBOARD_MIMETYPE, slice);
393
+ return true;
394
+ } catch (e) {
395
+ return false;
396
+ }
397
+ }
398
+ });
399
+ function isEditorNode(v) {
400
+ return Boolean(v);
401
+ }
293
402
  function chatExtension() {
294
403
  return [
295
- field
404
+ field,
405
+ copyPasteHandler
296
406
  // selectionEnlarger.of(state => {
297
407
  // const decorations = state.field(field);
298
408
  // const cursor = decorations.iter();
@@ -333,7 +443,7 @@ function insertElement({ view }) {
333
443
  let selection = view.state.selection.main;
334
444
  const hasFocused = view.state.field(focusedField, false);
335
445
  if (hasFocused === false) {
336
- selection = EditorSelection.cursor(view.state.doc.length);
446
+ selection = EditorSelection2.cursor(view.state.doc.length);
337
447
  }
338
448
  const insert = toElementString(element);
339
449
  view.dispatch({
@@ -342,7 +452,7 @@ function insertElement({ view }) {
342
452
  to: selection.to,
343
453
  insert
344
454
  },
345
- selection: EditorSelection.cursor(selection.from + insert.length)
455
+ selection: EditorSelection2.cursor(selection.from + insert.length)
346
456
  });
347
457
  };
348
458
  }
@@ -373,7 +483,7 @@ import {
373
483
  useInjector
374
484
  } from "@coze-editor/react";
375
485
  import { ViewPlugin } from "@codemirror/view";
376
- import { EditorSelection as EditorSelection2 } from "@codemirror/state";
486
+ import { EditorSelection as EditorSelection3 } from "@codemirror/state";
377
487
  function useCurrentElement() {
378
488
  const editor = useEditor();
379
489
  const elementId = useElementId();
@@ -393,7 +503,7 @@ function useCurrentElement() {
393
503
  const { spec } = cursor.value;
394
504
  if (((_a = spec == null ? void 0 : spec.widget) == null ? void 0 : _a.id) === elementId) {
395
505
  view.dispatch({
396
- selection: EditorSelection2.range(cursor.from, cursor.to)
506
+ selection: EditorSelection3.range(cursor.from, cursor.to)
397
507
  });
398
508
  break;
399
509
  }
@@ -416,7 +526,7 @@ function useCurrentElement() {
416
526
  to: range.to,
417
527
  insert: ""
418
528
  },
419
- selection: EditorSelection2.cursor(range.from)
529
+ selection: EditorSelection3.cursor(range.from)
420
530
  });
421
531
  }
422
532
  }
@@ -489,6 +599,7 @@ var preset = [
489
599
  ];
490
600
  var index_default = preset;
491
601
  export {
602
+ CUSTOM_CLIPBOARD_MIMETYPE,
492
603
  index_default as default,
493
604
  schemaUtils,
494
605
  useCurrentElement
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/utils.ts","../../src/language.ts","../../src/schema.ts","../../src/plugins.ts","../../src/extension.ts","../../src/context.tsx","../../src/hooks.tsx"],"sourcesContent":["import universalPreset from '@coze-editor/preset-universal';\nimport { extension, type InferEditorAPIFromPlugins } from '@coze-editor/core';\nimport { EditorView, keymap } from '@codemirror/view';\nimport { defaultKeymap, historyKeymap, history } from '@codemirror/commands';\n\nimport {\n type EditorNode,\n type EditorElement,\n type EditorText,\n schemaUtils,\n} from './schema';\nimport plugins from './plugins';\nimport { htmlLanguage } from './language';\nimport { useCurrentElement } from './hooks';\n\nconst preset = [\n ...universalPreset,\n extension([\n EditorView.theme({\n '&.cm-focused': {\n outline: 'none',\n },\n }),\n htmlLanguage,\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n ]),\n ...plugins,\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { schemaUtils, useCurrentElement };\n\nexport type { EditorAPI, EditorNode, EditorElement, EditorText };\n","/* eslint-disable complexity */\n\nimport { type SyntaxNode } from '@lezer/common';\n\nfunction extractElementData(node: SyntaxNode, text: string) {\n const openTag = node.firstChild;\n\n let tagName: string | null = null;\n const attributes: Record<string, any> = {};\n\n if (openTag && openTag.name === 'OpenTag' && openTag.firstChild) {\n let sibling = openTag.firstChild.nextSibling;\n while (true) {\n if (!sibling) {\n break;\n }\n\n if (sibling.name === 'TagName') {\n const { from, to } = sibling;\n tagName = text.slice(from, to);\n } else if (sibling.name === 'Attribute') {\n const nameNode = sibling.firstChild;\n const isNode = nameNode?.nextSibling;\n const valueNode = isNode?.nextSibling;\n if (\n nameNode?.name === 'AttributeName' &&\n isNode?.name === 'Is' &&\n (valueNode?.name === 'AttributeValue' ||\n valueNode?.name === 'UnquotedAttributeValue')\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n const value = text.slice(valueNode.from, valueNode.to);\n\n if (valueNode.name === 'AttributeValue') {\n attributes[name] = decodeURIComponent(value.slice(1, -1));\n } else {\n try {\n attributes[name] = JSON.parse(decodeURIComponent(value));\n } catch (e) {\n /* empty */\n }\n }\n } else if (\n nameNode?.name === 'AttributeName' &&\n !isNode &&\n !valueNode\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n attributes[name] = true;\n }\n }\n\n sibling = sibling.nextSibling;\n }\n }\n\n if (tagName) {\n return {\n tagName,\n attributes,\n };\n }\n}\n\nexport { extractElementData };\n","import { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlParser = parser.configure({\n dialect: 'noMatch',\n});\n\nfunction parse(text: string) {\n return htmlParser.parse(text);\n}\n\nconst htmlLanguage = LRLanguage.define({\n parser: htmlParser,\n});\n\nexport { parse, htmlLanguage };\n","import { extractElementData } from './utils';\nimport { parse } from './language';\n\ninterface EditorElement<Attrs = Record<string, any>> {\n type: 'element';\n tagName: string;\n attributes: Attrs;\n}\n\ninterface EditorText {\n type: 'text';\n value: string;\n}\n\ntype EditorNode = EditorElement | EditorText;\n\nconst schemaUtils = {\n toJSON(text: string): EditorNode[] {\n const tree = parse(text);\n const tags: {\n from: number;\n to: number;\n tagName: string;\n attributes: Record<string, any>;\n }[] = [];\n tree.iterate({\n enter(node) {\n if (node.name === 'Element' && node.matchContext(['Document'])) {\n const data = extractElementData(node.node, text);\n if (data) {\n tags.push({\n from: node.from,\n to: node.to,\n ...data,\n });\n }\n }\n },\n });\n\n let pos = 0;\n const elements: EditorNode[] = [];\n for (const tag of tags) {\n const { from, to, tagName, attributes } = tag;\n\n // overlap, skip this element\n if (from < pos) {\n continue;\n }\n\n if (from > pos) {\n elements.push({\n type: 'text',\n value: text.slice(pos, from),\n });\n }\n\n elements.push({\n type: 'element',\n tagName,\n attributes,\n });\n\n pos = to;\n }\n\n if (pos < text.length) {\n elements.push({\n type: 'text',\n value: text.slice(pos),\n });\n }\n\n return elements;\n },\n fromJSON(elements: EditorNode[]): string {\n return elements\n .map(el => {\n if (el.type === 'element') {\n return toElementString(el);\n } else if (el.type === 'text') {\n return el.value;\n }\n return '';\n })\n .join('');\n },\n};\n\nfunction toElementString(element: Omit<EditorElement, 'type'>) {\n const attrsString = attributesToString(element.attributes);\n return `<${element.tagName}${attrsString ? ` ${attrsString}` : ''}></${element.tagName}>`;\n}\n\nconst INTERNAL_ID = 'cmid';\n\nfunction uniqueId() {\n return `e${Math.random()}`;\n}\n\nfunction attributesToString(attributes: EditorElement['attributes']) {\n const array: string[] = [];\n let hasId = false;\n\n Object.keys(attributes).forEach(key => {\n if (key === INTERNAL_ID) {\n hasId = true;\n }\n const value = attributes[key];\n if (value === true) {\n array.push(key);\n } else {\n array.push(`${key}=${JSON.stringify(encodeURIComponent(value))}`);\n }\n });\n\n if (!hasId) {\n array.unshift(`${INTERNAL_ID}=\"${uniqueId()}\"`);\n }\n\n return array.join(' ');\n}\n\nexport { schemaUtils, toElementString, INTERNAL_ID };\nexport type { EditorNode, EditorElement, EditorText };\n","import { api, extension, option } from '@coze-editor/core';\nimport { EditorView } from '@codemirror/view';\nimport { EditorSelection, StateEffect, StateField } from '@codemirror/state';\n\nimport { type EditorElement, toElementString } from './schema';\nimport {\n chatExtension,\n type ElementsDefinition,\n elementsFacet,\n} from './extension';\n\nconst focusedEffect = StateEffect.define();\n\nconst focusedField = StateField.define<boolean>({\n create() {\n return false;\n },\n update(value, tr) {\n for (const effect of tr.effects) {\n if (effect.is(focusedEffect)) {\n return true;\n }\n }\n\n return value;\n },\n});\n\nfunction insertElement({ view }: { view: EditorView }) {\n return (element: Omit<EditorElement, 'type'>) => {\n let selection = view.state.selection.main;\n\n const hasFocused = view.state.field(focusedField, false);\n if (hasFocused === false) {\n selection = EditorSelection.cursor(view.state.doc.length);\n }\n\n const insert = toElementString(element);\n view.dispatch({\n changes: {\n from: selection.from,\n to: selection.to,\n insert,\n },\n selection: EditorSelection.cursor(selection.from + insert.length),\n });\n };\n}\n\nconst plugins = [\n extension([\n focusedField,\n EditorView.domEventObservers({\n click(e, view) {\n view.dispatch({\n effects: focusedEffect.of(null),\n });\n },\n }),\n chatExtension(),\n ]),\n api('insertElement', insertElement),\n option('elements', (elements: ElementsDefinition) =>\n elementsFacet.of(elements),\n ),\n];\n\nexport default plugins;\n","import { createPortal, flushSync } from 'react-dom';\nimport { createElement, type ReactNode } from 'react';\n\nimport { createRoot, type Root } from 'react-dom/client';\nimport { type SyntaxNode } from '@lezer/common';\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport { connector } from '@coze-editor/react';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n WidgetType,\n} from '@codemirror/view';\nimport {\n type EditorState,\n Facet,\n RangeSetBuilder,\n StateField,\n} from '@codemirror/state';\nimport { syntaxTree } from '@codemirror/language';\n\nimport { extractElementData } from './utils';\nimport { INTERNAL_ID } from './schema';\nimport { ElementProvider } from './context';\n\ninterface ElementDefinition {\n render: (props: any) => ReactNode;\n}\n\ninterface ElementsDefinition {\n [key: string]: ElementDefinition;\n}\n\nclass ElementWidget extends WidgetType {\n public $$type = 'element';\n private root: Root;\n private element: HTMLElement;\n private view: EditorView | null = null;\n constructor(\n public definition: ElementDefinition,\n public id: string,\n public props: any,\n ) {\n super();\n\n const element = document.createElement('span');\n this.element = element;\n this.root = createRoot(element);\n }\n\n get elementId() {\n return `element-${this.id}`;\n }\n\n toDOM(view: EditorView) {\n this.view = view;\n\n const c = view.state.facet(connector);\n queueMicrotask(() => {\n flushSync(() => {\n const jsxElement = createElement(ElementProvider, {\n internalId: this.id,\n children: createElement(this.definition.render, this.props),\n });\n c.connect(this.elementId, createPortal(jsxElement, this.element));\n });\n });\n return this.element;\n }\n\n eq(other: ElementWidget) {\n return (\n this.id === other.id &&\n this.props &&\n other.props &&\n JSON.stringify(this.props) === JSON.stringify(other.props)\n );\n }\n\n destroy(): void {\n if (this.view) {\n const c = this.view.state.facet(connector);\n c.disconnect(this.elementId);\n }\n }\n\n ignoreEvent(event: Event): boolean {\n return false;\n }\n}\n\n// function isElementWidget(widget: WidgetType | null) {\n// return (widget as any)?.$$type === 'element';\n// }\n\nconst elementsFacet = Facet.define<ElementsDefinition, ElementsDefinition>({\n combine: FacetCombineStrategy.Last,\n});\n\nconst field = StateField.define({\n create(state) {\n return build(state);\n },\n update(value, tr) {\n if (tr.docChanged) {\n return build(tr.state);\n }\n return value;\n },\n provide(f) {\n return [\n EditorView.decorations.of(view => view.state.field(f)),\n EditorView.atomicRanges.of(view => view.state.field(f)),\n ];\n },\n});\n\nfunction build(state: EditorState): DecorationSet {\n const tree = syntaxTree(state);\n const builder = new RangeSetBuilder<Decoration>();\n tree.iterate({\n enter(node) {\n const data = extract(node.node, state);\n if (data) {\n const allElements = state.facet(elementsFacet);\n const definition = allElements[data.tagName];\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ElementWidget(definition, data.internalId, data.props),\n }),\n );\n }\n\n if (node.matchContext(['Document'])) {\n return false;\n }\n\n return true;\n },\n });\n\n const decorations = builder.finish();\n\n return decorations;\n}\n\nfunction extract(node: SyntaxNode, state: EditorState) {\n if (node.name === 'Element') {\n const elementData = extractElementData(node.node, state.doc.toString());\n\n if (elementData) {\n const { tagName, attributes } = elementData;\n const { [INTERNAL_ID]: internalId, ...props } = attributes ?? {};\n\n return {\n tagName,\n internalId,\n props,\n };\n }\n }\n}\n\nfunction chatExtension() {\n return [\n field,\n // selectionEnlarger.of(state => {\n // const decorations = state.field(field);\n // const cursor = decorations.iter();\n // const array = [];\n\n // while (cursor.value) {\n // const widget = cursor.value.spec?.widget;\n // const { from, to } = cursor;\n // if (isElementWidget(widget)) {\n // array.push({\n // source: { from, to },\n // target: { from, to },\n // });\n // }\n\n // cursor.next();\n // }\n\n // return array;\n // }),\n ];\n}\n\nexport { field, chatExtension, elementsFacet };\n\nexport type { ElementsDefinition };\n","import React, { createContext, type ReactNode, useContext } from 'react';\n\nconst Context = createContext('');\n\nfunction ElementProvider({\n internalId,\n children,\n}: {\n internalId: string;\n children: ReactNode;\n}) {\n return <Context.Provider value={internalId}>{children}</Context.Provider>;\n}\n\nfunction useElementId() {\n const id = useContext(Context);\n return id;\n}\n\nexport { ElementProvider, useElementId };\n","import { useLayoutEffect, useRef, useState } from 'react';\n\nimport {\n type BuiltinEditorAPI,\n useEditor,\n useInjector,\n} from '@coze-editor/react';\nimport { type EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\nimport { EditorSelection, type EditorState } from '@codemirror/state';\n\nimport { field } from './extension';\nimport { useElementId } from './context';\n\nfunction useCurrentElement() {\n const editor = useEditor<BuiltinEditorAPI | null>();\n const elementId = useElementId();\n const injector = useInjector();\n const [isSelected, setIsSelected] = useState(false);\n const elementIdRef = useRef(elementId);\n\n elementIdRef.current = elementId;\n\n function select() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n const decorations = view.state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n view.dispatch({\n selection: EditorSelection.range(cursor.from, cursor.to),\n });\n break;\n }\n cursor.next();\n }\n }\n\n function remove() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n if (view.state.readOnly) {\n return;\n }\n\n const range = findElement(view.state, elementId);\n if (range) {\n view.dispatch({\n changes: {\n from: range.from,\n to: range.to,\n insert: '',\n },\n selection: EditorSelection.cursor(range.from),\n });\n }\n }\n\n useLayoutEffect(() => {\n function selectionContainsCurrentElement(state: EditorState) {\n const range = findElement(state, elementId);\n const { ranges } = state.selection;\n if (!range) {\n return false;\n }\n\n for (const r of ranges) {\n if (r.from <= range.from && r.to >= range.to) {\n return true;\n }\n }\n\n return false;\n }\n\n const plugin = ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const contains = selectionContainsCurrentElement(view.state);\n setIsSelected(contains);\n }\n\n update(update: ViewUpdate) {\n if (update.selectionSet) {\n const contains = selectionContainsCurrentElement(update.state);\n setIsSelected(contains);\n }\n }\n },\n );\n\n return injector.inject([plugin]);\n }, [injector]);\n\n return {\n isSelected,\n select,\n remove,\n };\n}\n\nfunction findElement(state: EditorState, elementId: string) {\n const decorations = state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n return {\n from: cursor.from,\n to: cursor.to,\n };\n }\n cursor.next();\n }\n}\n\nexport { useCurrentElement };\n"],"mappings":"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","names":["extension","EditorView","EditorView","StateField","StateField","EditorView","EditorSelection","EditorSelection","extension","EditorView"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/utils.ts","../../src/language.ts","../../src/schema.ts","../../src/plugins.ts","../../src/extension.ts","../../src/context.tsx","../../src/hooks.tsx"],"sourcesContent":["import universalPreset from '@coze-editor/preset-universal';\nimport { extension, type InferEditorAPIFromPlugins } from '@coze-editor/core';\nimport { EditorView, keymap } from '@codemirror/view';\nimport { defaultKeymap, historyKeymap, history } from '@codemirror/commands';\n\nimport {\n type EditorNode,\n type EditorElement,\n type EditorText,\n schemaUtils,\n} from './schema';\nimport plugins from './plugins';\nimport { htmlLanguage } from './language';\nimport { useCurrentElement } from './hooks';\nimport { CUSTOM_CLIPBOARD_MIMETYPE, type ElementDefinition } from './extension';\n\nconst preset = [\n ...universalPreset,\n extension([\n EditorView.theme({\n '&.cm-focused': {\n outline: 'none',\n },\n }),\n htmlLanguage,\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n ]),\n ...plugins,\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { schemaUtils, useCurrentElement, CUSTOM_CLIPBOARD_MIMETYPE };\n\nexport type {\n EditorAPI,\n ElementDefinition,\n EditorNode,\n EditorElement,\n EditorText,\n};\n","/* eslint-disable complexity */\n\nimport { type SyntaxNode } from '@lezer/common';\n\nfunction extractElementData(node: SyntaxNode, text: string) {\n const openTag = node.firstChild;\n\n let tagName: string | null = null;\n const attributes: Record<string, any> = {};\n\n if (openTag && openTag.name === 'OpenTag' && openTag.firstChild) {\n let sibling = openTag.firstChild.nextSibling;\n while (true) {\n if (!sibling) {\n break;\n }\n\n if (sibling.name === 'TagName') {\n const { from, to } = sibling;\n tagName = text.slice(from, to);\n } else if (sibling.name === 'Attribute') {\n const nameNode = sibling.firstChild;\n const isNode = nameNode?.nextSibling;\n const valueNode = isNode?.nextSibling;\n if (\n nameNode?.name === 'AttributeName' &&\n isNode?.name === 'Is' &&\n (valueNode?.name === 'AttributeValue' ||\n valueNode?.name === 'UnquotedAttributeValue')\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n const fullValue = text.slice(valueNode.from, valueNode.to);\n\n let value = fullValue;\n if (valueNode.name === 'AttributeValue') {\n value = fullValue.slice(1, -1);\n }\n\n try {\n attributes[name] = JSON.parse(decodeURIComponent(value));\n } catch (e) {\n /* empty */\n }\n } else if (\n nameNode?.name === 'AttributeName' &&\n !isNode &&\n !valueNode\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n attributes[name] = true;\n }\n }\n\n sibling = sibling.nextSibling;\n }\n }\n\n if (tagName) {\n return {\n tagName,\n attributes,\n };\n }\n}\n\nexport { extractElementData };\n","import { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlParser = parser.configure({\n dialect: 'noMatch',\n});\n\nfunction parse(text: string) {\n return htmlParser.parse(text);\n}\n\nconst htmlLanguage = LRLanguage.define({\n parser: htmlParser,\n});\n\nexport { parse, htmlLanguage };\n","import { extractElementData } from './utils';\nimport { parse } from './language';\n\ninterface EditorElement<Attrs = Record<string, any>> {\n type: 'element';\n tagName: string;\n attributes: Attrs;\n raw?: string;\n}\n\ninterface EditorText {\n type: 'text';\n value: string;\n}\n\ntype EditorNode = EditorElement | EditorText;\n\nfunction isElementRegistered(\n tagName: string,\n validTagNames: string[] | undefined,\n) {\n if (!Array.isArray(validTagNames)) {\n return false;\n }\n\n if (validTagNames.includes(tagName)) {\n return true;\n }\n\n return false;\n}\n\nconst schemaUtils = {\n toJSON(text: string, options?: { validTagNames?: string[] }): EditorNode[] {\n if (text === '') {\n return [];\n }\n\n const tree = parse(text);\n const tags: {\n from: number;\n to: number;\n tagName: string;\n attributes: Record<string, any>;\n raw: string;\n }[] = [];\n tree.iterate({\n enter(node) {\n if (node.name === 'Element') {\n const data = extractElementData(node.node, text);\n if (\n data &&\n isElementRegistered(data.tagName, options?.validTagNames)\n ) {\n tags.push({\n from: node.from,\n to: node.to,\n raw: text.slice(node.from, node.to),\n ...data,\n });\n }\n }\n },\n });\n\n let pos = 0;\n const elements: EditorNode[] = [];\n for (const tag of tags) {\n const { from, to, tagName, attributes, raw } = tag;\n const { cmid, ...restAttributes } = attributes ?? {};\n\n // overlap, skip this element\n if (from < pos) {\n continue;\n }\n\n if (from > pos) {\n elements.push({\n type: 'text',\n value: text.slice(pos, from),\n });\n }\n\n elements.push({\n type: 'element',\n tagName,\n attributes: restAttributes,\n raw,\n });\n\n pos = to;\n }\n\n if (pos < text.length) {\n elements.push({\n type: 'text',\n value: text.slice(pos),\n });\n }\n\n return elements;\n },\n fromJSON(elements: EditorNode[]): string {\n return elements\n .map(el => {\n if (el.type === 'element') {\n return toElementString(el);\n } else if (el.type === 'text') {\n return el.value;\n }\n return '';\n })\n .join('');\n },\n};\n\nfunction toElementString(element: Omit<EditorElement, 'type'>) {\n const attrsString = attributesToString(element.attributes);\n return `<${element.tagName}${attrsString ? ` ${attrsString}` : ''}></${element.tagName}>`;\n}\n\nconst INTERNAL_ID = 'cmid';\n\nfunction uniqueId() {\n return `e${Math.random()}`;\n}\n\nfunction attributesToString(attributes: EditorElement['attributes']) {\n const array: string[] = [];\n let hasId = false;\n\n Object.keys(attributes).forEach(key => {\n if (key === INTERNAL_ID) {\n hasId = true;\n }\n const value = attributes[key];\n if (value === true) {\n array.push(key);\n } else if (typeof value !== 'undefined') {\n array.push(`${key}=\"${encodeURIComponent(JSON.stringify(value))}\"`);\n }\n });\n\n if (!hasId) {\n array.unshift(\n `${INTERNAL_ID}=\"${encodeURIComponent(JSON.stringify(uniqueId()))}\"`,\n );\n }\n\n return array.join(' ');\n}\n\nexport { schemaUtils, toElementString, INTERNAL_ID };\nexport type { EditorNode, EditorElement, EditorText };\n","import { api, extension, option } from '@coze-editor/core';\nimport { EditorView } from '@codemirror/view';\nimport { EditorSelection, StateEffect, StateField } from '@codemirror/state';\n\nimport { type EditorElement, toElementString } from './schema';\nimport {\n chatExtension,\n type ElementsDefinition,\n elementsFacet,\n} from './extension';\n\nconst focusedEffect = StateEffect.define();\n\nconst focusedField = StateField.define<boolean>({\n create() {\n return false;\n },\n update(value, tr) {\n for (const effect of tr.effects) {\n if (effect.is(focusedEffect)) {\n return true;\n }\n }\n\n return value;\n },\n});\n\nfunction insertElement({ view }: { view: EditorView }) {\n return (element: Omit<EditorElement, 'type'>) => {\n let selection = view.state.selection.main;\n\n const hasFocused = view.state.field(focusedField, false);\n if (hasFocused === false) {\n selection = EditorSelection.cursor(view.state.doc.length);\n }\n\n const insert = toElementString(element);\n view.dispatch({\n changes: {\n from: selection.from,\n to: selection.to,\n insert,\n },\n selection: EditorSelection.cursor(selection.from + insert.length),\n });\n };\n}\n\nconst plugins = [\n extension([\n focusedField,\n EditorView.domEventObservers({\n click(e, view) {\n view.dispatch({\n effects: focusedEffect.of(null),\n });\n },\n }),\n chatExtension(),\n ]),\n api('insertElement', insertElement),\n option('elements', (elements: ElementsDefinition) =>\n elementsFacet.of(elements),\n ),\n];\n\nexport default plugins;\n","import { createPortal, flushSync } from 'react-dom';\nimport { createElement, type ReactNode } from 'react';\n\nimport { createRoot, type Root } from 'react-dom/client';\nimport { type SyntaxNode } from '@lezer/common';\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport { connector } from '@coze-editor/react';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n WidgetType,\n} from '@codemirror/view';\nimport {\n EditorSelection,\n type EditorState,\n Facet,\n RangeSetBuilder,\n StateField,\n} from '@codemirror/state';\nimport { ensureSyntaxTree, syntaxTree } from '@codemirror/language';\n\nimport { extractElementData } from './utils';\nimport {\n type EditorElement,\n type EditorNode,\n INTERNAL_ID,\n schemaUtils,\n} from './schema';\nimport { ElementProvider } from './context';\n\ninterface ElementDefinition<Attrs = any> {\n render: (props: Attrs) => ReactNode;\n toString?: (element: EditorElement<Attrs>) => string;\n}\n\ninterface ElementsDefinition {\n [key: string]: ElementDefinition;\n}\n\nclass ElementWidget extends WidgetType {\n public $$type = 'element';\n private root: Root;\n private element: HTMLElement;\n private view: EditorView | null = null;\n constructor(\n public definition: ElementDefinition,\n public id: string,\n public props: any,\n ) {\n super();\n\n const element = document.createElement('span');\n this.element = element;\n this.root = createRoot(element);\n }\n\n get elementId() {\n return `element-${this.id}`;\n }\n\n toDOM(view: EditorView) {\n this.view = view;\n\n const c = view.state.facet(connector);\n queueMicrotask(() => {\n flushSync(() => {\n const jsxElement = createElement(ElementProvider, {\n internalId: this.id,\n children: createElement(this.definition.render, this.props),\n });\n c.connect(this.elementId, createPortal(jsxElement, this.element));\n });\n });\n return this.element;\n }\n\n eq(other: ElementWidget) {\n return (\n this.id === other.id &&\n this.props &&\n other.props &&\n JSON.stringify(this.props) === JSON.stringify(other.props)\n );\n }\n\n destroy(): void {\n if (this.view) {\n const c = this.view.state.facet(connector);\n c.disconnect(this.elementId);\n }\n }\n\n ignoreEvent(event: Event): boolean {\n return false;\n }\n}\n\n// function isElementWidget(widget: WidgetType | null) {\n// return (widget as any)?.$$type === 'element';\n// }\n\nconst elementsFacet = Facet.define<\n ElementsDefinition | undefined,\n ElementsDefinition | undefined\n>({\n combine: FacetCombineStrategy.Last,\n});\n\nconst field = StateField.define({\n create(state) {\n return build(state);\n },\n update(value, tr) {\n if (tr.docChanged) {\n return build(tr.state);\n }\n return value;\n },\n provide(f) {\n return [\n EditorView.decorations.of(view => view.state.field(f)),\n EditorView.atomicRanges.of(view => view.state.field(f)),\n ];\n },\n});\n\nfunction build(state: EditorState): DecorationSet {\n const allElements = state.facet(elementsFacet);\n\n if (!allElements) {\n return Decoration.none;\n }\n\n const tree = ensureSyntaxTree(state, state.doc.length) ?? syntaxTree(state);\n const builder = new RangeSetBuilder<Decoration>();\n tree.iterate({\n enter(node) {\n const data = extract(node.node, state);\n if (data) {\n const definition = allElements[data.tagName];\n if (definition) {\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ElementWidget(\n definition,\n data.internalId,\n data.props,\n ),\n }),\n );\n }\n }\n\n // if (node.matchContext(['Document'])) {\n // return false;\n // }\n\n return true;\n },\n });\n\n const decorations = builder.finish();\n\n return decorations;\n}\n\nfunction extract(node: SyntaxNode, state: EditorState) {\n if (node.name === 'Element') {\n const elementData = extractElementData(node.node, state.doc.toString());\n\n if (elementData) {\n const { tagName, attributes } = elementData;\n const { [INTERNAL_ID]: internalId, ...props } = attributes ?? {};\n\n return {\n tagName,\n internalId,\n props,\n };\n }\n }\n}\n\nconst CUSTOM_CLIPBOARD_MIMETYPE = 'application/x-with-elements';\n\nconst copyPasteHandler = EditorView.domEventHandlers({\n paste(event, view) {\n try {\n let text = event.clipboardData?.getData(CUSTOM_CLIPBOARD_MIMETYPE);\n\n if (!text) {\n return false;\n }\n\n // normalize \\r\\n to \\n for Windows (if user copies rich text)\n text = text.replace(/\\r\\n/g, '\\n');\n\n const definitions = view.state.facet(elementsFacet);\n\n const nodes = schemaUtils.toJSON(text, {\n validTagNames: definitions ? Object.keys(definitions) : undefined,\n });\n const newText = schemaUtils.fromJSON(\n nodes\n .map(node => {\n if (node.type === 'text') {\n return node;\n }\n\n if (node.type === 'element') {\n return {\n ...node,\n attributes: {\n ...(node.attributes ?? {}),\n cmid: `e${Math.random()}`,\n },\n } satisfies EditorElement;\n }\n })\n .filter(v => isEditorNode(v)),\n );\n\n view.dispatch({\n changes: {\n from: view.state.selection.main.from,\n to: view.state.selection.main.to,\n insert: newText,\n },\n selection: EditorSelection.cursor(\n view.state.selection.main.from + newText.length,\n ),\n });\n return true;\n } catch (e) {\n return false;\n }\n },\n copy(event, view) {\n const definitions = view.state.facet(elementsFacet);\n\n if (!definitions) {\n return false;\n }\n\n try {\n const { from, to } = view.state.selection.main;\n const slice = view.state.doc.sliceString(from, to);\n const nodes = schemaUtils.toJSON(slice, {\n validTagNames: definitions ? Object.keys(definitions) : undefined,\n });\n\n const plainText = nodes\n .map(node => {\n if (node.type === 'text') {\n return node.value;\n }\n\n if (node.type === 'element') {\n const definition = definitions[node.tagName];\n const toString = definition?.toString;\n\n if (!definition) {\n return node.raw ?? '';\n }\n\n if (\n Object.prototype.hasOwnProperty.call(definition, 'toString') &&\n typeof toString === 'function'\n ) {\n return toString(node);\n }\n\n return `[${node.tagName}]`;\n }\n\n return '';\n })\n .join('');\n\n event.clipboardData?.setData('text/plain', plainText);\n event.clipboardData?.setData(CUSTOM_CLIPBOARD_MIMETYPE, slice);\n\n return true;\n } catch (e) {\n return false;\n }\n },\n});\n\nfunction isEditorNode(v: unknown): v is EditorNode {\n return Boolean(v);\n}\n\nfunction chatExtension() {\n return [\n field,\n copyPasteHandler,\n // selectionEnlarger.of(state => {\n // const decorations = state.field(field);\n // const cursor = decorations.iter();\n // const array = [];\n\n // while (cursor.value) {\n // const widget = cursor.value.spec?.widget;\n // const { from, to } = cursor;\n // if (isElementWidget(widget)) {\n // array.push({\n // source: { from, to },\n // target: { from, to },\n // });\n // }\n\n // cursor.next();\n // }\n\n // return array;\n // }),\n ];\n}\n\nexport { field, chatExtension, elementsFacet, CUSTOM_CLIPBOARD_MIMETYPE };\n\nexport type { ElementsDefinition, ElementDefinition };\n","import React, { createContext, type ReactNode, useContext } from 'react';\n\nconst Context = createContext('');\n\nfunction ElementProvider({\n internalId,\n children,\n}: {\n internalId: string;\n children: ReactNode;\n}) {\n return <Context.Provider value={internalId}>{children}</Context.Provider>;\n}\n\nfunction useElementId() {\n const id = useContext(Context);\n return id;\n}\n\nexport { ElementProvider, useElementId };\n","import { useLayoutEffect, useRef, useState } from 'react';\n\nimport {\n type BuiltinEditorAPI,\n useEditor,\n useInjector,\n} from '@coze-editor/react';\nimport { type EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\nimport { EditorSelection, type EditorState } from '@codemirror/state';\n\nimport { field } from './extension';\nimport { useElementId } from './context';\n\nfunction useCurrentElement() {\n const editor = useEditor<BuiltinEditorAPI | null>();\n const elementId = useElementId();\n const injector = useInjector();\n const [isSelected, setIsSelected] = useState(false);\n const elementIdRef = useRef(elementId);\n\n elementIdRef.current = elementId;\n\n function select() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n const decorations = view.state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n view.dispatch({\n selection: EditorSelection.range(cursor.from, cursor.to),\n });\n break;\n }\n cursor.next();\n }\n }\n\n function remove() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n if (view.state.readOnly) {\n return;\n }\n\n const range = findElement(view.state, elementId);\n if (range) {\n view.dispatch({\n changes: {\n from: range.from,\n to: range.to,\n insert: '',\n },\n selection: EditorSelection.cursor(range.from),\n });\n }\n }\n\n useLayoutEffect(() => {\n function selectionContainsCurrentElement(state: EditorState) {\n const range = findElement(state, elementId);\n const { ranges } = state.selection;\n if (!range) {\n return false;\n }\n\n for (const r of ranges) {\n if (r.from <= range.from && r.to >= range.to) {\n return true;\n }\n }\n\n return false;\n }\n\n const plugin = ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const contains = selectionContainsCurrentElement(view.state);\n setIsSelected(contains);\n }\n\n update(update: ViewUpdate) {\n if (update.selectionSet) {\n const contains = selectionContainsCurrentElement(update.state);\n setIsSelected(contains);\n }\n }\n },\n );\n\n return injector.inject([plugin]);\n }, [injector]);\n\n return {\n isSelected,\n select,\n remove,\n };\n}\n\nfunction findElement(state: EditorState, elementId: string) {\n const decorations = state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n return {\n from: cursor.from,\n to: cursor.to,\n };\n }\n cursor.next();\n }\n}\n\nexport { useCurrentElement };\n"],"mappings":"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","names":["extension","EditorView","EditorView","EditorSelection","StateField","StateField","EditorSelection","EditorView","EditorSelection","EditorSelection","extension","EditorView"]}
package/dist/index.d.mts CHANGED
@@ -4,17 +4,11 @@ import * as _codemirror_state from '@codemirror/state';
4
4
  import * as _coze_editor_core from '@coze-editor/core';
5
5
  import { InferEditorAPIFromPlugins } from '@coze-editor/core';
6
6
 
7
- interface ElementDefinition {
8
- render: (props: any) => ReactNode;
9
- }
10
- interface ElementsDefinition {
11
- [key: string]: ElementDefinition;
12
- }
13
-
14
7
  interface EditorElement<Attrs = Record<string, any>> {
15
8
  type: 'element';
16
9
  tagName: string;
17
10
  attributes: Attrs;
11
+ raw?: string;
18
12
  }
19
13
  interface EditorText {
20
14
  type: 'text';
@@ -22,10 +16,21 @@ interface EditorText {
22
16
  }
23
17
  type EditorNode = EditorElement | EditorText;
24
18
  declare const schemaUtils: {
25
- toJSON(text: string): EditorNode[];
19
+ toJSON(text: string, options?: {
20
+ validTagNames?: string[];
21
+ }): EditorNode[];
26
22
  fromJSON(elements: EditorNode[]): string;
27
23
  };
28
24
 
25
+ interface ElementDefinition<Attrs = any> {
26
+ render: (props: Attrs) => ReactNode;
27
+ toString?: (element: EditorElement<Attrs>) => string;
28
+ }
29
+ interface ElementsDefinition {
30
+ [key: string]: ElementDefinition;
31
+ }
32
+ declare const CUSTOM_CLIPBOARD_MIMETYPE = "application/x-with-elements";
33
+
29
34
  declare function useCurrentElement(): {
30
35
  isSelected: boolean;
31
36
  select: () => void;
@@ -57,4 +62,4 @@ declare const preset: (_coze_editor_core.ExtensionPluginSpec | _coze_editor_core
57
62
  }> | _coze_editor_core.EventPluginSpec<"focus", symbol> | _coze_editor_core.EventPluginSpec<"blur", symbol> | _coze_editor_core.DOMEventHandlerPluginSpec<"mousedown"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mouseup"> | _coze_editor_core.APIPluginSpec<"insertElement", [element: Omit<EditorElement<Record<string, any>>, "type">], void> | _coze_editor_core.OptionPluginSpec<"elements", ElementsDefinition>)[];
58
63
  type EditorAPI = InferEditorAPIFromPlugins<typeof preset>;
59
64
 
60
- export { type EditorAPI, type EditorElement, type EditorNode, type EditorText, preset as default, schemaUtils, useCurrentElement };
65
+ export { CUSTOM_CLIPBOARD_MIMETYPE, type EditorAPI, type EditorElement, type EditorNode, type EditorText, type ElementDefinition, preset as default, schemaUtils, useCurrentElement };
package/dist/index.d.ts CHANGED
@@ -4,17 +4,11 @@ import * as _codemirror_state from '@codemirror/state';
4
4
  import * as _coze_editor_core from '@coze-editor/core';
5
5
  import { InferEditorAPIFromPlugins } from '@coze-editor/core';
6
6
 
7
- interface ElementDefinition {
8
- render: (props: any) => ReactNode;
9
- }
10
- interface ElementsDefinition {
11
- [key: string]: ElementDefinition;
12
- }
13
-
14
7
  interface EditorElement<Attrs = Record<string, any>> {
15
8
  type: 'element';
16
9
  tagName: string;
17
10
  attributes: Attrs;
11
+ raw?: string;
18
12
  }
19
13
  interface EditorText {
20
14
  type: 'text';
@@ -22,10 +16,21 @@ interface EditorText {
22
16
  }
23
17
  type EditorNode = EditorElement | EditorText;
24
18
  declare const schemaUtils: {
25
- toJSON(text: string): EditorNode[];
19
+ toJSON(text: string, options?: {
20
+ validTagNames?: string[];
21
+ }): EditorNode[];
26
22
  fromJSON(elements: EditorNode[]): string;
27
23
  };
28
24
 
25
+ interface ElementDefinition<Attrs = any> {
26
+ render: (props: Attrs) => ReactNode;
27
+ toString?: (element: EditorElement<Attrs>) => string;
28
+ }
29
+ interface ElementsDefinition {
30
+ [key: string]: ElementDefinition;
31
+ }
32
+ declare const CUSTOM_CLIPBOARD_MIMETYPE = "application/x-with-elements";
33
+
29
34
  declare function useCurrentElement(): {
30
35
  isSelected: boolean;
31
36
  select: () => void;
@@ -57,4 +62,4 @@ declare const preset: (_coze_editor_core.ExtensionPluginSpec | _coze_editor_core
57
62
  }> | _coze_editor_core.EventPluginSpec<"focus", symbol> | _coze_editor_core.EventPluginSpec<"blur", symbol> | _coze_editor_core.DOMEventHandlerPluginSpec<"mousedown"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mouseup"> | _coze_editor_core.APIPluginSpec<"insertElement", [element: Omit<EditorElement<Record<string, any>>, "type">], void> | _coze_editor_core.OptionPluginSpec<"elements", ElementsDefinition>)[];
58
63
  type EditorAPI = InferEditorAPIFromPlugins<typeof preset>;
59
64
 
60
- export { type EditorAPI, type EditorElement, type EditorNode, type EditorText, preset as default, schemaUtils, useCurrentElement };
65
+ export { CUSTOM_CLIPBOARD_MIMETYPE, type EditorAPI, type EditorElement, type EditorNode, type EditorText, type ElementDefinition, preset as default, schemaUtils, useCurrentElement };
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.ts
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
+ CUSTOM_CLIPBOARD_MIMETYPE: () => CUSTOM_CLIPBOARD_MIMETYPE,
32
33
  default: () => index_default,
33
34
  schemaUtils: () => schemaUtils,
34
35
  useCurrentElement: () => useCurrentElement
@@ -59,14 +60,14 @@ function extractElementData(node, text) {
59
60
  const valueNode = isNode == null ? void 0 : isNode.nextSibling;
60
61
  if ((nameNode == null ? void 0 : nameNode.name) === "AttributeName" && (isNode == null ? void 0 : isNode.name) === "Is" && ((valueNode == null ? void 0 : valueNode.name) === "AttributeValue" || (valueNode == null ? void 0 : valueNode.name) === "UnquotedAttributeValue")) {
61
62
  const name = text.slice(nameNode.from, nameNode.to);
62
- const value = text.slice(valueNode.from, valueNode.to);
63
+ const fullValue = text.slice(valueNode.from, valueNode.to);
64
+ let value = fullValue;
63
65
  if (valueNode.name === "AttributeValue") {
64
- attributes[name] = decodeURIComponent(value.slice(1, -1));
65
- } else {
66
- try {
67
- attributes[name] = JSON.parse(decodeURIComponent(value));
68
- } catch (e) {
69
- }
66
+ value = fullValue.slice(1, -1);
67
+ }
68
+ try {
69
+ attributes[name] = JSON.parse(decodeURIComponent(value));
70
+ } catch (e) {
70
71
  }
71
72
  } else if ((nameNode == null ? void 0 : nameNode.name) === "AttributeName" && !isNode && !valueNode) {
72
73
  const name = text.slice(nameNode.from, nameNode.to);
@@ -98,18 +99,31 @@ var htmlLanguage = import_language.LRLanguage.define({
98
99
  });
99
100
 
100
101
  // src/schema.ts
102
+ function isElementRegistered(tagName, validTagNames) {
103
+ if (!Array.isArray(validTagNames)) {
104
+ return false;
105
+ }
106
+ if (validTagNames.includes(tagName)) {
107
+ return true;
108
+ }
109
+ return false;
110
+ }
101
111
  var schemaUtils = {
102
- toJSON(text) {
112
+ toJSON(text, options) {
113
+ if (text === "") {
114
+ return [];
115
+ }
103
116
  const tree = parse(text);
104
117
  const tags = [];
105
118
  tree.iterate({
106
119
  enter(node) {
107
- if (node.name === "Element" && node.matchContext(["Document"])) {
120
+ if (node.name === "Element") {
108
121
  const data = extractElementData(node.node, text);
109
- if (data) {
122
+ if (data && isElementRegistered(data.tagName, options == null ? void 0 : options.validTagNames)) {
110
123
  tags.push({
111
124
  from: node.from,
112
125
  to: node.to,
126
+ raw: text.slice(node.from, node.to),
113
127
  ...data
114
128
  });
115
129
  }
@@ -119,7 +133,8 @@ var schemaUtils = {
119
133
  let pos = 0;
120
134
  const elements = [];
121
135
  for (const tag of tags) {
122
- const { from, to, tagName, attributes } = tag;
136
+ const { from, to, tagName, attributes, raw } = tag;
137
+ const { cmid, ...restAttributes } = attributes ?? {};
123
138
  if (from < pos) {
124
139
  continue;
125
140
  }
@@ -132,7 +147,8 @@ var schemaUtils = {
132
147
  elements.push({
133
148
  type: "element",
134
149
  tagName,
135
- attributes
150
+ attributes: restAttributes,
151
+ raw
136
152
  });
137
153
  pos = to;
138
154
  }
@@ -173,12 +189,14 @@ function attributesToString(attributes) {
173
189
  const value = attributes[key];
174
190
  if (value === true) {
175
191
  array.push(key);
176
- } else {
177
- array.push(`${key}=${JSON.stringify(encodeURIComponent(value))}`);
192
+ } else if (typeof value !== "undefined") {
193
+ array.push(`${key}="${encodeURIComponent(JSON.stringify(value))}"`);
178
194
  }
179
195
  });
180
196
  if (!hasId) {
181
- array.unshift(`${INTERNAL_ID}="${uniqueId()}"`);
197
+ array.unshift(
198
+ `${INTERNAL_ID}="${encodeURIComponent(JSON.stringify(uniqueId()))}"`
199
+ );
182
200
  }
183
201
  return array.join(" ");
184
202
  }
@@ -278,24 +296,30 @@ var field = import_state.StateField.define({
278
296
  }
279
297
  });
280
298
  function build(state) {
281
- const tree = (0, import_language3.syntaxTree)(state);
299
+ const allElements = state.facet(elementsFacet);
300
+ if (!allElements) {
301
+ return import_view.Decoration.none;
302
+ }
303
+ const tree = (0, import_language3.ensureSyntaxTree)(state, state.doc.length) ?? (0, import_language3.syntaxTree)(state);
282
304
  const builder = new import_state.RangeSetBuilder();
283
305
  tree.iterate({
284
306
  enter(node) {
285
307
  const data = extract(node.node, state);
286
308
  if (data) {
287
- const allElements = state.facet(elementsFacet);
288
309
  const definition = allElements[data.tagName];
289
- builder.add(
290
- node.from,
291
- node.to,
292
- import_view.Decoration.replace({
293
- widget: new ElementWidget(definition, data.internalId, data.props)
294
- })
295
- );
296
- }
297
- if (node.matchContext(["Document"])) {
298
- return false;
310
+ if (definition) {
311
+ builder.add(
312
+ node.from,
313
+ node.to,
314
+ import_view.Decoration.replace({
315
+ widget: new ElementWidget(
316
+ definition,
317
+ data.internalId,
318
+ data.props
319
+ )
320
+ })
321
+ );
322
+ }
299
323
  }
300
324
  return true;
301
325
  }
@@ -317,9 +341,95 @@ function extract(node, state) {
317
341
  }
318
342
  }
319
343
  }
344
+ var CUSTOM_CLIPBOARD_MIMETYPE = "application/x-with-elements";
345
+ var copyPasteHandler = import_view.EditorView.domEventHandlers({
346
+ paste(event, view) {
347
+ var _a;
348
+ try {
349
+ let text = (_a = event.clipboardData) == null ? void 0 : _a.getData(CUSTOM_CLIPBOARD_MIMETYPE);
350
+ if (!text) {
351
+ return false;
352
+ }
353
+ text = text.replace(/\r\n/g, "\n");
354
+ const definitions = view.state.facet(elementsFacet);
355
+ const nodes = schemaUtils.toJSON(text, {
356
+ validTagNames: definitions ? Object.keys(definitions) : void 0
357
+ });
358
+ const newText = schemaUtils.fromJSON(
359
+ nodes.map((node) => {
360
+ if (node.type === "text") {
361
+ return node;
362
+ }
363
+ if (node.type === "element") {
364
+ return {
365
+ ...node,
366
+ attributes: {
367
+ ...node.attributes ?? {},
368
+ cmid: `e${Math.random()}`
369
+ }
370
+ };
371
+ }
372
+ }).filter((v) => isEditorNode(v))
373
+ );
374
+ view.dispatch({
375
+ changes: {
376
+ from: view.state.selection.main.from,
377
+ to: view.state.selection.main.to,
378
+ insert: newText
379
+ },
380
+ selection: import_state.EditorSelection.cursor(
381
+ view.state.selection.main.from + newText.length
382
+ )
383
+ });
384
+ return true;
385
+ } catch (e) {
386
+ return false;
387
+ }
388
+ },
389
+ copy(event, view) {
390
+ var _a, _b;
391
+ const definitions = view.state.facet(elementsFacet);
392
+ if (!definitions) {
393
+ return false;
394
+ }
395
+ try {
396
+ const { from, to } = view.state.selection.main;
397
+ const slice = view.state.doc.sliceString(from, to);
398
+ const nodes = schemaUtils.toJSON(slice, {
399
+ validTagNames: definitions ? Object.keys(definitions) : void 0
400
+ });
401
+ const plainText = nodes.map((node) => {
402
+ if (node.type === "text") {
403
+ return node.value;
404
+ }
405
+ if (node.type === "element") {
406
+ const definition = definitions[node.tagName];
407
+ const toString = definition == null ? void 0 : definition.toString;
408
+ if (!definition) {
409
+ return node.raw ?? "";
410
+ }
411
+ if (Object.prototype.hasOwnProperty.call(definition, "toString") && typeof toString === "function") {
412
+ return toString(node);
413
+ }
414
+ return `[${node.tagName}]`;
415
+ }
416
+ return "";
417
+ }).join("");
418
+ (_a = event.clipboardData) == null ? void 0 : _a.setData("text/plain", plainText);
419
+ (_b = event.clipboardData) == null ? void 0 : _b.setData(CUSTOM_CLIPBOARD_MIMETYPE, slice);
420
+ return true;
421
+ } catch (e) {
422
+ return false;
423
+ }
424
+ }
425
+ });
426
+ function isEditorNode(v) {
427
+ return Boolean(v);
428
+ }
320
429
  function chatExtension() {
321
430
  return [
322
- field
431
+ field,
432
+ copyPasteHandler
323
433
  // selectionEnlarger.of(state => {
324
434
  // const decorations = state.field(field);
325
435
  // const cursor = decorations.iter();
@@ -514,6 +624,7 @@ var preset = [
514
624
  var index_default = preset;
515
625
  // Annotate the CommonJS export names for ESM import in node:
516
626
  0 && (module.exports = {
627
+ CUSTOM_CLIPBOARD_MIMETYPE,
517
628
  schemaUtils,
518
629
  useCurrentElement
519
630
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/language.ts","../src/schema.ts","../src/plugins.ts","../src/extension.ts","../src/context.tsx","../src/hooks.tsx"],"sourcesContent":["import universalPreset from '@coze-editor/preset-universal';\nimport { extension, type InferEditorAPIFromPlugins } from '@coze-editor/core';\nimport { EditorView, keymap } from '@codemirror/view';\nimport { defaultKeymap, historyKeymap, history } from '@codemirror/commands';\n\nimport {\n type EditorNode,\n type EditorElement,\n type EditorText,\n schemaUtils,\n} from './schema';\nimport plugins from './plugins';\nimport { htmlLanguage } from './language';\nimport { useCurrentElement } from './hooks';\n\nconst preset = [\n ...universalPreset,\n extension([\n EditorView.theme({\n '&.cm-focused': {\n outline: 'none',\n },\n }),\n htmlLanguage,\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n ]),\n ...plugins,\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { schemaUtils, useCurrentElement };\n\nexport type { EditorAPI, EditorNode, EditorElement, EditorText };\n","/* eslint-disable complexity */\n\nimport { type SyntaxNode } from '@lezer/common';\n\nfunction extractElementData(node: SyntaxNode, text: string) {\n const openTag = node.firstChild;\n\n let tagName: string | null = null;\n const attributes: Record<string, any> = {};\n\n if (openTag && openTag.name === 'OpenTag' && openTag.firstChild) {\n let sibling = openTag.firstChild.nextSibling;\n while (true) {\n if (!sibling) {\n break;\n }\n\n if (sibling.name === 'TagName') {\n const { from, to } = sibling;\n tagName = text.slice(from, to);\n } else if (sibling.name === 'Attribute') {\n const nameNode = sibling.firstChild;\n const isNode = nameNode?.nextSibling;\n const valueNode = isNode?.nextSibling;\n if (\n nameNode?.name === 'AttributeName' &&\n isNode?.name === 'Is' &&\n (valueNode?.name === 'AttributeValue' ||\n valueNode?.name === 'UnquotedAttributeValue')\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n const value = text.slice(valueNode.from, valueNode.to);\n\n if (valueNode.name === 'AttributeValue') {\n attributes[name] = decodeURIComponent(value.slice(1, -1));\n } else {\n try {\n attributes[name] = JSON.parse(decodeURIComponent(value));\n } catch (e) {\n /* empty */\n }\n }\n } else if (\n nameNode?.name === 'AttributeName' &&\n !isNode &&\n !valueNode\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n attributes[name] = true;\n }\n }\n\n sibling = sibling.nextSibling;\n }\n }\n\n if (tagName) {\n return {\n tagName,\n attributes,\n };\n }\n}\n\nexport { extractElementData };\n","import { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlParser = parser.configure({\n dialect: 'noMatch',\n});\n\nfunction parse(text: string) {\n return htmlParser.parse(text);\n}\n\nconst htmlLanguage = LRLanguage.define({\n parser: htmlParser,\n});\n\nexport { parse, htmlLanguage };\n","import { extractElementData } from './utils';\nimport { parse } from './language';\n\ninterface EditorElement<Attrs = Record<string, any>> {\n type: 'element';\n tagName: string;\n attributes: Attrs;\n}\n\ninterface EditorText {\n type: 'text';\n value: string;\n}\n\ntype EditorNode = EditorElement | EditorText;\n\nconst schemaUtils = {\n toJSON(text: string): EditorNode[] {\n const tree = parse(text);\n const tags: {\n from: number;\n to: number;\n tagName: string;\n attributes: Record<string, any>;\n }[] = [];\n tree.iterate({\n enter(node) {\n if (node.name === 'Element' && node.matchContext(['Document'])) {\n const data = extractElementData(node.node, text);\n if (data) {\n tags.push({\n from: node.from,\n to: node.to,\n ...data,\n });\n }\n }\n },\n });\n\n let pos = 0;\n const elements: EditorNode[] = [];\n for (const tag of tags) {\n const { from, to, tagName, attributes } = tag;\n\n // overlap, skip this element\n if (from < pos) {\n continue;\n }\n\n if (from > pos) {\n elements.push({\n type: 'text',\n value: text.slice(pos, from),\n });\n }\n\n elements.push({\n type: 'element',\n tagName,\n attributes,\n });\n\n pos = to;\n }\n\n if (pos < text.length) {\n elements.push({\n type: 'text',\n value: text.slice(pos),\n });\n }\n\n return elements;\n },\n fromJSON(elements: EditorNode[]): string {\n return elements\n .map(el => {\n if (el.type === 'element') {\n return toElementString(el);\n } else if (el.type === 'text') {\n return el.value;\n }\n return '';\n })\n .join('');\n },\n};\n\nfunction toElementString(element: Omit<EditorElement, 'type'>) {\n const attrsString = attributesToString(element.attributes);\n return `<${element.tagName}${attrsString ? ` ${attrsString}` : ''}></${element.tagName}>`;\n}\n\nconst INTERNAL_ID = 'cmid';\n\nfunction uniqueId() {\n return `e${Math.random()}`;\n}\n\nfunction attributesToString(attributes: EditorElement['attributes']) {\n const array: string[] = [];\n let hasId = false;\n\n Object.keys(attributes).forEach(key => {\n if (key === INTERNAL_ID) {\n hasId = true;\n }\n const value = attributes[key];\n if (value === true) {\n array.push(key);\n } else {\n array.push(`${key}=${JSON.stringify(encodeURIComponent(value))}`);\n }\n });\n\n if (!hasId) {\n array.unshift(`${INTERNAL_ID}=\"${uniqueId()}\"`);\n }\n\n return array.join(' ');\n}\n\nexport { schemaUtils, toElementString, INTERNAL_ID };\nexport type { EditorNode, EditorElement, EditorText };\n","import { api, extension, option } from '@coze-editor/core';\nimport { EditorView } from '@codemirror/view';\nimport { EditorSelection, StateEffect, StateField } from '@codemirror/state';\n\nimport { type EditorElement, toElementString } from './schema';\nimport {\n chatExtension,\n type ElementsDefinition,\n elementsFacet,\n} from './extension';\n\nconst focusedEffect = StateEffect.define();\n\nconst focusedField = StateField.define<boolean>({\n create() {\n return false;\n },\n update(value, tr) {\n for (const effect of tr.effects) {\n if (effect.is(focusedEffect)) {\n return true;\n }\n }\n\n return value;\n },\n});\n\nfunction insertElement({ view }: { view: EditorView }) {\n return (element: Omit<EditorElement, 'type'>) => {\n let selection = view.state.selection.main;\n\n const hasFocused = view.state.field(focusedField, false);\n if (hasFocused === false) {\n selection = EditorSelection.cursor(view.state.doc.length);\n }\n\n const insert = toElementString(element);\n view.dispatch({\n changes: {\n from: selection.from,\n to: selection.to,\n insert,\n },\n selection: EditorSelection.cursor(selection.from + insert.length),\n });\n };\n}\n\nconst plugins = [\n extension([\n focusedField,\n EditorView.domEventObservers({\n click(e, view) {\n view.dispatch({\n effects: focusedEffect.of(null),\n });\n },\n }),\n chatExtension(),\n ]),\n api('insertElement', insertElement),\n option('elements', (elements: ElementsDefinition) =>\n elementsFacet.of(elements),\n ),\n];\n\nexport default plugins;\n","import { createPortal, flushSync } from 'react-dom';\nimport { createElement, type ReactNode } from 'react';\n\nimport { createRoot, type Root } from 'react-dom/client';\nimport { type SyntaxNode } from '@lezer/common';\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport { connector } from '@coze-editor/react';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n WidgetType,\n} from '@codemirror/view';\nimport {\n type EditorState,\n Facet,\n RangeSetBuilder,\n StateField,\n} from '@codemirror/state';\nimport { syntaxTree } from '@codemirror/language';\n\nimport { extractElementData } from './utils';\nimport { INTERNAL_ID } from './schema';\nimport { ElementProvider } from './context';\n\ninterface ElementDefinition {\n render: (props: any) => ReactNode;\n}\n\ninterface ElementsDefinition {\n [key: string]: ElementDefinition;\n}\n\nclass ElementWidget extends WidgetType {\n public $$type = 'element';\n private root: Root;\n private element: HTMLElement;\n private view: EditorView | null = null;\n constructor(\n public definition: ElementDefinition,\n public id: string,\n public props: any,\n ) {\n super();\n\n const element = document.createElement('span');\n this.element = element;\n this.root = createRoot(element);\n }\n\n get elementId() {\n return `element-${this.id}`;\n }\n\n toDOM(view: EditorView) {\n this.view = view;\n\n const c = view.state.facet(connector);\n queueMicrotask(() => {\n flushSync(() => {\n const jsxElement = createElement(ElementProvider, {\n internalId: this.id,\n children: createElement(this.definition.render, this.props),\n });\n c.connect(this.elementId, createPortal(jsxElement, this.element));\n });\n });\n return this.element;\n }\n\n eq(other: ElementWidget) {\n return (\n this.id === other.id &&\n this.props &&\n other.props &&\n JSON.stringify(this.props) === JSON.stringify(other.props)\n );\n }\n\n destroy(): void {\n if (this.view) {\n const c = this.view.state.facet(connector);\n c.disconnect(this.elementId);\n }\n }\n\n ignoreEvent(event: Event): boolean {\n return false;\n }\n}\n\n// function isElementWidget(widget: WidgetType | null) {\n// return (widget as any)?.$$type === 'element';\n// }\n\nconst elementsFacet = Facet.define<ElementsDefinition, ElementsDefinition>({\n combine: FacetCombineStrategy.Last,\n});\n\nconst field = StateField.define({\n create(state) {\n return build(state);\n },\n update(value, tr) {\n if (tr.docChanged) {\n return build(tr.state);\n }\n return value;\n },\n provide(f) {\n return [\n EditorView.decorations.of(view => view.state.field(f)),\n EditorView.atomicRanges.of(view => view.state.field(f)),\n ];\n },\n});\n\nfunction build(state: EditorState): DecorationSet {\n const tree = syntaxTree(state);\n const builder = new RangeSetBuilder<Decoration>();\n tree.iterate({\n enter(node) {\n const data = extract(node.node, state);\n if (data) {\n const allElements = state.facet(elementsFacet);\n const definition = allElements[data.tagName];\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ElementWidget(definition, data.internalId, data.props),\n }),\n );\n }\n\n if (node.matchContext(['Document'])) {\n return false;\n }\n\n return true;\n },\n });\n\n const decorations = builder.finish();\n\n return decorations;\n}\n\nfunction extract(node: SyntaxNode, state: EditorState) {\n if (node.name === 'Element') {\n const elementData = extractElementData(node.node, state.doc.toString());\n\n if (elementData) {\n const { tagName, attributes } = elementData;\n const { [INTERNAL_ID]: internalId, ...props } = attributes ?? {};\n\n return {\n tagName,\n internalId,\n props,\n };\n }\n }\n}\n\nfunction chatExtension() {\n return [\n field,\n // selectionEnlarger.of(state => {\n // const decorations = state.field(field);\n // const cursor = decorations.iter();\n // const array = [];\n\n // while (cursor.value) {\n // const widget = cursor.value.spec?.widget;\n // const { from, to } = cursor;\n // if (isElementWidget(widget)) {\n // array.push({\n // source: { from, to },\n // target: { from, to },\n // });\n // }\n\n // cursor.next();\n // }\n\n // return array;\n // }),\n ];\n}\n\nexport { field, chatExtension, elementsFacet };\n\nexport type { ElementsDefinition };\n","import React, { createContext, type ReactNode, useContext } from 'react';\n\nconst Context = createContext('');\n\nfunction ElementProvider({\n internalId,\n children,\n}: {\n internalId: string;\n children: ReactNode;\n}) {\n return <Context.Provider value={internalId}>{children}</Context.Provider>;\n}\n\nfunction useElementId() {\n const id = useContext(Context);\n return id;\n}\n\nexport { ElementProvider, useElementId };\n","import { useLayoutEffect, useRef, useState } from 'react';\n\nimport {\n type BuiltinEditorAPI,\n useEditor,\n useInjector,\n} from '@coze-editor/react';\nimport { type EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\nimport { EditorSelection, type EditorState } from '@codemirror/state';\n\nimport { field } from './extension';\nimport { useElementId } from './context';\n\nfunction useCurrentElement() {\n const editor = useEditor<BuiltinEditorAPI | null>();\n const elementId = useElementId();\n const injector = useInjector();\n const [isSelected, setIsSelected] = useState(false);\n const elementIdRef = useRef(elementId);\n\n elementIdRef.current = elementId;\n\n function select() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n const decorations = view.state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n view.dispatch({\n selection: EditorSelection.range(cursor.from, cursor.to),\n });\n break;\n }\n cursor.next();\n }\n }\n\n function remove() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n if (view.state.readOnly) {\n return;\n }\n\n const range = findElement(view.state, elementId);\n if (range) {\n view.dispatch({\n changes: {\n from: range.from,\n to: range.to,\n insert: '',\n },\n selection: EditorSelection.cursor(range.from),\n });\n }\n }\n\n useLayoutEffect(() => {\n function selectionContainsCurrentElement(state: EditorState) {\n const range = findElement(state, elementId);\n const { ranges } = state.selection;\n if (!range) {\n return false;\n }\n\n for (const r of ranges) {\n if (r.from <= range.from && r.to >= range.to) {\n return true;\n }\n }\n\n return false;\n }\n\n const plugin = ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const contains = selectionContainsCurrentElement(view.state);\n setIsSelected(contains);\n }\n\n update(update: ViewUpdate) {\n if (update.selectionSet) {\n const contains = selectionContainsCurrentElement(update.state);\n setIsSelected(contains);\n }\n }\n },\n );\n\n return injector.inject([plugin]);\n }, [injector]);\n\n return {\n isSelected,\n select,\n remove,\n };\n}\n\nfunction findElement(state: EditorState, elementId: string) {\n const decorations = state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n return {\n from: cursor.from,\n to: cursor.to,\n };\n }\n cursor.next();\n }\n}\n\nexport { useCurrentElement };\n"],"mappings":"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","names":["import_core","import_view","import_view","import_state","import_react","import_utils","import_language","React","import_react","import_view","import_state","universalPreset"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/language.ts","../src/schema.ts","../src/plugins.ts","../src/extension.ts","../src/context.tsx","../src/hooks.tsx"],"sourcesContent":["import universalPreset from '@coze-editor/preset-universal';\nimport { extension, type InferEditorAPIFromPlugins } from '@coze-editor/core';\nimport { EditorView, keymap } from '@codemirror/view';\nimport { defaultKeymap, historyKeymap, history } from '@codemirror/commands';\n\nimport {\n type EditorNode,\n type EditorElement,\n type EditorText,\n schemaUtils,\n} from './schema';\nimport plugins from './plugins';\nimport { htmlLanguage } from './language';\nimport { useCurrentElement } from './hooks';\nimport { CUSTOM_CLIPBOARD_MIMETYPE, type ElementDefinition } from './extension';\n\nconst preset = [\n ...universalPreset,\n extension([\n EditorView.theme({\n '&.cm-focused': {\n outline: 'none',\n },\n }),\n htmlLanguage,\n history(),\n keymap.of([...defaultKeymap, ...historyKeymap]),\n ]),\n ...plugins,\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { schemaUtils, useCurrentElement, CUSTOM_CLIPBOARD_MIMETYPE };\n\nexport type {\n EditorAPI,\n ElementDefinition,\n EditorNode,\n EditorElement,\n EditorText,\n};\n","/* eslint-disable complexity */\n\nimport { type SyntaxNode } from '@lezer/common';\n\nfunction extractElementData(node: SyntaxNode, text: string) {\n const openTag = node.firstChild;\n\n let tagName: string | null = null;\n const attributes: Record<string, any> = {};\n\n if (openTag && openTag.name === 'OpenTag' && openTag.firstChild) {\n let sibling = openTag.firstChild.nextSibling;\n while (true) {\n if (!sibling) {\n break;\n }\n\n if (sibling.name === 'TagName') {\n const { from, to } = sibling;\n tagName = text.slice(from, to);\n } else if (sibling.name === 'Attribute') {\n const nameNode = sibling.firstChild;\n const isNode = nameNode?.nextSibling;\n const valueNode = isNode?.nextSibling;\n if (\n nameNode?.name === 'AttributeName' &&\n isNode?.name === 'Is' &&\n (valueNode?.name === 'AttributeValue' ||\n valueNode?.name === 'UnquotedAttributeValue')\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n const fullValue = text.slice(valueNode.from, valueNode.to);\n\n let value = fullValue;\n if (valueNode.name === 'AttributeValue') {\n value = fullValue.slice(1, -1);\n }\n\n try {\n attributes[name] = JSON.parse(decodeURIComponent(value));\n } catch (e) {\n /* empty */\n }\n } else if (\n nameNode?.name === 'AttributeName' &&\n !isNode &&\n !valueNode\n ) {\n const name = text.slice(nameNode.from, nameNode.to);\n attributes[name] = true;\n }\n }\n\n sibling = sibling.nextSibling;\n }\n }\n\n if (tagName) {\n return {\n tagName,\n attributes,\n };\n }\n}\n\nexport { extractElementData };\n","import { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlParser = parser.configure({\n dialect: 'noMatch',\n});\n\nfunction parse(text: string) {\n return htmlParser.parse(text);\n}\n\nconst htmlLanguage = LRLanguage.define({\n parser: htmlParser,\n});\n\nexport { parse, htmlLanguage };\n","import { extractElementData } from './utils';\nimport { parse } from './language';\n\ninterface EditorElement<Attrs = Record<string, any>> {\n type: 'element';\n tagName: string;\n attributes: Attrs;\n raw?: string;\n}\n\ninterface EditorText {\n type: 'text';\n value: string;\n}\n\ntype EditorNode = EditorElement | EditorText;\n\nfunction isElementRegistered(\n tagName: string,\n validTagNames: string[] | undefined,\n) {\n if (!Array.isArray(validTagNames)) {\n return false;\n }\n\n if (validTagNames.includes(tagName)) {\n return true;\n }\n\n return false;\n}\n\nconst schemaUtils = {\n toJSON(text: string, options?: { validTagNames?: string[] }): EditorNode[] {\n if (text === '') {\n return [];\n }\n\n const tree = parse(text);\n const tags: {\n from: number;\n to: number;\n tagName: string;\n attributes: Record<string, any>;\n raw: string;\n }[] = [];\n tree.iterate({\n enter(node) {\n if (node.name === 'Element') {\n const data = extractElementData(node.node, text);\n if (\n data &&\n isElementRegistered(data.tagName, options?.validTagNames)\n ) {\n tags.push({\n from: node.from,\n to: node.to,\n raw: text.slice(node.from, node.to),\n ...data,\n });\n }\n }\n },\n });\n\n let pos = 0;\n const elements: EditorNode[] = [];\n for (const tag of tags) {\n const { from, to, tagName, attributes, raw } = tag;\n const { cmid, ...restAttributes } = attributes ?? {};\n\n // overlap, skip this element\n if (from < pos) {\n continue;\n }\n\n if (from > pos) {\n elements.push({\n type: 'text',\n value: text.slice(pos, from),\n });\n }\n\n elements.push({\n type: 'element',\n tagName,\n attributes: restAttributes,\n raw,\n });\n\n pos = to;\n }\n\n if (pos < text.length) {\n elements.push({\n type: 'text',\n value: text.slice(pos),\n });\n }\n\n return elements;\n },\n fromJSON(elements: EditorNode[]): string {\n return elements\n .map(el => {\n if (el.type === 'element') {\n return toElementString(el);\n } else if (el.type === 'text') {\n return el.value;\n }\n return '';\n })\n .join('');\n },\n};\n\nfunction toElementString(element: Omit<EditorElement, 'type'>) {\n const attrsString = attributesToString(element.attributes);\n return `<${element.tagName}${attrsString ? ` ${attrsString}` : ''}></${element.tagName}>`;\n}\n\nconst INTERNAL_ID = 'cmid';\n\nfunction uniqueId() {\n return `e${Math.random()}`;\n}\n\nfunction attributesToString(attributes: EditorElement['attributes']) {\n const array: string[] = [];\n let hasId = false;\n\n Object.keys(attributes).forEach(key => {\n if (key === INTERNAL_ID) {\n hasId = true;\n }\n const value = attributes[key];\n if (value === true) {\n array.push(key);\n } else if (typeof value !== 'undefined') {\n array.push(`${key}=\"${encodeURIComponent(JSON.stringify(value))}\"`);\n }\n });\n\n if (!hasId) {\n array.unshift(\n `${INTERNAL_ID}=\"${encodeURIComponent(JSON.stringify(uniqueId()))}\"`,\n );\n }\n\n return array.join(' ');\n}\n\nexport { schemaUtils, toElementString, INTERNAL_ID };\nexport type { EditorNode, EditorElement, EditorText };\n","import { api, extension, option } from '@coze-editor/core';\nimport { EditorView } from '@codemirror/view';\nimport { EditorSelection, StateEffect, StateField } from '@codemirror/state';\n\nimport { type EditorElement, toElementString } from './schema';\nimport {\n chatExtension,\n type ElementsDefinition,\n elementsFacet,\n} from './extension';\n\nconst focusedEffect = StateEffect.define();\n\nconst focusedField = StateField.define<boolean>({\n create() {\n return false;\n },\n update(value, tr) {\n for (const effect of tr.effects) {\n if (effect.is(focusedEffect)) {\n return true;\n }\n }\n\n return value;\n },\n});\n\nfunction insertElement({ view }: { view: EditorView }) {\n return (element: Omit<EditorElement, 'type'>) => {\n let selection = view.state.selection.main;\n\n const hasFocused = view.state.field(focusedField, false);\n if (hasFocused === false) {\n selection = EditorSelection.cursor(view.state.doc.length);\n }\n\n const insert = toElementString(element);\n view.dispatch({\n changes: {\n from: selection.from,\n to: selection.to,\n insert,\n },\n selection: EditorSelection.cursor(selection.from + insert.length),\n });\n };\n}\n\nconst plugins = [\n extension([\n focusedField,\n EditorView.domEventObservers({\n click(e, view) {\n view.dispatch({\n effects: focusedEffect.of(null),\n });\n },\n }),\n chatExtension(),\n ]),\n api('insertElement', insertElement),\n option('elements', (elements: ElementsDefinition) =>\n elementsFacet.of(elements),\n ),\n];\n\nexport default plugins;\n","import { createPortal, flushSync } from 'react-dom';\nimport { createElement, type ReactNode } from 'react';\n\nimport { createRoot, type Root } from 'react-dom/client';\nimport { type SyntaxNode } from '@lezer/common';\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport { connector } from '@coze-editor/react';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n WidgetType,\n} from '@codemirror/view';\nimport {\n EditorSelection,\n type EditorState,\n Facet,\n RangeSetBuilder,\n StateField,\n} from '@codemirror/state';\nimport { ensureSyntaxTree, syntaxTree } from '@codemirror/language';\n\nimport { extractElementData } from './utils';\nimport {\n type EditorElement,\n type EditorNode,\n INTERNAL_ID,\n schemaUtils,\n} from './schema';\nimport { ElementProvider } from './context';\n\ninterface ElementDefinition<Attrs = any> {\n render: (props: Attrs) => ReactNode;\n toString?: (element: EditorElement<Attrs>) => string;\n}\n\ninterface ElementsDefinition {\n [key: string]: ElementDefinition;\n}\n\nclass ElementWidget extends WidgetType {\n public $$type = 'element';\n private root: Root;\n private element: HTMLElement;\n private view: EditorView | null = null;\n constructor(\n public definition: ElementDefinition,\n public id: string,\n public props: any,\n ) {\n super();\n\n const element = document.createElement('span');\n this.element = element;\n this.root = createRoot(element);\n }\n\n get elementId() {\n return `element-${this.id}`;\n }\n\n toDOM(view: EditorView) {\n this.view = view;\n\n const c = view.state.facet(connector);\n queueMicrotask(() => {\n flushSync(() => {\n const jsxElement = createElement(ElementProvider, {\n internalId: this.id,\n children: createElement(this.definition.render, this.props),\n });\n c.connect(this.elementId, createPortal(jsxElement, this.element));\n });\n });\n return this.element;\n }\n\n eq(other: ElementWidget) {\n return (\n this.id === other.id &&\n this.props &&\n other.props &&\n JSON.stringify(this.props) === JSON.stringify(other.props)\n );\n }\n\n destroy(): void {\n if (this.view) {\n const c = this.view.state.facet(connector);\n c.disconnect(this.elementId);\n }\n }\n\n ignoreEvent(event: Event): boolean {\n return false;\n }\n}\n\n// function isElementWidget(widget: WidgetType | null) {\n// return (widget as any)?.$$type === 'element';\n// }\n\nconst elementsFacet = Facet.define<\n ElementsDefinition | undefined,\n ElementsDefinition | undefined\n>({\n combine: FacetCombineStrategy.Last,\n});\n\nconst field = StateField.define({\n create(state) {\n return build(state);\n },\n update(value, tr) {\n if (tr.docChanged) {\n return build(tr.state);\n }\n return value;\n },\n provide(f) {\n return [\n EditorView.decorations.of(view => view.state.field(f)),\n EditorView.atomicRanges.of(view => view.state.field(f)),\n ];\n },\n});\n\nfunction build(state: EditorState): DecorationSet {\n const allElements = state.facet(elementsFacet);\n\n if (!allElements) {\n return Decoration.none;\n }\n\n const tree = ensureSyntaxTree(state, state.doc.length) ?? syntaxTree(state);\n const builder = new RangeSetBuilder<Decoration>();\n tree.iterate({\n enter(node) {\n const data = extract(node.node, state);\n if (data) {\n const definition = allElements[data.tagName];\n if (definition) {\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ElementWidget(\n definition,\n data.internalId,\n data.props,\n ),\n }),\n );\n }\n }\n\n // if (node.matchContext(['Document'])) {\n // return false;\n // }\n\n return true;\n },\n });\n\n const decorations = builder.finish();\n\n return decorations;\n}\n\nfunction extract(node: SyntaxNode, state: EditorState) {\n if (node.name === 'Element') {\n const elementData = extractElementData(node.node, state.doc.toString());\n\n if (elementData) {\n const { tagName, attributes } = elementData;\n const { [INTERNAL_ID]: internalId, ...props } = attributes ?? {};\n\n return {\n tagName,\n internalId,\n props,\n };\n }\n }\n}\n\nconst CUSTOM_CLIPBOARD_MIMETYPE = 'application/x-with-elements';\n\nconst copyPasteHandler = EditorView.domEventHandlers({\n paste(event, view) {\n try {\n let text = event.clipboardData?.getData(CUSTOM_CLIPBOARD_MIMETYPE);\n\n if (!text) {\n return false;\n }\n\n // normalize \\r\\n to \\n for Windows (if user copies rich text)\n text = text.replace(/\\r\\n/g, '\\n');\n\n const definitions = view.state.facet(elementsFacet);\n\n const nodes = schemaUtils.toJSON(text, {\n validTagNames: definitions ? Object.keys(definitions) : undefined,\n });\n const newText = schemaUtils.fromJSON(\n nodes\n .map(node => {\n if (node.type === 'text') {\n return node;\n }\n\n if (node.type === 'element') {\n return {\n ...node,\n attributes: {\n ...(node.attributes ?? {}),\n cmid: `e${Math.random()}`,\n },\n } satisfies EditorElement;\n }\n })\n .filter(v => isEditorNode(v)),\n );\n\n view.dispatch({\n changes: {\n from: view.state.selection.main.from,\n to: view.state.selection.main.to,\n insert: newText,\n },\n selection: EditorSelection.cursor(\n view.state.selection.main.from + newText.length,\n ),\n });\n return true;\n } catch (e) {\n return false;\n }\n },\n copy(event, view) {\n const definitions = view.state.facet(elementsFacet);\n\n if (!definitions) {\n return false;\n }\n\n try {\n const { from, to } = view.state.selection.main;\n const slice = view.state.doc.sliceString(from, to);\n const nodes = schemaUtils.toJSON(slice, {\n validTagNames: definitions ? Object.keys(definitions) : undefined,\n });\n\n const plainText = nodes\n .map(node => {\n if (node.type === 'text') {\n return node.value;\n }\n\n if (node.type === 'element') {\n const definition = definitions[node.tagName];\n const toString = definition?.toString;\n\n if (!definition) {\n return node.raw ?? '';\n }\n\n if (\n Object.prototype.hasOwnProperty.call(definition, 'toString') &&\n typeof toString === 'function'\n ) {\n return toString(node);\n }\n\n return `[${node.tagName}]`;\n }\n\n return '';\n })\n .join('');\n\n event.clipboardData?.setData('text/plain', plainText);\n event.clipboardData?.setData(CUSTOM_CLIPBOARD_MIMETYPE, slice);\n\n return true;\n } catch (e) {\n return false;\n }\n },\n});\n\nfunction isEditorNode(v: unknown): v is EditorNode {\n return Boolean(v);\n}\n\nfunction chatExtension() {\n return [\n field,\n copyPasteHandler,\n // selectionEnlarger.of(state => {\n // const decorations = state.field(field);\n // const cursor = decorations.iter();\n // const array = [];\n\n // while (cursor.value) {\n // const widget = cursor.value.spec?.widget;\n // const { from, to } = cursor;\n // if (isElementWidget(widget)) {\n // array.push({\n // source: { from, to },\n // target: { from, to },\n // });\n // }\n\n // cursor.next();\n // }\n\n // return array;\n // }),\n ];\n}\n\nexport { field, chatExtension, elementsFacet, CUSTOM_CLIPBOARD_MIMETYPE };\n\nexport type { ElementsDefinition, ElementDefinition };\n","import React, { createContext, type ReactNode, useContext } from 'react';\n\nconst Context = createContext('');\n\nfunction ElementProvider({\n internalId,\n children,\n}: {\n internalId: string;\n children: ReactNode;\n}) {\n return <Context.Provider value={internalId}>{children}</Context.Provider>;\n}\n\nfunction useElementId() {\n const id = useContext(Context);\n return id;\n}\n\nexport { ElementProvider, useElementId };\n","import { useLayoutEffect, useRef, useState } from 'react';\n\nimport {\n type BuiltinEditorAPI,\n useEditor,\n useInjector,\n} from '@coze-editor/react';\nimport { type EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\nimport { EditorSelection, type EditorState } from '@codemirror/state';\n\nimport { field } from './extension';\nimport { useElementId } from './context';\n\nfunction useCurrentElement() {\n const editor = useEditor<BuiltinEditorAPI | null>();\n const elementId = useElementId();\n const injector = useInjector();\n const [isSelected, setIsSelected] = useState(false);\n const elementIdRef = useRef(elementId);\n\n elementIdRef.current = elementId;\n\n function select() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n const decorations = view.state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n view.dispatch({\n selection: EditorSelection.range(cursor.from, cursor.to),\n });\n break;\n }\n cursor.next();\n }\n }\n\n function remove() {\n if (!editor) {\n return;\n }\n\n const view = editor.$view;\n\n if (view.state.readOnly) {\n return;\n }\n\n const range = findElement(view.state, elementId);\n if (range) {\n view.dispatch({\n changes: {\n from: range.from,\n to: range.to,\n insert: '',\n },\n selection: EditorSelection.cursor(range.from),\n });\n }\n }\n\n useLayoutEffect(() => {\n function selectionContainsCurrentElement(state: EditorState) {\n const range = findElement(state, elementId);\n const { ranges } = state.selection;\n if (!range) {\n return false;\n }\n\n for (const r of ranges) {\n if (r.from <= range.from && r.to >= range.to) {\n return true;\n }\n }\n\n return false;\n }\n\n const plugin = ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const contains = selectionContainsCurrentElement(view.state);\n setIsSelected(contains);\n }\n\n update(update: ViewUpdate) {\n if (update.selectionSet) {\n const contains = selectionContainsCurrentElement(update.state);\n setIsSelected(contains);\n }\n }\n },\n );\n\n return injector.inject([plugin]);\n }, [injector]);\n\n return {\n isSelected,\n select,\n remove,\n };\n}\n\nfunction findElement(state: EditorState, elementId: string) {\n const decorations = state.field(field);\n\n const cursor = decorations.iter();\n while (cursor.value) {\n const { spec } = cursor.value;\n if (spec?.widget?.id === elementId) {\n return {\n from: cursor.from,\n to: cursor.to,\n };\n }\n cursor.next();\n }\n}\n\nexport { useCurrentElement };\n"],"mappings":"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","names":["import_core","import_view","import_view","import_state","import_react","import_utils","import_language","React","import_react","import_view","import_state","universalPreset"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-editor/preset-chat",
3
- "version": "0.1.0-alpha.687604",
3
+ "version": "0.1.0-alpha.a96b6d",
4
4
  "description": "preset-chat",
5
5
  "license": "MIT",
6
6
  "author": "fengzilong",
@@ -23,11 +23,11 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@codemirror/language": "^6.10.1",
26
- "@coze-editor/core": "0.1.0-alpha.687604",
27
- "@coze-editor/core-plugins": "0.1.0-alpha.687604",
28
- "@coze-editor/extensions": "0.1.0-alpha.687604",
29
- "@coze-editor/preset-universal": "0.1.0-alpha.687604",
30
- "@coze-editor/utils": "0.1.0-alpha.687604",
26
+ "@coze-editor/core": "0.1.0-alpha.a96b6d",
27
+ "@coze-editor/core-plugins": "0.1.0-alpha.a96b6d",
28
+ "@coze-editor/extensions": "0.1.0-alpha.a96b6d",
29
+ "@coze-editor/preset-universal": "0.1.0-alpha.a96b6d",
30
+ "@coze-editor/utils": "0.1.0-alpha.a96b6d",
31
31
  "@lezer/common": "^1.2.2",
32
32
  "@lezer/html": "^1.3.10"
33
33
  },
@@ -49,7 +49,7 @@
49
49
  "@codemirror/commands": "^6.3.3",
50
50
  "@codemirror/state": "^6.4.1",
51
51
  "@codemirror/view": "^6.26.1",
52
- "@coze-editor/react": "0.1.0-alpha.687604",
52
+ "@coze-editor/react": "0.1.0-alpha.a96b6d",
53
53
  "react": ">=18",
54
54
  "react-dom": ">=18"
55
55
  },