diff --git a/extensions/hyper-link/src/index.ts b/extensions/hyper-link/src/index.ts index 7b420cf28..130aaf81f 100644 --- a/extensions/hyper-link/src/index.ts +++ b/extensions/hyper-link/src/index.ts @@ -8,9 +8,9 @@ import { ViewUpdate, } from '@codemirror/view'; import { Extension, Range } from '@codemirror/state'; -import { syntaxTree } from '@codemirror/language'; const pathStr = ``; +const defaultRegexp = /\b((?:https?|ftp):\/\/[^\s/$.?#].[^\s]*)\b/gi; export interface HyperLinkState { at: number; @@ -40,28 +40,25 @@ class HyperLinkIcon extends WidgetType { } function hyperLinkDecorations(view: EditorView, anchor?: HyperLinkExtensionOptions['anchor']) { - const widgets: Array> = []; - for (const range of view.visibleRanges) { - syntaxTree(view.state).iterate({ - from: range.from, - to: range.to, - enter: ({ type, from, to }) => { - const callExp: string = view.state.doc.sliceString(from, to); - if (type.name === 'URL') { - const widget = Decoration.widget({ + const widgets: Array> = []; + const doc = view.state.doc; + let match; + + while ((match = defaultRegexp.exec(doc.toString())) !== null) { + const from = match.index; + const to = from + match[0].length; + const widget = Decoration.widget({ widget: new HyperLinkIcon({ - at: to, - url: callExp, - anchor, + at: to, + url: match[0], + anchor, }), side: 1, - }); - widgets.push(widget.range(to)); - } - }, - }); - } - return Decoration.set(widgets); + }); + widgets.push(widget.range(to)); + } + + return Decoration.set(widgets); } const linkDecorator = ( @@ -71,7 +68,7 @@ const linkDecorator = ( anchor?: HyperLinkExtensionOptions['anchor'], ) => new MatchDecorator({ - regexp: regexp || /\b((?:https?|ftp):\/\/[^\s/$.?#].[^\s]*)\b/gi, + regexp: regexp || defaultRegexp, decorate: (add, from, to, match, view) => { const url = match[0]; let urlStr = matchFn && typeof matchFn === 'function' ? matchFn(url, match.input, from, to) : url;