@lexical/react 0.1.13 → 0.1.14

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.
@@ -29,10 +29,12 @@ export interface Provider {
29
29
  on(type: 'status', cb: (arg0: {status: string}) => void): void;
30
30
  // $FlowFixMe: temp
31
31
  on(type: 'update', cb: (arg0: any) => void): void;
32
+ on(type: 'reload', cb: (doc: Doc) => boolean): void;
32
33
  off(type: 'sync', cb: (isSynced: boolean) => void): void;
33
34
  // $FlowFixMe: temp
34
35
  off(type: 'update', cb: (arg0: any) => void): void;
35
36
  off(type: 'status', cb: (arg0: {status: string}) => void): void;
37
+ off(type: 'reload', cb: (doc: Doc) => boolean): void;
36
38
  }
37
39
  type CollaborationContextType = {
38
40
  clientID: number;
@@ -22,7 +22,9 @@ var reactDom = require('react-dom');
22
22
  */
23
23
  const EditorPriority = 0;
24
24
  function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap) {
25
- const binding = React.useMemo(() => yjs.createBinding(editor, provider, id, docMap), [editor, provider, id, docMap]);
25
+ const isReloadingDoc = React.useRef(false);
26
+ const [doc, setDoc] = React.useState(docMap.get(id));
27
+ const binding = React.useMemo(() => yjs.createBinding(editor, provider, id, doc, docMap), [editor, provider, id, docMap, doc]);
26
28
  const connect = React.useCallback(() => {
27
29
  provider.connect();
28
30
  }, [provider]);
@@ -47,9 +49,11 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
47
49
  };
48
50
 
49
51
  const onSync = isSynced => {
50
- if (shouldBootstrap && isSynced && root.isEmpty() && root._xmlText._length === 0) {
52
+ if (shouldBootstrap && isSynced && root.isEmpty() && root._xmlText._length === 0 && isReloadingDoc.current === false) {
51
53
  initializeEditor(editor);
52
54
  }
55
+
56
+ isReloadingDoc.current = false;
53
57
  };
54
58
 
55
59
  const onAwarenessUpdate = () => {
@@ -63,6 +67,15 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
63
67
  };
64
68
 
65
69
  yjs.initLocalState(provider, name, color, document.activeElement === editor.getRootElement());
70
+
71
+ const onProviderDocReload = ydoc => {
72
+ clearEditorSkipCollab(editor);
73
+ setDoc(ydoc);
74
+ docMap.set(id, ydoc);
75
+ isReloadingDoc.current = true;
76
+ };
77
+
78
+ provider.on('reload', onProviderDocReload);
66
79
  provider.on('status', onStatus);
67
80
  provider.on('sync', onSync);
68
81
  awareness.on('update', onAwarenessUpdate);
@@ -75,18 +88,24 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
75
88
  normalizedNodes,
76
89
  tags
77
90
  }) => {
78
- yjs.syncLexicalUpdateToYjs(binding, provider, prevEditorState, editorState, dirtyElements, dirtyLeaves, normalizedNodes, tags);
91
+ if (tags.has('skip-collab') === false) {
92
+ yjs.syncLexicalUpdateToYjs(binding, provider, prevEditorState, editorState, dirtyElements, dirtyLeaves, normalizedNodes, tags);
93
+ }
79
94
  });
80
95
  connect();
81
96
  return () => {
82
- disconnect();
97
+ if (isReloadingDoc.current === false) {
98
+ disconnect();
99
+ }
100
+
83
101
  provider.off('sync', onSync);
84
102
  provider.off('status', onStatus);
103
+ provider.off('reload', onProviderDocReload);
85
104
  awareness.off('update', onAwarenessUpdate);
86
105
  root.getSharedType().unobserveDeep(onYjsTreeChanges);
87
106
  removeListener();
88
107
  };
