@lexical/react 0.12.2 → 0.12.4
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/LexicalAutoEmbedPlugin.d.ts +3 -2
- package/LexicalAutoEmbedPlugin.dev.js +4 -14
- package/LexicalAutoEmbedPlugin.prod.js +4 -3
- package/LexicalAutoFocusPlugin.dev.js +0 -1
- package/LexicalAutoLinkPlugin.dev.js +126 -73
- package/LexicalAutoLinkPlugin.prod.js +11 -7
- package/LexicalBlockWithAlignableContents.dev.js +0 -10
- package/LexicalCharacterLimitPlugin.dev.js +7 -46
- package/LexicalCheckListPlugin.dev.js +10 -48
- package/LexicalClearEditorPlugin.dev.js +1 -1
- package/LexicalClickableLinkPlugin.dev.js +2 -20
- package/LexicalCollaborationContext.dev.js +0 -3
- package/LexicalCollaborationPlugin.dev.js +8 -37
- package/LexicalComposer.d.ts +3 -7
- package/LexicalComposer.dev.js +9 -11
- package/LexicalComposer.js.flow +4 -4
- package/LexicalComposer.prod.js +2 -1
- package/LexicalComposerContext.dev.js +0 -6
- package/LexicalContentEditable.dev.js +1 -2
- package/LexicalContextMenuPlugin.d.ts +3 -2
- package/LexicalContextMenuPlugin.dev.js +28 -82
- package/LexicalContextMenuPlugin.prod.js +16 -15
- package/LexicalDecoratorBlockNode.dev.js +0 -6
- package/LexicalEditorRefPlugin.dev.js +0 -3
- package/LexicalHashtagPlugin.dev.js +73 -43
- package/LexicalHorizontalRuleNode.dev.js +0 -21
- package/LexicalHorizontalRulePlugin.dev.js +0 -4
- package/LexicalLinkPlugin.dev.js +4 -10
- package/LexicalListPlugin.dev.js +0 -2
- package/LexicalMarkdownShortcutPlugin.dev.js +2 -2
- package/LexicalNestedComposer.d.ts +2 -2
- package/LexicalNestedComposer.dev.js +18 -16
- package/LexicalNestedComposer.js.flow +7 -2
- package/LexicalNestedComposer.prod.js +4 -3
- package/LexicalNodeEventPlugin.dev.js +2 -6
- package/LexicalNodeMenuPlugin.d.ts +3 -2
- package/LexicalNodeMenuPlugin.dev.js +27 -83
- package/LexicalNodeMenuPlugin.prod.js +15 -15
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +8 -12
- package/LexicalRichTextPlugin.dev.js +8 -12
- package/LexicalTabIndentationPlugin.dev.js +7 -16
- package/LexicalTableOfContents.dev.js +5 -33
- package/LexicalTablePlugin.dev.js +11 -28
- package/LexicalTreeView.dev.js +14 -79
- package/LexicalTypeaheadMenuPlugin.d.ts +4 -3
- package/LexicalTypeaheadMenuPlugin.dev.js +39 -176
- package/LexicalTypeaheadMenuPlugin.prod.js +19 -20
- package/package.json +19 -19
- package/shared/LexicalMenu.d.ts +3 -2
- package/useLexicalEditable.dev.js +1 -5
- package/useLexicalIsTextContentEmpty.dev.js +1 -0
- package/useLexicalNodeSelection.dev.js +0 -7
- package/useLexicalSubscription.dev.js +1 -3
|
@@ -18,64 +18,97 @@ var react = require('react');
|
|
|
18
18
|
* LICENSE file in the root directory of this source tree.
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
|
-
|
|
22
21
|
function getHashtagRegexStringChars() {
|
|
23
22
|
// Latin accented characters
|
|
24
23
|
// Excludes 0xd7 from the range
|
|
25
24
|
// (the multiplication sign, confusable with "x").
|
|
26
25
|
// Also excludes 0xf7, the division sign
|
|
27
|
-
const latinAccents = '\xc0-\xd6' + '\xd8-\xf6' + '\xf8-\xff' + '\u0100-\u024f' + '\u0253-\u0254' + '\u0256-\u0257' + '\u0259' + '\u025b' + '\u0263' + '\u0268' + '\u026f' + '\u0272' + '\u0289' + '\u028b' + '\u02bb' + '\u0300-\u036f' + '\u1e00-\u1eff';
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'\
|
|
31
|
-
|
|
32
|
-
'\
|
|
33
|
-
|
|
34
|
-
'\
|
|
35
|
-
|
|
36
|
-
'\
|
|
37
|
-
|
|
38
|
-
'\
|
|
39
|
-
|
|
40
|
-
'\
|
|
41
|
-
|
|
42
|
-
'\
|
|
43
|
-
|
|
44
|
-
'\
|
|
45
|
-
|
|
46
|
-
'\
|
|
47
|
-
|
|
26
|
+
const latinAccents = '\xc0-\xd6' + '\xd8-\xf6' + '\xf8-\xff' + '\u0100-\u024f' + '\u0253-\u0254' + '\u0256-\u0257' + '\u0259' + '\u025b' + '\u0263' + '\u0268' + '\u026f' + '\u0272' + '\u0289' + '\u028b' + '\u02bb' + '\u0300-\u036f' + '\u1e00-\u1eff';
|
|
27
|
+
|
|
28
|
+
// Cyrillic (Russian, Ukrainian, etc.)
|
|
29
|
+
const nonLatinChars = '\u0400-\u04ff' +
|
|
30
|
+
// Cyrillic
|
|
31
|
+
'\u0500-\u0527' +
|
|
32
|
+
// Cyrillic Supplement
|
|
33
|
+
'\u2de0-\u2dff' +
|
|
34
|
+
// Cyrillic Extended A
|
|
35
|
+
'\ua640-\ua69f' +
|
|
36
|
+
// Cyrillic Extended B
|
|
37
|
+
'\u0591-\u05bf' +
|
|
38
|
+
// Hebrew
|
|
39
|
+
'\u05c1-\u05c2' + '\u05c4-\u05c5' + '\u05c7' + '\u05d0-\u05ea' + '\u05f0-\u05f4' + '\ufb12-\ufb28' +
|
|
40
|
+
// Hebrew Presentation Forms
|
|
41
|
+
'\ufb2a-\ufb36' + '\ufb38-\ufb3c' + '\ufb3e' + '\ufb40-\ufb41' + '\ufb43-\ufb44' + '\ufb46-\ufb4f' + '\u0610-\u061a' +
|
|
42
|
+
// Arabic
|
|
43
|
+
'\u0620-\u065f' + '\u066e-\u06d3' + '\u06d5-\u06dc' + '\u06de-\u06e8' + '\u06ea-\u06ef' + '\u06fa-\u06fc' + '\u06ff' + '\u0750-\u077f' +
|
|
44
|
+
// Arabic Supplement
|
|
45
|
+
'\u08a0' +
|
|
46
|
+
// Arabic Extended A
|
|
47
|
+
'\u08a2-\u08ac' + '\u08e4-\u08fe' + '\ufb50-\ufbb1' +
|
|
48
|
+
// Arabic Pres. Forms A
|
|
49
|
+
'\ufbd3-\ufd3d' + '\ufd50-\ufd8f' + '\ufd92-\ufdc7' + '\ufdf0-\ufdfb' + '\ufe70-\ufe74' +
|
|
50
|
+
// Arabic Pres. Forms B
|
|
51
|
+
'\ufe76-\ufefc' + '\u200c-\u200c' +
|
|
52
|
+
// Zero-Width Non-Joiner
|
|
53
|
+
'\u0e01-\u0e3a' +
|
|
54
|
+
// Thai
|
|
55
|
+
'\u0e40-\u0e4e' +
|
|
56
|
+
// Hangul (Korean)
|
|
57
|
+
'\u1100-\u11ff' +
|
|
58
|
+
// Hangul Jamo
|
|
59
|
+
'\u3130-\u3185' +
|
|
60
|
+
// Hangul Compatibility Jamo
|
|
61
|
+
'\uA960-\uA97F' +
|
|
62
|
+
// Hangul Jamo Extended-A
|
|
63
|
+
'\uAC00-\uD7AF' +
|
|
64
|
+
// Hangul Syllables
|
|
65
|
+
'\uD7B0-\uD7FF' +
|
|
66
|
+
// Hangul Jamo Extended-B
|
|
48
67
|
'\uFFA1-\uFFDC'; // Half-width Hangul
|
|
49
68
|
|
|
50
69
|
const charCode = String.fromCharCode;
|
|
51
|
-
const cjkChars = '\u30A1-\u30FA\u30FC-\u30FE' +
|
|
52
|
-
|
|
53
|
-
'\
|
|
54
|
-
|
|
55
|
-
'\
|
|
56
|
-
|
|
70
|
+
const cjkChars = '\u30A1-\u30FA\u30FC-\u30FE' +
|
|
71
|
+
// Katakana (full-width)
|
|
72
|
+
'\uFF66-\uFF9F' +
|
|
73
|
+
// Katakana (half-width)
|
|
74
|
+
'\uFF10-\uFF19\uFF21-\uFF3A' + '\uFF41-\uFF5A' +
|
|
75
|
+
// Latin (full-width)
|
|
76
|
+
'\u3041-\u3096\u3099-\u309E' +
|
|
77
|
+
// Hiragana
|
|
78
|
+
'\u3400-\u4DBF' +
|
|
79
|
+
// Kanji (CJK Extension A)
|
|
80
|
+
'\u4E00-\u9FFF' +
|
|
81
|
+
// Kanji (Unified)
|
|
57
82
|
// Disabled as it breaks the Regex.
|
|
58
83
|
// charCode(0x20000) + '-' + charCode(0x2A6DF) + // Kanji (CJK Extension B)
|
|
59
|
-
charCode(0x2a700) + '-' + charCode(0x2b73f) +
|
|
60
|
-
|
|
84
|
+
charCode(0x2a700) + '-' + charCode(0x2b73f) +
|
|
85
|
+
// Kanji (CJK Extension C)
|
|
86
|
+
charCode(0x2b740) + '-' + charCode(0x2b81f) +
|
|
87
|
+
// Kanji (CJK Extension D)
|
|
61
88
|
charCode(0x2f800) + '-' + charCode(0x2fa1f) + '\u3003\u3005\u303B'; // Kanji (CJK supplement)
|
|
62
89
|
|
|
63
|
-
const otherChars = latinAccents + nonLatinChars + cjkChars;
|
|
90
|
+
const otherChars = latinAccents + nonLatinChars + cjkChars;
|
|
91
|
+
// equivalent of \p{L}
|
|
92
|
+
|
|
93
|
+
const unicodeLetters = '\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u0241\u0250-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EE\u037A\u0386' + '\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03F5\u03F7-\u0481' + '\u048A-\u04CE\u04D0-\u04F9\u0500-\u050F\u0531-\u0556\u0559\u0561-\u0587' + '\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0640-\u064A\u066E-\u066F' + '\u0671-\u06D3\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710' + '\u0712-\u072F\u074D-\u076D\u0780-\u07A5\u07B1\u0904-\u0939\u093D\u0950' + '\u0958-\u0961\u097D\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0' + '\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1' + '\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33' + '\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D' + '\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD' + '\u0AD0\u0AE0-\u0AE1\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30' + '\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83' + '\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F' + '\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10' + '\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C' + '\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE' + '\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39' + '\u0D60-\u0D61\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6' + '\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E81-\u0E82\u0E84\u0E87-\u0E88' + '\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7' + '\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6' + '\u0EDC-\u0EDD\u0F00\u0F40-\u0F47\u0F49-\u0F6A\u0F88-\u0F8B\u1000-\u1021' + '\u1023-\u1027\u1029-\u102A\u1050-\u1055\u10A0-\u10C5\u10D0-\u10FA\u10FC' + '\u1100-\u1159\u115F-\u11A2\u11A8-\u11F9\u1200-\u1248\u124A-\u124D' + '\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0' + '\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310' + '\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C' + '\u166F-\u1676\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711' + '\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7' + '\u17DC\u1820-\u1877\u1880-\u18A8\u1900-\u191C\u1950-\u196D\u1970-\u1974' + '\u1980-\u19A9\u19C1-\u19C7\u1A00-\u1A16\u1D00-\u1DBF\u1E00-\u1E9B' + '\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D' + '\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC' + '\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC' + '\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u2094\u2102\u2107' + '\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D' + '\u212F-\u2131\u2133-\u2139\u213C-\u213F\u2145-\u2149\u2C00-\u2C2E' + '\u2C30-\u2C5E\u2C80-\u2CE4\u2D00-\u2D25\u2D30-\u2D65\u2D6F\u2D80-\u2D96' + '\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6' + '\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3006\u3031-\u3035' + '\u303B-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF' + '\u3105-\u312C\u3131-\u318E\u31A0-\u31B7\u31F0-\u31FF\u3400-\u4DB5' + '\u4E00-\u9FBB\uA000-\uA48C\uA800-\uA801\uA803-\uA805\uA807-\uA80A' + '\uA80C-\uA822\uAC00-\uD7A3\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9' + '\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C' + '\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F' + '\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A' + '\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7' + '\uFFDA-\uFFDC';
|
|
64
94
|
|
|
65
|
-
|
|
95
|
+
// equivalent of \p{Mn}\p{Mc}
|
|
96
|
+
const unicodeAccents = '\u0300-\u036F\u0483-\u0486\u0591-\u05B9\u05BB-\u05BD\u05BF' + '\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u0615\u064B-\u065E\u0670' + '\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A' + '\u07A6-\u07B0\u0901-\u0903\u093C\u093E-\u094D\u0951-\u0954\u0962-\u0963' + '\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7' + '\u09E2-\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D' + '\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD' + '\u0AE2-\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D' + '\u0B56-\u0B57\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7' + '\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56' + '\u0C82-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6' + '\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D82-\u0D83' + '\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2-\u0DF3\u0E31\u0E34-\u0E3A' + '\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19' + '\u0F35\u0F37\u0F39\u0F3E-\u0F3F\u0F71-\u0F84\u0F86-\u0F87\u0F90-\u0F97' + '\u0F99-\u0FBC\u0FC6\u102C-\u1032\u1036-\u1039\u1056-\u1059\u135F' + '\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B6-\u17D3\u17DD' + '\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8-\u19C9' + '\u1A17-\u1A1B\u1DC0-\u1DC3\u20D0-\u20DC\u20E1\u20E5-\u20EB\u302A-\u302F' + '\u3099-\u309A\uA802\uA806\uA80B\uA823-\uA827\uFB1E\uFE00-\uFE0F' + '\uFE20-\uFE23';
|
|
66
97
|
|
|
67
|
-
|
|
98
|
+
// equivalent of \p{Dn}
|
|
99
|
+
const unicodeDigits = '\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF' + '\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F' + '\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29' + '\u1040-\u1049\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9' + '\uFF10-\uFF19';
|
|
68
100
|
|
|
69
|
-
|
|
101
|
+
// An alpha char is a unicode chars including unicode marks or
|
|
70
102
|
// letter or char in otherChars range
|
|
103
|
+
const alpha = unicodeLetters + unicodeAccents + otherChars;
|
|
71
104
|
|
|
72
|
-
|
|
105
|
+
// A numeric character is any with the number digit property, or
|
|
73
106
|
// underscore. These characters can be included in hashtags, but a hashtag
|
|
74
107
|
// cannot have only these characters.
|
|
108
|
+
const numeric = unicodeDigits + '_';
|
|
75
109
|
|
|
76
|
-
|
|
110
|
+
// Alphanumeric char is any alpha char or a unicode char with decimal
|
|
77
111
|
// number property \p{Nd}
|
|
78
|
-
|
|
79
112
|
const alphanumeric = alpha + numeric;
|
|
80
113
|
const hashChars = '#\\uFF03'; // normal '#' or full-width '#'
|
|
81
114
|
|
|
@@ -85,7 +118,6 @@ function getHashtagRegexStringChars() {
|
|
|
85
118
|
hashChars
|
|
86
119
|
};
|
|
87
120
|
}
|
|
88
|
-
|
|
89
121
|
function getHashtagRegexString() {
|
|
90
122
|
const {
|
|
91
123
|
alpha,
|
|
@@ -95,13 +127,13 @@ function getHashtagRegexString() {
|
|
|
95
127
|
const hashtagAlpha = '[' + alpha + ']';
|
|
96
128
|
const hashtagAlphanumeric = '[' + alphanumeric + ']';
|
|
97
129
|
const hashtagBoundary = '^|$|[^&/' + alphanumeric + ']';
|
|
98
|
-
const hashCharList = '[' + hashChars + ']';
|
|
99
|
-
// but not all numbers.
|
|
130
|
+
const hashCharList = '[' + hashChars + ']';
|
|
100
131
|
|
|
132
|
+
// A hashtag contains characters, numbers and underscores,
|
|
133
|
+
// but not all numbers.
|
|
101
134
|
const hashtag = '(' + hashtagBoundary + ')(' + hashCharList + ')(' + hashtagAlphanumeric + '*' + hashtagAlpha + hashtagAlphanumeric + '*)';
|
|
102
135
|
return hashtag;
|
|
103
136
|
}
|
|
104
|
-
|
|
105
137
|
const REGEX = new RegExp(getHashtagRegexString(), 'i');
|
|
106
138
|
function HashtagPlugin() {
|
|
107
139
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
@@ -115,11 +147,9 @@ function HashtagPlugin() {
|
|
|
115
147
|
}, []);
|
|
116
148
|
const getHashtagMatch = react.useCallback(text => {
|
|
117
149
|
const matchArr = REGEX.exec(text);
|
|
118
|
-
|
|
119
150
|
if (matchArr === null) {
|
|
120
151
|
return null;
|
|
121
152
|
}
|
|
122
|
-
|
|
123
153
|
const hashtagLength = matchArr[3].length + 1;
|
|
124
154
|
const startOffset = matchArr.index + matchArr[1].length;
|
|
125
155
|
const endOffset = startOffset + hashtagLength;
|
|
@@ -20,7 +20,6 @@ var React = require('react');
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
const INSERT_HORIZONTAL_RULE_COMMAND = lexical.createCommand('INSERT_HORIZONTAL_RULE_COMMAND');
|
|
23
|
-
|
|
24
23
|
function HorizontalRuleComponent({
|
|
25
24
|
nodeKey
|
|
26
25
|
}) {
|
|
@@ -30,53 +29,43 @@ function HorizontalRuleComponent({
|
|
|
30
29
|
if (isSelected && lexical.$isNodeSelection(lexical.$getSelection())) {
|
|
31
30
|
event.preventDefault();
|
|
32
31
|
const node = lexical.$getNodeByKey(nodeKey);
|
|
33
|
-
|
|
34
32
|
if ($isHorizontalRuleNode(node)) {
|
|
35
33
|
node.remove();
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
|
-
|
|
39
36
|
return false;
|
|
40
37
|
}, [isSelected, nodeKey]);
|
|
41
38
|
React.useEffect(() => {
|
|
42
39
|
return utils.mergeRegister(editor.registerCommand(lexical.CLICK_COMMAND, event => {
|
|
43
40
|
const hrElem = editor.getElementByKey(nodeKey);
|
|
44
|
-
|
|
45
41
|
if (event.target === hrElem) {
|
|
46
42
|
if (!event.shiftKey) {
|
|
47
43
|
clearSelection();
|
|
48
44
|
}
|
|
49
|
-
|
|
50
45
|
setSelected(!isSelected);
|
|
51
46
|
return true;
|
|
52
47
|
}
|
|
53
|
-
|
|
54
48
|
return false;
|
|
55
49
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_DELETE_COMMAND, onDelete, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_BACKSPACE_COMMAND, onDelete, lexical.COMMAND_PRIORITY_LOW));
|
|
56
50
|
}, [clearSelection, editor, isSelected, nodeKey, onDelete, setSelected]);
|
|
57
51
|
React.useEffect(() => {
|
|
58
52
|
const hrElem = editor.getElementByKey(nodeKey);
|
|
59
|
-
|
|
60
53
|
if (hrElem !== null) {
|
|
61
54
|
hrElem.className = isSelected ? 'selected' : '';
|
|
62
55
|
}
|
|
63
56
|
}, [editor, isSelected, nodeKey]);
|
|
64
57
|
return null;
|
|
65
58
|
}
|
|
66
|
-
|
|
67
59
|
class HorizontalRuleNode extends lexical.DecoratorNode {
|
|
68
60
|
static getType() {
|
|
69
61
|
return 'horizontalrule';
|
|
70
62
|
}
|
|
71
|
-
|
|
72
63
|
static clone(node) {
|
|
73
64
|
return new HorizontalRuleNode(node.__key);
|
|
74
65
|
}
|
|
75
|
-
|
|
76
66
|
static importJSON(serializedNode) {
|
|
77
67
|
return $createHorizontalRuleNode();
|
|
78
68
|
}
|
|
79
|
-
|
|
80
69
|
static importDOM() {
|
|
81
70
|
return {
|
|
82
71
|
hr: () => ({
|
|
@@ -85,50 +74,40 @@ class HorizontalRuleNode extends lexical.DecoratorNode {
|
|
|
85
74
|
})
|
|
86
75
|
};
|
|
87
76
|
}
|
|
88
|
-
|
|
89
77
|
exportJSON() {
|
|
90
78
|
return {
|
|
91
79
|
type: 'horizontalrule',
|
|
92
80
|
version: 1
|
|
93
81
|
};
|
|
94
82
|
}
|
|
95
|
-
|
|
96
83
|
exportDOM() {
|
|
97
84
|
return {
|
|
98
85
|
element: document.createElement('hr')
|
|
99
86
|
};
|
|
100
87
|
}
|
|
101
|
-
|
|
102
88
|
createDOM() {
|
|
103
89
|
return document.createElement('hr');
|
|
104
90
|
}
|
|
105
|
-
|
|
106
91
|
getTextContent() {
|
|
107
92
|
return '\n';
|
|
108
93
|
}
|
|
109
|
-
|
|
110
94
|
isInline() {
|
|
111
95
|
return false;
|
|
112
96
|
}
|
|
113
|
-
|
|
114
97
|
updateDOM() {
|
|
115
98
|
return false;
|
|
116
99
|
}
|
|
117
|
-
|
|
118
100
|
decorate() {
|
|
119
101
|
return /*#__PURE__*/React.createElement(HorizontalRuleComponent, {
|
|
120
102
|
nodeKey: this.__key
|
|
121
103
|
});
|
|
122
104
|
}
|
|
123
|
-
|
|
124
105
|
}
|
|
125
|
-
|
|
126
106
|
function convertHorizontalRuleElement() {
|
|
127
107
|
return {
|
|
128
108
|
node: $createHorizontalRuleNode()
|
|
129
109
|
};
|
|
130
110
|
}
|
|
131
|
-
|
|
132
111
|
function $createHorizontalRuleNode() {
|
|
133
112
|
return lexical.$applyNodeReplacement(new HorizontalRuleNode());
|
|
134
113
|
}
|
|
@@ -24,18 +24,14 @@ function HorizontalRulePlugin() {
|
|
|
24
24
|
react.useEffect(() => {
|
|
25
25
|
return editor.registerCommand(LexicalHorizontalRuleNode.INSERT_HORIZONTAL_RULE_COMMAND, type => {
|
|
26
26
|
const selection = lexical.$getSelection();
|
|
27
|
-
|
|
28
27
|
if (!lexical.$isRangeSelection(selection)) {
|
|
29
28
|
return false;
|
|
30
29
|
}
|
|
31
|
-
|
|
32
30
|
const focusNode = selection.focus.getNode();
|
|
33
|
-
|
|
34
31
|
if (focusNode !== null) {
|
|
35
32
|
const horizontalRuleNode = LexicalHorizontalRuleNode.$createHorizontalRuleNode();
|
|
36
33
|
utils.$insertNodeToNearestRoot(horizontalRuleNode);
|
|
37
34
|
}
|
|
38
|
-
|
|
39
35
|
return true;
|
|
40
36
|
}, lexical.COMMAND_PRIORITY_EDITOR);
|
|
41
37
|
}, [editor]);
|
package/LexicalLinkPlugin.dev.js
CHANGED
|
@@ -27,7 +27,6 @@ function LinkPlugin({
|
|
|
27
27
|
if (!editor.hasNodes([link.LinkNode])) {
|
|
28
28
|
throw new Error('LinkPlugin: LinkNode not registered on editor');
|
|
29
29
|
}
|
|
30
|
-
|
|
31
30
|
return utils.mergeRegister(editor.registerCommand(link.TOGGLE_LINK_COMMAND, payload => {
|
|
32
31
|
if (payload === null) {
|
|
33
32
|
link.toggleLink(payload);
|
|
@@ -37,7 +36,6 @@ function LinkPlugin({
|
|
|
37
36
|
link.toggleLink(payload);
|
|
38
37
|
return true;
|
|
39
38
|
}
|
|
40
|
-
|
|
41
39
|
return false;
|
|
42
40
|
} else {
|
|
43
41
|
const {
|
|
@@ -55,26 +53,22 @@ function LinkPlugin({
|
|
|
55
53
|
}
|
|
56
54
|
}, lexical.COMMAND_PRIORITY_LOW), validateUrl !== undefined ? editor.registerCommand(lexical.PASTE_COMMAND, event => {
|
|
57
55
|
const selection = lexical.$getSelection();
|
|
58
|
-
|
|
59
56
|
if (!lexical.$isRangeSelection(selection) || selection.isCollapsed() || !(event instanceof ClipboardEvent) || event.clipboardData == null) {
|
|
60
57
|
return false;
|
|
61
58
|
}
|
|
62
|
-
|
|
63
59
|
const clipboardText = event.clipboardData.getData('text');
|
|
64
|
-
|
|
65
60
|
if (!validateUrl(clipboardText)) {
|
|
66
61
|
return false;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
}
|
|
63
|
+
// If we select nodes that are elements then avoid applying the link.
|
|
70
64
|
if (!selection.getNodes().some(node => lexical.$isElementNode(node))) {
|
|
71
65
|
editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, clipboardText);
|
|
72
66
|
event.preventDefault();
|
|
73
67
|
return true;
|
|
74
68
|
}
|
|
75
|
-
|
|
76
69
|
return false;
|
|
77
|
-
}, lexical.COMMAND_PRIORITY_LOW) : () => {
|
|
70
|
+
}, lexical.COMMAND_PRIORITY_LOW) : () => {
|
|
71
|
+
// Don't paste arbritrary text as a link when there's no validate function
|
|
78
72
|
});
|
|
79
73
|
}, [editor, validateUrl]);
|
|
80
74
|
return null;
|
package/LexicalListPlugin.dev.js
CHANGED
|
@@ -32,11 +32,9 @@ function useList(editor) {
|
|
|
32
32
|
return true;
|
|
33
33
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.INSERT_PARAGRAPH_COMMAND, () => {
|
|
34
34
|
const hasHandledInsertParagraph = list.$handleListInsertParagraph();
|
|
35
|
-
|
|
36
35
|
if (hasHandledInsertParagraph) {
|
|
37
36
|
return true;
|
|
38
37
|
}
|
|
39
|
-
|
|
40
38
|
return false;
|
|
41
39
|
}, lexical.COMMAND_PRIORITY_LOW));
|
|
42
40
|
}, [editor]);
|
|
@@ -25,14 +25,14 @@ const HR = {
|
|
|
25
25
|
},
|
|
26
26
|
regExp: /^(---|\*\*\*|___)\s?$/,
|
|
27
27
|
replace: (parentNode, _1, _2, isImport) => {
|
|
28
|
-
const line = LexicalHorizontalRuleNode.$createHorizontalRuleNode();
|
|
28
|
+
const line = LexicalHorizontalRuleNode.$createHorizontalRuleNode();
|
|
29
29
|
|
|
30
|
+
// TODO: Get rid of isImport flag
|
|
30
31
|
if (isImport || parentNode.getNextSibling() != null) {
|
|
31
32
|
parentNode.replace(line);
|
|
32
33
|
} else {
|
|
33
34
|
parentNode.insertBefore(line);
|
|
34
35
|
}
|
|
35
|
-
|
|
36
36
|
line.selectNext();
|
|
37
37
|
},
|
|
38
38
|
type: 'element'
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import { EditorThemeClasses, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
8
|
+
import { EditorThemeClasses, Klass, LexicalEditor, LexicalNode, LexicalNodeReplacement } from 'lexical';
|
|
9
9
|
import { ReactNode } from 'react';
|
|
10
10
|
export declare function LexicalNestedComposer({ initialEditor, children, initialNodes, initialTheme, skipCollabChecks, }: {
|
|
11
11
|
children: ReactNode;
|
|
12
12
|
initialEditor: LexicalEditor;
|
|
13
13
|
initialTheme?: EditorThemeClasses;
|
|
14
|
-
initialNodes?: ReadonlyArray<Klass<LexicalNode
|
|
14
|
+
initialNodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;
|
|
15
15
|
skipCollabChecks?: true;
|
|
16
16
|
}): JSX.Element;
|
|
@@ -26,29 +26,23 @@ function LexicalNestedComposer({
|
|
|
26
26
|
}) {
|
|
27
27
|
const wasCollabPreviouslyReadyRef = React.useRef(false);
|
|
28
28
|
const parentContext = React.useContext(LexicalComposerContext.LexicalComposerContext);
|
|
29
|
-
|
|
30
29
|
if (parentContext == null) {
|
|
31
30
|
{
|
|
32
31
|
throw Error(`Unexpected parent context null on a nested composer`);
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
|
-
|
|
36
34
|
const [parentEditor, {
|
|
37
35
|
getTheme: getParentTheme
|
|
38
36
|
}] = parentContext;
|
|
39
37
|
const composerContext = React.useMemo(() => {
|
|
40
38
|
const composerTheme = initialTheme || getParentTheme() || undefined;
|
|
41
39
|
const context = LexicalComposerContext.createLexicalComposerContext(parentContext, composerTheme);
|
|
42
|
-
|
|
43
40
|
if (composerTheme !== undefined) {
|
|
44
41
|
initialEditor._config.theme = composerTheme;
|
|
45
42
|
}
|
|
46
|
-
|
|
47
43
|
initialEditor._parentEditor = parentEditor;
|
|
48
|
-
|
|
49
44
|
if (!initialNodes) {
|
|
50
45
|
const parentNodes = initialEditor._nodes = new Map(parentEditor._nodes);
|
|
51
|
-
|
|
52
46
|
for (const [type, entry] of parentNodes) {
|
|
53
47
|
initialEditor._nodes.set(type, {
|
|
54
48
|
klass: entry.klass,
|
|
@@ -58,25 +52,32 @@ function LexicalNestedComposer({
|
|
|
58
52
|
});
|
|
59
53
|
}
|
|
60
54
|
} else {
|
|
61
|
-
for (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
for (let klass of initialNodes) {
|
|
56
|
+
let replace = null;
|
|
57
|
+
let replaceWithKlass = null;
|
|
58
|
+
if (typeof klass !== 'function') {
|
|
59
|
+
const options = klass;
|
|
60
|
+
klass = options.replace;
|
|
61
|
+
replace = options.with;
|
|
62
|
+
replaceWithKlass = options.withKlass || null;
|
|
63
|
+
}
|
|
64
|
+
initialEditor._nodes.set(klass.getType(), {
|
|
65
65
|
klass,
|
|
66
|
-
replace
|
|
67
|
-
replaceWithKlass
|
|
66
|
+
replace,
|
|
67
|
+
replaceWithKlass,
|
|
68
68
|
transforms: new Set()
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
|
|
73
72
|
initialEditor._config.namespace = parentEditor._config.namespace;
|
|
74
73
|
initialEditor._editable = parentEditor._editable;
|
|
75
74
|
return [initialEditor, context];
|
|
76
|
-
},
|
|
75
|
+
},
|
|
76
|
+
// We only do this for init
|
|
77
77
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
-
[]);
|
|
78
|
+
[]);
|
|
79
79
|
|
|
80
|
+
// If collaboration is enabled, make sure we don't render the children until the collaboration subdocument is ready.
|
|
80
81
|
const {
|
|
81
82
|
isCollabActive,
|
|
82
83
|
yjsDocMap
|
|
@@ -86,8 +87,9 @@ function LexicalNestedComposer({
|
|
|
86
87
|
if (isCollabReady) {
|
|
87
88
|
wasCollabPreviouslyReadyRef.current = true;
|
|
88
89
|
}
|
|
89
|
-
}, [isCollabReady]);
|
|
90
|
+
}, [isCollabReady]);
|
|
90
91
|
|
|
92
|
+
// Update `isEditable` state of nested editor in response to the same change on parent editor.
|
|
91
93
|
React.useEffect(() => {
|
|
92
94
|
return parentEditor.registerEditableListener(editable => {
|
|
93
95
|
initialEditor.setEditable(editable);
|
|
@@ -7,11 +7,16 @@
|
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
LexicalEditor,
|
|
12
|
+
EditorThemeClasses,
|
|
13
|
+
LexicalNode,
|
|
14
|
+
LexicalNodeReplacement,
|
|
15
|
+
} from 'lexical';
|
|
11
16
|
|
|
12
17
|
declare export function LexicalNestedComposer({
|
|
13
18
|
children: React$Node,
|
|
14
19
|
initialEditor: LexicalEditor,
|
|
15
20
|
initialTheme?: EditorThemeClasses,
|
|
16
|
-
initialNodes?: $ReadOnlyArray<Class<LexicalNode
|
|
21
|
+
initialNodes?: $ReadOnlyArray<Class<LexicalNode> | LexicalNodeReplacement>,
|
|
17
22
|
}): React$Node;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
'use strict';var
|
|
8
|
-
exports.LexicalNestedComposer=function({initialEditor:a,children:
|
|
9
|
-
|
|
7
|
+
'use strict';var d=require("@lexical/react/LexicalCollaborationContext"),k=require("@lexical/react/LexicalComposerContext"),q=require("react");function r(a){let h=new URLSearchParams;h.append("code",a);for(let e=1;e<arguments.length;e++)h.append("v",arguments[e]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${h} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
|
|
8
|
+
exports.LexicalNestedComposer=function({initialEditor:a,children:h,initialNodes:e,initialTheme:t,skipCollabChecks:u}){let p=q.useRef(!1),l=q.useContext(k.LexicalComposerContext);null==l&&r(9);let [f,{getTheme:v}]=l,y=q.useMemo(()=>{var b=t||v()||void 0;const w=k.createLexicalComposerContext(l,b);void 0!==b&&(a._config.theme=b);a._parentEditor=f;if(e)for(var c of e){var g=b=null;"function"!==typeof c&&(g=c,c=g.replace,b=g.with,g=g.withKlass||null);a._nodes.set(c.getType(),{klass:c,replace:b,replaceWithKlass:g,
|
|
9
|
+
transforms:new Set})}else{c=a._nodes=new Map(f._nodes);for(const [x,m]of c)a._nodes.set(x,{klass:m.klass,replace:m.replace,replaceWithKlass:m.replaceWithKlass,transforms:new Set})}a._config.namespace=f._config.namespace;a._editable=f._editable;return[a,w]},[]),{isCollabActive:z,yjsDocMap:A}=d.useCollaborationContext(),n=u||p.current||A.has(a.getKey());q.useEffect(()=>{n&&(p.current=!0)},[n]);q.useEffect(()=>f.registerEditableListener(b=>{a.setEditable(b)}),[a,f]);return q.createElement(k.LexicalComposerContext.Provider,
|
|
10
|
+
{value:y},!z||n?h:null)}
|
|
@@ -29,14 +29,11 @@ function NodeEventPlugin({
|
|
|
29
29
|
listenerRef.current = eventListener;
|
|
30
30
|
react.useEffect(() => {
|
|
31
31
|
const isCaptured = capturedEvents.has(eventType);
|
|
32
|
-
|
|
33
32
|
const onEvent = event => {
|
|
34
33
|
editor.update(() => {
|
|
35
34
|
const nearestNode = lexical.$getNearestNodeFromDOMNode(event.target);
|
|
36
|
-
|
|
37
35
|
if (nearestNode !== null) {
|
|
38
36
|
const targetNode = isCaptured ? nearestNode instanceof nodeType ? nearestNode : null : utils.$findMatchingParent(nearestNode, node => node instanceof nodeType);
|
|
39
|
-
|
|
40
37
|
if (targetNode !== null) {
|
|
41
38
|
listenerRef.current(event, editor, targetNode.getKey());
|
|
42
39
|
return;
|
|
@@ -44,16 +41,15 @@ function NodeEventPlugin({
|
|
|
44
41
|
}
|
|
45
42
|
});
|
|
46
43
|
};
|
|
47
|
-
|
|
48
44
|
return editor.registerRootListener((rootElement, prevRootElement) => {
|
|
49
45
|
if (rootElement) {
|
|
50
46
|
rootElement.addEventListener(eventType, onEvent, isCaptured);
|
|
51
47
|
}
|
|
52
|
-
|
|
53
48
|
if (prevRootElement) {
|
|
54
49
|
prevRootElement.removeEventListener(eventType, onEvent, isCaptured);
|
|
55
50
|
}
|
|
56
|
-
});
|
|
51
|
+
});
|
|
52
|
+
// We intentionally don't respect changes to eventType.
|
|
57
53
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
54
|
}, [editor, nodeType]);
|
|
59
55
|
return null;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/// <reference types="react" />
|
|
9
9
|
import type { MenuRenderFn, MenuResolution } from './shared/LexicalMenu';
|
|
10
|
-
import { NodeKey, TextNode } from 'lexical';
|
|
10
|
+
import { CommandListenerPriority, NodeKey, TextNode } from 'lexical';
|
|
11
11
|
import { MenuOption } from './shared/LexicalMenu';
|
|
12
12
|
export type NodeMenuPluginProps<TOption extends MenuOption> = {
|
|
13
13
|
onSelectOption: (option: TOption, textNodeContainingQuery: TextNode | null, closeMenu: () => void, matchingString: string) => void;
|
|
@@ -17,6 +17,7 @@ export type NodeMenuPluginProps<TOption extends MenuOption> = {
|
|
|
17
17
|
onOpen?: (resolution: MenuResolution) => void;
|
|
18
18
|
menuRenderFn: MenuRenderFn<TOption>;
|
|
19
19
|
anchorClassName?: string;
|
|
20
|
+
commandPriority?: CommandListenerPriority;
|
|
20
21
|
};
|
|
21
|
-
export declare function LexicalNodeMenuPlugin<TOption extends MenuOption>({ options, nodeKey, onClose, onOpen, onSelectOption, menuRenderFn, anchorClassName, }: NodeMenuPluginProps<TOption>): JSX.Element | null;
|
|
22
|
+
export declare function LexicalNodeMenuPlugin<TOption extends MenuOption>({ options, nodeKey, onClose, onOpen, onSelectOption, menuRenderFn, anchorClassName, commandPriority, }: NodeMenuPluginProps<TOption>): JSX.Element | null;
|
|
22
23
|
export { MenuOption, MenuRenderFn, MenuResolution };
|