@expensify/react-native-live-markdown 0.1.116 → 0.1.118

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 (90) hide show
  1. package/lib/commonjs/MarkdownTextInput.js +2 -4
  2. package/lib/commonjs/MarkdownTextInput.js.map +1 -1
  3. package/lib/commonjs/MarkdownTextInput.web.js +105 -149
  4. package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
  5. package/lib/commonjs/styleUtils.js.map +1 -1
  6. package/lib/commonjs/web/utils/blockUtils.js +77 -0
  7. package/lib/commonjs/web/utils/blockUtils.js.map +1 -0
  8. package/lib/commonjs/web/utils/browserUtils.js +18 -0
  9. package/lib/commonjs/web/utils/browserUtils.js.map +1 -0
  10. package/lib/commonjs/web/utils/cursorUtils.js +111 -0
  11. package/lib/commonjs/web/utils/cursorUtils.js.map +1 -0
  12. package/lib/commonjs/web/utils/inputUtils.js +108 -0
  13. package/lib/commonjs/web/utils/inputUtils.js.map +1 -0
  14. package/lib/commonjs/web/utils/parserUtils.js +266 -0
  15. package/lib/commonjs/web/utils/parserUtils.js.map +1 -0
  16. package/lib/commonjs/web/utils/treeUtils.js +85 -0
  17. package/lib/commonjs/web/utils/treeUtils.js.map +1 -0
  18. package/lib/commonjs/web/utils/webStyleUtils.js +51 -0
  19. package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -0
  20. package/lib/module/MarkdownTextInput.js +2 -2
  21. package/lib/module/MarkdownTextInput.js.map +1 -1
  22. package/lib/module/MarkdownTextInput.web.js +101 -145
  23. package/lib/module/MarkdownTextInput.web.js.map +1 -1
  24. package/lib/module/styleUtils.js.map +1 -1
  25. package/lib/module/web/utils/blockUtils.js +72 -0
  26. package/lib/module/web/utils/blockUtils.js.map +1 -0
  27. package/lib/module/web/utils/browserUtils.js +12 -0
  28. package/lib/module/web/utils/browserUtils.js.map +1 -0
  29. package/lib/module/web/utils/cursorUtils.js +102 -0
  30. package/lib/module/web/utils/cursorUtils.js.map +1 -0
  31. package/lib/module/web/utils/inputUtils.js +99 -0
  32. package/lib/module/web/utils/inputUtils.js.map +1 -0
  33. package/lib/module/web/utils/parserUtils.js +260 -0
  34. package/lib/module/web/utils/parserUtils.js.map +1 -0
  35. package/lib/module/web/utils/treeUtils.js +78 -0
  36. package/lib/module/web/utils/treeUtils.js.map +1 -0
  37. package/lib/module/web/utils/webStyleUtils.js +45 -0
  38. package/lib/module/web/utils/webStyleUtils.js.map +1 -0
  39. package/lib/typescript/src/MarkdownTextInput.d.ts +1 -2
  40. package/lib/typescript/src/MarkdownTextInput.d.ts.map +1 -1
  41. package/lib/typescript/src/MarkdownTextInput.web.d.ts +9 -3
  42. package/lib/typescript/src/MarkdownTextInput.web.d.ts.map +1 -1
  43. package/lib/typescript/src/styleUtils.d.ts +1 -2
  44. package/lib/typescript/src/styleUtils.d.ts.map +1 -1
  45. package/lib/typescript/src/web/utils/blockUtils.d.ts +5 -0
  46. package/lib/typescript/src/web/utils/blockUtils.d.ts.map +1 -0
  47. package/lib/typescript/src/web/utils/browserUtils.d.ts +12 -0
  48. package/lib/typescript/src/web/utils/browserUtils.d.ts.map +1 -0
  49. package/lib/typescript/src/web/utils/cursorUtils.d.ts +12 -0
  50. package/lib/typescript/src/web/utils/cursorUtils.d.ts.map +1 -0
  51. package/lib/typescript/src/web/utils/inputUtils.d.ts +9 -0
  52. package/lib/typescript/src/web/utils/inputUtils.d.ts.map +1 -0
  53. package/lib/typescript/src/web/utils/parserUtils.d.ts +22 -0
  54. package/lib/typescript/src/web/utils/parserUtils.d.ts.map +1 -0
  55. package/lib/typescript/src/web/utils/treeUtils.d.ts +17 -0
  56. package/lib/typescript/src/web/utils/treeUtils.d.ts.map +1 -0
  57. package/lib/typescript/src/web/utils/webStyleUtils.d.ts +6 -0
  58. package/lib/typescript/src/web/utils/webStyleUtils.d.ts.map +1 -0
  59. package/package.json +5 -2
  60. package/src/MarkdownTextInput.tsx +4 -7
  61. package/src/MarkdownTextInput.web.tsx +142 -171
  62. package/src/styleUtils.ts +1 -3
  63. package/src/web/utils/blockUtils.ts +72 -0
  64. package/src/web/utils/browserUtils.ts +13 -0
  65. package/src/web/utils/cursorUtils.ts +116 -0
  66. package/src/web/utils/inputUtils.ts +106 -0
  67. package/src/web/utils/parserUtils.ts +302 -0
  68. package/src/web/utils/treeUtils.ts +103 -0
  69. package/src/web/utils/webStyleUtils.ts +54 -0
  70. package/lib/commonjs/web/browserUtils.js +0 -16
  71. package/lib/commonjs/web/browserUtils.js.map +0 -1
  72. package/lib/commonjs/web/cursorUtils.js +0 -167
  73. package/lib/commonjs/web/cursorUtils.js.map +0 -1
  74. package/lib/commonjs/web/parserUtils.js +0 -214
  75. package/lib/commonjs/web/parserUtils.js.map +0 -1
  76. package/lib/module/web/browserUtils.js +0 -11
  77. package/lib/module/web/browserUtils.js.map +0 -1
  78. package/lib/module/web/cursorUtils.js +0 -154
  79. package/lib/module/web/cursorUtils.js.map +0 -1
  80. package/lib/module/web/parserUtils.js +0 -206
  81. package/lib/module/web/parserUtils.js.map +0 -1
  82. package/lib/typescript/src/web/browserUtils.d.ts +0 -10
  83. package/lib/typescript/src/web/browserUtils.d.ts.map +0 -1
  84. package/lib/typescript/src/web/cursorUtils.d.ts +0 -12
  85. package/lib/typescript/src/web/cursorUtils.d.ts.map +0 -1
  86. package/lib/typescript/src/web/parserUtils.d.ts +0 -17
  87. package/lib/typescript/src/web/parserUtils.d.ts.map +0 -1
  88. package/src/web/browserUtils.ts +0 -11
  89. package/src/web/cursorUtils.ts +0 -177
  90. package/src/web/parserUtils.ts +0 -228
