Guest User

Untitled

a guest
Jun 30th, 2025
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.78 KB | None | 0 0
  1. javascript:(function() {
  2.  
  3. if (!window.__karaKeepBookmarkletLog) window.__karaKeepBookmarkletLog = [];
  4. const log = msg => {
  5. window.__karaKeepBookmarkletLog.push({ time: Date.now(), msg });
  6. console.log("[🔍 KaraKeep Assistant] " + msg);
  7. };
  8.  
  9.  
  10. const ADD_SPACE_AFTER_FILTER = true;
  11.  
  12. if (window.__karaKeepUIInjected) {
  13. log("UI already active. Use 'removeKaraKeepFilterUI()' to remove");
  14. return;
  15. }
  16. window.__karaKeepUIInjected = true;
  17.  
  18. log("Activated! Click the 'Search Filters' button to add advanced filters");
  19. log("Version 1.3 - Compatible with KaraKeep v0.25.0+");
  20. log(`Space after filters: ${ADD_SPACE_AFTER_FILTER ? "ENABLED" : "DISABLED"}`);
  21.  
  22. const searchInput = document.querySelector('input[placeholder="Search"]');
  23. if (!searchInput) {
  24. log("❌ Error: Search input not found");
  25. return;
  26. }
  27.  
  28. const FILTERS = [
  29. { name: "Favorited", value: "is:fav", desc: "Favorited bookmarks" },
  30. { name: "Archived", value: "is:archived", desc: "Archived bookmarks" },
  31. { name: "Tagged", value: "is:tagged", desc: "Has one or more tags" },
  32. { name: "In List", value: "is:inlist", desc: "Is in at least one list" },
  33. { name: "Type: Link", value: "is:link", desc: "Type: link" },
  34. { name: "Type: Text", value: "is:text", desc: "Type: text" },
  35. { name: "Type: Media", value: "is:media", desc: "Type: media" },
  36. { name: "URL", value: "url:example.com", desc: "Match URL substring" },
  37. { name: "After Date", value: "after:2024-01-01", desc: "After date (YYYY-MM-DD)" },
  38. { name: "Before Date", value: "before:2025-01-01", desc: "Before date (YYYY-MM-DD)" },
  39. { name: "Tag", value: "#important", desc: "With tag" },
  40. { name: "List", value: 'list:"to review"', desc: "In specific list" },
  41. { name: "Feed", value: "feed:Hackernews", desc: "Imported from feed" },
  42. { name: "Age <1w", value: "age:<1w", desc: "Younger than 1 week" },
  43. { name: "Age >1y", value: "age:>1y", desc: "Older than 1 year" }
  44. ];
  45.  
  46.  
  47. const btn = document.createElement("button");
  48. btn.id = "karaKeepFilterBtn";
  49. btn.textContent = "Search Filters";
  50. btn.type = "button";
  51.  
  52.  
  53. btn.style.cssText = `
  54. display: inline-flex;
  55. align-items: center;
  56. justify-content: center;
  57. white-space: nowrap;
  58. border-radius: 0.375rem;
  59. padding: 0 1rem;
  60. height: 2.5rem;
  61. font-size: 0.875rem;
  62. font-weight: 500;
  63. cursor: pointer;
  64. background-color: transparent;
  65. border: none;
  66. color: hsl(var(--foreground));
  67. transition: background-color 0.2s ease;
  68. margin-left: 0.5rem;
  69. `;
  70.  
  71.  
  72. btn.onmouseenter = () => btn.style.backgroundColor = 'hsl(var(--accent))';
  73. btn.onmouseleave = () => btn.style.backgroundColor = 'transparent';
  74.  
  75.  
  76. const menu = document.createElement("div");
  77. menu.id = "karaKeepFilterMenu";
  78. menu.style.cssText = `
  79. display: none;
  80. position: fixed;
  81. z-index: 100000;
  82. background: #fff;
  83. box-shadow: 0 8px 20px rgba(0,0,0,.18);
  84. border: 1px solid #ccc;
  85. border-radius: 6px;
  86. padding: 8px 0;
  87. color: #222;
  88. font-size: 15px;
  89. max-height: 260px;
  90. overflow-y: auto;
  91. `;
  92.  
  93.  
  94. FILTERS.forEach(f => {
  95. const item = document.createElement("button");
  96. item.textContent = f.name;
  97. item.title = f.desc;
  98. item.style.cssText = `
  99. display: block;
  100. width: 100%;
  101. background: none;
  102. border: none;
  103. text-align: left;
  104. padding: 6px 20px;
  105. cursor: pointer;
  106. font-size: 15px;
  107. color: #222;
  108. outline: none;
  109. transition: background 0.2s;
  110. `;
  111. item.onmouseenter = () => item.style.background = "#e6f0fa";
  112. item.onmouseleave = () => item.style.background = "none";
  113.  
  114. item.onclick = e => {
  115. e.preventDefault();
  116. searchInput.focus();
  117. let start = searchInput.selectionStart;
  118. let end = searchInput.selectionEnd;
  119.  
  120. if (typeof start === "number") {
  121. const orig = searchInput.value;
  122. const insertText = f.value + (ADD_SPACE_AFTER_FILTER ? " " : "");
  123. searchInput.value = orig.slice(0, start) + insertText + orig.slice(end);
  124. searchInput.selectionStart = searchInput.selectionEnd = start + insertText.length;
  125. } else {
  126. searchInput.value += f.value + (ADD_SPACE_AFTER_FILTER ? " " : "");
  127. }
  128.  
  129. menu.style.display = "none";
  130. log(`Added filter: '${f.value}${ADD_SPACE_AFTER_FILTER ? ' ' : ''}'`);
  131. };
  132. menu.appendChild(item);
  133. });
  134.  
  135.  
  136. btn.onclick = e => {
  137. e.stopPropagation();
  138. if (menu.style.display === "block") {
  139. menu.style.display = "none";
  140. } else {
  141. const rect = btn.getBoundingClientRect();
  142. menu.style.top = (rect.bottom + 4) + "px";
  143. menu.style.left = rect.left + "px";
  144. menu.style.display = "block";
  145. document.body.appendChild(menu);
  146. }
  147. };
  148.  
  149.  
  150. document.addEventListener("mousedown", e => {
  151. if (!btn.contains(e.target) && !menu.contains(e.target)) {
  152. menu.style.display = "none";
  153. }
  154. });
  155.  
  156.  
  157. const buttonsContainer = document.querySelector('.flex.min-w-max.flex-wrap.overflow-hidden');
  158. if (buttonsContainer) {
  159.  
  160. const editButton = buttonsContainer.querySelector('button:not([disabled])');
  161. if (editButton) {
  162. buttonsContainer.insertBefore(btn, editButton);
  163. log("UI injected successfully!");
  164. } else {
  165. buttonsContainer.appendChild(btn);
  166. log("UI injected at end of buttons");
  167. }
  168. } else {
  169. document.body.appendChild(btn);
  170. log("Buttons container not found, added to body");
  171. }
  172.  
  173.  
  174. window.removeKaraKeepFilterUI = () => {
  175. btn.remove();
  176. if (menu.parentNode) menu.parentNode.removeChild(menu);
  177. window.__karaKeepUIInjected = false;
  178. log("Assistant removed. Refresh page to restore original UI");
  179. };
  180. })();
  181.  
Advertisement
Add Comment
Please, Sign In to add comment