Skip to content

Commit 08e7dfb

Browse files
committed
feat: fix editor
1 parent 3cf7ed4 commit 08e7dfb

File tree

1 file changed

+85
-63
lines changed

1 file changed

+85
-63
lines changed

apps/frontend/src/components/new-launch/editor.tsx

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -759,66 +759,84 @@ export const OnlyEditor = forwardRef<
759759
InterceptUnderlineShortcut,
760760
BulletList,
761761
ListItem,
762-
Link.configure({
763-
openOnClick: false,
764-
autolink: true,
765-
defaultProtocol: 'https',
766-
protocols: ['http', 'https'],
767-
isAllowedUri: (url, ctx) => {
768-
try {
769-
// construct URL
770-
const parsedUrl = url.includes(':')
771-
? new URL(url)
772-
: new URL(`${ctx.defaultProtocol}://${url}`);
773-
774-
// use default validation
775-
if (!ctx.defaultValidate(parsedUrl.href)) {
776-
return false;
777-
}
778-
779-
// disallowed protocols
780-
const disallowedProtocols = ['ftp', 'file', 'mailto'];
781-
const protocol = parsedUrl.protocol.replace(':', '');
782-
783-
if (disallowedProtocols.includes(protocol)) {
784-
return false;
785-
}
786-
787-
// only allow protocols specified in ctx.protocols
788-
const allowedProtocols = ctx.protocols.map((p) =>
789-
typeof p === 'string' ? p : p.scheme
790-
);
791-
792-
if (!allowedProtocols.includes(protocol)) {
793-
return false;
794-
}
795-
796-
// all checks have passed
797-
return true;
798-
} catch {
799-
return false;
800-
}
801-
},
802-
shouldAutoLink: (url) => {
803-
try {
804-
// construct URL
805-
const parsedUrl = url.includes(':')
806-
? new URL(url)
807-
: new URL(`https://${url}`);
808-
809-
// only auto-link if the domain is not in the disallowed list
810-
const disallowedDomains = [
811-
'example-no-autolink.com',
812-
'another-no-autolink.com',
813-
];
814-
const domain = parsedUrl.hostname;
815-
816-
return !disallowedDomains.includes(domain);
817-
} catch {
818-
return false;
819-
}
820-
},
821-
}),
762+
...(editorType === 'html' || editorType === 'markdown'
763+
? [
764+
Link.configure({
765+
openOnClick: false,
766+
autolink: true,
767+
defaultProtocol: 'https',
768+
protocols: ['http', 'https'],
769+
isAllowedUri: (url, ctx) => {
770+
try {
771+
// prevent transforming plain emails like foo@bar.com into links
772+
const trimmed = String(url).trim();
773+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
774+
if (emailPattern.test(trimmed)) {
775+
return false;
776+
}
777+
778+
// construct URL
779+
const parsedUrl = url.includes(':')
780+
? new URL(url)
781+
: new URL(`${ctx.defaultProtocol}://${url}`);
782+
783+
// use default validation
784+
if (!ctx.defaultValidate(parsedUrl.href)) {
785+
return false;
786+
}
787+
788+
// disallowed protocols
789+
const disallowedProtocols = ['ftp', 'file', 'mailto'];
790+
const protocol = parsedUrl.protocol.replace(':', '');
791+
792+
if (disallowedProtocols.includes(protocol)) {
793+
return false;
794+
}
795+
796+
// only allow protocols specified in ctx.protocols
797+
const allowedProtocols = ctx.protocols.map((p) =>
798+
typeof p === 'string' ? p : p.scheme
799+
);
800+
801+
if (!allowedProtocols.includes(protocol)) {
802+
return false;
803+
}
804+
805+
// all checks have passed
806+
return true;
807+
} catch {
808+
return false;
809+
}
810+
},
811+
shouldAutoLink: (url) => {
812+
try {
813+
// prevent auto-linking of plain emails like [email protected]
814+
const trimmed = String(url).trim();
815+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
816+
if (emailPattern.test(trimmed)) {
817+
return false;
818+
}
819+
820+
// construct URL
821+
const parsedUrl = url.includes(':')
822+
? new URL(url)
823+
: new URL(`https://${url}`);
824+
825+
// only auto-link if the domain is not in the disallowed list
826+
const disallowedDomains = [
827+
'example-no-autolink.com',
828+
'another-no-autolink.com',
829+
];
830+
const domain = parsedUrl.hostname;
831+
832+
return !disallowedDomains.includes(domain);
833+
} catch {
834+
return false;
835+
}
836+
},
837+
}),
838+
]
839+
: []),
822840
...(internal?.integration?.id
823841
? [
824842
Mention.configure({
@@ -839,9 +857,13 @@ export const OnlyEditor = forwardRef<
839857
}),
840858
]
841859
: []),
842-
Heading.configure({
843-
levels: [1, 2, 3],
844-
}),
860+
...(editorType === 'html' || editorType === 'markdown'
861+
? [
862+
Heading.configure({
863+
levels: [1, 2, 3],
864+
}),
865+
]
866+
: []),
845867
History.configure({
846868
depth: 100, // default is 100
847869
newGroupDelay: 100, // default is 500ms

0 commit comments

Comments
 (0)