mirror of
https://github.com/suitenumerique/docs.git
synced 2026-04-25 17:15:01 +02:00
🐛(frontend) sanitize pasted toolbar links
Strip < and > from pasted BlockNote links to keep valid external URLs.
This commit is contained in:
@@ -11,17 +11,18 @@ and this project adheres to
|
||||
- 🚸(frontend) redirect on current url tab after 401 #2197
|
||||
- 🐛(frontend) abort check media status unmount #2194
|
||||
- ✨(backend) order pinned documents by last updated at #2028
|
||||
- 🐛(frontend) sanitize pasted toolbar links #2214
|
||||
|
||||
### Changed
|
||||
|
||||
- ♿️(frontend) structure correctly 5xx error alerts #2128
|
||||
- ♿️(frontend) structure correctly 5xx error alerts #2128
|
||||
|
||||
## [v4.8.6] - 2026-04-08
|
||||
|
||||
### Added
|
||||
|
||||
- 🚸(frontend) allow opening "@page" links with
|
||||
ctrl/command/middle-mouse click #2170
|
||||
- 🚸(frontend) allow opening "@page" links with
|
||||
ctrl/command/middle-mouse click #2170
|
||||
- ✅ E2E - Any instance friendly #2142
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -88,6 +88,38 @@ interface BlockNoteEditorProps {
|
||||
provider: HocuspocusProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips angle brackets wrapping URLs (e.g. `<https://example.com>` → `https://example.com`).
|
||||
* BlockNote copies links in Markdown autolink format; pasting into the link
|
||||
* toolbar input keeps the brackets, producing broken hrefs.
|
||||
*/
|
||||
const stripAngleBrackets = (text: string): string =>
|
||||
text.replace(/^<(.+)>$/, '$1');
|
||||
|
||||
const handlePasteUrlBrackets = (e: React.ClipboardEvent<HTMLDivElement>) => {
|
||||
const target = e.target;
|
||||
if (
|
||||
!(target instanceof HTMLInputElement) &&
|
||||
!(target instanceof HTMLTextAreaElement)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const text = e.clipboardData?.getData('text/plain') ?? '';
|
||||
const cleaned = stripAngleBrackets(text.trim());
|
||||
if (cleaned === text) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
// Use the native value setter (input/textarea) so React-controlled fields pick up the pasted value change.
|
||||
const proto =
|
||||
target instanceof HTMLInputElement
|
||||
? HTMLInputElement.prototype
|
||||
: HTMLTextAreaElement.prototype;
|
||||
const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
|
||||
setter?.call(target, cleaned);
|
||||
target.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
};
|
||||
|
||||
export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
||||
const { user } = useAuth();
|
||||
const { setEditor } = useEditorStore();
|
||||
@@ -267,6 +299,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
|
||||
return (
|
||||
<Box
|
||||
ref={refEditorContainer}
|
||||
onPasteCapture={handlePasteUrlBrackets}
|
||||
$css={css`
|
||||
${cssEditor};
|
||||
${cssComments(showComments, currentUserAvatarUrl)}
|
||||
|
||||
Reference in New Issue
Block a user