Skip to content

Commit 9458739

Browse files
author
Sravan S
authored
hot-fix: NodeList conversion on MessageInput.Paste (#536)
NodeList cannot use Array methods, but our conversion was not really explicit. So, during the ESLint upgrade, NodeList -> Array(Nodes) conversion was deleted As a fix, we make explicit function to convert NodeList to Array(Nodes)
1 parent 35bf516 commit 9458739

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import jsdom from 'jsdom';
2+
3+
import { nodeListToArray } from '../utils';
4+
5+
describe('MessageInputUtils/nodeListToArray', () => {
6+
it('should convert node list to array', () => {
7+
const P_COUNT = 4;
8+
const dom = new jsdom.JSDOM(`
9+
<div>${Array(P_COUNT).fill(0).map(() => '<p></p>').join('')}
10+
</div>
11+
`);
12+
const nodes = nodeListToArray(dom.window.document.querySelectorAll('p'));
13+
expect(nodes.length).toEqual(4);
14+
});
15+
16+
it('should return empty array if nodelist is null', () => {
17+
const nodes = nodeListToArray(null);
18+
expect(nodes.length).toBe(0);
19+
});
20+
21+
it('should return empty array if nodelist is undefined', () => {
22+
const nodes = nodeListToArray(null);
23+
expect(nodes.length).toBe(0);
24+
});
25+
});

src/ui/MessageInput/hooks/usePaste/utils.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { Word } from './types';
1212
import { TEXT_MESSAGE_BODY_CLASSNAME } from '../../../TextMessageItemBody/consts';
1313
import { OG_MESSAGE_BODY_CLASSNAME } from '../../../OGMessageItemBody/consts';
14+
import { nodeListToArray } from '../../utils';
1415

1516
export function querySelectorIncludingSelf(
1617
master: HTMLElement,
@@ -30,15 +31,15 @@ export function getLeafNodes(master: HTMLElement): ChildNode[] {
3031
// og message
3132
const ogMessage = querySelectorIncludingSelf(master, `.${OG_MESSAGE_BODY_CLASSNAME}`);
3233
if (ogMessage) {
33-
return Array.from(ogMessage.childNodes);
34+
return nodeListToArray(ogMessage.childNodes);
3435
}
3536

3637
const textMessageBody = querySelectorIncludingSelf(master, `.${TEXT_MESSAGE_BODY_CLASSNAME}`);
3738
if (textMessageBody) {
38-
return Array.from(textMessageBody.childNodes);
39+
return nodeListToArray(textMessageBody.childNodes);
3940
}
4041

41-
return Array.from(master.childNodes);
42+
return nodeListToArray(master.childNodes);
4243
}
4344

4445
export function createPasteNode(): HTMLDivElement | null {

src/ui/MessageInput/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import renderMentionLabelToString from '../MentionUserLabel/renderToString';
1818
import Icon, { IconTypes, IconColors } from '../Icon';
1919
import Label, { LabelTypography, LabelColors } from '../Label';
2020
import { LocalizationContext } from '../../lib/LocalizationContext';
21-
import { sanitizeString } from './utils';
21+
import { nodeListToArray, sanitizeString } from './utils';
2222
import {
2323
arrayEqual,
2424
getClassName,
@@ -215,7 +215,7 @@ const MessageInput = React.forwardRef((props, ref) => {
215215
if (targetString && startNodeIndex !== null && startOffsetIndex !== null) {
216216
// const textField = document.getElementById(textFieldId);
217217
const textField = ref?.current;
218-
const childNodes = textField?.childNodes;
218+
const childNodes = nodeListToArray(textField?.childNodes);
219219
const frontTextNode = document?.createTextNode(
220220
childNodes[startNodeIndex]?.textContent.slice(0, startOffsetIndex),
221221
);

src/ui/MessageInput/utils.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,17 @@ export const sanitizeString = (str) => (
2525
str?.replace(/[\u00A0-\u9999<>]/gim, (i) => ''.concat('&#', i.charCodeAt(0), ';'))
2626
);
2727

28+
/**
29+
* NodeList cannot be used with Array methods
30+
* @param {childNodes} NodeList
31+
* @returns Array of child nodes
32+
*/
33+
export const nodeListToArray = (childNodes) => {
34+
try {
35+
return Array.from(childNodes);
36+
} catch (error) {
37+
return [];
38+
}
39+
};
40+
2841
export default debounce;

0 commit comments

Comments
 (0)