@@ -1,228 +0,0 @@
1
- import * as CursorUtils from './cursorUtils';
2
- import type * as StyleUtilsTypes from '../styleUtils';
3
- import * as BrowserUtils from './browserUtils';
4
-
5
- type PartialMarkdownStyle = StyleUtilsTypes.PartialMarkdownStyle;
6
-
7
- type MarkdownType = 'bold' | 'italic' | 'strikethrough' | 'emoji' | 'link' | 'code' | 'pre' | 'blockquote' | 'h1' | 'syntax' | 'mention-here' | 'mention-user' | 'mention-report';
8
-
9
- type MarkdownRange = {
10
- type: MarkdownType;
11
- start: number;
12
- length: number;
13
- depth?: number;
14
- };
15
-
16
- type NestedNode = {
17
- node: HTMLElement;
18
- endIndex: number;
19
- };
20
-
21
- function addStyling(targetElement: HTMLElement, type: MarkdownType, markdownStyle: PartialMarkdownStyle) {
22
- const node = targetElement;
23
- switch (type) {
24
- case 'syntax':
25
- Object.assign(node.style, markdownStyle.syntax);
26
- break;
27
- case 'bold':
28
- node.style.fontWeight = 'bold';
29
- break;
30
- case 'italic':
31
- node.style.fontStyle = 'italic';
32
- break;
33
- case 'strikethrough':
34
- node.style.textDecoration = 'line-through';
35
- break;
36
- case 'emoji':
37
- Object.assign(node.style, {...markdownStyle.emoji, verticalAlign: 'middle'});
38
- break;
39
- case 'mention-here':
40
- Object.assign(node.style, markdownStyle.mentionHere);
41
- break;
42
- case 'mention-user':
43
- Object.assign(node.style, markdownStyle.mentionUser);
44
- break;
45
- case 'mention-report':
46
- Object.assign(node.style, markdownStyle.mentionReport);
47
- break;
48
- case 'link':
49
- Object.assign(node.style, {
50
- ...markdownStyle.link,
51
- textDecoration: 'underline',
52
- });
53
- break;
54
- case 'code':
55
- Object.assign(node.style, markdownStyle.code);
56
- break;
57
- case 'pre':
58
- Object.assign(node.style, markdownStyle.pre);
59
- break;
60
-
61
- case 'blockquote':
62
- Object.assign(node.style, {
63
- ...markdownStyle.blockquote,
64
- borderLeftStyle: 'solid',
65
- display: 'inline-block',
66
- maxWidth: '100%',
67
- boxSizing: 'border-box',
68
- });
69
- break;
70
- case 'h1':
71
- Object.assign(node.style, {
72
- ...markdownStyle.h1,
73
- fontWeight: 'bold',
74
- });
75
- break;
76
- default:
77
- break;
78
- }
79
- }
80
-
81
- function addSubstringAsTextNode(root: HTMLElement, text: string, startIndex: number, endIndex: number) {
82
- const substring = text.substring(startIndex, endIndex);
83
- if (substring.length > 0) {
84
- root.appendChild(document.createTextNode(substring));
85
- }
86
- }
87
-
88
- function ungroupRanges(ranges: MarkdownRange[]): MarkdownRange[] {
89
- const ungroupedRanges: MarkdownRange[] = [];
90
- ranges.forEach((range) => {
91
- if (!range.depth) {
92
- ungroupedRanges.push(range);
93
- }
94
- const {depth, ...rangeWithoutDepth} = range;
95
- Array.from({length: depth!}).forEach(() => {
96
- ungroupedRanges.push(rangeWithoutDepth);
97
- });
98
- });
99
- return ungroupedRanges;
100
- }
101
-
102
- function parseRangesToHTMLNodes(text: string, ranges: MarkdownRange[], markdownStyle: PartialMarkdownStyle = {}, disableInlineStyles = false): HTMLElement {
103
- const root: HTMLElement = document.createElement('span');
104
- root.className = 'root';
105
- const textLength = text.length;
106
- if (ranges.length === 0) {
107
- addSubstringAsTextNode(root, text, 0, textLength);
108
- return root;
109
- }
110
-
111
- const stack = ungroupRanges(ranges);
112
- const nestedStack: NestedNode[] = [{node: root, endIndex: textLength}];
113
- let lastRangeEndIndex = 0;
114
- while (stack.length > 0) {
115
- const range = stack.shift();
116
- if (!range) {
117
- break;
118
- }
119
- let currentRoot = nestedStack[nestedStack.length - 1];
120
- if (!currentRoot) {
121
- break;
122
- }
123
-
124
- const endOfCurrentRange = range.start + range.length;
125
- const nextRangeStartIndex = stack.length > 0 && !!stack[0] ? stack[0].start || 0 : textLength;
126
-
127
- addSubstringAsTextNode(currentRoot.node, text, lastRangeEndIndex, range.start); // add text with newlines before current range
128
-
129
- const span = document.createElement('span');
130
- if (disableInlineStyles) {
131
- span.className = range.type;
132
- } else {
133
- addStyling(span, range.type, markdownStyle);
134
- }
135
-
136
- if (stack.length > 0 && nextRangeStartIndex < endOfCurrentRange && range.type !== 'syntax') {
137
- // tag nesting
138
- currentRoot.node.appendChild(span);
139
- nestedStack.push({node: span, endIndex: endOfCurrentRange});
140
- lastRangeEndIndex = range.start;
141
- } else {
142
- addSubstringAsTextNode(span, text, range.start, endOfCurrentRange);
143
- currentRoot.node.appendChild(span);
144
- lastRangeEndIndex = endOfCurrentRange;
145
-
146
- // end of tag nesting
147
- while (nestedStack.length - 1 > 0 && nextRangeStartIndex >= currentRoot.endIndex) {
148
- addSubstringAsTextNode(currentRoot.node, text, lastRangeEndIndex, currentRoot.endIndex);
149
- const prevRoot = nestedStack.pop();
150
- if (!prevRoot) {
151
- break;
152
- }
153
- lastRangeEndIndex = prevRoot.endIndex;
154
- currentRoot = nestedStack[nestedStack.length - 1] || currentRoot;
155
- }
156
- }
157
- }
158
-
159
- if (nestedStack.length > 1) {
160
- const lastNestedNode = nestedStack[nestedStack.length - 1];
161
- if (lastNestedNode) {
162
- root.appendChild(lastNestedNode.node);
163
- }
164
- }
165
-
166
- addSubstringAsTextNode(root, text, lastRangeEndIndex, textLength);
167
- return root;
168
- }
169
-
170
- function moveCursor(isFocused: boolean, alwaysMoveCursorToTheEnd: boolean, cursorPosition: number | null, target: HTMLElement) {
171
- if (!isFocused) {
172
- return;
173
- }
174
-
175
- if (alwaysMoveCursorToTheEnd || cursorPosition === null) {
176
- CursorUtils.moveCursorToEnd(target);
177
- } else if (cursorPosition !== null) {
178
- CursorUtils.setCursorPosition(target, cursorPosition);
179
- }
180
- }
181
-
182
- function parseText(target: HTMLElement, text: string, cursorPositionIndex: number | null, markdownStyle: PartialMarkdownStyle = {}, alwaysMoveCursorToTheEnd = false) {
183
- const targetElement = target;
184
-
185
- // in case the cursorPositionIndex is larger than text length, cursorPosition will be null, i.e: move the caret to the end
186
- let cursorPosition: number | null = cursorPositionIndex && cursorPositionIndex <= text.length ? cursorPositionIndex : null;
187
- const isFocused = document.activeElement === target;
188
- if (isFocused && cursorPositionIndex === null) {
189
- const selection = CursorUtils.getCurrentCursorPosition(target);
190
- cursorPosition = selection ? selection.end : null;
191
- }
192
- const ranges = global.parseExpensiMarkToRanges(text);
193
-
194
- const markdownRanges: MarkdownRange[] = ranges as MarkdownRange[];
195
- const rootSpan = targetElement.firstChild as HTMLElement | null;
196
-
197
- if (!text || targetElement.innerHTML === '<br>' || (rootSpan && rootSpan.innerHTML === '\n')) {
198
- targetElement.innerHTML = '';
199
- targetElement.innerText = '';
200
- }
201
-
202
- // We don't want to parse text with single '\n', because contentEditable represents it as invisible <br />
203
- if (text) {
204
- const dom = parseRangesToHTMLNodes(text, markdownRanges, markdownStyle);
205
-
206
- if (!rootSpan || !rootSpan?.classList?.contains('root') || rootSpan.innerHTML !== dom.innerHTML) {
207
- targetElement.innerHTML = '';
208
- targetElement.innerText = '';
209
- target.appendChild(dom);
210
-
211
- if (BrowserUtils.isChromium) {
212
- moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, target);
213
- }
214
- }
215
-
216
- if (!BrowserUtils.isChromium) {
217
- moveCursor(isFocused, alwaysMoveCursorToTheEnd, cursorPosition, target);
218
- }
219
- }
220
-
221
- CursorUtils.setPrevText(target);
222
-
223
- return {text: target.innerText, cursorPosition: cursorPosition || 0};
224
- }
225
-
226
- export {parseText, parseRangesToHTMLNodes};
227
-
228
- export type {MarkdownRange, MarkdownType};