Friendly Sidebar Display of Custom Search API Results

Enhance your Google search experience by displaying additional search results from the Google Custom Search API in a convenient sidebar. Perfect for power users who want more information at their fingertips.

  1. // ==UserScript==
  2. // @name Friendly Sidebar Display of Custom Search API Results
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Enhance your Google search experience by displaying additional search results from the Google Custom Search API in a convenient sidebar. Perfect for power users who want more information at their fingertips.
  6. // @author Your Name
  7. // @match https://www.google.com/search?*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_addStyle
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. // Add custom styles for the sidebar
  18. GM_addStyle(`
  19. #custom-search-sidebar {
  20. position: fixed;
  21. right: 0;
  22. top: 0;
  23. width: 30%; /* Adjust width as needed */
  24. height: 100%;
  25. background-color: white;
  26. overflow-y: auto;
  27. border-left: 1px solid #ccc;
  28. z-index: 9999;
  29. padding: 10px;
  30. box-sizing: border-box;
  31. }
  32. #settings-form {
  33. position: fixed;
  34. top: 10px;
  35. right: 10px;
  36. background-color: white;
  37. padding: 10px;
  38. border: 1px solid #ccc;
  39. z-index: 10000;
  40. display: none; /* Initially hidden */
  41. }
  42. #show-settings {
  43. position: fixed;
  44. top: 10px;
  45. right: 10px;
  46. z-index: 10001;
  47. }
  48. `);
  49. // Function to load settings with a default value for dateRestrict
  50. function loadSettings() {
  51. return {
  52. apiKey: localStorage.getItem('apiKey') || '',
  53. searchEngineId: localStorage.getItem('searchEngineId') || '',
  54. dateRestrict: localStorage.getItem('dateRestrict') || '' // Default to 'm1' if not set
  55. };
  56. }
  57.  
  58. // Function to save settings
  59. function saveSettings(apiKey, searchEngineId, dateRestrict) {
  60. localStorage.setItem('apiKey', apiKey);
  61. localStorage.setItem('searchEngineId', searchEngineId);
  62. localStorage.setItem('dateRestrict', dateRestrict);
  63. }
  64.  
  65. // Function to create settings form
  66. function createSettingsForm() {
  67. const form = document.createElement('div');
  68. form.id = 'settings-form';
  69. form.innerHTML = `
  70. <input type="text" id="api-key-input" placeholder="API Key" value="${loadSettings().apiKey}">
  71. <input type="text" id="search-engine-id-input" placeholder="Search Engine ID" value="${loadSettings().searchEngineId}">
  72. <button id="save-settings">Save</button>
  73. `;
  74. document.body.appendChild(form);
  75.  
  76. document.getElementById('save-settings').addEventListener('click', function () {
  77. const apiKey = document.getElementById('api-key-input').value;
  78. const searchEngineId = document.getElementById('search-engine-id-input').value;
  79. saveSettings(apiKey, searchEngineId);
  80. form.style.display = 'none'; // Hide the form after saving settings
  81. });
  82. }
  83.  
  84. // Create a button to show/hide the settings form
  85. const showSettingsButton = document.createElement('button');
  86. showSettingsButton.id = 'show-settings';
  87. showSettingsButton.textContent = 'Settings';
  88. document.body.appendChild(showSettingsButton);
  89.  
  90. showSettingsButton.addEventListener('click', function () {
  91. const form = document.getElementById('settings-form');
  92. form.style.display = form.style.display === 'none' ? 'block' : 'none';
  93. });
  94.  
  95. // Create settings form on script load
  96. createSettingsForm();
  97.  
  98.  
  99. // Extract the search query from the URL
  100. const params = new URLSearchParams(window.location.search);
  101. const query = params.get('q');
  102.  
  103. // Create the sidebar div
  104. const sidebar = document.createElement('div');
  105. sidebar.id = 'custom-search-sidebar';
  106. document.body.appendChild(sidebar);
  107.  
  108. // Use the settings to construct the initial API request URL
  109. const { apiKey, searchEngineId, dateRestrict } = loadSettings();
  110. const requestUrl = `https://www.googleapis.com/customsearch/v1?key=${apiKey}&cx=${searchEngineId}&q=${encodeURIComponent(query)}&dateRestrict=${dateRestrict}`;
  111.  
  112. // ...之前的代码...
  113.  
  114. // Make the API request
  115. GM_xmlhttpRequest({
  116. method: 'GET',
  117. url: requestUrl,
  118. onload: function (response) {
  119. const results = JSON.parse(response.responseText);
  120. displayResults(results);
  121. },
  122. onerror: function (error) {
  123. console.error('API Request failed', error);
  124. }
  125. });
  126.  
  127. // ...之前的代码...
  128.  
  129. // Function to display results in the sidebar
  130. function displayResults(data) {
  131. const sidebar = document.getElementById('custom-search-sidebar');
  132.  
  133. // Save the date restrict select element and remove it temporarily from the sidebar
  134. const dateRestrictSelect = document.getElementById('date-restrict-select');
  135. if (dateRestrictSelect && dateRestrictSelect.parentNode) {
  136. dateRestrictSelect.parentNode.removeChild(dateRestrictSelect);
  137. }
  138.  
  139. // Clear existing results
  140. sidebar.innerHTML = '';
  141.  
  142. // Re-add the date restrict select element to the sidebar
  143. if (dateRestrictSelect) {
  144. sidebar.appendChild(dateRestrictSelect);
  145. }
  146.  
  147. if (data.items && data.items.length > 0) {
  148. const list = document.createElement('ul');
  149. list.style.listStyle = 'none';
  150. list.style.padding = '0';
  151. list.style.margin = '0';
  152.  
  153. data.items.forEach(item => {
  154. const listItem = document.createElement('li');
  155. listItem.style.marginBottom = '10px';
  156.  
  157. const title = document.createElement('div');
  158. title.style.fontWeight = 'bold';
  159. title.textContent = item.title;
  160.  
  161. const link = document.createElement('a');
  162. link.href = item.link;
  163. link.textContent = item.displayLink;
  164. link.style.display = 'block';
  165. link.style.marginBottom = '5px';
  166. link.style.color = '#1a0dab';
  167. link.target = '_blank';
  168.  
  169. const snippet = document.createElement('div');
  170. snippet.textContent = item.snippet;
  171.  
  172. listItem.appendChild(title);
  173. listItem.appendChild(link);
  174. listItem.appendChild(snippet);
  175.  
  176. list.appendChild(listItem);
  177. });
  178.  
  179. sidebar.appendChild(list);
  180. } else {
  181. sidebar.textContent = 'No results found.';
  182. }
  183. }
  184.  
  185. // ...之后的代码...
  186.  
  187.  
  188. // ...之前的代码...
  189.  
  190. // Function to create the date restrict selector within the sidebar
  191. function createDateRestrictSelectorInSidebar() {
  192. const selector = document.createElement('select');
  193. selector.id = 'date-restrict-select';
  194. selector.innerHTML = `
  195. <option value="">Any time</option>
  196. <option value="d1">Past 24 hours</option>
  197. <option value="d7">Past week</option>
  198. <option value="m1">Past month</option>
  199. <option value="y1">Past year</option>
  200. `;
  201.  
  202. // Pre-select the saved date restrict option
  203. const savedDateRestrict = loadSettings().dateRestrict;
  204. if (savedDateRestrict) {
  205. selector.value = savedDateRestrict;
  206. }
  207.  
  208. // Event listener to update results on change
  209. selector.addEventListener('change', function () {
  210. const dateRestrict = selector.value;
  211. console.log(dateRestrict)
  212. saveSettings(loadSettings().apiKey, loadSettings().searchEngineId, dateRestrict);
  213. updateSearchResults();
  214. });
  215.  
  216. // Add the selector to the sidebar
  217. const sidebar = document.getElementById('custom-search-sidebar');
  218. sidebar.insertBefore(selector, sidebar.firstChild);
  219. }
  220.  
  221. // Function to update search results
  222. function updateSearchResults() {
  223. // Extract the search query from the URL
  224. const params = new URLSearchParams(window.location.search);
  225. const query = params.get('q');
  226.  
  227. console.log(loadSettings())
  228. // Get updated settings
  229. const { apiKey, searchEngineId, dateRestrict } = loadSettings();
  230.  
  231. // Construct the API request URL
  232. const requestUrl = dateRestrict
  233. ? `https://www.googleapis.com/customsearch/v1?key=${apiKey}&cx=${searchEngineId}&q=${encodeURIComponent(query)}&dateRestrict=${dateRestrict}`
  234. : `https://www.googleapis.com/customsearch/v1?key=${apiKey}&cx=${searchEngineId}&q=${encodeURIComponent(query)}`;
  235.  
  236. // Make the API request and update the sidebar
  237. GM_xmlhttpRequest({
  238. method: 'GET',
  239. url: requestUrl,
  240. onload: function (response) {
  241. const results = JSON.parse(response.responseText);
  242. displayResults(results);
  243. },
  244. onerror: function (error) {
  245. console.error('API Request failed', error);
  246. }
  247. });
  248. }
  249.  
  250. // ...之前的代码...
  251.  
  252.  
  253. // Call this function to create the date restrict selector inside the sidebar
  254. createDateRestrictSelectorInSidebar();
  255.  
  256. // Rest of your script...
  257.  
  258.  
  259. })();