00_toolkit.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * @license
  3. * (C) Copyright Contributors to the SearXNG project.
  4. * (C) Copyright Contributors to the searx project (2014 - 2021).
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. window.searxng = (function (w, d) {
  8. 'use strict';
  9. // not invented here tookit with bugs fixed elsewhere
  10. // purposes : be just good enough and as small as possible
  11. // from https://plainjs.com/javascript/events/live-binding-event-handlers-14/
  12. if (w.Element) {
  13. (function (ElementPrototype) {
  14. ElementPrototype.matches = ElementPrototype.matches ||
  15. ElementPrototype.matchesSelector ||
  16. ElementPrototype.webkitMatchesSelector ||
  17. ElementPrototype.msMatchesSelector ||
  18. function (selector) {
  19. var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
  20. while (nodes[++i] && nodes[i] != node);
  21. return !!nodes[i];
  22. };
  23. })(Element.prototype);
  24. }
  25. function callbackSafe (callback, el, e) {
  26. try {
  27. callback.call(el, e);
  28. } catch (exception) {
  29. console.log(exception);
  30. }
  31. }
  32. var searxng = window.searxng || {};
  33. searxng.on = function (obj, eventType, callback, useCapture) {
  34. useCapture = useCapture || false;
  35. if (typeof obj !== 'string') {
  36. // obj HTMLElement, HTMLDocument
  37. obj.addEventListener(eventType, callback, useCapture);
  38. } else {
  39. // obj is a selector
  40. d.addEventListener(eventType, function (e) {
  41. var el = e.target || e.srcElement, found = false;
  42. while (el && el.matches && el !== d && !(found = el.matches(obj))) el = el.parentElement;
  43. if (found) callbackSafe(callback, el, e);
  44. }, useCapture);
  45. }
  46. };
  47. searxng.ready = function (callback) {
  48. if (document.readyState != 'loading') {
  49. callback.call(w);
  50. } else {
  51. w.addEventListener('DOMContentLoaded', callback.bind(w));
  52. }
  53. };
  54. searxng.http = function (method, url, data = null) {
  55. return new Promise(function (resolve, reject) {
  56. try {
  57. var req = new XMLHttpRequest();
  58. req.open(method, url, true);
  59. req.timeout = 20000;
  60. // On load
  61. req.onload = function () {
  62. if (req.status == 200) {
  63. resolve(req.response, req.responseType);
  64. } else {
  65. reject(Error(req.statusText));
  66. }
  67. };
  68. // Handle network errors
  69. req.onerror = function () {
  70. reject(Error("Network Error"));
  71. };
  72. req.onabort = function () {
  73. reject(Error("Transaction is aborted"));
  74. };
  75. req.ontimeout = function () {
  76. reject(Error("Timeout"));
  77. }
  78. // Make the request
  79. if (data) {
  80. req.send(data)
  81. } else {
  82. req.send();
  83. }
  84. } catch (ex) {
  85. reject(ex);
  86. }
  87. });
  88. };
  89. searxng.loadStyle = function (src) {
  90. var path = searxng.settings.theme_static_path + "/" + src,
  91. id = "style_" + src.replace('.', '_'),
  92. s = d.getElementById(id);
  93. if (s === null) {
  94. s = d.createElement('link');
  95. s.setAttribute('id', id);
  96. s.setAttribute('rel', 'stylesheet');
  97. s.setAttribute('type', 'text/css');
  98. s.setAttribute('href', path);
  99. d.body.appendChild(s);
  100. }
  101. };
  102. searxng.loadScript = function (src, callback) {
  103. var path = searxng.settings.theme_static_path + "/" + src,
  104. id = "script_" + src.replace('.', '_'),
  105. s = d.getElementById(id);
  106. if (s === null) {
  107. s = d.createElement('script');
  108. s.setAttribute('id', id);
  109. s.setAttribute('src', path);
  110. s.onload = callback;
  111. s.onerror = function () {
  112. s.setAttribute('error', '1');
  113. };
  114. d.body.appendChild(s);
  115. } else if (!s.hasAttribute('error')) {
  116. try {
  117. callback.apply(s, []);
  118. } catch (exception) {
  119. console.log(exception);
  120. }
  121. } else {
  122. console.log("callback not executed : script '" + path + "' not loaded.");
  123. }
  124. };
  125. searxng.insertBefore = function (newNode, referenceNode) {
  126. referenceNode.parentNode.insertBefore(newNode, referenceNode);
  127. };
  128. searxng.insertAfter = function (newNode, referenceNode) {
  129. referenceNode.parentNode.insertAfter(newNode, referenceNode.nextSibling);
  130. };
  131. searxng.on('.close', 'click', function () {
  132. this.parentNode.classList.add('invisible');
  133. });
  134. function getEndpoint () {
  135. for (var className of d.getElementsByTagName('body')[0].classList.values()) {
  136. if (className.endsWith('_endpoint')) {
  137. return className.split('_')[0];
  138. }
  139. }
  140. return '';
  141. }
  142. searxng.endpoint = getEndpoint();
  143. return searxng;
  144. })(window, document);