From da6a2d3b513c7ba7b4ef3fe6e5144257cee9f3cc Mon Sep 17 00:00:00 2001 From: Matt Panaro Date: Tue, 31 Dec 2024 12:27:08 -0500 Subject: [PATCH 1/3] introduce drag & drop handlers to search box without modification, default browser behavior for dropping new text on top of pre-existing text in an input field is to insert the new text in between whatever characters the mouse is pointing to at time of drop. Instead, by adding handlers, the pre-existing content can be overwritten/replaced. The primary use-case is for accessing quoted toots, or referenced hashtags or accounts, in the feed by searching for the linked URLs & showing the original/expanded version of them in the search results (as opposed to clicking on the links themselves and having them open in a new tab, on a potentially different mastodon server) Since the search box is designed to actively process its input for context-clues, after the text has been dropped, an Input event is triggered to bubble up from the search-box's new handleDrop method, that will cause the handleChange method to be invoked. This strategy was adapted from https://stackoverflow.com/a/47409362 --- .../features/compose/components/search.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/app/javascript/mastodon/features/compose/components/search.tsx b/app/javascript/mastodon/features/compose/components/search.tsx index 84e11e44b5..d5f7e00baf 100644 --- a/app/javascript/mastodon/features/compose/components/search.tsx +++ b/app/javascript/mastodon/features/compose/components/search.tsx @@ -451,6 +451,33 @@ export const Search: React.FC<{ setSelectedOption(-1); }, [setExpanded, setSelectedOption]); + const handleDragOver = useCallback( + (event: React.DragEvent) => { + event.preventDefault(); + }, + [], + ); + const handleDrop = useCallback( + (event: React.DragEvent) => { + event.preventDefault(); + + handleClear(); + + const query = + event.dataTransfer.getData('URL') || + event.dataTransfer.getData('text/plain'); + + Object.getOwnPropertyDescriptor( + window.HTMLInputElement.prototype, + 'value', + )?.set?.call(event.target, query); + + event.currentTarget.focus(); + event.target.dispatchEvent(new Event('change', { bubbles: true })); + }, + [handleClear], + ); + return (