Skip to content

Commit

Permalink
feat(hyper-link): add anchor options. (#525)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Jun 25, 2023
1 parent 194e2ee commit 097ad2e
Showing 1 changed file with 18 additions and 9 deletions.
27 changes: 18 additions & 9 deletions extensions/hyper-link/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const pathStr = `<svg viewBox="0 0 1024 1024" width="16" height="16" fill="curre
export interface HyperLinkState {
at: number;
url: string;
anchor: HyperLinkExtensionOptions['anchor'];
}

class HyperLinkIcon extends WidgetType {
Expand All @@ -33,11 +34,12 @@ class HyperLinkIcon extends WidgetType {
wrapper.innerHTML = pathStr;
wrapper.className = 'cm-hyper-link-icon';
wrapper.rel = 'nofollow';
return wrapper;
const anchor = this.state.anchor && this.state.anchor(wrapper);
return anchor || wrapper;
}
}

function hyperLinkDecorations(view: EditorView) {
function hyperLinkDecorations(view: EditorView, anchor?: HyperLinkExtensionOptions['anchor']) {
const widgets: Array<Range<Decoration>> = [];
for (const range of view.visibleRanges) {
syntaxTree(view.state).iterate({
Expand All @@ -50,6 +52,7 @@ function hyperLinkDecorations(view: EditorView) {
widget: new HyperLinkIcon({
at: to,
url: callExp,
anchor,
}),
side: 1,
});
Expand All @@ -61,7 +64,12 @@ function hyperLinkDecorations(view: EditorView) {
return Decoration.set(widgets);
}

const linkDecorator = (regexp?: RegExp, matchData?: Record<string, string>, matchFn?: (str: string) => string) =>
const linkDecorator = (
regexp?: RegExp,
matchData?: Record<string, string>,
matchFn?: (str: string) => string,
anchor?: HyperLinkExtensionOptions['anchor'],
) =>
new MatchDecorator({
regexp: regexp || /\b((?:https?|ftp):\/\/[^\s/$.?#].[^\s]*)\b/gi,
decorate: (add, from, to, match, view) => {
Expand All @@ -72,36 +80,37 @@ const linkDecorator = (regexp?: RegExp, matchData?: Record<string, string>, matc
}
const start = to,
end = to;
const linkIcon = new HyperLinkIcon({ at: start, url: urlStr });
const linkIcon = new HyperLinkIcon({ at: start, url: urlStr, anchor });
add(start, end, Decoration.widget({ widget: linkIcon, side: 1 }));
},
});

export type hyperLinkExtensionOptions = {
export type HyperLinkExtensionOptions = {
regexp?: RegExp;
match?: Record<string, string>;
handle?: (value: string) => string;
anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement;
};

export function hyperLinkExtension({ regexp, match, handle }: hyperLinkExtensionOptions = {}) {
export function hyperLinkExtension({ regexp, match, handle, anchor }: HyperLinkExtensionOptions = {}) {
return ViewPlugin.fromClass(
class HyperLinkView {
decorator?: MatchDecorator;
decorations: DecorationSet;
constructor(view: EditorView) {
if (regexp) {
this.decorator = linkDecorator(regexp, match, handle);
this.decorator = linkDecorator(regexp, match, handle, anchor);
this.decorations = this.decorator.createDeco(view);
} else {
this.decorations = hyperLinkDecorations(view);
this.decorations = hyperLinkDecorations(view, anchor);
}
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
if (regexp && this.decorator) {
this.decorations = this.decorator.updateDeco(update, this.decorations);
} else {
this.decorations = hyperLinkDecorations(update.view);
this.decorations = hyperLinkDecorations(update.view, anchor);
}
}
}
Expand Down

0 comments on commit 097ad2e

Please sign in to comment.