@atlarafirm/atlara-editor 1.0.0

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.
Files changed (68) hide show
  1. package/README.md +1381 -0
  2. package/dist/KaTeX_AMS-Regular.ttf +0 -0
  3. package/dist/KaTeX_AMS-Regular.woff +0 -0
  4. package/dist/KaTeX_AMS-Regular.woff2 +0 -0
  5. package/dist/KaTeX_Caligraphic-Bold.ttf +0 -0
  6. package/dist/KaTeX_Caligraphic-Bold.woff +0 -0
  7. package/dist/KaTeX_Caligraphic-Bold.woff2 +0 -0
  8. package/dist/KaTeX_Caligraphic-Regular.ttf +0 -0
  9. package/dist/KaTeX_Caligraphic-Regular.woff +0 -0
  10. package/dist/KaTeX_Caligraphic-Regular.woff2 +0 -0
  11. package/dist/KaTeX_Fraktur-Bold.ttf +0 -0
  12. package/dist/KaTeX_Fraktur-Bold.woff +0 -0
  13. package/dist/KaTeX_Fraktur-Bold.woff2 +0 -0
  14. package/dist/KaTeX_Fraktur-Regular.ttf +0 -0
  15. package/dist/KaTeX_Fraktur-Regular.woff +0 -0
  16. package/dist/KaTeX_Fraktur-Regular.woff2 +0 -0
  17. package/dist/KaTeX_Main-Bold.ttf +0 -0
  18. package/dist/KaTeX_Main-Bold.woff +0 -0
  19. package/dist/KaTeX_Main-Bold.woff2 +0 -0
  20. package/dist/KaTeX_Main-BoldItalic.ttf +0 -0
  21. package/dist/KaTeX_Main-BoldItalic.woff +0 -0
  22. package/dist/KaTeX_Main-BoldItalic.woff2 +0 -0
  23. package/dist/KaTeX_Main-Italic.ttf +0 -0
  24. package/dist/KaTeX_Main-Italic.woff +0 -0
  25. package/dist/KaTeX_Main-Italic.woff2 +0 -0
  26. package/dist/KaTeX_Main-Regular.ttf +0 -0
  27. package/dist/KaTeX_Main-Regular.woff +0 -0
  28. package/dist/KaTeX_Main-Regular.woff2 +0 -0
  29. package/dist/KaTeX_Math-BoldItalic.ttf +0 -0
  30. package/dist/KaTeX_Math-BoldItalic.woff +0 -0
  31. package/dist/KaTeX_Math-BoldItalic.woff2 +0 -0
  32. package/dist/KaTeX_Math-Italic.ttf +0 -0
  33. package/dist/KaTeX_Math-Italic.woff +0 -0
  34. package/dist/KaTeX_Math-Italic.woff2 +0 -0
  35. package/dist/KaTeX_SansSerif-Bold.ttf +0 -0
  36. package/dist/KaTeX_SansSerif-Bold.woff +0 -0
  37. package/dist/KaTeX_SansSerif-Bold.woff2 +0 -0
  38. package/dist/KaTeX_SansSerif-Italic.ttf +0 -0
  39. package/dist/KaTeX_SansSerif-Italic.woff +0 -0
  40. package/dist/KaTeX_SansSerif-Italic.woff2 +0 -0
  41. package/dist/KaTeX_SansSerif-Regular.ttf +0 -0
  42. package/dist/KaTeX_SansSerif-Regular.woff +0 -0
  43. package/dist/KaTeX_SansSerif-Regular.woff2 +0 -0
  44. package/dist/KaTeX_Script-Regular.ttf +0 -0
  45. package/dist/KaTeX_Script-Regular.woff +0 -0
  46. package/dist/KaTeX_Script-Regular.woff2 +0 -0
  47. package/dist/KaTeX_Size1-Regular.ttf +0 -0
  48. package/dist/KaTeX_Size1-Regular.woff +0 -0
  49. package/dist/KaTeX_Size1-Regular.woff2 +0 -0
  50. package/dist/KaTeX_Size2-Regular.ttf +0 -0
  51. package/dist/KaTeX_Size2-Regular.woff +0 -0
  52. package/dist/KaTeX_Size2-Regular.woff2 +0 -0
  53. package/dist/KaTeX_Size3-Regular.ttf +0 -0
  54. package/dist/KaTeX_Size3-Regular.woff +0 -0
  55. package/dist/KaTeX_Size3-Regular.woff2 +0 -0
  56. package/dist/KaTeX_Size4-Regular.ttf +0 -0
  57. package/dist/KaTeX_Size4-Regular.woff +0 -0
  58. package/dist/KaTeX_Size4-Regular.woff2 +0 -0
  59. package/dist/KaTeX_Typewriter-Regular.ttf +0 -0
  60. package/dist/KaTeX_Typewriter-Regular.woff +0 -0
  61. package/dist/KaTeX_Typewriter-Regular.woff2 +0 -0
  62. package/dist/atlara-editor.js +2 -0
  63. package/dist/atlara-editor.js.map +1 -0
  64. package/dist/fa-brands-400.woff2 +0 -0
  65. package/dist/fa-regular-400.woff2 +0 -0
  66. package/dist/fa-solid-900.woff2 +0 -0
  67. package/dist/fa-v4compatibility.woff2 +0 -0
  68. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,1381 @@