89
- }, [binding, color, connect, disconnect, editor, name, provider, shouldBootstrap]);
108
+ }, [binding, color, connect, disconnect, docMap, editor, id, name, provider, shouldBootstrap]);
90
109
  const cursorsContainer = React.useMemo(() => {
91
110
  const ref = element => {
92
111
  binding.cursorsContainer = element;
@@ -119,18 +138,18 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
119
138
  }, [connect, disconnect, editor]);
120
139
  return [cursorsContainer, binding];
121
140
  }
122
- function useYjsFocusTracking(editor, provider) {
141
+ function useYjsFocusTracking(editor, provider, name, color) {
123
142
  React.useEffect(() => {
124
143
  return editor.addListener('command', (type, payload) => {
125
144
  if (type === 'focus') {
126
- yjs.setLocalStateFocus(provider, true);
145
+ yjs.setLocalStateFocus(provider, name, color, true);
127
146
  } else if (type === 'blur') {
128
- yjs.setLocalStateFocus(provider, false);
147
+ yjs.setLocalStateFocus(provider, name, color, false);
129
148
  }
130
149
 
131
150
  return false;
132
151
  }, EditorPriority);
133
- }, [editor, provider]);
152
+ }, [color, editor, name, provider]);
134
153
  }
135
154
  function useYjsHistory(editor, binding) {
136
155
  const undoManager = React.useMemo(() => yjs.createUndoManager(binding, binding.root.getSharedType()), [binding]);
@@ -184,6 +203,16 @@ function initializeEditor(editor) {
184
203
  });
185
204
  }
186
205
 
