Greasy Fork is available in English.

DuckDuckMenu

Extends DuckDuckGo by adding a customizable list of additional search engines for making fast searches from other engines.

  1. // ==UserScript==
  2. // @name DuckDuckMenu
  3. // @description Extends DuckDuckGo by adding a customizable list of additional search engines for making fast searches from other engines.
  4. // @namespace greasyfork.org/users/3926-jguer
  5. // @homepage https://github.com/Jguer/DuckduckGo-Mextended
  6. // @icon https://raw.githubusercontent.com/Jguer/DuckduckGo-Mextended/master/resources/large.png
  7. // @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=joaogg3@hotmail.com&item_name=Kickass+24+donation
  8. // @include *://duckduckgo.com/?q=*
  9. // @match http://mycroftproject.com/*
  10. // @require //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM_xmlhttpRequest
  14. // @license MIT
  15. // @version 3.0.1 Build 292
  16. // @author Jguer
  17. // ==/UserScript==
  18. //Styles
  19.  
  20. function addGlobalStyle(css) {
  21. var head,
  22. style;
  23. head = document.getElementsByTagName('head') [0];
  24. if (!head) {
  25. return;
  26. }
  27. style = document.createElement('style');
  28. style.type = 'text/css';
  29. style.innerHTML = css;
  30. head.appendChild(style);
  31. }
  32. //Main Menu Style
  33. addGlobalStyle('.ddgm { background-color: #24272A; height: auto; display: inline-block;width: 100%; }');
  34. //Button Style
  35. addGlobalStyle('.ddgmbtn { background-color: #24272A; height: 25px; width: auto; text-align: center; display: inline-block; vertical-align: middle;padding-top: 6px;padding-bottom: 6px; font-family: inherit; font-size: 1.2em; font-weight: 600; color: white; border-width: 3px; border-bottom-width: 0px; border-color: #24272A; padding-left: 4px; padding-right: 4px; border-style: solid;}');
  36. addGlobalStyle('.ddgmbtn:hover { background-color: #5A6269; color: white; text-decoration:none;}');
  37. addGlobalStyle('.ddgmbtn:visited {color: white;}');
  38. //Custom Engine Style
  39. addGlobalStyle('.cddgmbtn { background-color: #24272A;}');
  40. //Engine Add Style
  41. addGlobalStyle('.addengine { float: right;}');
  42. addGlobalStyle('.addengine:hover { background-color: #5A6269; color: white; text-decoration:none;}');
  43. addGlobalStyle('.addengine:visited {color: white;}');
  44. //Edit Menu Style
  45. addGlobalStyle('.enginedit { float: right;}');
  46. addGlobalStyle('.enginedit:hover { background-color: #5A6269; color: white; text-decoration:none;}');
  47. addGlobalStyle('.enginedit:visited {color: white;}');
  48. addGlobalStyle('.removex { color: red;font-family: inherit; font-weight: bold; position:relative; top:-5px;}');
  49. addGlobalStyle('.removex:visited {color: red;}')
  50. addGlobalStyle('.removex:hover { color: white; text-decoration:none;}');
  51. addGlobalStyle('.ddgem { background-color: #24272A; height: 20px; }');
  52. addGlobalStyle('.ddgembtn { float: right; background-color: #24272A; height: 14px; width: auto; text-align: center; display: inline-block; vertical-align: middle;padding-top: 3px;padding-bottom: 3px; font-family: inherit; font-size: 0.8em; font-weight: 600; color: white; border-width: 3px; border-bottom-width: 0px;border-top-width: 0px; border-color: #24272A; padding-left: 4px; padding-right: 4px; border-style: solid;position:relative; top:-2px;}');
  53. addGlobalStyle('.ddgembtn:hover { background-color: #5A6269; color: white; text-decoration:none;}');
  54. addGlobalStyle('.ddgembtn:visited {color: white;}');
  55.  
  56. //News Style
  57. addGlobalStyle('.ddgmnews {color: white; background-color: #DE5833;text-align: center;-o-text-overflow: ellipsis;text-overflow: ellipsis;width: auto;height: auto; padding: 5px;margin: 0;overflow: visible;display: block;float: none;z-index: auto;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;position: static;opacity: 1;cursor: default;border: none;-webkit-border-radius: 0 0 20px 20px;border-radius: 0 0 20px 20px;}');
  58.  
  59. //-DDG-//
  60. function ddm() {
  61. //Create Menu
  62. var searchVal = $('#search_form_input').val();
  63. $('<div>').addClass('ddgm').prependTo('body');
  64. console.log('##Search term is ' + searchVal);
  65. console.log('#Created the Menu');
  66. //Load default Engines
  67. function LoadDefault() {
  68. var gname = GM_getValue('ddgmDisEngines', 'empty');
  69. var dname;
  70. var durl;
  71. for (var i = 0; i < 7; i++) {
  72. switch (i) {
  73. case 0:
  74. dname = 'Google';
  75. durl = 'http://www.google.com/search?q=';
  76. break;
  77. case 1:
  78. dname = 'Youtube';
  79. durl = 'http://www.youtube.com/results?search_query=';
  80. break;
  81. case 2:
  82. dname = 'Wikipedia';
  83. durl = 'http://en.wikipedia.org/w/index.php?title=Special%3ASearch&profile=default&search=';
  84. break;
  85. case 3:
  86. dname = 'Github';
  87. durl = 'https://github.com/search?q=';
  88. break;
  89. case 4:
  90. dname = 'Kickass.to';
  91. durl = 'https://kickass.to/usearch/';
  92. break;
  93. case 5:
  94. dname = 'The Pirate Bay';
  95. durl = 'https://thepiratebay.se/search/';
  96. break;
  97. case 6:
  98. dname = 'Subtitle Seeker';
  99. durl = 'http://subtitleseeker.ee/search/request.php?q=';
  100. break;
  101. default:
  102. alert('Error');
  103. }
  104. if (gname.indexOf(dname) < 0)
  105. {
  106. btncreate(dname, durl, searchVal);
  107. }
  108. }
  109. console.log('#Loaded Default Engines');
  110. }
  111.  
  112. //Load Custom Engines
  113. function LoadCustom() {
  114. var _CEngineName = [undefined];
  115. var _CEngineURL = [undefined];
  116. var arrayLength;
  117. for (var i = 0; i < 15; i++) {
  118. _CEngineName[i] = GM_getValue('CEngineName' + i, 'empty');
  119. _CEngineURL[i] = GM_getValue('CEngineUrl' + i, 'empty');
  120. if (_CEngineName[i] != 'empty') {
  121. cbtncreate(_CEngineName[i], _CEngineURL[i], searchVal);
  122. }
  123. }
  124. }
  125. LoadDefault();
  126. LoadCustom();
  127. //Create Settings Menu
  128. $('<a>').addClass('enginedit').addClass('ddgmbtn').text('Edit Menu').attr('href', '#').appendTo('.ddgm');
  129.  
  130. /*
  131.  
  132.  
  133. Logic
  134.  
  135.  
  136. */
  137. //Default Engine Creator
  138. function btncreate(name, searchEngine, _searchVal) {
  139. if (name != undefined & searchEngine != undefined) {
  140. $('<a>').addClass('ddgmbtn').addClass('engine').hide().text(name).attr('href', searchEngine + _searchVal).appendTo('.ddgm').fadeIn(100);
  141. console.log('##Added Button with ' + name);
  142. }
  143. };
  144. //Custom Engine Creator
  145. function cbtncreate(name, searchEngine, _searchVal) {
  146. if (name != undefined & searchEngine != undefined) {
  147. searchEngine = searchEngine.replace('{searchTerms}', _searchVal);
  148. $('<a>').addClass('ddgmbtn').addClass('engine').addClass('cddgmbtn').hide().text(name).attr('href', searchEngine).prependTo('.ddgm').fadeIn(100);
  149. console.log('##Added Button first with ' + name);
  150. }
  151. };
  152. //Edit Engines
  153. $('.enginedit').click(function () {
  154. if ($('#restoredengines').length) {
  155. //if removex exists remove edit menu
  156. $('.removex').fadeOut(200, function () {
  157. $(this).remove();
  158. });
  159. $('.ddgem').slideUp(300, function () {
  160. $(this).remove();
  161. });
  162. }
  163. else {
  164. //if removex doesn't exist add menu
  165. $('<a>').text(' x').addClass('removex').hide().attr('href', '#').appendTo('.engine').fadeIn(300);
  166. $('<div>').addClass('ddgem').slideDown(300).insertAfter('.ddgm');
  167. $('<a>').addClass('ddgembtn').attr('id', 'addmengine').text('Add new Engine (Manual)').attr('href', '#').appendTo('.ddgem');
  168. $('<a>').addClass('ddgembtn').attr('id', 'restoredengines').text('Restore default Engines').attr('href', '#').appendTo('.ddgem');
  169. }
  170. });
  171. //Add Engines Manually
  172. $(document).on('click', '#addmengine', function () {
  173. var cName = prompt('Engine Name', 'Display Name');
  174. if (name.length < 25) {
  175. console.log('Called Search Engine Prompt');
  176. var cSearchEngine = prompt('Engine URL (Example:http://www.google.com/search?q={searchTerms})', 'URL');
  177. cbtncreate(cName, cSearchEngine, searchVal);
  178. //Save Custom engine
  179. var cEnginesave = [undefined];
  180. for (var i = 0; i < 15; i++) {
  181. cEnginesave[i] = GM_getValue('CEngineName' + i, 'empty');
  182. if (cEnginesave[i] == 'empty') {
  183. GM_setValue('CEngineName' + i, cName);
  184. GM_setValue('CEngineUrl' + i, cSearchEngine);
  185. break;
  186. }
  187. }
  188. }
  189. else
  190. {
  191. alert('Your title is too long');
  192. }
  193. });
  194. //Restore Default Engines
  195. $(document).on('click', '#restoredengines', function () {
  196. GM_setValue('ddgmDisEngines', 'empty');
  197. location.reload();
  198. });
  199. //Remove Engine
  200. $(document).on('click', '.removex', function () {
  201. var comparedel = $(this).parent('.engine').clone().children().remove().end().text();
  202. $(this).closest('.engine').remove();
  203. console.log('#Removed Engine ' + comparedel);
  204. var cEnginedel = [undefined];
  205. for (var i = 0; i < 15; i++) {
  206. cEnginedel[i] = GM_getValue('CEngineName' + i, 'empty');
  207. if (cEnginedel[i] == comparedel) {
  208. GM_setValue('CEngineName' + i, 'empty');
  209. GM_setValue('CEngineUrl' + i, 'empty');
  210. break;
  211. }
  212. }
  213. var disabledengines = GM_getValue('ddgmDisEngines', 'empty');
  214. GM_setValue('ddgmDisEngines', disabledengines + ' ' + comparedel);
  215. disabledengines = GM_getValue('ddgmDisEngines', 'empty');
  216. console.log('#Disabled Engines ' + disabledengines)
  217. });
  218. }
  219. //-MyCroft-//
  220.  
  221. var mycroft = {
  222. plugins: null,
  223. addLinks: function (p) {
  224. if (p) {
  225. this.plugins = document.evaluate('//a[@href="/jsreq.html"]', p, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  226. var reviews = document.evaluate('//a[.="[Review]"]', p, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  227. var addLink = document.createElement('a');
  228. addLink.setAttribute('href', 'javascript:void(0)');
  229. addLink.setAttribute('style', 'margin-left:5px; color:#000099');
  230. addLink.innerHTML = '[Add to DDM]';
  231. for (var i = 0, tmp; i < reviews.snapshotLength; i++) {
  232. tmp = addLink.cloneNode(true);
  233. tmp.setAttribute('data-ind', i);
  234. tmp.addEventListener('click', this.addNewEngine, false);
  235. reviews.snapshotItem(i).parentNode.insertBefore(tmp, reviews.snapshotItem(i).nextSibling);
  236. }
  237. }
  238. },
  239. addNewEngine: function () {
  240. var i = this.getAttribute('data-ind');
  241. var name = mycroft.plugins.snapshotItem(i).innerHTML.split(' (') [0].split(' -') [0];
  242. var newEngine = mycroft.plugins.snapshotItem(i).getAttribute('onClick').split('\'') [1];
  243. var newName = prompt('This engine will be added to DDG Extended.\nGive a name or cancel.', name);
  244. if (newName && newName.length > 0) {
  245. this.innerHTML = '[Added]';
  246. this.removeEventListener('click', this.addNewEngine, false);
  247. this.style.color = '#009900';
  248. this.removeAttribute('href');
  249. GM_xmlhttpRequest({
  250. method: 'GET',
  251. url: 'http://mycroftproject.com/externalos.php/' + newEngine + '.xml',
  252. onload: function (response) {
  253. var responseXML = null;
  254. // Inject responseXML into existing Object (only appropriate for XML content).
  255. if (!response.responseXML) {
  256. responseXML = new DOMParser().parseFromString(response.responseText, 'text/xml');
  257. }
  258. var engine = responseXML.getElementsByTagName('Url');
  259. if (engine.length > 0 && engine[0].getAttribute('template')) {
  260. var cEnginesave = [undefined];
  261. for (var f = 0; f < 15; f++) {
  262. cEnginesave[f] = GM_getValue('CEngineName' + f, 'empty');
  263. if (cEnginesave[f] == 'empty') {
  264. GM_setValue('CEngineName' + f, newName);
  265. GM_setValue('CEngineUrl' + f, engine[0].getAttribute('template'));
  266. console.log('Added engine with name: ' + newName + ' and URL: ' + engine[0].getAttribute('template'));
  267. break;
  268. }
  269. }
  270. }
  271. }
  272. });
  273. }
  274. }
  275. };
  276.  
  277. function News() {
  278. var Displaynews = GM_getValue('DDMv301b282', "1");
  279. if(Displaynews == "1"){
  280. $('<div>').addClass('ddgmnews').text("New: Did you know? If you go to mycroftproject.com you can add add engines just by searching their name. This type of message will only appear once after updates.").insertAfter($("#header_wrapper"));
  281. };
  282. GM_setValue('DDMv301b282', "0");
  283. }
  284. //Function Calling
  285. if (window.location.href.indexOf('http://mycroftproject.com/') !== - 1) {
  286. mycroft.addLinks(document.getElementById('plugins'));
  287. } else {
  288. ddm();
  289. News();
  290. }