1
+ # AtlaraEditor
2
+
3
+ A powerful JavaScript library that transforms basic HTML textareas into full-featured rich-text editors with toolbar support, multiple view modes, and mathematical expression rendering.
4
+
5
+ ## Features
6
+
7
+ - **Rich Text Editing**: Full WYSIWYG editor with formatting capabilities
8
+ - **Page View**: Render content on a virtual piece of paper (8.5" x 11") with realistic margins, similar to Microsoft Word
9
+ - **Comprehensive Toolbar**:
10
+ - Text formatting (Bold, Italic, Underline, Strikethrough)
11
+ - Text alignment (Left, Center, Right)
12
+ - **Lists**:
13
+ - Bullet lists (Unordered)
14
+ - Numbered lists (Ordered)
15
+ - Multiple bullet styles (disc, circle, square)
16
+ - Multiple numbering styles (1,2,3 | a,b,c | i,ii,iii | etc.)
17
+ - Edit individual list item numbers with custom values
18
+ - Headings (H1, H2, H3) and Paragraph styles
19
+ - Insert links, images, and icons
20
+ - Undo/Redo functionality
21
+ - Page view toggle
22
+ - **Advanced Image Support**:
23
+ - Insert images with URL
24
+ - Specify pixel dimensions (width/height) when inserting
25
+ - Drag corner handles to resize images
26
+ - Proportional resizing maintains aspect ratio
27
+ - Visual resize handles on all images
28
+ - **Advanced Table Support**:
29
+ - Create tables with custom rows and columns
30
+ - Resizable columns (drag to resize)
31
+ - Resizable rows (drag to resize)
32
+ - Auto-fit columns to content (double-click column edge)
33
+ - Custom border colors with color picker
34
+ - Add/remove rows and columns dynamically
35
+ - Full manipulation toolbar
36
+ - **Column Layout Support**:
37
+ - Multi-column layouts (newspaper-style columns)
38
+ - 1-column, 2-column, and 3-column layouts
39
+ - Automatic text flow across columns
40
+ - Visual column dividers
41
+ - Easy toggle between layouts
42
+ - **Multiple View Modes**:
43
+ - **Rich Text Mode**: Visual editing with formatting toolbar
44
+ - **HTML Mode**: Direct HTML code editing
45
+ - **CSS Mode**: View and edit extracted inline styles
46
+ - **Mathematical Expression Support**:
47
+ - LaTeX rendering using KaTeX
48
+ - Native MathML support
49
+ - Configurable default font size for all math elements
50
+ - **Custom HTML Snippets**:
51
+ - Define custom snippet groups for reusable HTML content
52
+ - Browse and insert snippets via toolbar buttons
53
+ - Perfect for frequently used templates, components, or formulas
54
+ - **Icon Support**:
55
+ - Bootstrap Icons library with 1,800+ icons
56
+ - Font Awesome library with 30,000+ icons
57
+ - Custom icon URLs for your own images
58
+ - Easy-to-use icon browser modal
59
+ - **History Management**: Undo/redo with configurable history limit
60
+ - **Keyboard Shortcuts**:
61
+ - Ctrl/Cmd + B (Bold)
62
+ - Ctrl/Cmd + I (Italic)
63
+ - Ctrl/Cmd + U (Underline)
64
+ - Ctrl/Cmd + Z (Undo)
65
+ - Ctrl/Cmd + Shift + Z / Ctrl/Cmd + Y (Redo)
66
+ - **Plugin System**:
67
+ - Modular architecture - load only what you need
68
+ - Reduce JavaScript bundle size by selecting specific features
69
+ - Create custom plugins to extend functionality
70
+ - Dynamic plugin loading/unloading at runtime
71
+ - All features are now plugins (backward compatible)
72
+ - **Flexible Configuration**: Customizable toolbar, mode switching, and editor height
73
+ - **Easy Integration**: Simple API for getting and setting content
74
+ - **Backend API** (NEW!):
75
+ - Complete REST API for productization and distribution
76
+ - API key management with usage tracking
77
+ - Feature access control based on subscription plans
78
+ - Stripe payment integration
79
+ - Docker and Docker Compose support for easy deployment
80
+ - **Heroku deployment ready** - Deploy backend, frontend, editor library, and examples in one unified container
81
+ - See [backend/README.md](backend/README.md) for API details
82
+ - See [DOCKER.md](DOCKER.md) for Docker deployment instructions
83
+ - See [QUICK_HEROKU_DEPLOY.md](QUICK_HEROKU_DEPLOY.md) for Heroku deployment (or [HEROKU_DEPLOYMENT_REWORK.md](HEROKU_DEPLOYMENT_REWORK.md) for details)
84
+
85
+ ## Installation
86
+
87
+ ### Using npm
88
+
89
+ ```bash
90
+ npm install @atlarafirm/atlara-editor
91
+ ```
92
+
93
+ ### Using CDN
94
+
95
+ You can include AtlaraEditor directly in your HTML using a CDN link. This is the easiest way to get started without any build tools.
96
+
97
+ #### unpkg
98
+
99
+ ```html
100
+ <!-- Latest version -->
101
+ <script src="https://unpkg.com/@atlarafirm/atlara-editor@1.0.0/dist/atlara-editor.js"></script>
102
+
103
+ <!-- Or use the latest version (always up-to-date, but may break with major updates) -->
104
+ <script src="https://unpkg.com/@atlarafirm/atlara-editor/dist/atlara-editor.js"></script>
105
+ ```
106
+
107
+ #### jsDelivr
108
+
109
+ ```html
110
+ <!-- Latest version -->
111
+ <script src="https://cdn.jsdelivr.net/npm/@atlarafirm/atlara-editor@1.0.0/dist/atlara-editor.js"></script>
112
+
113
+ <!-- Or use the latest version -->
114
+ <script src="https://cdn.jsdelivr.net/npm/@atlarafirm/atlara-editor/dist/atlara-editor.js"></script>
115
+ ```
116
+
117
+ ### Direct Download
118
+
119
+ Download the `atlara-editor.js` file from the `dist` folder and include it in your HTML:
120
+
121
+ ```html
122
+ <script src="path/to/atlara-editor.js"></script>
123
+ ```
124
+
125
+ ## Usage
126
+
127
+ AtlaraEditor supports two initialization patterns: the **Global API** pattern (recommended for new projects) and the traditional constructor pattern (for backward compatibility).
128
+
129
+ ### Global API Pattern (Recommended)
130
+
131
+ The new global API provides instance management and a global event system:
132
+
133
+ ```html
134
+ <!DOCTYPE html>
135
+ <html>
136
+ <head>
137
+ <title>AtlaraEditor Example</title>
138
+ </head>
139
+ <body>
140
+ <textarea id="my-editor">
141
+ <h1>Hello World!</h1>
142
+ <p>Start editing here...</p>
143
+ </textarea>
144
+
145
+ <script src="dist/atlara-editor.js"></script>
146
+ <script>
147
+ // Initialize using global API
148
+ const editor = AtlaraEditor.init('#my-editor');
149
+
150
+ // Access from anywhere on the page
151
+ const editor = AtlaraEditor.getInstance('my-editor');
152
+ </script>
153
+ </body>
154
+ </html>
155
+ ```
156
+
157
+ ### Traditional Constructor Pattern
158
+
159
+ ```html
160
+ <script src="dist/atlara-editor.js"></script>
161
+ <script>
162
+ // Traditional way (still fully supported)
163
+ const editor = new AtlaraEditor('#my-editor');
164
+ </script>
165
+ ```
166
+
167
+ ### With Options
168
+
169
+ Both patterns support the same options:
170
+
171
+ ```javascript
172
+ // Global API
173
+ const editor = AtlaraEditor.init('#my-editor', {
174
+ toolbar: true, // Show toolbar (default: true)
175
+ modeSwitching: true, // Enable mode switching tabs (default: true)
176
+ mathSupport: true, // Enable LaTeX and MathML support (default: true)
177
+ mathFontSize: null, // Default font size for math (e.g., '20pt', '1.5em') (default: null)
178
+ height: '500px', // Custom editor height (default: '400px')
179
+ pageView: true, // Enable page view mode (default: true)
180
+ customSnippets: {} // Custom HTML snippet groups (default: {})
181
+ });
182
+
183
+ // Or traditional constructor
184
+ const editor = new AtlaraEditor('#my-editor', {
185
+ toolbar: true,
186
+ modeSwitching: true,
187
+ // ... same options
188
+ });
189
+ ```
190
+
191
+ ### Minimal Editor (No Toolbar)
192
+
193
+ ```javascript
194
+ const editor = AtlaraEditor.init('#my-editor', {
195
+ toolbar: false,
196
+ modeSwitching: false
197
+ });
198
+ ```
199
+
200
+ ### Editor with Custom HTML Snippets
201
+
202
+ ```javascript
203
+ const editor = new AtlaraEditor('#my-editor', {
204
+ customSnippets: {
205
+ 'math-components': [
206
+ {
207
+ name: 'Einstein Equation',
208
+ html: '<div class="equation">E = mc²</div>'
209
+ },
210
+ {
211
+ name: 'Pythagorean Theorem',
212
+ html: '<div class="equation">a² + b² = c²</div>'
213
+ }
214
+ ],
215
+ 'text-templates': [
216
+ {
217
+ name: 'Info Box',
218
+ html: '<div class="info">Important information here</div>'
219
+ }
220
+ ]
221
+ }
222
+ });
223
+ ```
224
+
225
+ ## Plugin System
226
+
227
+ AtlaraEditor features a modular plugin system that allows you to load only the features you need, significantly reducing bundle size.
228
+
229
+ ### Using the Plugin System
230
+
231
+ **Load all features (default):**
232
+ ```javascript
233
+ const editor = AtlaraEditor.init('#my-editor');
234
+ ```
235
+
236
+ **Load specific plugins only:**
237
+ ```javascript
238
+ const editor = AtlaraEditor.init('#my-editor', {
239
+ plugins: ['textFormatting', 'alignment', 'list', 'history']
240
+ });
241
+ ```
242
+
243
+ **Minimal editor:**
244
+ ```javascript
245
+ const editor = AtlaraEditor.init('#my-editor', {
246
+ plugins: ['textFormatting', 'history']
247
+ });
248
+ ```
249
+
250
+ ### Available Built-in Plugins
251
+
252
+ - `textFormatting` - Bold, italic, underline, strikethrough
253
+ - `alignment` - Text alignment (left, center, right)
254
+ - `list` - Bullet and numbered lists
255
+ - `blockFormatting` - Headings (H1-H3) and paragraphs
256
+ - `link` - Link insertion
257
+ - `image` - Image insertion and resizing
258
+ - `table` - Table creation and manipulation
259
+ - `column` - Multi-column layouts (1, 2, or 3 columns)
260
+ - `history` - Undo/redo functionality
261
+ - `pageView` - Page view mode
262
+ - `math` - LaTeX and MathML support
263
+
264
+ ### Creating Custom Plugins
265
+
266
+ ```javascript
267
+ import { Plugin } from '@atlarafirm/atlara-editor';
268
+
269
+ class MyCustomPlugin extends Plugin {
270
+ constructor(editor, options = {}) {
271
+ super(editor, options);
272
+ this.name = 'MyCustomPlugin';
273
+ }
274
+
275
+ getToolbarButtons() {
276
+ return [{
277
+ name: 'my-buttons',
278
+ buttons: [
279
+ { command: 'myCommand', label: '⚡', title: 'My Command' }
280
+ ]
281
+ }];
282
+ }
283
+
284
+ executeCommand(command, value) {
285
+ if (command === 'myCommand') {
286
+ // Your logic here
287
+ }
288
+ }
289
+
290
+ getMetadata() {
291
+ return {
292
+ name: 'My Custom Plugin',
293
+ version: '1.0.0',
294
+ description: 'Does something amazing',
295
+ author: 'Your Name'
296
+ };
297
+ }
298
+ }
299
+
300
+ // Register and use
301
+ const editor = AtlaraEditor.init('#my-editor');
302
+ editor.pluginManager.register('myCustom', MyCustomPlugin);
303
+ editor.pluginManager.load('myCustom');
304
+ ```
305
+
306
+ ### Dynamic Plugin Loading
307
+
308
+ ```javascript
309
+ // Load a plugin at runtime
310
+ editor.pluginManager.load('math');
311
+
312
+ // Unload a plugin
313
+ editor.pluginManager.unload('alignment');
314
+
315
+ // Check if loaded
316
+ if (editor.pluginManager.isLoaded('table')) {
317
+ console.log('Table plugin is available');
318
+ }
319
+ ```
320
+
321
+ For comprehensive documentation, see [PLUGIN_SYSTEM.md](PLUGIN_SYSTEM.md) and the plugin system demo in `examples/plugin-system-demo.html`.
322
+
323
+ ## API
324
+
325
+ ### Global API Methods
326
+
327
+ The Global API provides static methods for managing editor instances across your application.
328
+
329
+ #### `AtlaraEditor.init(textarea, options)`
330
+
331
+ Initialize a new editor instance with automatic instance tracking.
332
+
333
+ ```javascript
334
+ const editor = AtlaraEditor.init('#my-editor', { height: '500px' });
335
+ ```
336
+
337
+ - **textarea**: Either a textarea DOM element or a CSS selector string
338
+ - **options**: Configuration object (optional)
339
+ - **Returns**: Editor instance (returns existing instance if already initialized)
340
+
341
+ #### `AtlaraEditor.getInstance(id)`
342
+
343
+ Get an editor instance by its textarea ID.
344
+
345
+ ```javascript
346
+ const editor = AtlaraEditor.getInstance('my-editor');
347
+ if (editor) {
348
+ console.log(editor.getValue());
349
+ }
350
+ ```
351
+
352
+ #### `AtlaraEditor.getAllInstances()`
353
+
354
+ Get an array of all active editor instances.
355
+
356
+ ```javascript
357
+ const allEditors = AtlaraEditor.getAllInstances();
358
+ console.log(`Total editors: ${allEditors.length}`);
359
+ ```
360
+
361
+ #### `AtlaraEditor.destroyInstance(id)`
362
+
363
+ Destroy a specific editor instance by ID.
364
+
365
+ ```javascript
366
+ const destroyed = AtlaraEditor.destroyInstance('my-editor');
367
+ // Returns true if destroyed, false if not found
368
+ ```
369
+
370
+ #### `AtlaraEditor.destroyAll()`
371
+
372
+ Destroy all editor instances.
373
+
374
+ ```javascript
375
+ AtlaraEditor.destroyAll();
376
+ ```
377
+
378
+ #### `AtlaraEditor.on(event, callback)`
379
+
380
+ Register a global event listener.
381
+
382
+ ```javascript
383
+ AtlaraEditor.on('init', (data) => {
384
+ console.log(`Editor ${data.id} initialized`);
385
+ });
386
+ ```
387
+
388
+ Built-in events:
389
+ - **init**: Fired when an editor is initialized via `AtlaraEditor.init()`
390
+ - **destroy**: Fired when an editor is destroyed
391
+
392
+ #### `AtlaraEditor.off(event, callback)`
393
+
394
+ Remove a global event listener.
395
+
396
+ ```javascript
397
+ const handler = (data) => console.log(data);
398
+ AtlaraEditor.on('init', handler);
399
+ // Later...
400
+ AtlaraEditor.off('init', handler);
401
+ // Or remove all listeners for an event
402
+ AtlaraEditor.off('init');
403
+ ```
404
+
405
+ #### `AtlaraEditor.emit(event, data)`
406
+
407
+ Emit a custom event to all listeners.
408
+
409
+ ```javascript
410
+ AtlaraEditor.emit('custom-event', { message: 'Hello!' });
411
+ ```
412
+
413
+ ### Constructor (Traditional Pattern)
414
+
415
+ ```javascript
416
+ new AtlaraEditor(textarea, options)
417
+ ```
418
+
419
+ - **textarea**: Either a textarea DOM element or a CSS selector string
420
+ - **options**: Configuration object (optional)
421
+
422
+ **Note**: Instances created with `new AtlaraEditor()` are not tracked in the global instance map.
423
+
424
+ ### Instance Methods
425
+
426
+ #### `getValue()`
427
+ Get the current HTML content as a string.
428
+
429
+ ```javascript
430
+ const html = editor.getValue();
431
+ ```
432
+
433
+ #### `setValue(value)`
434
+ Set the editor content.
435
+
436
+ ```javascript
437
+ editor.setValue('<h1>New Content</h1><p>Some text...</p>');
438
+ ```
439
+
440
+ #### `getMode()`
441
+ Get the current view mode ('rich', 'html', or 'css').
442
+
443
+ ```javascript
444
+ const mode = editor.getMode(); // Returns: 'rich', 'html', or 'css'
445
+ ```
446
+
447
+ #### `setMode(mode)`
448
+ Switch to a different view mode.
449
+
450
+ ```javascript
451
+ editor.setMode('html'); // Switch to HTML mode
452
+ editor.setMode('rich'); // Switch to Rich Text mode
453
+ editor.setMode('css'); // Switch to CSS mode
454
+ ```
455
+
456
+ #### `destroy()`
457
+ Remove the editor and restore the original textarea.
458
+
459
+ ```javascript
460
+ editor.destroy();
461
+ ```
462
+
463
+ ## View Modes
464
+
465
+ ### Rich Text Mode
466
+ - Visual WYSIWYG editing
467
+ - Full toolbar functionality
468
+ - Real-time formatting
469
+
470
+ ### HTML Mode
471
+ - Direct HTML code editing
472
+ - Syntax-friendly monospace font
473
+ - Ideal for manual HTML adjustments
474
+
475
+ ### CSS Mode
476
+ - Automatically extracts inline styles from HTML
477
+ - Displays styles in CSS format
478
+ - Useful for viewing and understanding applied styles
479
+
480
+ ## Page View
481
+
482
+ The editor includes a **Page View** feature that renders content on a virtual piece of paper, similar to Microsoft Word:
483
+
484
+ - **Paper Size**: 8.5" x 11" (standard US Letter size)
485
+ - **Margins**: 1 inch on all sides
486
+ - **Appearance**: Realistic paper with shadow effect
487
+ - **Toggle**: Click the 📄 button in the toolbar to enable/disable
488
+
489
+ This feature provides a better visualization of how documents will look when printed and creates a more professional editing experience.
490
+
491
+ ```javascript
492
+ // Enable page view (default)
493
+ const editor = new AtlaraEditor('#my-editor', {
494
+ pageView: true
495
+ });
496
+
497
+ // Disable page view
498
+ const editor = new AtlaraEditor('#my-editor', {
499
+ pageView: false
500
+ });
501
+ ```
502
+
503
+ ## Custom HTML Snippets
504
+
505
+ The editor supports **Custom HTML Snippets**, allowing end users to define reusable HTML content that can be easily inserted via the toolbar.
506
+
507
+ ### How It Works
508
+
509
+ 1. **Define snippet groups** when initializing the editor
510
+ 2. Each group gets its own **⊕ button** in the toolbar
511
+ 3. Clicking the button opens a **modal** showing all snippets in that group
512
+ 4. Users can **preview** snippets and **insert** them with one click
513
+
514
+ ### Configuration
515
+
516
+ Add custom snippets through the `customSnippets` option:
517
+
518
+ ```javascript
519
+ const editor = new AtlaraEditor('#my-editor', {
520
+ customSnippets: {
521
+ 'math-components': [
522
+ {
523
+ name: 'Einstein Equation',
524
+ html: '<div style="text-align: center;">E = mc²</div>'
525
+ },
526
+ {
527
+ name: 'Pythagorean Theorem',
528
+ html: '<div style="text-align: center;">a² + b² = c²</div>'
529
+ }
530
+ ],
531
+ 'text-templates': [
532
+ {
533
+ name: 'Info Box',
534
+ html: '<div style="background: #e7f3ff; border-left: 4px solid #007bff; padding: 15px;"><strong>Note:</strong> Important information</div>'
535
+ },
536
+ {
537
+ name: 'Warning Box',
538
+ html: '<div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px;"><strong>Warning:</strong> Please be careful</div>'
539
+ }
540
+ ]
541
+ }
542
+ });
543
+ ```
544
+
545
+ ### Snippet Structure
546
+
547
+ Each snippet object has two properties:
548
+ - **`name`** (string): The display name shown in the snippet browser
549
+ - **`html`** (string): The HTML content to insert when the snippet is selected
550
+
551
+ ### Use Cases
552
+
553
+ Custom snippets are perfect for:
554
+ - **Mathematical formulas** and equations
555
+ - **Text templates** (headers, footers, callout boxes)
556
+ - **Reusable components** (contact forms, cards, tables)
557
+ - **Branded content** (company logos, disclaimers, signatures)
558
+ - **Code blocks** or special formatting
559
+
560
+ ### Security Note
561
+
562
+ Custom snippets are defined by developers during editor initialization and are treated as trusted content. Ensure that snippet HTML comes from trusted sources only, as it will be inserted directly into the editor without sanitization.
563
+
564
+ ## Icon Support
565
+
566
+ AtlaraEditor includes powerful icon support, allowing users to easily insert icons from popular icon libraries or custom icon URLs into their documents.
567
+
568
+ ### Features
569
+
570
+ - **Bootstrap Icons**: Access to 1,800+ high-quality icons from the Bootstrap Icons library
571
+ - **Font Awesome**: Access to 30,000+ icons from the world's most popular icon toolkit
572
+ - **Custom Icons**: Use your own icon images via URLs
573
+ - **Interactive Browser**: Beautiful modal interface to browse and select icons
574
+ - **Tab Navigation**: Switch between different icon sources with ease
575
+ - **Automatic CSS Loading**: Automatically injects required icon library CSS when needed
576
+
577
+ ### Configuration
578
+
579
+ Enable icon support when initializing the editor:
580
+
581
+ ```javascript
582
+ const editor = new AtlaraEditor('#my-editor', {
583
+ icons: {
584
+ enabled: true, // Enable icon support (default: true)
585
+ bootstrap: true, // Enable Bootstrap Icons (default: true)
586
+ fontAwesome: true, // Enable Font Awesome (default: true)
587
+ autoLoadCss: true, // Auto-inject CSS for icon libraries (default: true)
588
+ bootstrapCdn: 'https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css',
589
+ fontAwesomeCdn: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
590
+ customIcons: [ // Custom icon URLs (default: [])
591
+ {
592
+ name: 'My Logo',
593
+ url: 'https://example.com/logo.png'
594
+ },
595
+ {
596
+ name: 'Custom Icon',
597
+ url: 'https://example.com/icon.svg'
598
+ }
599
+ ]
600
+ }
601
+ });
602
+ ```
603
+
604
+ ### Automatic CSS Loading
605
+
606
+ **New in this version**: AtlaraEditor now automatically injects the required CSS for icon libraries when you open the icon modal. This ensures icons render properly without requiring you to manually include CSS links in your HTML.
607
+
608
+ **How it works:**
609
+ - When you click the icon button (⭐) to open the icon modal, the editor checks if the required CSS is already loaded
610
+ - If not loaded, it automatically injects the CSS into the document `<head>`
611
+ - Smart duplicate detection prevents loading the same CSS multiple times
612
+ - Works with both default CDN URLs and custom CDN URLs
613
+
614
+ **Configuration options:**
615
+ - **`autoLoadCss`** (default: `true`): Enable/disable automatic CSS injection
616
+ - **`bootstrapCdn`**: Custom CDN URL for Bootstrap Icons CSS
617
+ - **`fontAwesomeCdn`**: Custom CDN URL for Font Awesome CSS
618
+
619
+ **To disable auto-loading** (if you prefer to manage CSS yourself):
620
+ ```javascript
621
+ const editor = new AtlaraEditor('#my-editor', {
622
+ icons: {
623
+ enabled: true,
624
+ autoLoadCss: false // Disable automatic CSS injection
625
+ }
626
+ });
627
+ ```
628
+
629
+ ### Icon Sources
630
+
631
+ #### Bootstrap Icons
632
+
633
+ Bootstrap Icons are automatically loaded when you open the icon modal (if `autoLoadCss` is enabled).
634
+
635
+ Alternatively, you can manually include the CDN in your HTML:
636
+
637
+ ```html
638
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
639
+ ```
640
+
641
+ Bootstrap Icons are inserted as icon fonts:
642
+ ```html
643
+ <i class="bi bi-heart"></i>
644
+ ```
645
+
646
+ #### Font Awesome
647
+
648
+ Font Awesome CSS is automatically loaded when you open the icon modal (if `autoLoadCss` is enabled).
649
+
650
+ Alternatively, you can manually include the CDN in your HTML:
651
+
652
+ ```html
653
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
654
+ ```
655
+
656
+ Font Awesome icons are inserted as icon fonts:
657
+ ```html
658
+ <i class="fas fa-coffee"></i>
659
+ ```
660
+
661
+ #### Custom Icons
662
+
663
+ Custom icons are inserted as `<img>` tags with the URL you provide:
664
+
665
+ ```html
666
+ <img src="https://example.com/icon.png" alt="My Icon" style="max-width: 32px; max-height: 32px; vertical-align: middle;" />
667
+ ```
668
+
669
+ ### Usage
670
+
671
+ 1. Click the **⭐ icon button** in the toolbar
672
+ 2. Browse icons in the modal that appears
673
+ 3. Switch between tabs (Bootstrap Icons, Font Awesome, Custom Icons) if multiple sources are enabled
674
+ 4. Click on an icon to insert it at the cursor position
675
+
676
+ ### Examples
677
+
678
+ **Enable only Bootstrap Icons:**
679
+ ```javascript
680
+ const editor = new AtlaraEditor('#my-editor', {
681
+ icons: {
682
+ enabled: true,
683
+ bootstrap: true,
684
+ fontAwesome: false,
685
+ customIcons: []
686
+ }
687
+ });
688
+ ```
689
+
690
+ **Enable only Font Awesome:**
691
+ ```javascript
692
+ const editor = new AtlaraEditor('#my-editor', {
693
+ icons: {
694
+ enabled: true,
695
+ bootstrap: false,
696
+ fontAwesome: true,
697
+ customIcons: []
698
+ }
699
+ });
700
+ ```
701
+
702
+ **Use only custom icons:**
703
+ ```javascript
704
+ const editor = new AtlaraEditor('#my-editor', {
705
+ icons: {
706
+ enabled: true,
707
+ bootstrap: false,
708
+ fontAwesome: false,
709
+ customIcons: [
710
+ { name: 'Logo', url: 'https://example.com/logo.png' },
711
+ { name: 'Badge', url: 'https://example.com/badge.svg' }
712
+ ]
713
+ }
714
+ });
715
+ ```
716
+
717
+ **Use custom CDN URLs:**
718
+ ```javascript
719
+ const editor = new AtlaraEditor('#my-editor', {
720
+ icons: {
721
+ enabled: true,
722
+ bootstrap: true,
723
+ fontAwesome: true,
724
+ autoLoadCss: true,
725
+ bootstrapCdn: 'https://your-cdn.example.com/bootstrap-icons.css',
726
+ fontAwesomeCdn: 'https://your-cdn.example.com/font-awesome.css'
727
+ }
728
+ });
729
+ ```
730
+
731
+ **Disable icon support:**
732
+ ```javascript
733
+ const editor = new AtlaraEditor('#my-editor', {
734
+ icons: {
735
+ enabled: false
736
+ }
737
+ });
738
+ ```
739
+
740
+ ### Demo
741
+
742
+ See the `examples/icons-demo.html` and `examples/test-icon-css-injection.html` files for complete demos showcasing all icon features, including automatic CSS injection.
743
+
744
+ ## Image Support
745
+
746
+ AtlaraEditor provides comprehensive image functionality with resizing capabilities and dimension control.
747
+
748
+ ### Inserting Images
749
+
750
+ Click the **🖼** button in the toolbar to open the image insertion dialog:
751
+
752
+ 1. Enter the image URL (HTTP, HTTPS, or Data URL)
753
+ 2. Optionally specify alternative text for accessibility
754
+ 3. Optionally specify width in pixels
755
+ 4. Optionally specify height in pixels
756
+ 5. Click Insert
757
+
758
+ ```javascript
759
+ // You can also insert images programmatically
760
+ import * as SelectionUtils from './SelectionUtils';
761
+
762
+ // Insert with URL only
763
+ SelectionUtils.insertImage('https://example.com/image.jpg');
764
+
765
+ // Insert with alt text
766
+ SelectionUtils.insertImage('https://example.com/image.jpg', 'Description');
767
+
768
+ // Insert with dimensions
769
+ SelectionUtils.insertImage('https://example.com/image.jpg', 'Description', 400, 300);
770
+ ```
771
+
772
+ ### Resizing Images
773
+
774
+ After inserting an image, you can resize it visually:
775
+
776
+ #### Drag to Resize
777
+
778
+ - Hover over any corner of an image to see resize handles
779
+ - Click and drag any corner handle to resize the image
780
+ - **Proportional Resizing**: Dragging maintains the original aspect ratio
781
+ - **Minimum Size**: Images cannot be resized smaller than 50px
782
+
783
+ #### Visual Feedback
784
+
785
+ - Blue corner handles appear at all four corners: northwest, northeast, southwest, southeast
786
+ - Handles are visible when hovering over or interacting with images
787
+ - Cursor changes to indicate resize direction
788
+
789
+ ### Specify Dimensions
790
+
791
+ When inserting an image, you can specify exact pixel dimensions:
792
+
793
+ - **Width**: Enter the desired width in pixels
794
+ - **Height**: Enter the desired height in pixels
795
+ - **Leave blank**: Image will use its natural dimensions
796
+ - **Specify one**: Aspect ratio is maintained automatically
797
+
798
+ ### Technical Details
799
+
800
+ - Images are wrapped in a container div for resize handle positioning
801
+ - Resize handles are automatically added via MutationObserver
802
+ - All images get the `atlara-editor-image` class
803
+ - Resizing maintains aspect ratio for proportional scaling
804
+ - All image operations support undo/redo
805
+ - Minimum dimensions ensure usability
806
+
807
+ ### Example
808
+
809
+ ```javascript
810
+ const editor = new AtlaraEditor('#my-editor', {
811
+ toolbar: true,
812
+ height: '500px'
813
+ });
814
+
815
+ // Images are inserted interactively via the UI
816
+ // Resize handles appear automatically on all images
817
+ ```
818
+
819
+ ### Demo
820
+
821
+ See the `examples/image-resize-demo.html` file for a complete demo showcasing all image features.
822
+
823
+ ## Table Support
824
+
825
+ AtlaraEditor provides comprehensive table functionality with advanced resizing capabilities and customization options.
826
+
827
+ ### Creating Tables
828
+
829
+ Click the **⊞** button in the toolbar to open the table creation dialog:
830
+
831
+ 1. Specify the number of rows (1-20)
832
+ 2. Specify the number of columns (1-20)
833
+ 3. Choose a custom border color using the color picker
834
+ 4. Click Insert
835
+
836
+ ### Resizing Tables
837
+
838
+ #### Column Width Resizing
839
+
840
+ - Hover over the right edge of any column (except the last one) to see the resize cursor
841
+ - Click and drag to adjust the column width
842
+ - Minimum column width is 50px
843
+
844
+ #### Row Height Resizing
845
+
846
+ - Hover over the bottom edge of any row (except the last one) to see the resize cursor
847
+ - Click and drag to adjust the row height
848
+ - Minimum row height is 30px
849
+
850
+ #### Auto-Fit to Content
851
+
852
+ - **Double-click** the right edge of any column to automatically fit the column width to its content
853
+ - The editor calculates the maximum content width across all cells in the column
854
+
855
+ ### Custom Border Colors
856
+
857
+ When creating a table, you can specify a custom border color:
858
+
859
+ - Use the color picker in the table creation dialog
860
+ - Default border color is #dddddd (light gray)
861
+ - Border colors are preserved when adding new rows or columns
862
+
863
+ ### Table Manipulation
864
+
865
+ Use the table manipulation buttons in the toolbar:
866
+
867
+ - **↑+** Add Row Above - Insert a row above the current cursor position
868
+ - **↓+** Add Row Below - Insert a row below the current cursor position
869
+ - **←+** Add Column Left - Insert a column to the left of the cursor
870
+ - **→+** Add Column Right - Insert a column to the right of the cursor
871
+ - **↕−** Remove Row - Delete the row containing the cursor
872
+ - **↔−** Remove Column - Delete the column containing the cursor
873
+ - **⊠** Delete Table - Remove the entire table
874
+
875
+ ### Technical Details
876
+
877
+ - Tables use `table-layout: fixed` for predictable resizing
878
+ - Resize handles are automatically added via MutationObserver
879
+ - Border colors are stored as data attributes on table elements
880
+ - All table operations support undo/redo
881
+ - Minimum dimensions ensure usability
882
+
883
+ ### Example
884
+
885
+ ```javascript
886
+ const editor = new AtlaraEditor('#my-editor', {
887
+ toolbar: true,
888
+ height: '600px'
889
+ });
890
+
891
+ // Tables are created interactively via the UI
892
+ // Resize handles appear automatically when tables are inserted
893
+ ```
894
+
895
+ ### Demo
896
+
897
+ See the `examples/table-demo.html` and `examples/table-resize-demo.html` files for complete demos showcasing all table features.
898
+
899
+ ## Column Layout Support
900
+
901
+ AtlaraEditor supports multi-column layouts, similar to newspaper columns, allowing you to create professional-looking documents with text flowing across multiple columns.
902
+
903
+ ### Features
904
+
905
+ - **Multiple Column Options**: Choose between 1-column (normal), 2-column, or 3-column layouts
906
+ - **Automatic Text Flow**: Content flows naturally from one column to the next
907
+ - **Visual Column Dividers**: Clear separation between columns with 1px borders
908
+ - **Consistent Spacing**: 20px gap between columns for optimal readability
909
+ - **Element Preservation**: Headings, images, tables, and paragraphs avoid breaking across columns
910
+
911
+ ### Using Column Layouts
912
+
913
+ Click the column buttons in the toolbar:
914
+
915
+ - **1 Col** - Single column layout (removes columns, returns to normal)
916
+ - **2 Col** - Two-column layout
917
+ - **3 Col** - Three-column layout
918
+
919
+ ### How It Works
920
+
921
+ When you apply a column layout:
922
+
923
+ 1. Your content is wrapped in a column container
924
+ 2. CSS multi-column properties automatically flow the text
925
+ 3. Column dividers appear between columns
926
+ 4. Elements like headings and images stay intact (no awkward breaks)
927
+
928
+ ### Toggling Between Layouts
929
+
930
+ You can easily switch between different column layouts:
931
+
932
+ - Apply 2 columns to your content
933
+ - Switch to 3 columns for more compact layout
934
+ - Return to 1 column for normal viewing
935
+
936
+ ### Programmatic Usage
937
+
938
+ ```javascript
939
+ // Initialize editor (column support is enabled by default)
940
+ const editor = AtlaraEditor.init('#my-editor', {
941
+ toolbar: true,
942
+ height: '600px'
943
+ });
944
+
945
+ // Access the column plugin
946
+ const columnPlugin = editor.pluginManager.get('column');
947
+
948
+ // Apply 2-column layout programmatically
949
+ columnPlugin.setColumnCount(2);
950
+
951
+ // Apply 3-column layout
952
+ columnPlugin.setColumnCount(3);
953
+
954
+ // Remove columns (back to single column)
955
+ columnPlugin.setColumnCount(1);
956
+ ```
957
+
958
+ ### Use Cases
959
+
960
+ Column layouts are perfect for:
961
+
962
+ - **Newsletters**: Create professional company newsletters
963
+ - **Magazine Articles**: Design magazine-style content
964
+ - **Brochures**: Marketing materials with attractive layouts
965
+ - **Academic Papers**: Conference proceedings with multi-column format
966
+ - **Reports**: Make long reports more readable
967
+
968
+ ### Technical Details
969
+
970
+ - Uses CSS `column-count`, `column-gap`, and `column-rule` properties
971
+ - Content is wrapped in containers with class `atlara-column-container`
972
+ - Automatic break-inside prevention for common elements
973
+ - Full undo/redo support
974
+ - Compatible with page view mode
975
+
976
+ ### Example
977
+
978
+ ```javascript
979
+ const editor = new AtlaraEditor('#my-editor', {
980
+ toolbar: true,
981
+ pageView: true,
982
+ height: '600px'
983
+ });
984
+
985
+ // Columns are applied interactively via toolbar buttons
986
+ // Or programmatically using the column plugin
987
+ ```
988
+
989
+ ### Demo
990
+
991
+ See the `examples/column-demo.html` file for a complete interactive demo showcasing all column features.
992
+
993
+ ## Math Support
994
+
995
+ ### LaTeX
996
+
997
+ Click the "TeX" button in the toolbar or use the API:
998
+
999
+ ```javascript
1000
+ // Renders using KaTeX
1001
+ // Example: E = mc^2
1002
+ ```
1003
+
1004
+ ### MathML
1005
+
1006
+ Click the "ML" button to insert MathML code directly:
1007
+
1008
+ ```xml
1009
+ <math>
1010
+ <mrow>
1011
+ <mi>E</mi>
1012
+ <mo>=</mo>
1013
+ <mi>m</mi>
1014
+ <msup>
1015
+ <mi>c</mi>
1016
+ <mn>2</mn>
1017
+ </msup>
1018
+ </mrow>
1019
+ </math>
1020
+ ```
1021
+
1022
+ ### Configuring Math Font Size
1023
+
1024
+ You can set a default font size for all mathematical expressions using the `mathFontSize` option:
1025
+
1026
+ ```javascript
1027
+ const editor = new AtlaraEditor('#my-editor', {
1028
+ mathSupport: true,
1029
+ mathFontSize: '20pt' // All math will render at 20pt by default
1030
+ });
1031
+ ```
1032
+
1033
+ The `mathFontSize` option accepts any valid CSS font-size value:
1034
+ - **Absolute sizes**: `'12pt'`, `'16pt'`, `'20pt'`, `'24pt'`
1035
+ - **Relative sizes**: `'1.2em'`, `'1.5em'`, `'120%'`
1036
+ - **Keywords**: `'larger'`, `'smaller'` (not recommended)
1037
+
1038
+ **Notes:**
1039
+ - When `mathFontSize` is not specified (or set to `null`), math elements render at the browser's default size
1040
+ - Users can still change individual math element sizes using the Font Size dropdown in the toolbar
1041
+ - The default size only applies to newly inserted math and math loaded from content
1042
+ - Existing math elements with explicit font sizes are not overridden
1043
+
1044
+ **Example:**
1045
+
1046
+ ```javascript
1047
+ // Create an editor with large math by default
1048
+ const editor = new AtlaraEditor('#scientific-doc', {
1049
+ mathSupport: true,
1050
+ mathFontSize: '24pt' // Great for presentations
1051
+ });
1052
+
1053
+ // Create an editor with compact math
1054
+ const compactEditor = new AtlaraEditor('#compact-doc', {
1055
+ mathSupport: true,
1056
+ mathFontSize: '12pt' // Good for dense documentation
1057
+ });
1058
+
1059
+ // Create an editor with proportional math sizing
1060
+ const flexEditor = new AtlaraEditor('#flex-doc', {
1061
+ mathSupport: true,
1062
+ mathFontSize: '1.5em' // Scales with surrounding text
1063
+ });
1064
+ ```
1065
+
1066
+ See `demo-math-font-size.html` for a complete working example.
1067
+
1068
+ ## Development
1069
+
1070
+ ### Build
1071
+
1072
+ ```bash
1073
+ npm run build
1074
+ ```
1075
+
1076
+ ### Run Tests
1077
+
1078
+ ```bash
1079
+ npm test
1080
+ ```
1081
+
1082
+ ### Lint Code
1083
+
1084
+ ```bash
1085
+ npm run lint
1086
+ ```
1087
+
1088
+ ### Development Mode (with watch)
1089
+
1090
+ ```bash
1091
+ npm run dev
1092
+ ```
1093
+
1094
+ ## Testing
1095
+
1096
+ The library includes a comprehensive test suite covering:
1097
+ - Initialization and configuration
1098
+ - Content management
1099
+ - Mode switching
1100
+ - Toolbar commands
1101
+ - History management (undo/redo)
1102
+ - Math support
1103
+ - Events and synchronization
1104
+ - CSS extraction
1105
+
1106
+ Run tests with:
1107
+
1108
+ ```bash
1109
+ npm test
1110
+ ```
1111
+
1112
+ ## Browser Support
1113
+
1114
+ AtlaraEditor works in all modern browsers that support:
1115
+ - ES6+ JavaScript
1116
+ - ContentEditable API
1117
+ - Modern Selection API and Range API
1118
+ - DOMParser API
1119
+ - CSS Grid/Flexbox
1120
+
1121
+ Tested in:
1122
+ - Chrome/Edge 90+
1123
+ - Firefox 88+
1124
+ - Safari 14+
1125
+
1126
+ ## Security Considerations
1127
+
1128
+ AtlaraEditor is designed to work with HTML content and allows users to edit and render HTML directly. When using this library:
1129
+
1130
+ - **Content Sanitization**: If you're accepting content from untrusted sources, you should sanitize the HTML before passing it to the editor to prevent XSS attacks. Consider using a library like [DOMPurify](https://github.com/cure53/DOMPurify) to sanitize user input.
1131
+ - **Trusted Content**: The library is best suited for environments where the content is created by trusted users (e.g., internal content management systems, personal note-taking apps).
1132
+ - **Server-Side Validation**: Always validate and sanitize content on the server side before storing or displaying it to other users.
1133
+
1134
+ Example of safe usage with DOMPurify:
1135
+
1136
+ ```javascript
1137
+ import DOMPurify from 'dompurify';
1138
+
1139
+ const editor = new AtlaraEditor('#my-editor');
1140
+
1141
+ // When loading untrusted content
1142
+ const untrustedContent = getUserContent();
1143
+ const cleanContent = DOMPurify.sanitize(untrustedContent);
1144
+ editor.setValue(cleanContent);
1145
+
1146
+ // When saving content
1147
+ const content = editor.getValue();
1148
+ // Send to server for validation and sanitization
1149
+ ```
1150
+
1151
+ ## Examples
1152
+
1153
+ See the `examples/index.html` file for a complete demo showcasing all features.
1154
+
1155
+ ## Technical Details
1156
+
1157
+ ### Modern Selection API and Range API
1158
+
1159
+ AtlaraEditor uses the modern [Selection API](https://developer.mozilla.org/en-US/docs/Web/API/Selection) and [Range API](https://developer.mozilla.org/en-US/docs/Web/API/Range) for all text selection and manipulation operations. This ensures compatibility with current web standards and future browser versions.
1160
+
1161
+ The deprecated `document.execCommand()` API has been completely replaced with modern alternatives:
1162
+ - Text formatting (bold, italic, underline, strikethrough) uses direct DOM manipulation with Range objects
1163
+ - Block formatting uses Range-based node manipulation
1164
+ - Link and image insertion uses Range.insertNode()
1165
+ - HTML insertion uses document fragments with Range API
1166
+
1167
+ ## Known Limitations
1168
+
1169
+ - **Browser Dialogs**: Link insertion currently uses browser `prompt()` dialogs. A future version may implement custom modal dialogs for better UX.
1170
+
1171
+ ## Frontend Platform
1172
+
1173
+ AtlaraEditor includes a complete web application frontend that provides a professional interface for users to manage their accounts, API keys, and test the editor! The frontend offers:
1174
+
1175
+ ### Features
1176
+
1177
+ - **Landing Page**: Modern marketing site with features, pricing, and call-to-actions
1178
+ - **Authentication**: Sign in, sign up, password reset, and session management
1179
+ - **User Dashboard**: Overview of API usage, statistics, and quick actions
1180
+ - **API Key Management**: Create, view, copy, and delete API keys
1181
+ - **Editor Playground**: Live testing environment with plan-based feature access
1182
+ - **Settings & Billing**: Profile management, subscription plans, and preferences
1183
+ - **Responsive Design**: Mobile, tablet, and desktop optimized
1184
+
1185
+ ### Quick Start
1186
+
1187
+ ```bash
1188
+ # Navigate to frontend directory
1189
+ cd frontend
1190
+
1191
+ # Serve the application
1192
+ python -m http.server 8080
1193
+ # Or using Node.js
1194
+ npx http-server . -p 8080
1195
+ ```
1196
+
1197
+ Then open http://localhost:8080 in your browser.
1198
+
1199
+ ### Documentation
1200
+
1201
+ - **Frontend Guide**: [frontend/README.md](frontend/README.md)
1202
+ - **Backend Integration**: Configure API endpoint in `frontend/js/api.js`
1203
+ - **Customization**: Modify CSS variables in `frontend/css/main.css` for branding
1204
+
1205
+ ### Screenshots
1206
+
1207
+ See the [frontend README](frontend/README.md) for screenshots of the landing page, dashboard, API keys management, playground, and settings.
1208
+
1209
+ ## Backend API
1210
+
1211
+ AtlaraEditor also includes a complete backend API system for productization and distribution! The backend provides:
1212
+
1213
+ ### Features
1214
+
1215
+ - **API Key Management**: Create, manage, and track API keys with usage limits
1216
+ - **Subscription Plans**: Four-tier system (Free, Basic, Pro, Enterprise) with progressive features
1217
+ - **Feature Access Control**: Control which editor features are available based on subscription
1218
+ - **Payment Integration**: Full Stripe integration for subscription management
1219
+ - **Usage Tracking**: Monitor API usage and enforce limits
1220
+ - **Webhook Support**: Automatic handling of Stripe payment events
1221
+ - **Admin Panel**: Comprehensive admin dashboard for managing users, viewing statistics, and controlling subscriptions
1222
+
1223
+ ### Quick Start
1224
+
1225
+ ```bash
1226
+ # Navigate to backend directory
1227
+ cd backend
1228
+
1229
+ # Install dependencies
1230
+ npm install
1231
+
1232
+ # Configure environment
1233
+ cp .env.example .env
1234
+ # Edit .env with your configuration
1235
+
1236
+ # Start the server
1237
+ npm start
1238
+ ```
1239
+
1240
+ The server will start on `http://localhost:3000`
1241
+
1242
+ ### API Endpoints
1243
+
1244
+ | Endpoint | Description |
1245
+ |----------|-------------|
1246
+ | `POST /api/keys` | Create a new API key |
1247
+ | `GET /api/keys` | List all API keys |
1248
+ | `GET /api/subscriptions` | Get subscription details |
1249
+ | `GET /api/subscriptions/plans` | View available plans |
1250
+ | `POST /api/payments/checkout` | Create Stripe checkout session |
1251
+
1252
+ ### Subscription Plans
1253
+
1254
+ - **Free**: Basic editor, HTML mode (1K API calls/month)
1255
+ - **Basic**: + Rich text, toolbar (10K API calls/month) - $9/mo
1256
+ - **Pro**: + Math, tables, images (100K API calls/month) - $29/mo
1257
+ - **Enterprise**: + Custom plugins, unlimited API calls - $99/mo
1258
+
1259
+ ### Documentation
1260
+
1261
+ - **Full API Documentation**: [backend/README.md](backend/README.md)
1262
+ - **Quick Start Guide**: [backend/QUICKSTART.md](backend/QUICKSTART.md)
1263
+ - **Admin Panel Guide**: [ADMIN_PANEL.md](ADMIN_PANEL.md)
1264
+ - **Implementation Summary**: [backend/IMPLEMENTATION_SUMMARY.md](backend/IMPLEMENTATION_SUMMARY.md)
1265
+ - **Examples**: See [backend/examples/](backend/examples/)
1266
+
1267
+ ### Integration Example
1268
+
1269
+ ```javascript
1270
+ // Create an API key
1271
+ const response = await fetch('http://localhost:3000/api/keys', {
1272
+ method: 'POST',
1273
+ headers: { 'Content-Type': 'application/json' },
1274
+ body: JSON.stringify({
1275
+ name: 'My App',
1276
+ userId: 'user_123',
1277
+ plan: 'pro'
1278
+ })
1279
+ });
1280
+
1281
+ const { data } = await response.json();
1282
+ const apiKey = data.key;
1283
+
1284
+ // Use the API key
1285
+ const editor = AtlaraEditor.init('#editor', {
1286
+ apiKey: apiKey,
1287
+ // Features will be automatically enabled based on plan
1288
+ });
1289
+ ```
1290
+
1291
+ ## Future Enhancements
1292
+
1293
+ Potential improvements for future versions:
1294
+
1295
+ **Editor:**
1296
+ - Custom modal dialog for link insertion (images and math already have custom modals)
1297
+ - Drag-and-drop image upload with file handling
1298
+ - Image cropping and editing tools
1299
+ - More comprehensive CSS editing with syntax highlighting
1300
+ - Export to PDF or Word formats
1301
+ - Collaborative editing support
1302
+ - Webpack code splitting for dynamic plugin loading
1303
+
1304
+ **Frontend Platform:**
1305
+ - Two-factor authentication
1306
+ - Email verification
1307
+ - Team/organization management
1308
+ - Usage analytics dashboard with charts
1309
+ - Webhook management UI
1310
+ - API documentation viewer
1311
+ - Dark mode theme
1312
+ - Internationalization (i18n)
1313
+ - Mobile app (React Native/Flutter)
1314
+
1315
+ ## CI/CD
1316
+
1317
+ This project uses GitHub Actions for continuous integration and deployment:
1318
+
1319
+ ### Continuous Integration (CI)
1320
+
1321
+ The CI workflow runs on every push and pull request to `main` and `develop` branches:
1322
+ - **Linting**: Checks code style with ESLint
1323
+ - **Testing**: Runs the full test suite with Jest
1324
+ - **Building**: Builds the production bundle with Webpack
1325
+ - **Multi-version Testing**: Tests against Node.js 16.x, 18.x, and 20.x
1326
+ - **Coverage**: Uploads code coverage to Codecov (optional)
1327
+ - **Artifacts**: Stores build artifacts for 7 days
1328
+
1329
+ ### NPM Publishing
1330
+
1331
+ The NPM publish workflow automatically publishes the package to the public NPM registry:
1332
+ - **Triggers**: Runs on every push to the `main` branch
1333
+ - **Pre-publish Checks**: Runs linting, tests, and build before publishing
1334
+ - **Version Check**: Automatically checks if the version already exists on NPM and only publishes new versions
1335
+ - **Registry**: Publishes to [npmjs.com](https://www.npmjs.com/package/atlara-editor)
1336
+ - **Provenance**: Uses NPM provenance for supply chain security
1337
+ - **Requirements**: Requires `NPM_TOKEN` secret to be configured in repository settings
1338
+
1339
+ ### Docker Build and Push
1340
+
1341
+ The Docker workflow automatically builds and publishes Docker images to GitHub Container Registry:
1342
+ - **Triggers**: Runs on pushes to `main`, version tags (`v*`), releases, and manual dispatch
1343
+ - **Multi-platform**: Builds for both `linux/amd64` and `linux/arm64`
1344
+ - **Caching**: Uses GitHub Actions cache for faster builds
1345
+ - **Tagging**: Automatically tags images with version numbers, branch names, and `latest`
1346
+ - **Registry**: Publishes to `ghcr.io/atlarafirm/atlaraeditor`
1347
+
1348
+ ### Using the Docker Image
1349
+
1350
+ Pull and run the latest Docker image:
1351
+
1352
+ ```bash
1353
+ docker pull ghcr.io/atlarafirm/atlaraeditor:latest
1354
+ docker run -p 8080:80 ghcr.io/atlarafirm/atlaraeditor:latest
1355
+ ```
1356
+
1357
+ Then open http://localhost:8080/examples/ in your browser to see the demo.
1358
+
1359
+ ## License
1360
+
1361
+ MIT
1362
+
1363
+ ## Contributing
1364
+
1365
+ Contributions are welcome! Please feel free to submit a Pull Request.
1366
+
1367
+ ### Development Setup
1368
+
1369
+ 1. Clone the repository
1370
+ 2. Install dependencies: `npm install`
1371
+ 3. Run tests: `npm test`
1372
+ 4. Build: `npm run build`
1373
+ 5. Run development server: `npm run dev`
1374
+
1375
+ ### CI/CD Requirements
1376
+
1377
+ - All pull requests must pass CI checks (linting, tests, build)
1378
+ - Code coverage should be maintained or improved
1379
+ - Docker builds are automatically triggered on merges to `main`
1380
+ - NPM publishing is automatically triggered on merges to `main` (only if version has changed)
1381
+ - Update package version in `package.json` before merging to `main` to publish a new version