206
+ function clearEditorSkipCollab(editor) {
207
+ editor.update(() => {
208
+ const root = lexical.$getRoot();
209
+ root.clear();
210
+ root.select();
211
+ }, {
212
+ tag: 'skip-collab'
213
+ });
214
+ }
215
+
187
216
  /**
188
217
  * Copyright (c) Meta Platforms, Inc. and affiliates.
189
218
  *
@@ -210,7 +239,7 @@ function CollaborationPlugin({
210
239
  const [cursors, binding] = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap);
211
240
  collabContext.clientID = binding.clientID;
212
241
  useYjsHistory(editor, binding);
213
- useYjsFocusTracking(editor, provider);
242
+ useYjsFocusTracking(editor, provider, name, color);
214
243
  return cursors;
215
244
  }
216
245
  const CollaborationContext = /*#__PURE__*/React.createContext({
@@ -18,7 +18,7 @@ export type UserState = {
18
18
  };
19
19
 
20
20
  export type ProviderAwareness = {
21
- getLocalState: () => UserState,
21
+ getLocalState: () => UserState | null,
22
22
  setLocalState: (UserState) => void,
23
23
  getStates: () => Map<number, UserState>,
24
24
  on: (type: 'update', cb: () => void) => void,
@@ -33,10 +33,12 @@ export interface Provider {
33
33
  on(type: 'status', cb: ({status: string}) => void): void;
34
34
  // $FlowFixMe: temp
35
35
  on(type: 'update', cb: (any) => void): void;
36
+ on(type: 'reload', cb: (doc: Doc) => void): void;
36
37
  off(type: 'sync', cb: (isSynced: boolean) => void): void;
37
38
  // $FlowFixMe: temp
38
39
  off(type: 'update', cb: (any) => void): void;
39
40
  off(type: 'status', cb: ({status: string}) => void): void;
41
+ off(type: 'reload', cb: (doc: Doc) => void): void;
40
42
  }
41
43
 
42
44
  type CollaborationContextType = {
@@ -4,10 +4,11 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- var d=require("@lexical/react/LexicalComposerContext"),g=require("react"),u=require("@lexical/yjs"),A=require("lexical"),B=require("react-dom");
8
- function C(b,c,a,h,n,p,q){const e=g.useMemo(()=>u.createBinding(b,a,c,h),[b,a,c,h]),k=g.useCallback(()=>{a.connect()},[a]),l=g.useCallback(()=>{try{a.disconnect()}catch(f){}},[a]);g.useEffect(()=>{const {root:f}=e,{awareness:r}=a,w=({status:m})=>{b.execCommand("connected","connected"===m)},x=m=>{q&&m&&f.isEmpty()&&0===f._xmlText._length&&D(b)},y=()=>{u.syncCursorPositions(e,a)},z=(m,v)=>{v.origin!==e&&u.syncYjsChangesToLexical(e,a,m)};u.initLocalState(a,n,p,document.activeElement===b.getRootElement());
9
- a.on("status",w);a.on("sync",x);r.on("update",y);f.getSharedType().observeDeep(z);const M=b.addListener("update",({prevEditorState:m,editorState:v,dirtyLeaves:I,dirtyElements:J,normalizedNodes:K,tags:L})=>{u.syncLexicalUpdateToYjs(e,a,m,v,J,I,K,L)});k();return()=>{l();a.off("sync",x);a.off("status",w);r.off("update",y);f.getSharedType().unobserveDeep(z);M()}},[e,p,k,l,b,n,a,q]);const t=g.useMemo(()=>B.createPortal(g.createElement("div",{ref:f=>{e.cursorsContainer=f}}),document.body),[e]);g.useEffect(()=>
10
- b.addListener("command",(f,r)=>{"toggleConnect"===f&&void 0!==k&&void 0!==l&&(r?(console.log("Collaboration connected!"),k()):(console.log("Collaboration disconnected!"),l()));return!1},0),[k,l,b]);return[t,e]}function E(b,c){g.useEffect(()=>b.addListener("command",a=>{"focus"===a?u.setLocalStateFocus(c,!0):"blur"===a&&u.setLocalStateFocus(c,!1);return!1},0),[b,c])}
11
- function F(b,c){const a=g.useMemo(()=>u.createUndoManager(c,c.root.getSharedType()),[c]);g.useEffect(()=>b.addListener("command",h=>"undo"===h?(a.undo(),!0):"redo"===h?(a.redo(),!0):!1,0));return g.useCallback(()=>{a.clear()},[a])}function D(b){b.update(()=>{var c=A.$getRoot();if(null===c.getFirstChild()){const a=A.$createParagraphNode();c.append(a);c=document.activeElement;(null!==A.$getSelection()||null!==c&&c===b.getRootElement())&&a.select()}},{tag:"history-merge"})}
12
- const G=[["Cat","255,165,0"],["Dog","0,200,55"],["Rabbit","160,0,200"],["Frog","0,172,200"],["Fox","197,200,0"],["Hedgehog","31,200,0"],["Pigeon","200,0,0"],["Squirrel","200,0,148"],["Bear","255,235,0"],["Tiger","86,255,0"],["Leopard","0,255,208"],["Zebra","0,243,255"],["Wolf","0,102,255"],["Owl","147,0,255"],["Gull","255,0,153"],["Squid","0,220,255"]],H=G[Math.floor(Math.random()*(G.length-1+1))],N=g.createContext({clientID:0,color:H[1],name:H[0],yjsDocMap:new Map});
13
- function O(){return g.useContext(N)}exports.CollaborationContext=N;exports.CollaborationPlugin=function({id:b,providerFactory:c,shouldBootstrap:a}){const h=O(),{yjsDocMap:n,name:p,color:q}=h,[e]=d.useLexicalComposerContext(),k=g.useMemo(()=>c(b,n),[b,c,n]),[l,t]=C(e,b,k,n,p,q,a);h.clientID=t.clientID;F(e,t);E(e,k);return l};exports.useCollaborationContext=O;
7
+ var d=require("@lexical/react/LexicalComposerContext"),l=require("react"),u=require("@lexical/yjs"),E=require("lexical"),F=require("react-dom");
8
+ function G(c,b,a,e,h,n,p){const m=l.useRef(!1),[q,w]=l.useState(e.get(b)),f=l.useMemo(()=>u.createBinding(c,a,b,q,e),[c,a,b,e,q]),r=l.useCallback(()=>{a.connect()},[a]),t=l.useCallback(()=>{try{a.disconnect()}catch(k){}},[a]);l.useEffect(()=>{const {root:k}=f,{awareness:v}=a,y=({status:g})=>{c.execCommand("connected","connected"===g)},z=g=>{p&&g&&k.isEmpty()&&0===k._xmlText._length&&!1===m.current&&H(c);m.current=!1},A=()=>{u.syncCursorPositions(f,a)},B=(g,x)=>{x.origin!==f&&u.syncYjsChangesToLexical(f,
9
+ a,g)};u.initLocalState(a,h,n,document.activeElement===c.getRootElement());const C=g=>{I(c);w(g);e.set(b,g);m.current=!0};a.on("reload",C);a.on("status",y);a.on("sync",z);v.on("update",A);k.getSharedType().observeDeep(B);const Q=c.addListener("update",({prevEditorState:g,editorState:x,dirtyLeaves:N,dirtyElements:O,normalizedNodes:P,tags:D})=>{!1===D.has("skip-collab")&&u.syncLexicalUpdateToYjs(f,a,g,x,O,N,P,D)});r();return()=>{!1===m.current&&t();a.off("sync",z);a.off("status",y);a.off("reload",C);
10
+ v.off("update",A);k.getSharedType().unobserveDeep(B);Q()}},[f,n,r,t,e,c,b,h,a,p]);const R=l.useMemo(()=>F.createPortal(l.createElement("div",{ref:k=>{f.cursorsContainer=k}}),document.body),[f]);l.useEffect(()=>c.addListener("command",(k,v)=>{"toggleConnect"===k&&void 0!==r&&void 0!==t&&(v?(console.log("Collaboration connected!"),r()):(console.log("Collaboration disconnected!"),t()));return!1},0),[r,t,c]);return[R,f]}
11
+ function J(c,b,a,e){l.useEffect(()=>c.addListener("command",h=>{"focus"===h?u.setLocalStateFocus(b,a,e,!0):"blur"===h&&u.setLocalStateFocus(b,a,e,!1);return!1},0),[e,c,a,b])}function K(c,b){const a=l.useMemo(()=>u.createUndoManager(b,b.root.getSharedType()),[b]);l.useEffect(()=>c.addListener("command",e=>"undo"===e?(a.undo(),!0):"redo"===e?(a.redo(),!0):!1,0));return l.useCallback(()=>{a.clear()},[a])}
12
+ function H(c){c.update(()=>{var b=E.$getRoot();if(null===b.getFirstChild()){const a=E.$createParagraphNode();b.append(a);b=document.activeElement;(null!==E.$getSelection()||null!==b&&b===c.getRootElement())&&a.select()}},{tag:"history-merge"})}function I(c){c.update(()=>{const b=E.$getRoot();b.clear();b.select()},{tag:"skip-collab"})}
13
+ const L=[["Cat","255,165,0"],["Dog","0,200,55"],["Rabbit","160,0,200"],["Frog","0,172,200"],["Fox","197,200,0"],["Hedgehog","31,200,0"],["Pigeon","200,0,0"],["Squirrel","200,0,148"],["Bear","255,235,0"],["Tiger","86,255,0"],["Leopard","0,255,208"],["Zebra","0,243,255"],["Wolf","0,102,255"],["Owl","147,0,255"],["Gull","255,0,153"],["Squid","0,220,255"]],M=L[Math.floor(Math.random()*(L.length-1+1))],S=l.createContext({clientID:0,color:M[1],name:M[0],yjsDocMap:new Map});
14
+ function T(){return l.useContext(S)}exports.CollaborationContext=S;exports.CollaborationPlugin=function({id:c,providerFactory:b,shouldBootstrap:a}){const e=T(),{yjsDocMap:h,name:n,color:p}=e,[m]=d.useLexicalComposerContext(),q=l.useMemo(()=>b(c,h),[c,b,h]),[w,f]=G(m,c,q,h,n,p,a);e.clientID=f.clientID;K(m,f);J(m,q,n,p);return w};exports.useCollaborationContext=T;
@@ -105,6 +105,18 @@ function getHashtagRegexString() {
105
105
 
106
106
  const REGEX = new RegExp(getHashtagRegexString(), 'ig');
107
107
 
108
+ function isValidCharacter(character) {
109
+ return character === '' || character.search(/[\s.,\\\/#!$%\^&\*;:{}=\-`~()@]/) > -1;
110
+ }
111
+
112
+ function startsWithValidChar(string) {
113
+ return isValidCharacter(string[0]);
114
+ }
115
+
116
+ function endsWithValidChar(string) {
117
+ return isValidCharacter(string[string.length - 1]);
118
+ }
119
+
108
120
  function textNodeTransform(node) {
109
121
  if (!node.isSimpleText()) {
110
122
  return;
@@ -118,12 +130,27 @@ function textNodeTransform(node) {
118
130
  const matchArr = REGEX.exec(text);
119
131
 
120
132
  if (matchArr === null) {
133
+ if (currentNode != null) {
134
+ const nextSibling = currentNode.getNextSibling();
135
+
136
+ if (HashtagNode.$isHashtagNode(nextSibling) && !endsWithValidChar(text) && !isNextNodeValid(currentNode)) {
137
+ HashtagNode.$toggleHashtag(nextSibling);
138
+ }
139
+ }
140
+
121
141
  return;
122
142
  }
123
143
 
124
144
  const hashtagLength = matchArr[3].length + 1;
125
145
  const startOffset = matchArr.index + matchArr[1].length - adjustedOffset;
126
146
  const endOffset = startOffset + hashtagLength;
147
+ const prevChar = text[startOffset - 1] || '';
148
+ const nextChar = text[endOffset] || '';
149
+
150
+ if (startOffset === 0 && HashtagNode.$isHashtagNode(currentNode.getPreviousSibling()) || !isValidCharacter(prevChar) || !isValidCharacter(nextChar)) {
151
+ continue;
152
+ }
153
+
127
154
  let targetNode;
128
155
 
129
156
  if (startOffset === 0) {
@@ -137,9 +164,37 @@ function textNodeTransform(node) {
137
164
  }
138
165
  }
139
166
 
167
+ function isPreviousNodeValid(node) {
168
+ const previousNode = node.getPreviousSibling();
169
+ return previousNode === null || lexical.$isLineBreakNode(previousNode) || lexical.$isTextNode(previousNode) && !HashtagNode.$isHashtagNode(previousNode) && endsWithValidChar(previousNode.getTextContent());
170
+ }
171
+
172
+ function isNextNodeValid(node) {
173
+ const nextNode = node.getNextSibling();
174
+ return nextNode === null || lexical.$isLineBreakNode(nextNode) || lexical.$isTextNode(nextNode) && !HashtagNode.$isHashtagNode(nextNode) && startsWithValidChar(nextNode.getTextContent());
175
+ }
176
+
177
+ function $hashtagToPlainTextTransform(hashtagNode) {
178
+ // Check neighbors
179
+ if (!isPreviousNodeValid(hashtagNode) || !isNextNodeValid(hashtagNode)) {
180
+ $convertHashtagNodeToPlainTextNode(hashtagNode);
181
+ return;
182
+ }
183
+ }
184
+
185
+ function $convertHashtagNodeToPlainTextNode(node) {
186
+ const textNode = lexical.$createTextNode(node.getTextContent());
187
+ node.replace(textNode);
188
+ }
189
+
140
190
  function useHashtags(editor) {
141
191
  react.useEffect(() => {
142
- return editor.addTransform(lexical.TextNode, textNodeTransform);
192
+ const removePlainTextTransform = editor.addTransform(lexical.TextNode, textNodeTransform);
193
+ const removeHashtagToPlainTextTransform = editor.addTransform(HashtagNode.HashtagNode, $hashtagToPlainTextTransform);
194
+ return () => {
195
+ removePlainTextTransform();
196
+ removeHashtagToPlainTextTransform();
197
+ };
143
198
  }, [editor]);
144
199
  }
145
200
 
@@ -4,7 +4,10 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- var c=require("@lexical/react/LexicalComposerContext"),f=require("lexical"),g=require("lexical/HashtagNode"),h=require("react"),l=RegExp;
8
- const m=String.fromCharCode,n="A-Za-z\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u0241\u0250-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ee\u037a\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03ce\u03d0-\u03f5\u03f7-\u0481\u048a-\u04ce\u04d0-\u04f9\u0500-\u050f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0621-\u063a\u0640-\u064a\u066e-\u066f\u0671-\u06d3\u06d5\u06e5-\u06e6\u06ee-\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u076d\u0780-\u07a5\u07b1\u0904-\u0939\u093d\u0950\u0958-\u0961\u097d\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0-\u0ae1\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c60-\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0-\u0ce1\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d60-\u0d61\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32-\u0e33\u0e40-\u0e46\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edd\u0f00\u0f40-\u0f47\u0f49-\u0f6a\u0f88-\u0f8b\u1000-\u1021\u1023-\u1027\u1029-\u102a\u1050-\u1055\u10a0-\u10c5\u10d0-\u10fa\u10fc\u1100-\u1159\u115f-\u11a2\u11a8-\u11f9\u1200-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u1676\u1681-\u169a\u16a0-\u16ea\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19a9\u19c1-\u19c7\u1a00-\u1a16\u1d00-\u1dbf\u1e00-\u1e9b\u1ea0-\u1ef9\u1f00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u2094\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2131\u2133-\u2139\u213c-\u213f\u2145-\u2149\u2c00-\u2c2e\u2c30-\u2c5e\u2c80-\u2ce4\u2d00-\u2d25\u2d30-\u2d65\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3006\u3031-\u3035\u303b-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312c\u3131-\u318e\u31a0-\u31b7\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fbb\ua000-\ua48c\ua800-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\uac00-\ud7a3\uf900-\ufa2d\ufa30-\ufa6a\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\u0300-\u036f\u0483-\u0486\u0591-\u05b9\u05bb-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u0615\u064b-\u065e\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u0901-\u0903\u093c\u093e-\u094d\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7-\u09c8\u09cb-\u09cd\u09d7\u09e2-\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a70-\u0a71\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b43\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c82-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d43\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d82-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2-\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f3f\u0f71-\u0f84\u0f86-\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102c-\u1032\u1036-\u1039\u1056-\u1059\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b6-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u19b0-\u19c0\u19c8-\u19c9\u1a17-\u1a1b\u1dc0-\u1dc3\u20d0-\u20dc\u20e1\u20e5-\u20eb\u302a-\u302f\u3099-\u309a\ua802\ua806\ua80b\ua823-\ua827\ufb1e\ufe00-\ufe0f\ufe20-\ufe23\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253-\u0254\u0256-\u0257\u0259\u025b\u0263\u0268\u026f\u0272\u0289\u028b\u02bb\u0300-\u036f\u1e00-\u1eff\u0400-\u04ff\u0500-\u0527\u2de0-\u2dff\ua640-\ua69f\u0591-\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f4\ufb12-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4f\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06de-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0750-\u077f\u08a0\u08a2-\u08ac\u08e4-\u08fe\ufb50-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\u200c-\u200c\u0e01-\u0e3a\u0e40-\u0e4e\u1100-\u11ff\u3130-\u3185\ua960-\ua97f\uac00-\ud7af\ud7b0-\ud7ff\uffa1-\uffdc\u30a1-\u30fa\u30fc-\u30fe\uff66-\uff9f\uff10-\uff19\uff21-\uff3a\uff41-\uff5a\u3041-\u3096\u3099-\u309e\u3400-\u4dbf\u4e00-\u9fff"+(m(173824)+
9
- "-"+m(177983)+m(177984)+"-"+m(178207)+m(194560)+"-"+m(195103)+"\u3003\u3005\u303b"),{alpha:p,alphanumeric:q,hashChars:r}={alpha:n,alphanumeric:n+"0-9\u0660-\u0669\u06f0-\u06f9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\uff10-\uff19_",hashChars:"#\\uFF03"},t="["+q+"]",u=new l("(^|$|[^&/"+(q+"])([")+(r+"])(")+t+"*["+(p+"]")+
10
- t+"*)","ig");function v(a){if(a.isSimpleText())for(var w=a.getTextContent(),k=0;;){var b=u.exec(w);if(null===b)break;const d=b.index+b[1].length-k;b=d+(b[3].length+1);let e;0===d?[e,a]=a.splitText(b):[,e,a]=a.splitText(d,b);k+=b;g.$toggleHashtag(e)}}function x(a){h.useEffect(()=>a.addTransform(f.TextNode,v),[a])}module.exports=function(){const [a]=c.useLexicalComposerContext();x(a);return null};
7
+ var e=require("@lexical/react/LexicalComposerContext"),f=require("lexical"),g=require("lexical/HashtagNode"),h=require("react"),m=RegExp;
8
+ const n=String.fromCharCode,p="A-Za-z\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u0241\u0250-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ee\u037a\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03ce\u03d0-\u03f5\u03f7-\u0481\u048a-\u04ce\u04d0-\u04f9\u0500-\u050f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0621-\u063a\u0640-\u064a\u066e-\u066f\u0671-\u06d3\u06d5\u06e5-\u06e6\u06ee-\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u076d\u0780-\u07a5\u07b1\u0904-\u0939\u093d\u0950\u0958-\u0961\u097d\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0-\u0ae1\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c60-\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0-\u0ce1\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d60-\u0d61\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32-\u0e33\u0e40-\u0e46\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edd\u0f00\u0f40-\u0f47\u0f49-\u0f6a\u0f88-\u0f8b\u1000-\u1021\u1023-\u1027\u1029-\u102a\u1050-\u1055\u10a0-\u10c5\u10d0-\u10fa\u10fc\u1100-\u1159\u115f-\u11a2\u11a8-\u11f9\u1200-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u1676\u1681-\u169a\u16a0-\u16ea\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19a9\u19c1-\u19c7\u1a00-\u1a16\u1d00-\u1dbf\u1e00-\u1e9b\u1ea0-\u1ef9\u1f00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u2094\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2131\u2133-\u2139\u213c-\u213f\u2145-\u2149\u2c00-\u2c2e\u2c30-\u2c5e\u2c80-\u2ce4\u2d00-\u2d25\u2d30-\u2d65\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3006\u3031-\u3035\u303b-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312c\u3131-\u318e\u31a0-\u31b7\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fbb\ua000-\ua48c\ua800-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\uac00-\ud7a3\uf900-\ufa2d\ufa30-\ufa6a\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\u0300-\u036f\u0483-\u0486\u0591-\u05b9\u05bb-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u0615\u064b-\u065e\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u0901-\u0903\u093c\u093e-\u094d\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7-\u09c8\u09cb-\u09cd\u09d7\u09e2-\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a70-\u0a71\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b43\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c82-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d43\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d82-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2-\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f3f\u0f71-\u0f84\u0f86-\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102c-\u1032\u1036-\u1039\u1056-\u1059\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b6-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u19b0-\u19c0\u19c8-\u19c9\u1a17-\u1a1b\u1dc0-\u1dc3\u20d0-\u20dc\u20e1\u20e5-\u20eb\u302a-\u302f\u3099-\u309a\ua802\ua806\ua80b\ua823-\ua827\ufb1e\ufe00-\ufe0f\ufe20-\ufe23\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253-\u0254\u0256-\u0257\u0259\u025b\u0263\u0268\u026f\u0272\u0289\u028b\u02bb\u0300-\u036f\u1e00-\u1eff\u0400-\u04ff\u0500-\u0527\u2de0-\u2dff\ua640-\ua69f\u0591-\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f4\ufb12-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4f\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06de-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0750-\u077f\u08a0\u08a2-\u08ac\u08e4-\u08fe\ufb50-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\u200c-\u200c\u0e01-\u0e3a\u0e40-\u0e4e\u1100-\u11ff\u3130-\u3185\ua960-\ua97f\uac00-\ud7af\ud7b0-\ud7ff\uffa1-\uffdc\u30a1-\u30fa\u30fc-\u30fe\uff66-\uff9f\uff10-\uff19\uff21-\uff3a\uff41-\uff5a\u3041-\u3096\u3099-\u309e\u3400-\u4dbf\u4e00-\u9fff"+(n(173824)+
9
+ "-"+n(177983)+n(177984)+"-"+n(178207)+n(194560)+"-"+n(195103)+"\u3003\u3005\u303b"),{alpha:q,alphanumeric:r,hashChars:t}={alpha:p,alphanumeric:p+"0-9\u0660-\u0669\u06f0-\u06f9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\uff10-\uff19_",hashChars:"#\\uFF03"},u="["+r+"]",v=new m("(^|$|[^&/"+(r+"])([")+(t+"])(")+u+"*["+(q+"]")+
10
+ u+"*)","ig");function w(a){return""===a||-1<a.search(/[\s.,\\\/#!$%\^&\*;:{}=\-`~()@]/)}
11
+ function x(a){if(a.isSimpleText())for(var b=a.getTextContent(),c=0;;){var d=v.exec(b);if(null===d){if(null!=a){var k=a.getNextSibling();!g.$isHashtagNode(k)||w(b[b.length-1])||y(a)||g.$toggleHashtag(k)}break}const l=d.index+d[1].length-c;d=l+(d[3].length+1);const z=b[l-1]||"",A=b[d]||"";0===l&&g.$isHashtagNode(a.getPreviousSibling())||!w(z)||!w(A)||(0===l?[k,a]=a.splitText(d):[,k,a]=a.splitText(l,d),c+=d,g.$toggleHashtag(k))}}
12
+ function y(a){a=a.getNextSibling();return null===a||f.$isLineBreakNode(a)||f.$isTextNode(a)&&!g.$isHashtagNode(a)&&w(a.getTextContent()[0])}function B(a){var b=a.getPreviousSibling(),c;!(c=null===b||f.$isLineBreakNode(b))&&(c=f.$isTextNode(b)&&!g.$isHashtagNode(b))&&(b=b.getTextContent(),c=w(b[b.length-1]));c&&y(a)||(b=f.$createTextNode(a.getTextContent()),a.replace(b))}
13
+ function C(a){h.useEffect(()=>{const b=a.addTransform(f.TextNode,x),c=a.addTransform(g.HashtagNode,B);return()=>{b();c()}},[a])}module.exports=function(){const [a]=e.useLexicalComposerContext();C(a);return null};
package/package.json CHANGED
@@ -12,16 +12,16 @@
12
12
  "rich-text"
13
13
  ],
14
14
  "license": "MIT",
15
- "version": "0.1.13",
15
+ "version": "0.1.14",
16
16
  "dependencies": {
17
- "@lexical/helpers": "0.1.13",
18
- "@lexical/clipboard": "0.1.13",
19
- "@lexical/list": "0.1.13",
20
- "@lexical/table": "0.1.13",
21
- "@lexical/yjs": "0.1.13"
17
+ "@lexical/helpers": "0.1.14",
18
+ "@lexical/clipboard": "0.1.14",
19
+ "@lexical/list": "0.1.14",
20
+ "@lexical/table": "0.1.14",
21
+ "@lexical/yjs": "0.1.14"
22
22
  },
23
23
  "peerDependencies": {
24
- "lexical": "0.1.13",
24
+ "lexical": "0.1.14",
25
25
  "react": ">=17.x",
26
26
  "react-dom": ">=17.x"
27
27
  },