Skip to content

Commit

Permalink
[WEB-617] fix: link behaviour fixed on formatting (#3855)
Browse files Browse the repository at this point in the history
* fix: link behaviour fixed on formatting

* chore: added harmful script checks for links
  • Loading branch information
Palanikannan1437 authored Mar 6, 2024
1 parent 87eadc3 commit 126d01b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ export function clickHandler(options: ClickHandlerOptions): Plugin {
return false;
}

const eventTarget = event.target as HTMLElement;
let a = event.target as HTMLElement;
const els = [];

if (eventTarget.nodeName !== "A") {
while (a.nodeName !== "DIV") {
els.push(a);
a = a.parentNode as HTMLElement;
}

if (!els.find((value) => value.nodeName === "A")) {
return false;
}

Expand All @@ -28,9 +34,7 @@ export function clickHandler(options: ClickHandlerOptions): Plugin {
const target = link?.target ?? attrs.target;

if (link && href) {
if (view.editable) {
window.open(href, target);
}
window.open(href, target);

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,8 @@ export function pasteHandler(options: PasteHandlerOptions): Plugin {
return false;
}

const html = event.clipboardData?.getData("text/html");

const hrefRegex = /href="([^"]*)"/;

const existingLink = html?.match(hrefRegex);

const url = existingLink ? existingLink[1] : link.href;

options.editor.commands.setMark(options.type, {
href: url,
href: link.href,
});

return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,76 @@
import { Mark, markPasteRule, mergeAttributes } from "@tiptap/core";
import { Mark, markPasteRule, mergeAttributes, PasteRuleMatch } from "@tiptap/core";
import { Plugin } from "@tiptap/pm/state";
import { find, registerCustomProtocol, reset } from "linkifyjs";

import { autolink } from "src/ui/extensions/custom-link/helpers/autolink";
import { clickHandler } from "src/ui/extensions/custom-link/helpers/clickHandler";
import { pasteHandler } from "src/ui/extensions/custom-link/helpers/pasteHandler";
import { autolink } from "./helpers/autolink";
import { clickHandler } from "./helpers/clickHandler";
import { pasteHandler } from "./helpers/pasteHandler";

export interface LinkProtocolOptions {
scheme: string;
optionalSlashes?: boolean;
}

export const pasteRegex =
/https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;

export interface LinkOptions {
/**
* If enabled, it adds links as you type.
*/
autolink: boolean;
inclusive: boolean;
/**
* An array of custom protocols to be registered with linkifyjs.
*/
protocols: Array<LinkProtocolOptions | string>;
/**
* If enabled, links will be opened on click.
*/
openOnClick: boolean;
/**
* If enabled, links will be inclusive i.e. if you move your cursor to the
* link text, and start typing, it'll be a part of the link itself.
*/
inclusive: boolean;
/**
* Adds a link to the current selection if the pasted content only contains an url.
*/
linkOnPaste: boolean;
/**
* A list of HTML attributes to be rendered.
*/
HTMLAttributes: Record<string, any>;
/**
* A validation function that modifies link verification for the auto linker.
* @param url - The url to be validated.
* @returns - True if the url is valid, false otherwise.
*/
validate?: (url: string) => boolean;
}

declare module "@tiptap/core" {
interface Commands<ReturnType> {
link: {
/**
* Set a link mark
*/
setLink: (attributes: {
href: string;
target?: string | null;
rel?: string | null;
class?: string | null;
}) => ReturnType;
/**
* Toggle a link mark
*/
toggleLink: (attributes: {
href: string;
target?: string | null;
rel?: string | null;
class?: string | null;
}) => ReturnType;
/**
* Unset a link mark
*/
unsetLink: () => ReturnType;
};
}
Expand Down Expand Up @@ -150,37 +185,31 @@ export const CustomLinkExtension = Mark.create<LinkOptions>({
addPasteRules() {
return [
markPasteRule({
find: (text) =>
find(text)
.filter((link) => {
if (this.options.validate) {
return this.options.validate(link.value);
}
return true;
})
.filter((link) => link.isLink)
.map((link) => ({
text: link.value,
index: link.start,
data: link,
})),
type: this.type,
getAttributes: (match, pasteEvent) => {
const html = pasteEvent?.clipboardData?.getData("text/html");
const hrefRegex = /href="([^"]*)"/;

const existingLink = html?.match(hrefRegex);

if (existingLink) {
return {
href: existingLink[1],
};
find: (text) => {
const foundLinks: PasteRuleMatch[] = [];

if (text) {
const links = find(text).filter((item) => item.isLink);

if (links.length) {
links.forEach((link) =>
foundLinks.push({
text: link.value,
data: {
href: link.href,
},
index: link.start,
})
);
}
}

return {
href: match.data?.href,
};
return foundLinks;
},
type: this.type,
getAttributes: (match) => ({
href: match.data?.href,
}),
}),
];
},
Expand Down

0 comments on commit 126d01b

Please sign in to comment.