autumnnote 1.5.0 → 1.6.1

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 (53) hide show
  1. package/README.md +10 -8
  2. package/dist/autumnnote.css +324 -4
  3. package/dist/autumnnote.es.js +943 -526
  4. package/dist/autumnnote.es.js.map +1 -1
  5. package/dist/autumnnote.umd.js +935 -519
  6. package/dist/autumnnote.umd.js.map +1 -1
  7. package/package.json +21 -3
  8. package/src/js/Context.js +23 -16
  9. package/src/js/core/detectLang.js +98 -0
  10. package/src/js/core/dom.js +67 -11
  11. package/src/js/core/env.js +1 -1
  12. package/src/js/core/func.js +1 -1
  13. package/src/js/core/lists.js +1 -1
  14. package/src/js/core/markdown.js +32 -31
  15. package/src/js/core/range.js +8 -8
  16. package/src/js/editing/History.js +10 -10
  17. package/src/js/editing/Style.js +44 -44
  18. package/src/js/editing/Table.js +5 -7
  19. package/src/js/editing/Typing.js +19 -19
  20. package/src/js/i18n/en.js +2 -0
  21. package/src/js/i18n/vi.js +2 -0
  22. package/src/js/index.js +3 -2
  23. package/src/js/module/AutoSaveRestore.js +2 -4
  24. package/src/js/module/BubbleToolbar.js +51 -34
  25. package/src/js/module/Buttons.js +20 -18
  26. package/src/js/module/Clipboard.js +16 -17
  27. package/src/js/module/CodeTooltip.js +48 -24
  28. package/src/js/module/Codeview.js +5 -7
  29. package/src/js/module/ContextMenu.js +37 -37
  30. package/src/js/module/Editor.js +77 -26
  31. package/src/js/module/EmojiDialog.js +24 -18
  32. package/src/js/module/FindReplace.js +93 -66
  33. package/src/js/module/Fullscreen.js +1 -1
  34. package/src/js/module/IconDialog.js +39 -35
  35. package/src/js/module/ImageCropOverlay.js +13 -13
  36. package/src/js/module/ImageDialog.js +19 -13
  37. package/src/js/module/ImageResizer.js +5 -5
  38. package/src/js/module/ImageTooltip.js +20 -16
  39. package/src/js/module/LinkDialog.js +20 -14
  40. package/src/js/module/LinkTooltip.js +15 -12
  41. package/src/js/module/MarkdownShortcuts.js +11 -14
  42. package/src/js/module/Mention.js +11 -13
  43. package/src/js/module/Placeholder.js +1 -1
  44. package/src/js/module/ShortcutsDialog.js +2 -4
  45. package/src/js/module/Statusbar.js +5 -7
  46. package/src/js/module/TableTooltip.js +196 -36
  47. package/src/js/module/Toolbar.js +35 -34
  48. package/src/js/module/VideoDialog.js +16 -10
  49. package/src/js/module/VideoResizer.js +7 -9
  50. package/src/js/module/VideoTooltip.js +15 -10
  51. package/src/js/renderer.js +5 -3
  52. package/src/js/settings.js +53 -36
  53. package/src/styles/autumnnote.scss +332 -7
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Autumn Note
1
+ # AutumnNote — WYSIWYG Rich Text Editor
2
2
 
3
3
  <p align="center"><img src="public/image/banner.png" width="120" alt="AutumnNote Banner"/></p>
4
4
 
