« get me outta code hell

client: sidebar-search: drop search - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/static/js/client
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-12-11 17:18:59 -0400
committer(quasar) nebula <qznebula@protonmail.com>2024-12-11 17:18:59 -0400
commitc0c04fc74bae6768e080ad90b704319ce420229b (patch)
tree1d28a61ef7dc3c0566b157d70bee3a488e1c24f4 /src/static/js/client
parenta1d61014c37ccbfe26fee18abab221a7ef2f0583 (diff)
client: sidebar-search: drop search
Diffstat (limited to 'src/static/js/client')
-rw-r--r--src/static/js/client/sidebar-search.js65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/static/js/client/sidebar-search.js b/src/static/js/client/sidebar-search.js
index fd571ac0..b7b0b8f0 100644
--- a/src/static/js/client/sidebar-search.js
+++ b/src/static/js/client/sidebar-search.js
@@ -15,6 +15,8 @@ import {
   templateContent,
 } from '../client-util.js';
 
+import {getLatestDraggedLink} from './dragged-link.js';
+
 import {
   info as wikiSearchInfo,
   getSearchWorkerDownloadContext,
@@ -325,6 +327,8 @@ export function addPageListeners() {
       }, settings.stoppedTypingDelay);
   });
 
+  info.searchInput.addEventListener('drop', handleDroppedIntoSearchInput);
+
   info.endSearchLink.addEventListener('click', domEvent => {
     domEvent.preventDefault();
     clearSidebarSearch();
@@ -901,3 +905,64 @@ function restoreSidebarSearchColumn() {
   state.collapsedDetailsForTidiness = [];
   state.tidiedSidebar = null;
 }
+
+async function handleDroppedIntoSearchInput(domEvent) {
+  const itemByType = type =>
+    Array.from(domEvent.dataTransfer.items)
+      .find(item => item.type === type);
+
+  const textItem = itemByType('text/plain');
+
+  if (!textItem) return;
+
+  domEvent.preventDefault();
+
+  const getAssTring = item =>
+    new Promise(res => item.getAsString(res))
+      .then(string => string.trim());
+
+  const timer = Date.now();
+
+  let droppedText =
+    await getAssTring(textItem);
+
+  if (Date.now() - timer > 500) return;
+  if (!droppedText) return;
+
+  let droppedURL;
+  try {
+    droppedURL = new URL(droppedText);
+  } catch (error) {
+    droppedURL = null;
+  }
+
+  if (droppedURL) matchLink: {
+    const isDroppedURL = a =>
+      a.toString() === droppedURL.toString();
+
+    const matchingLinks =
+      Array.from(document.getElementsByTagName('a'))
+        .filter(a =>
+          isDroppedURL(new URL(a.href, document.documentURI)));
+
+    const latestDraggedLink = getLatestDraggedLink();
+
+    if (!matchingLinks.includes(latestDraggedLink)) {
+      break matchLink;
+    }
+
+    let matchedLink = latestDraggedLink;
+
+    if (matchedLink.querySelector('.normal-content')) {
+      matchedLink = matchedLink.cloneNode(true);
+      for (const node of matchedLink.querySelectorAll('.normal-content')) {
+        node.remove();
+      }
+    }
+
+    droppedText = matchedLink.innerText;
+  }
+
+  info.searchInput.value = droppedText;
+  activateSidebarSearch(info.searchInput.value);
+}