@connectedxm/entity-editor 0.0.1 → 0.0.2
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/README.md +205 -106
- package/dist/index.es.js +127 -127
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Entity Editor
|
|
2
2
|
|
|
3
|
-
A **zero-dependency**, lightweight React text editor
|
|
3
|
+
A **zero-dependency**, lightweight React text editor with intelligent entity recognition and real-time formatting using an innovative bitmap-based architecture.
|
|
4
4
|
|
|
5
5
|
## ✨ Features
|
|
6
6
|
|
|
@@ -9,12 +9,13 @@ A **zero-dependency**, lightweight React text editor that intelligently recogniz
|
|
|
9
9
|
- **@mentions** (`@username`)
|
|
10
10
|
- **#interests** (`#hashtag`)
|
|
11
11
|
- **🔗 Links** (`https://example.com`)
|
|
12
|
-
|
|
13
|
-
- **⚡ Real-time Processing**: Instant styling as you type with
|
|
12
|
+
- **📝 Rich Text Formatting**: Bold, italic, underline, strikethrough with keyboard shortcuts
|
|
13
|
+
- **⚡ Real-time Processing**: Instant styling as you type with optimized performance
|
|
14
14
|
- **🗜️ Bitmap Architecture**: Ultra-efficient character-level state tracking using bit operations
|
|
15
|
+
- **🎨 Customizable Styling**: Configurable colors and styles for all entity types
|
|
16
|
+
- **🔍 Search & Autocomplete**: Built-in search functionality for mentions and interests
|
|
17
|
+
- **⌨️ Keyboard Shortcuts**: Cmd/Ctrl+B/I/U/Shift+S for formatting
|
|
15
18
|
- **📱 Accessible**: Built on standard `contentEditable` with proper cursor management
|
|
16
|
-
- **🎨 Customizable**: CSS classes for easy theming
|
|
17
|
-
- **⌨️ Keyboard Shortcuts**: Cmd/Ctrl+B/I/U/S for formatting selected text
|
|
18
19
|
|
|
19
20
|
## 🏗️ Bitmap Architecture
|
|
20
21
|
|
|
@@ -58,53 +59,142 @@ npm install @connectedxm/entity-editor
|
|
|
58
59
|
### Basic Usage
|
|
59
60
|
|
|
60
61
|
```tsx
|
|
61
|
-
import React, { useState } from "react";
|
|
62
|
-
import
|
|
62
|
+
import React, { useState, useRef } from "react";
|
|
63
|
+
import {
|
|
64
|
+
Editor,
|
|
65
|
+
EditorRef,
|
|
66
|
+
Entity,
|
|
67
|
+
MarkState,
|
|
68
|
+
SearchEntity,
|
|
69
|
+
} from "@connectedxm/entity-editor";
|
|
63
70
|
|
|
64
71
|
function App() {
|
|
72
|
+
const editorRef = useRef<EditorRef>(null);
|
|
65
73
|
const [plainText, setPlainText] = useState("");
|
|
66
|
-
const [entities, setEntities] = useState([]);
|
|
67
|
-
const [
|
|
74
|
+
const [entities, setEntities] = useState<Entity[]>([]);
|
|
75
|
+
const [markState, setMarkState] = useState<MarkState>({
|
|
76
|
+
bold: false,
|
|
77
|
+
italic: false,
|
|
78
|
+
underline: false,
|
|
79
|
+
strike: false,
|
|
80
|
+
});
|
|
81
|
+
const [search, setSearch] = useState<SearchEntity | null>(null);
|
|
68
82
|
|
|
69
83
|
return (
|
|
70
84
|
<Editor
|
|
85
|
+
ref={editorRef}
|
|
71
86
|
plainText={plainText}
|
|
72
87
|
setPlainText={setPlainText}
|
|
73
88
|
entities={entities}
|
|
74
89
|
setEntities={setEntities}
|
|
90
|
+
markState={markState}
|
|
91
|
+
setMarkState={setMarkState}
|
|
75
92
|
search={search}
|
|
76
93
|
setSearch={setSearch}
|
|
77
|
-
options={{
|
|
78
|
-
|
|
94
|
+
options={{
|
|
95
|
+
mentions: true,
|
|
96
|
+
interests: true,
|
|
97
|
+
links: true,
|
|
98
|
+
}}
|
|
99
|
+
style={{
|
|
100
|
+
border: "1px solid #ccc",
|
|
101
|
+
minHeight: "100px",
|
|
102
|
+
padding: "10px",
|
|
103
|
+
}}
|
|
79
104
|
/>
|
|
80
105
|
);
|
|
81
106
|
}
|
|
82
107
|
```
|
|
83
108
|
|
|
84
|
-
### Advanced
|
|
85
|
-
|
|
86
|
-
The editor supports entity recognition options and debounced updates for performance:
|
|
109
|
+
### Advanced Usage with Custom Styling
|
|
87
110
|
|
|
88
111
|
```tsx
|
|
89
112
|
<Editor
|
|
113
|
+
ref={editorRef}
|
|
90
114
|
plainText={plainText}
|
|
91
115
|
setPlainText={setPlainText}
|
|
92
116
|
entities={entities}
|
|
93
117
|
setEntities={setEntities}
|
|
118
|
+
markState={markState}
|
|
119
|
+
setMarkState={setMarkState}
|
|
94
120
|
search={search}
|
|
95
121
|
setSearch={setSearch}
|
|
96
122
|
options={{
|
|
97
|
-
mentions: true,
|
|
98
|
-
interests: true,
|
|
99
|
-
links: true,
|
|
123
|
+
mentions: true,
|
|
124
|
+
interests: true,
|
|
125
|
+
links: true,
|
|
126
|
+
}}
|
|
127
|
+
entityStyles={{
|
|
128
|
+
mentionColor: "#1da1f2",
|
|
129
|
+
interestColor: "#ff6b35",
|
|
130
|
+
linkColor: "#9c27b0",
|
|
100
131
|
}}
|
|
101
|
-
debounceDelay={250} // Delay before processing changes
|
|
102
|
-
debounceMaxWait={500} // Maximum wait time for updates
|
|
103
132
|
className="custom-editor"
|
|
133
|
+
debug={false}
|
|
104
134
|
/>
|
|
105
135
|
```
|
|
106
136
|
|
|
107
|
-
###
|
|
137
|
+
### Using the Editor Ref API
|
|
138
|
+
|
|
139
|
+
The editor exposes imperative methods through a ref:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
const editorRef = useRef<EditorRef>(null);
|
|
143
|
+
|
|
144
|
+
// Programmatically select/replace entities
|
|
145
|
+
const handleMentionSelect = (username: string) => {
|
|
146
|
+
if (search?.type === "mention") {
|
|
147
|
+
editorRef.current?.selectEntity(
|
|
148
|
+
"mention",
|
|
149
|
+
search.startIndex,
|
|
150
|
+
search.endIndex,
|
|
151
|
+
username
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Toggle formatting programmatically
|
|
157
|
+
const makeBold = () => {
|
|
158
|
+
editorRef.current?.toggleMark("bold");
|
|
159
|
+
};
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Handling Search and Autocomplete
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
// Handle search results for mentions
|
|
166
|
+
{
|
|
167
|
+
search?.type === "mention" && (
|
|
168
|
+
<div className="autocomplete-dropdown">
|
|
169
|
+
<h4>Select a user to mention:</h4>
|
|
170
|
+
{searchResults.map((user) => (
|
|
171
|
+
<div key={user.id} onClick={() => handleMentionSelect(user.username)}>
|
|
172
|
+
{user.name} (@{user.username})
|
|
173
|
+
</div>
|
|
174
|
+
))}
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Handle search results for interests
|
|
180
|
+
{
|
|
181
|
+
search?.type === "interest" && (
|
|
182
|
+
<div className="autocomplete-dropdown">
|
|
183
|
+
<h4>Select an interest to tag:</h4>
|
|
184
|
+
{interestResults.map((interest) => (
|
|
185
|
+
<div
|
|
186
|
+
key={interest.id}
|
|
187
|
+
onClick={() => handleInterestSelect(interest.name)}
|
|
188
|
+
>
|
|
189
|
+
#{interest.name}
|
|
190
|
+
</div>
|
|
191
|
+
))}
|
|
192
|
+
</div>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Styling Entities with CSS
|
|
108
198
|
|
|
109
199
|
Add CSS to style the recognized entities:
|
|
110
200
|
|
|
@@ -117,34 +207,35 @@ Add CSS to style the recognized entities:
|
|
|
117
207
|
}
|
|
118
208
|
|
|
119
209
|
.activity-interest {
|
|
120
|
-
color: #
|
|
210
|
+
color: #ff6b35;
|
|
121
211
|
font-weight: 500;
|
|
122
212
|
}
|
|
123
213
|
|
|
124
214
|
.activity-link {
|
|
125
|
-
color: #
|
|
215
|
+
color: #9c27b0;
|
|
126
216
|
text-decoration: underline;
|
|
127
217
|
}
|
|
128
218
|
|
|
129
219
|
.activity-bold {
|
|
130
220
|
font-weight: bold;
|
|
131
221
|
}
|
|
222
|
+
|
|
132
223
|
.activity-italic {
|
|
133
224
|
font-style: italic;
|
|
134
225
|
}
|
|
226
|
+
|
|
135
227
|
.activity-underline {
|
|
136
228
|
text-decoration: underline;
|
|
137
229
|
}
|
|
230
|
+
|
|
138
231
|
.activity-strike {
|
|
139
232
|
text-decoration: line-through;
|
|
140
233
|
}
|
|
141
234
|
```
|
|
142
235
|
|
|
143
|
-
## 📊
|
|
144
|
-
|
|
145
|
-
The bitmap system automatically converts character-level bit data into structured entities for easy consumption:
|
|
236
|
+
## 📊 Entity Structure
|
|
146
237
|
|
|
147
|
-
|
|
238
|
+
The editor converts bitmap data into structured entities for easy consumption:
|
|
148
239
|
|
|
149
240
|
```typescript
|
|
150
241
|
interface Entity {
|
|
@@ -152,49 +243,38 @@ interface Entity {
|
|
|
152
243
|
startIndex: number;
|
|
153
244
|
endIndex: number;
|
|
154
245
|
marks: ("bold" | "italic" | "underline" | "strike")[];
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
interest?: string; // For
|
|
246
|
+
href?: string; // For links
|
|
247
|
+
username?: string; // For mentions
|
|
248
|
+
interest?: string; // For interests
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
interface SearchEntity {
|
|
252
|
+
type: "mention" | "interest" | "link";
|
|
253
|
+
search: string;
|
|
254
|
+
startIndex: number;
|
|
255
|
+
endIndex: number;
|
|
158
256
|
}
|
|
159
257
|
```
|
|
160
258
|
|
|
161
|
-
### Conversion
|
|
259
|
+
### Bitmap to Entity Conversion
|
|
162
260
|
|
|
163
261
|
1. **Bitmap Scanning**: The system scans through the bitmap array
|
|
164
262
|
2. **Grouping**: Consecutive characters with identical bit values are grouped together
|
|
165
263
|
3. **Entity Creation**: Each group becomes an entity with its type determined by the bitmap value
|
|
166
264
|
4. **Mark Extraction**: Formatting bits are converted to a `marks` array
|
|
167
265
|
|
|
168
|
-
**Example Conversion**:
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
// Input bitmap for "Hello @john"
|
|
172
|
-
bitmap: [0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 32];
|
|
173
|
-
|
|
174
|
-
// Output entities
|
|
175
|
-
entities: [
|
|
176
|
-
{
|
|
177
|
-
type: "mention",
|
|
178
|
-
startIndex: 6,
|
|
179
|
-
endIndex: 11,
|
|
180
|
-
marks: [],
|
|
181
|
-
mention: undefined, // Will be filled when mention is resolved
|
|
182
|
-
},
|
|
183
|
-
];
|
|
184
|
-
```
|
|
185
|
-
|
|
186
266
|
## 🎯 Recognition Patterns
|
|
187
267
|
|
|
188
268
|
- **Mentions**: `@username` (alphanumeric, underscores, hyphens, apostrophes)
|
|
189
269
|
- **Interests**: `#hashtag` (alphanumeric, underscores, hyphens)
|
|
190
270
|
- **Links**: `https://` or `http://` URLs
|
|
191
|
-
- **Formatting**:
|
|
271
|
+
- **Formatting**: Applied via keyboard shortcuts or toolbar
|
|
192
272
|
|
|
193
273
|
## ⚡ Performance Benefits
|
|
194
274
|
|
|
195
275
|
### Why Bitmap Architecture?
|
|
196
276
|
|
|
197
|
-
The bitmap approach provides significant performance advantages
|
|
277
|
+
The bitmap approach provides significant performance advantages:
|
|
198
278
|
|
|
199
279
|
**Memory Efficiency**:
|
|
200
280
|
|
|
@@ -206,48 +286,81 @@ The bitmap approach provides significant performance advantages over traditional
|
|
|
206
286
|
|
|
207
287
|
- Bit operations are CPU-native and extremely fast
|
|
208
288
|
- O(1) property checks vs O(n) object property lookups
|
|
209
|
-
- Efficient grouping algorithm for entity generation
|
|
210
289
|
- **5-10x faster** entity processing
|
|
211
290
|
|
|
212
291
|
**Update Performance**:
|
|
213
292
|
|
|
214
293
|
- Only modified bitmap regions trigger re-rendering
|
|
215
|
-
-
|
|
216
|
-
- Minimal React re-renders through optimized state management
|
|
294
|
+
- Optimized React re-renders through efficient state management
|
|
217
295
|
|
|
218
|
-
|
|
296
|
+
## 📝 API Reference
|
|
219
297
|
|
|
220
|
-
|
|
221
|
-
Traditional Approach vs Bitmap Approach
|
|
222
|
-
───────────────────── ──────────────────
|
|
223
|
-
Memory: 500KB+ Memory: 40KB
|
|
224
|
-
Update: 15-30ms Update: 2-5ms
|
|
225
|
-
Bundle: +50KB deps Bundle: 0KB deps
|
|
226
|
-
```
|
|
298
|
+
### Props
|
|
227
299
|
|
|
228
|
-
|
|
300
|
+
| Prop | Type | Required | Description |
|
|
301
|
+
| -------------- | ---------------------------------------- | -------- | ------------------------------------- |
|
|
302
|
+
| `ref` | `React.RefObject<EditorRef>` | Yes | Ref to access editor methods |
|
|
303
|
+
| `plainText` | `string` | Yes | The current plain text content |
|
|
304
|
+
| `setPlainText` | `(text: string) => void` | Yes | Callback to update plain text |
|
|
305
|
+
| `entities` | `Entity[]` | Yes | Array of recognized entities |
|
|
306
|
+
| `setEntities` | `(entities: Entity[]) => void` | Yes | Callback to update entities |
|
|
307
|
+
| `markState` | `MarkState` | Yes | Current formatting state |
|
|
308
|
+
| `setMarkState` | `(state: MarkState) => void` | Yes | Callback to update formatting state |
|
|
309
|
+
| `search` | `SearchEntity \| null` | Yes | Current search state for autocomplete |
|
|
310
|
+
| `setSearch` | `(search: SearchEntity \| null) => void` | Yes | Callback to update search state |
|
|
311
|
+
| `options` | `EntityOptions` | No | Configure which entities to detect |
|
|
312
|
+
| `entityStyles` | `StyleOptions` | No | Custom colors for entity types |
|
|
313
|
+
| `style` | `React.CSSProperties` | No | Inline styles for the editor |
|
|
314
|
+
| `className` | `string` | No | CSS class name for the editor |
|
|
315
|
+
| `debug` | `boolean` | No | Enable debug mode (default: false) |
|
|
316
|
+
|
|
317
|
+
### Interfaces
|
|
229
318
|
|
|
230
|
-
|
|
319
|
+
```typescript
|
|
320
|
+
interface EntityOptions {
|
|
321
|
+
mentions?: boolean; // Enable @mention detection
|
|
322
|
+
interests?: boolean; // Enable #hashtag detection
|
|
323
|
+
links?: boolean; // Enable URL detection
|
|
324
|
+
}
|
|
231
325
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
326
|
+
interface StyleOptions {
|
|
327
|
+
mentionColor?: string; // Custom color for mentions
|
|
328
|
+
interestColor?: string; // Custom color for interests
|
|
329
|
+
linkColor?: string; // Custom color for links
|
|
330
|
+
}
|
|
237
331
|
|
|
238
|
-
|
|
332
|
+
interface MarkState {
|
|
333
|
+
bold: boolean;
|
|
334
|
+
italic: boolean;
|
|
335
|
+
underline: boolean;
|
|
336
|
+
strike: boolean;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
interface EditorRef {
|
|
340
|
+
selectEntity: (
|
|
341
|
+
entityType: EntityType,
|
|
342
|
+
startIndex: number,
|
|
343
|
+
endIndex: number,
|
|
344
|
+
newText: string
|
|
345
|
+
) => void;
|
|
346
|
+
toggleMark: (markType: MarkType) => void;
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Keyboard Shortcuts
|
|
351
|
+
|
|
352
|
+
- **Ctrl/Cmd + B**: Toggle bold
|
|
353
|
+
- **Ctrl/Cmd + I**: Toggle italic
|
|
354
|
+
- **Ctrl/Cmd + U**: Toggle underline
|
|
355
|
+
- **Ctrl/Cmd + Shift + S**: Toggle strikethrough
|
|
239
356
|
|
|
240
|
-
|
|
357
|
+
## 🧪 Testing
|
|
241
358
|
|
|
242
|
-
|
|
243
|
-
- **Entity Conversion**: Bitmap-to-entity transformation accuracy
|
|
244
|
-
- **Keyboard Shortcuts**: Formatting toggle functionality via Cmd/Ctrl+B/I/U/S
|
|
245
|
-
- **Edge Cases**: Boundary conditions, overlapping entities, empty states
|
|
246
|
-
- **Performance**: Large document handling and update efficiency
|
|
359
|
+
Run the test suite:
|
|
247
360
|
|
|
248
361
|
```bash
|
|
249
|
-
npm test # Run
|
|
250
|
-
npm run test:run # Run tests once
|
|
362
|
+
npm test # Run tests in watch mode
|
|
363
|
+
npm run test:run # Run tests once
|
|
251
364
|
```
|
|
252
365
|
|
|
253
366
|
## 🏗️ Development
|
|
@@ -262,37 +375,19 @@ npm run dev
|
|
|
262
375
|
# Build for production
|
|
263
376
|
npm run build
|
|
264
377
|
|
|
265
|
-
#
|
|
266
|
-
npm
|
|
378
|
+
# Create local package
|
|
379
|
+
npm run local
|
|
267
380
|
```
|
|
268
381
|
|
|
269
|
-
##
|
|
270
|
-
|
|
271
|
-
### Props
|
|
382
|
+
## 🏆 Why Zero Dependencies?
|
|
272
383
|
|
|
273
|
-
|
|
274
|
-
| ----------------- | ---------------------------------------- | ------- | ------------------------------------- |
|
|
275
|
-
| `plainText` | `string` | - | The current plain text content |
|
|
276
|
-
| `setPlainText` | `(text: string) => void` | - | Callback to update plain text |
|
|
277
|
-
| `entities` | `Entity[]` | - | Array of recognized entities |
|
|
278
|
-
| `setEntities` | `(entities: Entity[]) => void` | - | Callback to update entities |
|
|
279
|
-
| `search` | `ActiveEntity \| null` | - | Current search state for autocomplete |
|
|
280
|
-
| `setSearch` | `(search: ActiveEntity \| null) => void` | - | Callback to update search state |
|
|
281
|
-
| `options` | `EntityOptions` | `{}` | Configure which entities to detect |
|
|
282
|
-
| `debounceDelay` | `number` | `250` | Delay before processing changes (ms) |
|
|
283
|
-
| `debounceMaxWait` | `number` | `500` | Maximum wait time for updates (ms) |
|
|
284
|
-
| `style` | `React.CSSProperties` | - | Optional inline styles |
|
|
285
|
-
| `className` | `string` | - | Optional CSS class name |
|
|
286
|
-
|
|
287
|
-
### EntityOptions
|
|
384
|
+
This editor proves that powerful text editing doesn't require heavy libraries:
|
|
288
385
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
```
|
|
386
|
+
- **Performance**: No bundle bloat, faster load times
|
|
387
|
+
- **Security**: No third-party vulnerabilities
|
|
388
|
+
- **Control**: Full understanding and control over every feature
|
|
389
|
+
- **Maintenance**: Easier updates and customization
|
|
390
|
+
- **Reliability**: No breaking changes from external dependencies
|
|
296
391
|
|
|
297
392
|
## 🤝 Contributing
|
|
298
393
|
|
|
@@ -302,16 +397,20 @@ This project maintains its zero-dependency philosophy and bitmap-based architect
|
|
|
302
397
|
2. **Bitmap First**: All new features should leverage the bitmap system
|
|
303
398
|
3. **Performance Focused**: Optimize for memory usage and processing speed
|
|
304
399
|
4. **TypeScript**: Maintain strict typing throughout
|
|
305
|
-
5. **Test Coverage**: Add comprehensive tests for
|
|
400
|
+
5. **Test Coverage**: Add comprehensive tests for new features
|
|
306
401
|
6. **API Stability**: Keep the component interface simple and focused
|
|
307
402
|
|
|
308
403
|
### Understanding the Codebase
|
|
309
404
|
|
|
405
|
+
- `src/Editor.tsx` - Main editor component
|
|
406
|
+
- `src/interfaces.ts` - TypeScript interfaces and types
|
|
310
407
|
- `src/helpers/bitmap.ts` - Core bitmap manipulation functions
|
|
311
408
|
- `src/helpers/entities.ts` - Bitmap-to-entity conversion logic
|
|
312
409
|
- `src/helpers/marks/` - Individual formatting bit operations
|
|
313
410
|
- `src/helpers/entities/` - Entity type detection and processing
|
|
314
411
|
- `src/helpers/dom.ts` - DOM manipulation and cursor management
|
|
412
|
+
- `src/helpers/keyboard.ts` - Keyboard shortcut handling
|
|
413
|
+
- `src/hooks/useDebounce.ts` - Debounce hook for performance
|
|
315
414
|
|
|
316
415
|
## 📄 License
|
|
317
416
|
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import C, { useState as
|
|
2
|
-
var J = { exports: {} },
|
|
1
|
+
import C, { useState as xe, useRef as he, useEffect as $e } from "react";
|
|
2
|
+
var J = { exports: {} }, B = {};
|
|
3
3
|
/**
|
|
4
4
|
* @license React
|
|
5
5
|
* react-jsx-runtime.production.js
|
|
@@ -10,8 +10,8 @@ var J = { exports: {} }, x = {};
|
|
|
10
10
|
* LICENSE file in the root directory of this source tree.
|
|
11
11
|
*/
|
|
12
12
|
var Ne;
|
|
13
|
-
function
|
|
14
|
-
if (Ne) return
|
|
13
|
+
function Ye() {
|
|
14
|
+
if (Ne) return B;
|
|
15
15
|
Ne = 1;
|
|
16
16
|
var e = Symbol.for("react.transitional.element"), t = Symbol.for("react.fragment");
|
|
17
17
|
function r(s, n, i) {
|
|
@@ -29,9 +29,9 @@ function Be() {
|
|
|
29
29
|
props: i
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
return
|
|
32
|
+
return B.Fragment = t, B.jsx = r, B.jsxs = r, B;
|
|
33
33
|
}
|
|
34
|
-
var
|
|
34
|
+
var x = {};
|
|
35
35
|
/**
|
|
36
36
|
* @license React
|
|
37
37
|
* react-jsx-runtime.development.js
|
|
@@ -42,7 +42,7 @@ var B = {};
|
|
|
42
42
|
* LICENSE file in the root directory of this source tree.
|
|
43
43
|
*/
|
|
44
44
|
var Ae;
|
|
45
|
-
function
|
|
45
|
+
function We() {
|
|
46
46
|
return Ae || (Ae = 1, process.env.NODE_ENV !== "production" && (function() {
|
|
47
47
|
function e(o) {
|
|
48
48
|
if (o == null) return null;
|
|
@@ -67,7 +67,7 @@ function $e() {
|
|
|
67
67
|
switch (typeof o.tag == "number" && console.error(
|
|
68
68
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
69
69
|
), o.$$typeof) {
|
|
70
|
-
case
|
|
70
|
+
case T:
|
|
71
71
|
return "Portal";
|
|
72
72
|
case ue:
|
|
73
73
|
return (o.displayName || "Context") + ".Provider";
|
|
@@ -99,8 +99,8 @@ function $e() {
|
|
|
99
99
|
}
|
|
100
100
|
if (a) {
|
|
101
101
|
a = console;
|
|
102
|
-
var
|
|
103
|
-
return
|
|
102
|
+
var m = a.error, k = typeof Symbol == "function" && Symbol.toStringTag && o[Symbol.toStringTag] || o.constructor.name || "Object";
|
|
103
|
+
return m.call(
|
|
104
104
|
a,
|
|
105
105
|
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
106
106
|
k
|
|
@@ -119,7 +119,7 @@ function $e() {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
function n() {
|
|
122
|
-
var o =
|
|
122
|
+
var o = g.A;
|
|
123
123
|
return o === null ? null : o.getOwner();
|
|
124
124
|
}
|
|
125
125
|
function i() {
|
|
@@ -133,14 +133,14 @@ function $e() {
|
|
|
133
133
|
return o.key !== void 0;
|
|
134
134
|
}
|
|
135
135
|
function l(o, a) {
|
|
136
|
-
function
|
|
136
|
+
function m() {
|
|
137
137
|
A || (A = !0, console.error(
|
|
138
138
|
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
139
139
|
a
|
|
140
140
|
));
|
|
141
141
|
}
|
|
142
|
-
|
|
143
|
-
get:
|
|
142
|
+
m.isReactWarning = !0, Object.defineProperty(o, "key", {
|
|
143
|
+
get: m,
|
|
144
144
|
configurable: !0
|
|
145
145
|
});
|
|
146
146
|
}
|
|
@@ -150,14 +150,14 @@ function $e() {
|
|
|
150
150
|
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
151
151
|
)), o = this.props.ref, o !== void 0 ? o : null;
|
|
152
152
|
}
|
|
153
|
-
function
|
|
154
|
-
return
|
|
153
|
+
function h(o, a, m, k, P, I, fe, de) {
|
|
154
|
+
return m = I.ref, o = {
|
|
155
155
|
$$typeof: S,
|
|
156
156
|
type: o,
|
|
157
157
|
key: a,
|
|
158
158
|
props: I,
|
|
159
159
|
_owner: P
|
|
160
|
-
}, (
|
|
160
|
+
}, (m !== void 0 ? m : null) !== null ? Object.defineProperty(o, "ref", {
|
|
161
161
|
enumerable: !1,
|
|
162
162
|
get: f
|
|
163
163
|
}) : Object.defineProperty(o, "ref", { enumerable: !1, value: null }), o._store = {}, Object.defineProperty(o._store, "validated", {
|
|
@@ -182,11 +182,11 @@ function $e() {
|
|
|
182
182
|
value: de
|
|
183
183
|
}), Object.freeze && (Object.freeze(o.props), Object.freeze(o)), o;
|
|
184
184
|
}
|
|
185
|
-
function N(o, a,
|
|
185
|
+
function N(o, a, m, k, P, I, fe, de) {
|
|
186
186
|
var b = a.children;
|
|
187
187
|
if (b !== void 0)
|
|
188
188
|
if (k)
|
|
189
|
-
if (
|
|
189
|
+
if (E(b)) {
|
|
190
190
|
for (k = 0; k < b.length; k++)
|
|
191
191
|
le(b[k]);
|
|
192
192
|
Object.freeze && Object.freeze(b);
|
|
@@ -197,8 +197,8 @@ function $e() {
|
|
|
197
197
|
else le(b);
|
|
198
198
|
if (d.call(a, "key")) {
|
|
199
199
|
b = e(o);
|
|
200
|
-
var D = Object.keys(a).filter(function(
|
|
201
|
-
return
|
|
200
|
+
var D = Object.keys(a).filter(function(Be) {
|
|
201
|
+
return Be !== "key";
|
|
202
202
|
});
|
|
203
203
|
k = 0 < D.length ? "{key: someKey, " + D.join(": ..., ") + ": ...}" : "{key: someKey}", p[b + k] || (D = 0 < D.length ? "{" + D.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
204
204
|
`A props object containing a "key" prop is being spread into JSX:
|
|
@@ -213,21 +213,21 @@ React keys must be passed directly to JSX without using spread:
|
|
|
213
213
|
b
|
|
214
214
|
), p[b + k] = !0);
|
|
215
215
|
}
|
|
216
|
-
if (b = null,
|
|
217
|
-
|
|
216
|
+
if (b = null, m !== void 0 && (r(m), b = "" + m), c(a) && (r(a.key), b = "" + a.key), "key" in a) {
|
|
217
|
+
m = {};
|
|
218
218
|
for (var Ee in a)
|
|
219
|
-
Ee !== "key" && (
|
|
220
|
-
} else
|
|
219
|
+
Ee !== "key" && (m[Ee] = a[Ee]);
|
|
220
|
+
} else m = a;
|
|
221
221
|
return b && l(
|
|
222
|
-
|
|
222
|
+
m,
|
|
223
223
|
typeof o == "function" ? o.displayName || o.name || "Unknown" : o
|
|
224
|
-
),
|
|
224
|
+
), h(
|
|
225
225
|
o,
|
|
226
226
|
b,
|
|
227
227
|
I,
|
|
228
228
|
P,
|
|
229
229
|
n(),
|
|
230
|
-
|
|
230
|
+
m,
|
|
231
231
|
fe,
|
|
232
232
|
de
|
|
233
233
|
);
|
|
@@ -235,36 +235,36 @@ React keys must be passed directly to JSX without using spread:
|
|
|
235
235
|
function le(o) {
|
|
236
236
|
typeof o == "object" && o !== null && o.$$typeof === S && o._store && (o._store.validated = 1);
|
|
237
237
|
}
|
|
238
|
-
var
|
|
238
|
+
var j = C, S = Symbol.for("react.transitional.element"), T = Symbol.for("react.portal"), L = Symbol.for("react.fragment"), U = Symbol.for("react.strict_mode"), F = Symbol.for("react.profiler"), V = Symbol.for("react.consumer"), ue = Symbol.for("react.context"), v = Symbol.for("react.forward_ref"), M = Symbol.for("react.suspense"), z = Symbol.for("react.suspense_list"), G = Symbol.for("react.memo"), X = Symbol.for("react.lazy"), ae = Symbol.for("react.activity"), u = Symbol.for("react.client.reference"), g = j.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, d = Object.prototype.hasOwnProperty, E = Array.isArray, R = console.createTask ? console.createTask : function() {
|
|
239
239
|
return null;
|
|
240
240
|
};
|
|
241
|
-
|
|
241
|
+
j = {
|
|
242
242
|
react_stack_bottom_frame: function(o) {
|
|
243
243
|
return o();
|
|
244
244
|
}
|
|
245
245
|
};
|
|
246
|
-
var A, O = {}, y =
|
|
247
|
-
|
|
246
|
+
var A, O = {}, y = j.react_stack_bottom_frame.bind(
|
|
247
|
+
j,
|
|
248
248
|
i
|
|
249
249
|
)(), _ = R(s(i)), p = {};
|
|
250
|
-
|
|
251
|
-
var I = 1e4 >
|
|
250
|
+
x.Fragment = L, x.jsx = function(o, a, m, k, P) {
|
|
251
|
+
var I = 1e4 > g.recentlyCreatedOwnerStacks++;
|
|
252
252
|
return N(
|
|
253
253
|
o,
|
|
254
254
|
a,
|
|
255
|
-
|
|
255
|
+
m,
|
|
256
256
|
!1,
|
|
257
257
|
k,
|
|
258
258
|
P,
|
|
259
259
|
I ? Error("react-stack-top-frame") : y,
|
|
260
260
|
I ? R(s(o)) : _
|
|
261
261
|
);
|
|
262
|
-
},
|
|
263
|
-
var I = 1e4 >
|
|
262
|
+
}, x.jsxs = function(o, a, m, k, P) {
|
|
263
|
+
var I = 1e4 > g.recentlyCreatedOwnerStacks++;
|
|
264
264
|
return N(
|
|
265
265
|
o,
|
|
266
266
|
a,
|
|
267
|
-
|
|
267
|
+
m,
|
|
268
268
|
!0,
|
|
269
269
|
k,
|
|
270
270
|
P,
|
|
@@ -272,13 +272,13 @@ React keys must be passed directly to JSX without using spread:
|
|
|
272
272
|
I ? R(s(o)) : _
|
|
273
273
|
);
|
|
274
274
|
};
|
|
275
|
-
})()),
|
|
275
|
+
})()), x;
|
|
276
276
|
}
|
|
277
277
|
var Oe;
|
|
278
|
-
function
|
|
279
|
-
return Oe || (Oe = 1, process.env.NODE_ENV === "production" ? J.exports =
|
|
278
|
+
function Ke() {
|
|
279
|
+
return Oe || (Oe = 1, process.env.NODE_ENV === "production" ? J.exports = Ye() : J.exports = We()), J.exports;
|
|
280
280
|
}
|
|
281
|
-
var
|
|
281
|
+
var Ue = Ke();
|
|
282
282
|
const Ie = () => {
|
|
283
283
|
const e = window.getSelection(), t = document.getElementById("entity-editor");
|
|
284
284
|
if (!e || !t) return { start: 0, end: 0 };
|
|
@@ -291,30 +291,30 @@ const Ie = () => {
|
|
|
291
291
|
return { start: n, end: c };
|
|
292
292
|
} else
|
|
293
293
|
return null;
|
|
294
|
-
},
|
|
294
|
+
}, Fe = (e, t) => {
|
|
295
295
|
const r = document.createTreeWalker(e, NodeFilter.SHOW_TEXT);
|
|
296
296
|
let s = 0, n = r.nextNode(), i = null, c = null, l = 0, f = 0;
|
|
297
297
|
for (; n; ) {
|
|
298
|
-
const
|
|
299
|
-
if (!i &&
|
|
298
|
+
const h = s + (n.textContent?.length || 0);
|
|
299
|
+
if (!i && h >= t.start && (i = n, l = t.start - s), !c && h >= t.end) {
|
|
300
300
|
c = n, f = t.end - s;
|
|
301
301
|
break;
|
|
302
302
|
}
|
|
303
|
-
s =
|
|
303
|
+
s = h, n = r.nextNode();
|
|
304
304
|
}
|
|
305
305
|
if (i && c) {
|
|
306
|
-
const
|
|
307
|
-
|
|
306
|
+
const h = document.createRange();
|
|
307
|
+
h.setStart(
|
|
308
308
|
i,
|
|
309
309
|
Math.min(l, i.textContent?.length || 0)
|
|
310
|
-
),
|
|
310
|
+
), h.setEnd(
|
|
311
311
|
c,
|
|
312
312
|
Math.min(f, c.textContent?.length || 0)
|
|
313
313
|
);
|
|
314
314
|
const N = window.getSelection();
|
|
315
|
-
N?.removeAllRanges(), N?.addRange(
|
|
315
|
+
N?.removeAllRanges(), N?.addRange(h);
|
|
316
316
|
}
|
|
317
|
-
},
|
|
317
|
+
}, Ve = (e, t, r) => {
|
|
318
318
|
let s = "", n = "", i = "", c = "";
|
|
319
319
|
t.includes("bold") && (n = "bold"), t.includes("italic") && (i = "italic"), (t.includes("underline") || e === "link") && (c += "underline"), t.includes("strike") && (c += " line-through"), e !== "segment" && (s = "#1da1f2", e === "mention" && r.mentionColor ? s = r.mentionColor : e === "interest" && r.interestColor ? s = r.interestColor : e === "link" && r.linkColor && (s = r.linkColor));
|
|
320
320
|
let l = "";
|
|
@@ -325,31 +325,31 @@ const Ie = () => {
|
|
|
325
325
|
let s = "", n = 0;
|
|
326
326
|
return t.forEach((i) => {
|
|
327
327
|
n < i.startIndex && (s += e.slice(n, i.startIndex));
|
|
328
|
-
const c = e.slice(i.startIndex, i.endIndex), l =
|
|
328
|
+
const c = e.slice(i.startIndex, i.endIndex), l = Ve(i.type, i.marks, r);
|
|
329
329
|
s += `<span style="${l}">${c}</span>`, n = i.endIndex;
|
|
330
330
|
}), s += e.slice(n), s;
|
|
331
|
-
},
|
|
331
|
+
}, ze = (e, t) => {
|
|
332
332
|
let r = !1;
|
|
333
333
|
e.key === "Enter" && !e.shiftKey ? (e.preventDefault(), document.execCommand("insertLineBreak"), r = !0) : (e.metaKey || e.ctrlKey) && (e.key === "b" ? (t("bold"), r = !0) : e.key === "i" ? (t("italic"), r = !0) : e.key === "u" ? (t("underline"), r = !0) : e.key === "s" && (t("strike"), r = !0)), r && e.preventDefault();
|
|
334
|
-
}, ee = 128,
|
|
334
|
+
}, ee = 128, Ge = /^(?<protocol>[a-z\-]+)?:?(?<host>\/\/.*\.[^\/]+)$/, Xe = "()[]{}", pe = "", Me = (e, t) => {
|
|
335
335
|
const r = Se(
|
|
336
336
|
e,
|
|
337
337
|
t,
|
|
338
|
-
|
|
339
|
-
|
|
338
|
+
Xe,
|
|
339
|
+
pe
|
|
340
340
|
);
|
|
341
|
-
return r?.search.match(
|
|
341
|
+
return r?.search.match(Ge) ? {
|
|
342
342
|
type: "link",
|
|
343
343
|
...r
|
|
344
344
|
} : null;
|
|
345
|
-
}, te = (e) => (e & ee) !== 0, ge = (e, t) => t ? e | ee : e & ~ee, re = 32,
|
|
345
|
+
}, te = (e) => (e & ee) !== 0, ge = (e, t) => t ? e | ee : e & ~ee, re = 32, Je = /^@[a-zA-Z0-9_'-]+$/, qe = `.,!?;()[]{}"'<>#`, ne = "@", De = (e, t) => {
|
|
346
346
|
const r = Se(
|
|
347
347
|
e,
|
|
348
348
|
t,
|
|
349
|
-
|
|
349
|
+
qe,
|
|
350
350
|
ne
|
|
351
351
|
);
|
|
352
|
-
return r?.search.match(
|
|
352
|
+
return r?.search.match(Je) ? {
|
|
353
353
|
type: "mention",
|
|
354
354
|
...r
|
|
355
355
|
} : null;
|
|
@@ -392,17 +392,17 @@ const Ie = () => {
|
|
|
392
392
|
let l = [...e];
|
|
393
393
|
const f = w(l, s);
|
|
394
394
|
if (oe(f) ? l = me(l, s, oe, Re) : ce(f) ? l = me(l, s, ce, ve) : te(f) && (l = me(l, s, te, ge)), n > 0 && l.splice(s, n), c > 0) {
|
|
395
|
-
let
|
|
396
|
-
r.bold && (
|
|
397
|
-
const N = new Array(c).fill(
|
|
395
|
+
let h = 0;
|
|
396
|
+
r.bold && (h = _e(h, !0)), r.italic && (h = ke(h, !0)), r.underline && (h = we(h, !0)), r.strike && (h = be(h, !0));
|
|
397
|
+
const N = new Array(c).fill(h);
|
|
398
398
|
l.splice(s, 0, ...N);
|
|
399
399
|
}
|
|
400
400
|
return l;
|
|
401
|
-
},
|
|
401
|
+
}, He = (e) => /\s/.test(e) || /[\u2000-\u200B\u2028\u2029\u3000]/.test(e), Se = (e, t, r, s) => {
|
|
402
402
|
if (t <= 0 || t > e.length)
|
|
403
403
|
return null;
|
|
404
404
|
let n = "", i = t - 1, c = t;
|
|
405
|
-
const l = (f) =>
|
|
405
|
+
const l = (f) => He(f) || r.includes(f);
|
|
406
406
|
for (let f = i; f >= 0; f--) {
|
|
407
407
|
if (l(e[f])) {
|
|
408
408
|
i = f + 1;
|
|
@@ -426,20 +426,20 @@ const Ie = () => {
|
|
|
426
426
|
startIndex: i,
|
|
427
427
|
endIndex: c
|
|
428
428
|
};
|
|
429
|
-
}, se = 64,
|
|
429
|
+
}, se = 64, Ze = `.,!?;()[]{}"'<>@`, Qe = /^#[\w-]+$/, ie = "#", Le = (e, t) => {
|
|
430
430
|
const r = Se(
|
|
431
431
|
e,
|
|
432
432
|
t,
|
|
433
|
-
|
|
433
|
+
Ze,
|
|
434
434
|
ie
|
|
435
435
|
);
|
|
436
|
-
return r?.search.match(
|
|
436
|
+
return r?.search.match(Qe) ? {
|
|
437
437
|
type: "interest",
|
|
438
438
|
...r
|
|
439
439
|
} : null;
|
|
440
|
-
}, ce = (e) => (e & se) !== 0, ve = (e, t) => t ? e | se : e & ~se,
|
|
440
|
+
}, ce = (e) => (e & se) !== 0, ve = (e, t) => t ? e | se : e & ~se, et = (e, t) => e.find(
|
|
441
441
|
(r) => r.startIndex <= t && r.endIndex > t
|
|
442
|
-
),
|
|
442
|
+
), tt = (e, t, r) => {
|
|
443
443
|
const s = [];
|
|
444
444
|
let n = 0;
|
|
445
445
|
for (; n < t.length; ) {
|
|
@@ -452,28 +452,28 @@ const Ie = () => {
|
|
|
452
452
|
let l = n;
|
|
453
453
|
for (; l + 1 < t.length && w(t, l + 1) === i; )
|
|
454
454
|
l++;
|
|
455
|
-
const f =
|
|
455
|
+
const f = rt(i, r), h = nt(i), N = {
|
|
456
456
|
type: f,
|
|
457
457
|
startIndex: c,
|
|
458
458
|
endIndex: l + 1,
|
|
459
|
-
marks:
|
|
460
|
-
username: f === "mention" ?
|
|
461
|
-
interest: f === "interest" ?
|
|
459
|
+
marks: h,
|
|
460
|
+
username: f === "mention" ? De(e, l)?.search.replace(ne, "") : void 0,
|
|
461
|
+
interest: f === "interest" ? Le(e, l)?.search.replace(
|
|
462
462
|
ie,
|
|
463
463
|
""
|
|
464
464
|
) : void 0,
|
|
465
|
-
href: f === "link" ?
|
|
465
|
+
href: f === "link" ? Me(e, c)?.search : void 0
|
|
466
466
|
};
|
|
467
467
|
s.push(N), n = l + 1;
|
|
468
468
|
}
|
|
469
469
|
return s;
|
|
470
|
-
},
|
|
470
|
+
}, rt = (e, t) => e & re && t.mentions ? "mention" : e & se && t.interests ? "interest" : e & ee && t.links ? "link" : (e & ($ | Y | K | W), "segment"), nt = (e) => {
|
|
471
471
|
const t = [];
|
|
472
472
|
return e & $ && t.push("bold"), e & Y && t.push("italic"), e & K && t.push("underline"), e & W && t.push("strike"), t;
|
|
473
473
|
}, w = (e, t) => {
|
|
474
474
|
const r = e[t];
|
|
475
475
|
return typeof r != "number" ? 0 : r;
|
|
476
|
-
},
|
|
476
|
+
}, ot = (e, t, r) => {
|
|
477
477
|
const s = w(e, t);
|
|
478
478
|
switch (r) {
|
|
479
479
|
case "mention":
|
|
@@ -484,7 +484,7 @@ const Ie = () => {
|
|
|
484
484
|
return ge(s, !0);
|
|
485
485
|
}
|
|
486
486
|
return s;
|
|
487
|
-
},
|
|
487
|
+
}, st = (e, t, r, s) => {
|
|
488
488
|
let n = w(e, t);
|
|
489
489
|
switch (r) {
|
|
490
490
|
case "bold":
|
|
@@ -503,7 +503,7 @@ const Ie = () => {
|
|
|
503
503
|
return e;
|
|
504
504
|
}
|
|
505
505
|
return e[t] = n, e;
|
|
506
|
-
},
|
|
506
|
+
}, it = (e, t, r) => {
|
|
507
507
|
const s = w(e, t);
|
|
508
508
|
switch (r) {
|
|
509
509
|
case "bold":
|
|
@@ -517,26 +517,26 @@ const Ie = () => {
|
|
|
517
517
|
default:
|
|
518
518
|
throw Error(`Invalid mark type: ${r}`);
|
|
519
519
|
}
|
|
520
|
-
},
|
|
520
|
+
}, ct = (e, t, r, s) => {
|
|
521
521
|
for (let n = e; n < t; n++)
|
|
522
|
-
if (!
|
|
522
|
+
if (!it(s, n, r)) return !1;
|
|
523
523
|
return !0;
|
|
524
|
-
},
|
|
524
|
+
}, je = (e) => oe(e) || ce(e) || te(e), lt = (e, t, r, s) => {
|
|
525
525
|
let n = [...e];
|
|
526
|
-
for (;
|
|
526
|
+
for (; je(w(e, t - 1)) && t > 0; )
|
|
527
527
|
t--;
|
|
528
|
-
for (;
|
|
528
|
+
for (; je(w(e, r)) && r < e.length; )
|
|
529
529
|
r++;
|
|
530
530
|
let i = !0;
|
|
531
|
-
|
|
531
|
+
ct(t, r, s, n) && (i = !1);
|
|
532
532
|
for (let c = t; c < r; c++)
|
|
533
|
-
n =
|
|
533
|
+
n = st(n, c, s, i);
|
|
534
534
|
return n;
|
|
535
|
-
},
|
|
535
|
+
}, Te = (e, t) => {
|
|
536
536
|
const r = new Array(e.length).fill(0);
|
|
537
537
|
for (let s = 0; s < e.length; s++) {
|
|
538
538
|
let n = 0;
|
|
539
|
-
const i =
|
|
539
|
+
const i = et(t, s);
|
|
540
540
|
if (i) {
|
|
541
541
|
i.type === "mention" ? n = Re(n, !0) : i.type === "interest" ? n = ve(n, !0) : i.type === "link" && (n = ge(n, !0));
|
|
542
542
|
for (const c of i.marks)
|
|
@@ -546,8 +546,8 @@ const Ie = () => {
|
|
|
546
546
|
}
|
|
547
547
|
return r;
|
|
548
548
|
}, ut = (e, t, r) => {
|
|
549
|
-
const [s, n] =
|
|
550
|
-
return
|
|
549
|
+
const [s, n] = xe(e), i = he(Date.now()), c = he(null), l = he(null);
|
|
550
|
+
return $e(() => (c.current && clearTimeout(c.current), l.current && clearTimeout(l.current), Date.now() - i.current, c.current = setTimeout(() => {
|
|
551
551
|
n(e), i.current = Date.now();
|
|
552
552
|
}, t), () => {
|
|
553
553
|
c.current && clearTimeout(c.current), l.current && clearTimeout(l.current);
|
|
@@ -562,23 +562,23 @@ const Ie = () => {
|
|
|
562
562
|
setMarkState: c,
|
|
563
563
|
search: l,
|
|
564
564
|
setSearch: f,
|
|
565
|
-
options:
|
|
565
|
+
options: h = {},
|
|
566
566
|
entityStyles: N = {},
|
|
567
567
|
debug: le = !1,
|
|
568
|
-
...
|
|
568
|
+
...j
|
|
569
569
|
}) => {
|
|
570
|
-
const S = C.useRef(null), [
|
|
571
|
-
|
|
570
|
+
const S = C.useRef(null), [T, L] = C.useState({ start: 0, end: 0 }), [U, F] = C.useState(!1), [V, ue] = C.useState(!1), [v, M] = C.useState(
|
|
571
|
+
Te(t, s)
|
|
572
572
|
);
|
|
573
573
|
e.current = {
|
|
574
|
-
selectEntity: (u,
|
|
574
|
+
selectEntity: (u, g, d, E) => {
|
|
575
575
|
if (!S.current) return;
|
|
576
576
|
let R = [...v];
|
|
577
|
-
u === "mention" ?
|
|
578
|
-
const A = t.slice(0,
|
|
579
|
-
O
|
|
580
|
-
for (let y =
|
|
581
|
-
R[y] =
|
|
577
|
+
u === "mention" ? E = ne + E : u === "interest" ? E = ie + E : u === "link" && (E = pe + E);
|
|
578
|
+
const A = t.slice(0, g) + E + t.slice(d), O = ye(t, A);
|
|
579
|
+
O ? R = Pe(v, O, i) : R = Te(A, s);
|
|
580
|
+
for (let y = g; y < g + E.length; y++)
|
|
581
|
+
R[y] = ot(R, y, u);
|
|
582
582
|
r(A), M(R), f(null);
|
|
583
583
|
},
|
|
584
584
|
toggleMark: (u) => {
|
|
@@ -592,29 +592,29 @@ const Ie = () => {
|
|
|
592
592
|
}
|
|
593
593
|
}, []), C.useEffect(() => {
|
|
594
594
|
if (!S.current) return;
|
|
595
|
-
const u =
|
|
596
|
-
S.current.innerHTML = d, n(u), V &&
|
|
595
|
+
const u = tt(t, v, h), g = Ie() ?? T, d = Ce(t, u, N);
|
|
596
|
+
S.current.innerHTML = d, n(u), V && Fe(S.current, g);
|
|
597
597
|
}, [v]);
|
|
598
|
-
const z = ut(
|
|
598
|
+
const z = ut(T, 500);
|
|
599
599
|
C.useEffect(() => {
|
|
600
|
-
let { start: u, end:
|
|
601
|
-
if (!d && !oe(w(v, u - 1)) && (d =
|
|
602
|
-
let
|
|
603
|
-
if (u ===
|
|
600
|
+
let { start: u, end: g } = z, d = null;
|
|
601
|
+
if (!d && !oe(w(v, u - 1)) && (d = De(t, u), d && (d.search = d.search.replace(ne, ""))), !d && !ce(w(v, u - 1)) && (d = Le(t, u), d && (d.search = d.search.replace(ie, ""))), !d && !te(w(v, u - 1)) && (d = Me(t, u)), d ? f(d) : l && f(null), U) return;
|
|
602
|
+
let E = !0, R = !0, A = !0, O = !0;
|
|
603
|
+
if (u === g)
|
|
604
604
|
if (u > 0) {
|
|
605
605
|
const _ = w(v, u - 1);
|
|
606
|
-
|
|
606
|
+
E = q(_), R = H(_), A = Q(_), O = Z(_);
|
|
607
607
|
} else {
|
|
608
608
|
const _ = w(v, u);
|
|
609
|
-
|
|
609
|
+
E = q(_), R = H(_), A = Q(_), O = Z(_);
|
|
610
610
|
}
|
|
611
611
|
else
|
|
612
|
-
for (let _ = u; _ <
|
|
612
|
+
for (let _ = u; _ < g; _++) {
|
|
613
613
|
const p = w(v, _);
|
|
614
|
-
|
|
614
|
+
E = q(p) ? E : !1, R = H(p) ? R : !1, A = Q(p) ? A : !1, O = Z(p) ? O : !1;
|
|
615
615
|
}
|
|
616
616
|
c({
|
|
617
|
-
bold:
|
|
617
|
+
bold: E,
|
|
618
618
|
italic: R,
|
|
619
619
|
underline: A,
|
|
620
620
|
strike: O
|
|
@@ -623,47 +623,47 @@ const Ie = () => {
|
|
|
623
623
|
const G = (u) => {
|
|
624
624
|
if (F(!0), !S.current)
|
|
625
625
|
return;
|
|
626
|
-
const { start:
|
|
627
|
-
if (
|
|
628
|
-
const R =
|
|
626
|
+
const { start: g, end: d } = T;
|
|
627
|
+
if (g !== d) {
|
|
628
|
+
const R = lt(v, g, d, u);
|
|
629
629
|
M(R);
|
|
630
630
|
}
|
|
631
|
-
const
|
|
632
|
-
u === "bold" ?
|
|
631
|
+
const E = { ...i };
|
|
632
|
+
u === "bold" ? E.bold = !i.bold : u === "italic" ? E.italic = !i.italic : u === "underline" ? E.underline = !i.underline : u === "strike" && (E.strike = !i.strike), c(E);
|
|
633
633
|
}, X = (u) => {
|
|
634
634
|
if (!S.current) return;
|
|
635
635
|
if (U && F(!1), u.target.textContent.length === 0) {
|
|
636
636
|
r(""), M([]), n([]);
|
|
637
637
|
return;
|
|
638
638
|
}
|
|
639
|
-
const
|
|
639
|
+
const g = u.target.innerText || "", d = ye(t, g);
|
|
640
640
|
if (d) {
|
|
641
|
-
const
|
|
641
|
+
const E = Pe(
|
|
642
642
|
v,
|
|
643
643
|
d,
|
|
644
644
|
i
|
|
645
645
|
);
|
|
646
|
-
M(
|
|
646
|
+
M(E);
|
|
647
647
|
}
|
|
648
|
-
r(
|
|
648
|
+
r(g);
|
|
649
649
|
}, ae = (u) => {
|
|
650
|
-
S.current &&
|
|
650
|
+
S.current && ze(u, G);
|
|
651
651
|
};
|
|
652
652
|
return C.useEffect(() => {
|
|
653
653
|
const u = () => {
|
|
654
|
-
const
|
|
655
|
-
(
|
|
654
|
+
const g = Ie() ?? { start: 0, end: 0 };
|
|
655
|
+
(g.start !== T.start || g.end !== T.end) && L(g);
|
|
656
656
|
};
|
|
657
657
|
return document.addEventListener("selectionchange", u), () => {
|
|
658
658
|
document.removeEventListener("selectionchange", u);
|
|
659
659
|
};
|
|
660
|
-
}, []), /* @__PURE__ */
|
|
660
|
+
}, []), /* @__PURE__ */ Ue.jsx(
|
|
661
661
|
"div",
|
|
662
662
|
{
|
|
663
663
|
id: "entity-editor",
|
|
664
664
|
ref: S,
|
|
665
|
-
style:
|
|
666
|
-
className:
|
|
665
|
+
style: j.style,
|
|
666
|
+
className: j.className,
|
|
667
667
|
contentEditable: !0,
|
|
668
668
|
onKeyDown: ae,
|
|
669
669
|
onInput: X
|