chore(richtext-lexical): fix unchecked indexed access (part 3) (#11014)

I start to list the PRs because there may be a few.

1. https://github.com/payloadcms/payload/pull/10982
2. https://github.com/payloadcms/payload/pull/11013
This commit is contained in:
Germán Jabloñski
2025-02-06 12:44:02 -03:00
committed by GitHub
parent e413e1df1c
commit 5f58daffd0
11 changed files with 38 additions and 34 deletions

View File

@@ -92,7 +92,7 @@ export const getBlockMarkdownTransformers = ({
const childrenString = linesInBetween.join('\n').trim() const childrenString = linesInBetween.join('\n').trim()
const propsString: null | string = openMatch?.length > 2 ? openMatch[2]?.trim() : null const propsString = openMatch[2]?.trim()
const markdownToLexical = getMarkdownToLexical(allNodes, allTransformers) const markdownToLexical = getMarkdownToLexical(allNodes, allTransformers)

View File

@@ -38,17 +38,17 @@ export function linesFromStartToContentAndPropsString({
let isSelfClosing = false let isSelfClosing = false
let isWithinCodeBlockAmount = 0 let isWithinCodeBlockAmount = 0
const beforeStartLine = linesCopy[0].slice(0, startMatch.index) const beforeStartLine = linesCopy[0]!.slice(0, startMatch.index)
let endlineLastCharIndex = 0 let endlineLastCharIndex = 0
let endLineIndex = startLineIndex let endLineIndex = startLineIndex
mainLoop: for (let lineIndex = 0; lineIndex < linesCopy.length; lineIndex++) { mainLoop: for (const [lineIndex, lineCopy] of linesCopy.entries()) {
const line = trimChildren ? linesCopy[lineIndex].trim() : linesCopy[lineIndex] const line = trimChildren ? lineCopy.trim() : lineCopy
let amountOfBeginningSpacesRemoved = 0 let amountOfBeginningSpacesRemoved = 0
if (trimChildren) { if (trimChildren) {
for (let i = 0; i < linesCopy[lineIndex].length; i++) { for (let i = 0; i < lineCopy.length; i++) {
if (linesCopy[lineIndex][i] === ' ') { if (lineCopy[i] === ' ') {
amountOfBeginningSpacesRemoved++ amountOfBeginningSpacesRemoved++
} else { } else {
break break
@@ -159,7 +159,7 @@ export function linesFromStartToContentAndPropsString({
} }
} }
const afterEndLine = linesCopy[endLineIndex].trim().slice(endlineLastCharIndex) const afterEndLine = linesCopy[endLineIndex]!.trim().slice(endlineLastCharIndex)
return { return {
afterEndLine, afterEndLine,

View File

@@ -361,18 +361,19 @@ function getMarkdownTransformerForBlock(
if (beforeStartLine?.length) { if (beforeStartLine?.length) {
prevNodes = markdownToLexical({ markdown: beforeStartLine })?.root?.children ?? [] prevNodes = markdownToLexical({ markdown: beforeStartLine })?.root?.children ?? []
if (prevNodes?.length) { const firstPrevNode = prevNodes?.[0]
rootNode.append($parseSerializedNode(prevNodes[0])) if (firstPrevNode) {
rootNode.append($parseSerializedNode(firstPrevNode))
} }
} }
rootNode.append(node) rootNode.append(node)
if (afterEndLine?.length) { if (afterEndLine?.length) {
nextNodes = markdownToLexical({ markdown: afterEndLine })?.root?.children ?? [] nextNodes = markdownToLexical({ markdown: afterEndLine })?.root?.children
const lastChild = rootNode.getChildren()[rootNode.getChildren().length - 1] const lastChild = rootNode.getChildren()[rootNode.getChildren().length - 1]
const children = ($parseSerializedNode(nextNodes[0]) as ElementNode)?.getChildren() const children = ($parseSerializedNode(nextNodes[0]!) as ElementNode)?.getChildren()
if (children?.length) { if (children?.length) {
for (const child of children) { for (const child of children) {
;(lastChild as ElementNode).append(child) ;(lastChild as ElementNode).append(child)
@@ -408,7 +409,7 @@ function getMarkdownTransformerForBlock(
childrenString = linesInBetween.join('\n').trim() childrenString = linesInBetween.join('\n').trim()
} }
const propsString: null | string = openMatch?.length > 1 ? openMatch[1]?.trim() : null const propsString = openMatch[1]?.trim()
const markdownToLexical = getMarkdownToLexical(allNodes, allTransformers) const markdownToLexical = getMarkdownToLexical(allNodes, allTransformers)

View File

@@ -44,7 +44,7 @@ export const blockValidationHOC = (
let errorPaths: string[] = [] let errorPaths: string[] = []
for (const fieldKey in result) { for (const fieldKey in result) {
if (result[fieldKey].errorPaths) { if (result[fieldKey]?.errorPaths) {
errorPaths = errorPaths.concat(result[fieldKey].errorPaths) errorPaths = errorPaths.concat(result[fieldKey].errorPaths)
} }
} }

View File

@@ -210,13 +210,15 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
} }
const getCellColumnIndex = (tableCellNode: TableCellNode, tableMap: TableMapType) => { const getCellColumnIndex = (tableCellNode: TableCellNode, tableMap: TableMapType) => {
for (let row = 0; row < tableMap.length; row++) { let columnIndex: number | undefined
for (let column = 0; column < tableMap[row].length; column++) { tableMap.forEach((row) => {
if (tableMap[row][column].cell === tableCellNode) { row.forEach((cell, columnIndexInner) => {
return column if (cell.cell === tableCellNode) {
columnIndex = columnIndexInner
} }
} })
} })
return columnIndex
} }
const updateColumnWidth = useCallback( const updateColumnWidth = useCallback(

View File

@@ -65,8 +65,12 @@ export const TableMarkdownTransformer: (props: {
}, },
regExp: TABLE_ROW_REG_EXP, regExp: TABLE_ROW_REG_EXP,
replace: (parentNode, _1, match) => { replace: (parentNode, _1, match) => {
const match0 = match[0]
if (!match0) {
return
}
// Header row // Header row
if (TABLE_ROW_DIVIDER_REG_EXP.test(match[0])) { if (TABLE_ROW_DIVIDER_REG_EXP.test(match0)) {
const table = parentNode.getPreviousSibling() const table = parentNode.getPreviousSibling()
if (!table || !$isTableNode(table)) { if (!table || !$isTableNode(table)) {
return return
@@ -91,7 +95,7 @@ export const TableMarkdownTransformer: (props: {
return return
} }
const matchCells = mapToTableCells(match[0], allTransformers) const matchCells = mapToTableCells(match0, allTransformers)
if (matchCells == null) { if (matchCells == null) {
return return
@@ -136,7 +140,7 @@ export const TableMarkdownTransformer: (props: {
table.append(tableRow) table.append(tableRow)
for (let i = 0; i < maxCells; i++) { for (let i = 0; i < maxCells; i++) {
tableRow.append(i < cells.length ? cells[i] : $createTableCell('', allTransformers)) tableRow.append(i < cells.length ? cells[i]! : $createTableCell('', allTransformers))
} }
} }

View File

@@ -28,7 +28,7 @@ export const MarkdownTransformer: (enabledHeadingSizes: HeadingTagType[]) => Ele
}, },
regExp, regExp,
replace: createBlockNode((match) => { replace: createBlockNode((match) => {
const tag = ('h' + match[1].length) as HeadingTagType const tag = ('h' + match[1]?.length) as HeadingTagType
return $createHeadingNode(tag) return $createHeadingNode(tag)
}), }),
} }

View File

@@ -408,7 +408,7 @@ export function LinkEditor({ anchorElem }: { anchorElem: HTMLElement }): React.R
linkParent = getSelectedNode(selection).getParent() linkParent = getSelectedNode(selection).getParent()
} else { } else {
if (selectedNodes.length) { if (selectedNodes.length) {
linkParent = selectedNodes[0].getParent() linkParent = selectedNodes[0]?.getParent() ?? null
} }
} }

View File

@@ -295,9 +295,9 @@ export function $toggleLink(payload: ({ fields: LinkFields } & LinkPayload) | nu
if ($isLinkNode(parent)) { if ($isLinkNode(parent)) {
const children = parent.getChildren() const children = parent.getChildren()
for (let i = 0; i < children.length; i += 1) { children.forEach((child) => {
parent.insertBefore(children[i]) parent.insertBefore(child)
} })
parent.remove() parent.remove()
} }
@@ -307,7 +307,7 @@ export function $toggleLink(payload: ({ fields: LinkFields } & LinkPayload) | nu
} }
// Add or merge LinkNodes // Add or merge LinkNodes
if (nodes?.length === 1) { if (nodes?.length === 1) {
const firstNode = nodes[0] const firstNode = nodes[0]!
// if the first node is a LinkNode or if its // if the first node is a LinkNode or if its
// parent is a LinkNode, we update the URL, target and rel. // parent is a LinkNode, we update the URL, target and rel.
const linkNode: LinkNode | null = $isLinkNode(firstNode) const linkNode: LinkNode | null = $isLinkNode(firstNode)
@@ -375,10 +375,7 @@ export function $toggleLink(payload: ({ fields: LinkFields } & LinkPayload) | nu
} }
if (linkNode !== null) { if (linkNode !== null) {
const children = node.getChildren() const children = node.getChildren()
linkNode.append(...children)
for (let i = 0; i < children.length; i += 1) {
linkNode.append(children[i])
}
} }
node.remove() node.remove()

View File

@@ -36,7 +36,7 @@ export const linkValidation = (
let errorPaths: string[] = [] let errorPaths: string[] = []
for (const fieldKey in result) { for (const fieldKey in result) {
if (result[fieldKey].errorPaths) { if (result[fieldKey]?.errorPaths) {
errorPaths = errorPaths.concat(result[fieldKey].errorPaths) errorPaths = errorPaths.concat(result[fieldKey].errorPaths)
} }
} }

View File

@@ -34,7 +34,7 @@ export const listReplace = (listType: ListType): ElementTransformer['replace'] =
} }
listItem.append(...children) listItem.append(...children)
listItem.select(0, 0) listItem.select(0, 0)
const indent = Math.floor(match[1].length / LIST_INDENT_SIZE) const indent = Math.floor(match[1]!.length / LIST_INDENT_SIZE)
if (indent) { if (indent) {
listItem.setIndent(indent) listItem.setIndent(indent)
} }