Skip to content

Commit 7fda70f

Browse files
committed
fix(autolink): migrate from 'visit' to 'visitParents'
- essentially it's the same visitor underneath, just allow access all parents stack (ancestor) Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
1 parent f9f8547 commit 7fda70f

4 files changed

Lines changed: 30 additions & 27 deletions

File tree

src/components/NcRichText/autolink.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6+
import type { Node, Parent } from 'unist'
67
import type { Router } from 'vue-router'
78

89
import { getBaseUrl, getRootUrl } from '@nextcloud/router'
910
import { u } from 'unist-builder'
10-
import { SKIP, visit } from 'unist-util-visit'
11+
import { SKIP, visitParents } from 'unist-util-visit-parents'
1112
import { defineComponent, h } from 'vue'
1213
import { logger } from '../../utils/logger.ts'
1314
import { URL_PATTERN_AUTOLINK } from './helpers.js'
@@ -45,18 +46,19 @@ export function remarkAutolink({ autolink, useMarkdown, useExtendedMarkdown }) {
4546
return
4647
}
4748

48-
visit(tree, (node) => node.type === 'text', (node, index, parent) => {
49+
visitParents(tree, (node) => node.type === 'text', (node, ancestors: Parent[]) => {
4950
// Do not autolink text already inside a link node
50-
if (parent?.type === 'link' || parent?.type === 'linkReference') {
51+
if (ancestors.some((ancestor) => ancestor.type === 'link' || ancestor.type === 'linkReference')) {
5152
return
5253
}
5354

54-
let parsed = parseUrl(node.value)
55-
if (typeof parsed === 'string') {
56-
parsed = [u('text', parsed)]
57-
} else {
58-
parsed = parsed
59-
.map((n) => {
55+
const parent = ancestors.at(-1)
56+
const index = parent!.children.indexOf(node) ?? 0
57+
58+
const parsed = parseUrl(node.value)
59+
const parsedNodes: Node[] = (typeof parsed === 'string')
60+
? [u('text', parsed)]
61+
: parsed.map((n) => {
6062
if (typeof n === 'string') {
6163
return u('text', n)
6264
}
@@ -65,12 +67,11 @@ export function remarkAutolink({ autolink, useMarkdown, useExtendedMarkdown }) {
6567
url: n.props.href,
6668
}, [u('text', n.props.href)])
6769
})
68-
.filter((x) => x)
69-
.flat()
70-
}
70+
.filter((x) => x)
71+
.flat()
7172

72-
parent.children.splice(index, 1, ...parsed)
73-
return [SKIP, (index ?? 0) + parsed.length]
73+
parent!.children.splice(index, 1, ...parsedNodes)
74+
return [SKIP, index + parsedNodes.length]
7475
})
7576
}
7677
}

src/components/NcRichText/remarkPlaceholder.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { Node, Parent } from 'unist'
88
import type { TextNode } from './helpers.ts'
99

1010
import { u } from 'unist-builder'
11-
import { visit } from 'unist-util-visit'
11+
import { visitParents } from 'unist-util-visit-parents'
1212

1313
/**
1414
* Check if the given node is a literal and specifically a text node
@@ -21,14 +21,10 @@ function isTextNode(node: Node): node is TextNode {
2121

2222
const transformPlaceholders: Transformer = function(ast: Node) {
2323
// Apply the visitor to all text nodes of the AST
24-
visit(ast, isTextNode, visitor)
24+
visitParents(ast, isTextNode, (node: TextNode, ancestors: Parent[]) => {
25+
const parent = ancestors.at(-1)
26+
const index = parent!.children.indexOf(node)
2527

26-
/**
27-
* @param node - The text node
28-
* @param index - The index of the node
29-
* @param parent - The parent node
30-
*/
31-
function visitor(node: TextNode, index?: number, parent?: Parent) {
3228
const placeholders = node.value.split(/(\{[a-z\-_.0-9]+\})/ig)
3329
.map((entry: string) => {
3430
const matches = entry.match(/^\{([a-z\-_.0-9]+)\}$/i)
@@ -43,7 +39,7 @@ const transformPlaceholders: Transformer = function(ast: Node) {
4339
})
4440

4541
parent!.children.splice(index!, 1, ...placeholders)
46-
}
42+
})
4743
}
4844

4945
export const remarkPlaceholder: Plugin = () => transformPlaceholders

src/components/NcRichText/remarkStripCode.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Plugin } from 'unified'
77
import type { Node, Parent } from 'unist'
88
import type { TextNode } from './helpers.ts'
99

10-
import { SKIP, visit } from 'unist-util-visit'
10+
import { SKIP, visitParents } from 'unist-util-visit-parents'
1111

1212
/**
1313
* Check if the given node is a literal and specifically a fenced node (inline code or code block)
@@ -20,7 +20,10 @@ function isCodeNode(node: Node): node is TextNode {
2020

2121
export const remarkStripCode: Plugin = function() {
2222
return function(tree: Node) {
23-
visit(tree, isCodeNode, (node: TextNode, index?: number, parent?: Parent) => {
23+
visitParents(tree, isCodeNode, (node: TextNode, ancestors: Parent[]) => {
24+
const parent = ancestors.at(-1)
25+
const index = parent!.children.indexOf(node)
26+
2427
parent!.children.splice(index!, 1, {
2528
...node,
2629
value: '',

src/components/NcRichText/remarkUnescape.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Plugin } from 'unified'
77
import type { Node, Parent } from 'unist'
88
import type { TextNode } from './helpers.ts'
99

10-
import { SKIP, visit } from 'unist-util-visit'
10+
import { SKIP, visitParents } from 'unist-util-visit-parents'
1111

1212
/**
1313
* Check if the given node is a literal and specifically a text node
@@ -20,7 +20,10 @@ function isTextNode(node: Node): node is TextNode {
2020

2121
export const remarkUnescape: Plugin = function() {
2222
return function(tree: Node) {
23-
visit(tree, isTextNode, (node: TextNode, index?: number, parent?: Parent) => {
23+
visitParents(tree, isTextNode, (node: TextNode, ancestors: Parent[]) => {
24+
const parent = ancestors.at(-1)
25+
const index = parent!.children.indexOf(node)
26+
2427
parent!.children.splice(index!, 1, {
2528
...node,
2629
value: node.value.replace(/&lt;/gmi, '<').replace(/&gt;/gmi, '>'),

0 commit comments

Comments
 (0)