Duckduckgo - Quick bang

Skip one unnecessary page load and inmediately go to the bang search result on Enter

  1. // ==UserScript==
  2. // @name Duckduckgo - Quick bang
  3. // @namespace https://openuserjs.org/users/cuzi
  4. // @description Skip one unnecessary page load and inmediately go to the bang search result on Enter
  5. // @license MIT
  6. // @copyright 2017, cuzi (https://openuserjs.org/users/cuzi)
  7. // @version 2
  8. // @include https://duckduckgo.com/*
  9. // @include https://start.duckduckgo.com/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. // ==OpenUserJS==
  14. // @author cuzi
  15. // ==/OpenUserJS==
  16.  
  17. "use strict";
  18.  
  19. const bangUrl = "https://duckduckgo.com/bang.js";
  20. var input;
  21.  
  22. function load(s) {
  23. var req = new XMLHttpRequest();
  24. req.responseType = "json";
  25. req.open("GET", bangUrl, true);
  26. req.onload = function () {
  27. let arr = req.response;
  28. for (let i = 0; i < arr.length; i++) {
  29. localStorage.setItem(arr[i]["t"], arr[i]["u"]);
  30. }
  31. bang(s);
  32. };
  33. req.send(null);
  34. }
  35.  
  36. function bang(s) {
  37. try {
  38. if (!localStorage.getItem("g")) {
  39. return load(s);
  40. }
  41. let m = s.match(/(.*)\!(\w+)(\s*.*)/);
  42. let t = m[2];
  43. let q = encodeURIComponent(m[1] + m[3]);
  44. let u = localStorage.getItem(t);
  45. document.location.replace(u.replace("{{{s}}}", q));
  46. }
  47. catch (e) {
  48. document.querySelector("input[type=submit]").click();
  49. }
  50. }
  51.  
  52. function onsubmit(ev) {
  53. if (input.value.indexOf("!") !== -1) {
  54. bang(input.value);
  55. } else {
  56. document.querySelector("input[type=submit]").click();
  57. }
  58. }
  59.  
  60. (function () {
  61. input = document.querySelector("input[name=q]");
  62. if (input) {
  63. input.addEventListener("keydown", function (ev) {
  64. if (ev.keyCode === 13) {
  65. ev.preventDefault();
  66. return onsubmit.call(this, ev);
  67. }
  68. });
  69. }
  70. })();