@@ -12,7 +12,7 @@
12
12
  [![jQuery](https://img.shields.io/badge/jQuery-free-lightgrey)](#)
13
13
  [![TypeScript](https://img.shields.io/badge/TypeScript-definitions-3178C6?logo=typescript&logoColor=white)](types/index.d.ts)
14
14
 
15
- A modern WYSIWYG rich-text editor built with vanilla JavaScript (ES2022+) — no jQuery, no heavy dependencies.
15
+ A **zero-dependency WYSIWYG rich-text editor** built with vanilla JavaScript (ES2022+) — no jQuery, no runtime dependencies. Lightweight alternative to Summernote, Quill, TinyMCE, Froala, CKEditor, ProseMirror, Trix, and Slate — with official React and Vue 3 wrappers.
16
16
 
17
17
  > **Fast. Lightweight. Reliable. Efficient.**
18
18
 
@@ -67,7 +67,8 @@ A modern WYSIWYG rich-text editor built with vanilla JavaScript (ES2022+) — no
67
67
  - **FA Icon picker** — FontAwesome 6 Free Solid icons across 8 categories; keyword search; configurable style, size, and colour; inserts as `<i>` element; auto-injects FA CDN if not on the page
68
68
 
69
69
  ### Search
70
- - **Find and Replace** — `Ctrl+F` to find, `Ctrl+H` for find-and-replace; TreeWalker text matching; `<mark>` highlighting; case-sensitive toggle; Prev/Next navigation; single and replace-all modes
70
+ - **Find and Replace** — `Ctrl+F` to find, `Ctrl+H` for find-and-replace; compact non-blocking floating panel (top-right); TreeWalker text matching; `<mark>` highlighting; case-sensitive `Aa` toggle; icon-button Prev/Next navigation (↑ ↓); single and replace-all modes
71
+ - **Auto language detection** — when selected text is formatted as a code block the editor automatically analyses the content and applies Prism.js syntax highlighting; 20 languages detected: JavaScript, TypeScript, Python, HTML, CSS, SCSS, JSON, SQL, Bash, Java, C#, PHP, Ruby, Go, Rust, C++, C, Kotlin, Swift, XML
71
72
 
72
73
  ### Inline tooltips
73
74
  Floating toolbars appear automatically when the user clicks on an editable element:
@@ -77,8 +78,8 @@ Floating toolbars appear automatically when the user clicks on an editable eleme
77
78
  | **Link** | Open in new tab, Edit (reopens dialog), Unlink |
78
79
  | **Image** | Edit alt/URL (reopens dialog), Crop, Delete |
79
80
  | **Video** | Edit (reopens dialog), Delete |
80
- | **Table cell** | Row above/below, Delete row, Column left/right, Delete column, Merge cells, Unmerge cells, Cell selection mode, Column width, Row height, Border width, Delete table |
81
- | **Code block** | Copy code, Delete block |
81
+ | **Table cell** | Row above/below, Delete row, Column left/right, Delete column, Merge cells, Unmerge cells, Cell selection mode, Column width, Row height, Border width, **Cell background colour**, Delete table |
82
+ | **Code block** | Copy code, Language selector (20 languages + SCSS), Delete block |
82
83
 
83
84
  ### Context menu
84
85
  Right-click inside the editor opens a context menu with: **Undo**, **Redo**, **Cut**, **Copy**, **Paste**, **Bold**, **Italic**, **Underline**, **Copy Format**, **Paste Format**, **Remove Format**, and a **colour palette** for quick text/highlight colour changes.
@@ -92,7 +93,8 @@ Right-click inside the editor opens a context menu with: **Undo**, **Redo**, **C
92
93
  ### UI
93
94
  - **Toolbar** — fully configurable button groups; overflow strategy: `wrap` (default) or `scroll`; on viewports ≤ 640 px the toolbar automatically switches to a single horizontally-scrollable row regardless of the `toolbarOverflow` setting; FontAwesome icons with built-in SVG fallback
94
95
  - **Sticky toolbar** — `stickyToolbar: true` pins the toolbar to the viewport top; configurable offset for fixed nav bars
95
- - **Dark / light theme** — `theme: 'dark'` or `theme: 'light'` (default); full SCSS variable coverage
96
+ - **Dark / light theme** — `theme: 'dark'` or `theme: 'light'` (default); full SCSS variable coverage; dark styles propagate to all floating elements (dialogs, tooltips, colour pickers)
97
+ - **Draggable dialogs** — all dialogs (Link, Image, Video, Emoji, Icon, Find & Replace) can be repositioned by dragging their title bar; position is clamped to the viewport
96
98
  - **Image resizer** — drag handle on selected image to resize proportionally
97
99
  - **Video resizer** — drag handle on selected video embed to resize
98
100
  - **Statusbar** — live word and character count; drag handle to resize editor height; limit warnings when `maxChars` or `maxWords` is reached
@@ -744,9 +746,9 @@ Build output in `dist/`:
744
746
 
745
747
  ## Comparison
746
748
 
747
- The table below compares AutumnNote against editors commonly used in this category — such as Summernote, Quill, TinyMCE, and Froala. Specific library names are kept generic to avoid direct bias; the comparison is based on publicly documented feature sets.
749
+ The table below compares AutumnNote against popular WYSIWYG editors: **Summernote**, **Quill**, and **TinyMCE**. Comparison is based on publicly documented feature sets.
748
750
 
749
- | Feature | Editor A | Editor B | Editor C | **AutumnNote** |
751
+ | Feature | Summernote | Quill | TinyMCE | **AutumnNote** |
750
752
  |---|---|---|---|---|
751
753
  | jQuery dependency | Required | Required | Optional | **None** |
752
754
  | Runtime dependencies | Several | Several | 1–2 | **Zero** |
@@ -38,11 +38,9 @@
38
38
  }
39
39
  .an-container.an-disabled .an-editable img {
40
40
  -webkit-user-drag: none;
41
- user-drag: none;
42
41
  }
43
42
  .an-container.an-disabled .an-editable .an-video-wrapper {
44
43
  -webkit-user-drag: none;
45
- user-drag: none;
46
44
  }
47
45
  .an-container.an-disabled .an-editable .an-video-wrapper .an-video-shield {
48
46
  pointer-events: none;
@@ -560,6 +558,30 @@
560
558
  letter-spacing: 0.02em;
561
559
  }
562
560
 
561
+ .an-link-tooltip-btn--shade {
562
+ flex-direction: column;
563
+ gap: 1px;
564
+ padding: 4px 0 3px;
565
+ height: auto;
566
+ }
567
+ .an-link-tooltip-btn--shade .an-bubble-btn-svg {
568
+ display: flex;
569
+ align-items: center;
570
+ justify-content: center;
571
+ line-height: 0;
572
+ }
573
+ .an-link-tooltip-btn--shade .an-bubble-btn-svg svg {
574
+ display: block;
575
+ }
576
+ .an-link-tooltip-btn--shade .an-link-tooltip-color-strip {
577
+ display: block;
578
+ width: 13px;
579
+ height: 3px;
580
+ border-radius: 1px;
581
+ pointer-events: none;
582
+ background: transparent;
583
+ }
584
+
563
585
  .an-link-tooltip-btn--active {
564
586
  background: rgba(59, 130, 246, 0.12) !important;
565
587
  color: #3b82f6 !important;
@@ -626,6 +648,51 @@
626
648
  gap: 6px;
627
649
  }
628
650
 
651
+ .an-cell-shade-popover {
652
+ position: fixed;
653
+ z-index: 1200;
654
+ background: #ffffff;
655
+ border: 1px solid #d1d5db;
656
+ border-radius: 8px;
657
+ padding: 10px 10px 6px;
658
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
659
+ min-width: 166px;
660
+ }
661
+ .an-cell-shade-popover .an-size-popover-title {
662
+ font-size: 11px;
663
+ font-weight: 600;
664
+ color: #6b7280;
665
+ text-transform: uppercase;
666
+ letter-spacing: 0.5px;
667
+ margin-bottom: 8px;
668
+ }
669
+ .an-cell-shade-popover .an-shade-no-color {
670
+ display: inline-flex;
671
+ align-items: center;
672
+ gap: 4px;
673
+ padding: 3px 8px;
674
+ font-size: 12px;
675
+ color: #6b7280;
676
+ background: transparent;
677
+ border: 1px solid #d1d5db;
678
+ border-radius: 4px;
679
+ cursor: pointer;
680
+ font-family: inherit;
681
+ }
682
+ .an-cell-shade-popover .an-shade-no-color:hover {
683
+ background: #f3f4f6;
684
+ color: #111827;
685
+ }
686
+ .an-cell-shade-popover .an-shade-color-input {
687
+ width: 24px;
688
+ height: 24px;
689
+ padding: 0;
690
+ border: 1px solid #d1d5db;
691
+ border-radius: 4px;
692
+ cursor: pointer;
693
+ background: transparent;
694
+ }
695
+
629
696
  .an-codeview {
630
697
  flex: 1;
631
698
  width: 100%;
@@ -698,8 +765,31 @@
698
765
  gap: 10px;
699
766
  }
700
767
 
768
+ .an-dialog-header {
769
+ display: flex;
770
+ align-items: center;
771
+ gap: 12px;
772
+ margin-bottom: 4px;
773
+ }
774
+
775
+ .an-dialog-icon {
776
+ display: flex;
777
+ align-items: center;
778
+ justify-content: center;
779
+ width: 38px;
780
+ height: 38px;
781
+ flex-shrink: 0;
782
+ border-radius: 10px;
783
+ background: rgba(59, 130, 246, 0.1);
784
+ color: #3b82f6;
785
+ }
786
+ .an-dialog-icon svg {
787
+ display: block;
788
+ stroke: currentColor;
789
+ }
790
+
701
791
  .an-dialog-title {
702
- margin: 0 0 4px;
792
+ margin: 0;
703
793
  font-size: 16px;
704
794
  font-weight: 600;
705
795
  color: #111827;
@@ -750,6 +840,102 @@
750
840
  cursor: pointer;
751
841
  }
752
842
 
843
+ .an-fr-dialog {
844
+ background: transparent;
845
+ pointer-events: none;
846
+ align-items: flex-start;
847
+ justify-content: flex-end;
848
+ padding: 56px 16px 0 0;
849
+ }
850
+ .an-fr-dialog .an-fr-box {
851
+ pointer-events: auto;
852
+ width: 360px;
853
+ padding: 14px 16px 16px;
854
+ gap: 8px;
855
+ }
856
+
857
+ .an-fr-header {
858
+ display: flex;
859
+ align-items: center;
860
+ justify-content: space-between;
861
+ margin-bottom: 2px;
862
+ }
863
+ .an-fr-header .an-dialog-title {
864
+ margin: 0;
865
+ font-size: 14px;
866
+ }
867
+
868
+ .an-fr-search-bar {
869
+ display: flex;
870
+ align-items: center;
871
+ gap: 4px;
872
+ }
873
+ .an-fr-search-bar .an-fr-input {
874
+ flex: 1;
875
+ min-width: 0;
876
+ padding: 6px 8px;
877
+ font-size: 13px;
878
+ }
879
+
880
+ .an-fr-replace-row {
881
+ display: flex;
882
+ align-items: center;
883
+ gap: 6px;
884
+ }
885
+ .an-fr-replace-row .an-fr-input {
886
+ flex: 1;
887
+ min-width: 0;
888
+ padding: 6px 8px;
889
+ font-size: 13px;
890
+ }
891
+ .an-fr-replace-row .an-fr-replace-btn {
892
+ flex-shrink: 0;
893
+ padding: 5px 10px;
894
+ font-size: 12px;
895
+ white-space: nowrap;
896
+ }
897
+
898
+ .an-fr-icon-btn {
899
+ display: flex;
900
+ align-items: center;
901
+ justify-content: center;
902
+ flex-shrink: 0;
903
+ width: 28px;
904
+ height: 28px;
905
+ padding: 0;
906
+ font-size: 12px;
907
+ font-weight: 600;
908
+ font-family: inherit;
909
+ border: 1px solid transparent;
910
+ border-radius: 4px;
911
+ background: transparent;
912
+ color: #6b7280;
913
+ cursor: pointer;
914
+ }
915
+ .an-fr-icon-btn svg {
916
+ display: block;
917
+ stroke: currentColor;
918
+ }
919
+ .an-fr-icon-btn:hover {
920
+ background: #f3f4f6;
921
+ color: #111827;
922
+ border-color: #d1d5db;
923
+ }
924
+ .an-fr-icon-btn.an-fr-icon-btn--active {
925
+ background: rgba(59, 130, 246, 0.1);
926
+ color: #3b82f6;
927
+ border-color: rgba(59, 130, 246, 0.3);
928
+ }
929
+
930
+ .an-fr-counter {
931
+ font-size: 11px;
932
+ color: #6b7280;
933
+ white-space: nowrap;
934
+ min-width: 36px;
935
+ text-align: right;
936
+ flex-shrink: 0;
937
+ }
938
+
753
939
  .an-input {
754
940
  width: 100%;
755
941
  padding: 7px 10px;
@@ -1127,6 +1313,28 @@
1127
1313
  margin: 0;
1128
1314
  }
1129
1315
 
1316
+ .an-dialog-title-group {
1317
+ display: flex;
1318
+ align-items: center;
1319
+ gap: 10px;
1320
+ }
1321
+
1322
+ .an-dialog-icon--sm {
1323
+ width: 32px;
1324
+ height: 32px;
1325
+ border-radius: 8px;
1326
+ background: rgba(59, 130, 246, 0.1);
1327
+ color: #3b82f6;
1328
+ display: flex;
1329
+ align-items: center;
1330
+ justify-content: center;
1331
+ flex-shrink: 0;
1332
+ }
1333
+ .an-dialog-icon--sm svg {
1334
+ display: block;
1335
+ stroke: currentColor;
1336
+ }
1337
+
1130
1338
  .an-icon-close {
1131
1339
  display: flex;
1132
1340
  align-items: center;
@@ -1608,6 +1816,27 @@
1608
1816
  .an-theme-dark .an-dialog-title {
1609
1817
  color: #cdd6f4;
1610
1818
  }
1819
+ .an-theme-dark .an-dialog-icon,
1820
+ .an-theme-dark .an-dialog-icon--sm {
1821
+ background: rgba(129, 140, 248, 0.15);
1822
+ color: #818cf8;
1823
+ }
1824
+ .an-theme-dark .an-fr-icon-btn {
1825
+ color: #a6adc8;
1826
+ }
1827
+ .an-theme-dark .an-fr-icon-btn:hover {
1828
+ background: #313244;
1829
+ color: #cdd6f4;
1830
+ border-color: #45475a;
1831
+ }
1832
+ .an-theme-dark .an-fr-icon-btn.an-fr-icon-btn--active {
1833
+ background: rgba(129, 140, 248, 0.15);
1834
+ color: #818cf8;
1835
+ border-color: rgba(129, 140, 248, 0.3);
1836
+ }
1837
+ .an-theme-dark .an-fr-counter {
1838
+ color: #6c7086;
1839
+ }
1611
1840
  .an-theme-dark .an-label {
1612
1841
  color: #cdd6f4;
1613
1842
  }
@@ -1642,11 +1871,20 @@
1642
1871
  }
1643
1872
  .an-theme-dark .an-color-popup,
1644
1873
  .an-theme-dark .an-table-picker-popup,
1645
- .an-theme-dark .an-size-popover {
1874
+ .an-theme-dark .an-size-popover,
1875
+ .an-theme-dark .an-cell-shade-popover {
1646
1876
  background: #24273a;
1647
1877
  border-color: #3f3f5f;
1648
1878
  color: #cdd6f4;
1649
1879
  }
1880
+ .an-theme-dark .an-cell-shade-popover .an-shade-no-color {
1881
+ border-color: #3f3f5f;
1882
+ color: #a6adc8;
1883
+ }
1884
+ .an-theme-dark .an-cell-shade-popover .an-shade-no-color:hover {
1885
+ background: #313244;
1886
+ color: #cdd6f4;
1887
+ }
1650
1888
  .an-theme-dark .an-link-tooltip-btn--active {
1651
1889
  background: rgba(99, 102, 241, 0.2) !important;
1652
1890
  color: #818cf8 !important;
@@ -1666,6 +1904,19 @@
1666
1904
  background: rgba(99, 102, 241, 0.3);
1667
1905
  border-color: #6366f1;
1668
1906
  }
1907
+ .an-theme-dark .an-color-custom {
1908
+ border-top-color: #3f3f5f;
1909
+ color: #cdd6f4;
1910
+ }
1911
+ .an-theme-dark .an-color-arrow:hover {
1912
+ border-left-color: #45475a;
1913
+ }
1914
+ .an-theme-dark .an-table-label {
1915
+ color: #6c7086;
1916
+ }
1917
+ .an-theme-dark .an-context-table-grid-panel {
1918
+ border-top-color: #3f3f5f;
1919
+ }
1669
1920
  .an-theme-dark .an-context-item {
1670
1921
  color: #cdd6f4;
1671
1922
  }
@@ -1703,10 +1954,22 @@
1703
1954
  color: #cdd6f4;
1704
1955
  }
1705
1956
  .an-theme-dark .an-icon-cell {
1957
+ color: #a6adc8;
1958
+ }
1959
+ .an-theme-dark .an-icon-cell i {
1706
1960
  color: #cdd6f4;
1707
1961
  }
1708
1962
  .an-theme-dark .an-icon-cell:hover {
1709
1963
  background: #2a2a3e;
1964
+ border-color: #45475a;
1965
+ }
1966
+ .an-theme-dark .an-icon-cell.active {
1967
+ background: rgba(129, 140, 248, 0.15);
1968
+ border-color: #818cf8;
1969
+ color: #818cf8;
1970
+ }
1971
+ .an-theme-dark .an-icon-cell.active i {
1972
+ color: #818cf8;
1710
1973
  }
1711
1974
  .an-theme-dark .an-icon-close {
1712
1975
  color: #a6adc8;
@@ -1715,6 +1978,63 @@
1715
1978
  background: #2a2a3e;
1716
1979
  color: #cdd6f4;
1717
1980
  }
1981
+ .an-theme-dark .an-emoji-box {
1982
+ background: #1e1e2e;
1983
+ border-color: #45475a;
1984
+ }
1985
+ .an-theme-dark .an-emoji-cell {
1986
+ color: inherit;
1987
+ }
1988
+ .an-theme-dark .an-emoji-cell:hover {
1989
+ background: #313244;
1990
+ }
1991
+ .an-theme-dark .an-emoji-grid {
1992
+ scrollbar-color: #45475a transparent;
1993
+ }
1994
+ .an-theme-dark .an-icon-box {
1995
+ background: #1e1e2e;
1996
+ border-color: #45475a;
1997
+ }
1998
+ .an-theme-dark .an-icon-grid {
1999
+ background: #181825;
2000
+ border-color: #45475a;
2001
+ }
2002
+ .an-theme-dark .an-icon-options {
2003
+ background: #181825;
2004
+ border-color: #45475a;
2005
+ }
2006
+ .an-theme-dark .an-icon-preview {
2007
+ background: #181825;
2008
+ border-color: #45475a;
2009
+ color: #cdd6f4;
2010
+ }
2011
+ .an-theme-dark .an-icon-preview .an-icon-preview-empty {
2012
+ color: #6c7086;
2013
+ }
2014
+ .an-theme-dark .an-icon-option-select {
2015
+ background: #313244;
2016
+ border-color: #45475a;
2017
+ color: #cdd6f4;
2018
+ }
2019
+ .an-theme-dark .an-icon-empty {
2020
+ color: #6c7086;
2021
+ }
2022
+ .an-theme-dark .an-bubble-color-picker {
2023
+ background: #24273a;
2024
+ border-color: #3f3f5f;
2025
+ }
2026
+ .an-theme-dark .an-bubble-color-picker .an-context-color-custom {
2027
+ border-color: #3f3f5f;
2028
+ color: #a6adc8;
2029
+ }
2030
+ .an-theme-dark .an-table-tooltip {
2031
+ background: #24273a;
2032
+ border-color: #3f3f5f;
2033
+ }
2034
+ .an-theme-dark .an-fr-box {
2035
+ background: #1e1e2e;
2036
+ border-color: #45475a;
2037
+ }
1718
2038
 
1719
2039
  .an-toolbar-overflow-scroll .an-toolbar {
1720
2040
  flex-wrap: nowrap;