common.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. function htmlEncode(value) {
  16. return $('<div/>').text(value).html().replace(/"/g, "&quot;");
  17. }
  18. function htmlDecode(value) {
  19. return $('<div/>').html(value).text();
  20. }
  21. function HTTPRequest(url, method, data, isTextResponse, success, error, invalidToken, objAlertPlaceholder, objLoaderPlaceholder, processData, contentType, dontHideAlert, showInnerError) {
  22. var finalUrl;
  23. if ((url != null) && (url.url != null))
  24. finalUrl = arguments[0].url;
  25. else
  26. finalUrl = url;
  27. if (method == null)
  28. method = arguments[0].method;
  29. if (method == null)
  30. method = "GET";
  31. if (data == null) {
  32. if (arguments[0].data == null)
  33. data = "";
  34. else
  35. data = arguments[0].data;
  36. }
  37. if (isTextResponse == null)
  38. isTextResponse = arguments[0].isTextResponse;
  39. if (isTextResponse == null)
  40. isTextResponse = false;
  41. var dataType = isTextResponse ? null : "json";
  42. if (success == null)
  43. success = arguments[0].success;
  44. var async = success != null;
  45. if (error == null)
  46. error = arguments[0].error;
  47. if (invalidToken == null)
  48. invalidToken = arguments[0].invalidToken;
  49. if (objAlertPlaceholder == null)
  50. objAlertPlaceholder = arguments[0].objAlertPlaceholder;
  51. if (dontHideAlert == null)
  52. dontHideAlert = arguments[0].dontHideAlert;
  53. if ((dontHideAlert == null) || !dontHideAlert)
  54. hideAlert(objAlertPlaceholder);
  55. if (showInnerError == null)
  56. showInnerError = arguments[0].showInnerError;
  57. if (showInnerError == null)
  58. showInnerError = false;
  59. if (objLoaderPlaceholder == null)
  60. objLoaderPlaceholder = arguments[0].objLoaderPlaceholder;
  61. if (processData == null)
  62. processData = arguments[0].processData;
  63. if (contentType == null)
  64. contentType = arguments[0].contentType;
  65. if (objLoaderPlaceholder != null)
  66. objLoaderPlaceholder.html("<div style='width: 64px; height: inherit; margin: auto;'><div style='height: inherit; display: table-cell; vertical-align: middle;'><img src='/img/loader.gif'/></div></div>");
  67. var successFlag = false;
  68. $.ajax({
  69. type: method,
  70. url: finalUrl,
  71. data: data,
  72. dataType: dataType,
  73. async: async,
  74. cache: false,
  75. processData: processData,
  76. contentType: contentType,
  77. success: function (response, status, jqXHR) {
  78. if (objLoaderPlaceholder != null)
  79. objLoaderPlaceholder.html("");
  80. if (isTextResponse) {
  81. if (success == null)
  82. successFlag = true;
  83. else
  84. success(response);
  85. }
  86. else {
  87. switch (response.status) {
  88. case "ok":
  89. if (success == null)
  90. successFlag = true;
  91. else
  92. success(response);
  93. break;
  94. case "invalid-token":
  95. if (invalidToken != null)
  96. invalidToken();
  97. else if (error != null)
  98. error();
  99. else
  100. window.location = "/";
  101. break;
  102. case "error":
  103. showAlert("danger", "Error!", response.errorMessage + (showInnerError && (response.innerErrorMessage != null) ? " " + response.innerErrorMessage : ""), objAlertPlaceholder);
  104. if (error != null)
  105. error();
  106. break;
  107. default:
  108. showAlert("danger", "Invalid Response!", "Server returned invalid response status: " + response.status, objAlertPlaceholder);
  109. if (error != null)
  110. error();
  111. break;
  112. }
  113. }
  114. },
  115. error: function (jqXHR, textStatus, errorThrown) {
  116. if (objLoaderPlaceholder != null)
  117. objLoaderPlaceholder.html("");
  118. if (error != null)
  119. error();
  120. var msg;
  121. if ((textStatus === "error") && (errorThrown === ""))
  122. msg = "Unable to connect to the server. Please try again."
  123. else
  124. msg = textStatus + " - " + errorThrown;
  125. showAlert("danger", "Error!", msg, objAlertPlaceholder);
  126. }
  127. });
  128. return successFlag;
  129. }
  130. function showAlert(type, title, message, objAlertPlaceholder) {
  131. var alertHTML = "<div class=\"alert alert-" + type + "\">\
  132. <button type=\"button\" class=\"close\" data-dismiss=\"alert\">&times;</button>\
  133. <strong>" + title + "</strong>&nbsp;" + htmlEncode(message) + "\
  134. </div>";
  135. if (objAlertPlaceholder == null)
  136. objAlertPlaceholder = $(".AlertPlaceholder");
  137. objAlertPlaceholder.html(alertHTML);
  138. if (type == "success") {
  139. setTimeout(function () {
  140. hideAlert(objAlertPlaceholder);
  141. }, 5000);
  142. }
  143. }
  144. function hideAlert(objAlertPlaceholder) {
  145. if (objAlertPlaceholder == null)
  146. objAlertPlaceholder = $(".AlertPlaceholder");
  147. objAlertPlaceholder.html("");
  148. }
  149. function sortTable(tableId, n) {
  150. var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
  151. table = document.getElementById(tableId);
  152. switching = true;
  153. // Set the sorting direction to ascending:
  154. dir = "asc";
  155. /* Make a loop that will continue until
  156. no switching has been done: */
  157. while (switching) {
  158. // Start by saying: no switching is done:
  159. switching = false;
  160. rows = table.rows;
  161. /* Loop through all table rows */
  162. for (i = 0; i < (rows.length - 1); i++) {
  163. // Start by saying there should be no switching:
  164. shouldSwitch = false;
  165. /* Get the two elements you want to compare,
  166. one from current row and one from the next: */
  167. x = rows[i].getElementsByTagName("TD")[n];
  168. y = rows[i + 1].getElementsByTagName("TD")[n];
  169. /* Check if the two rows should switch place,
  170. based on the direction, asc or desc: */
  171. if (dir == "asc") {
  172. if (x.innerText.toLowerCase() > y.innerText.toLowerCase()) {
  173. // If so, mark as a switch and break the loop:
  174. shouldSwitch = true;
  175. break;
  176. }
  177. } else if (dir == "desc") {
  178. if (x.innerText.toLowerCase() < y.innerText.toLowerCase()) {
  179. // If so, mark as a switch and break the loop:
  180. shouldSwitch = true;
  181. break;
  182. }
  183. }
  184. }
  185. if (shouldSwitch) {
  186. /* If a switch has been marked, make the switch
  187. and mark that a switch has been done: */
  188. rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
  189. switching = true;
  190. // Each time a switch is done, increase this count by 1:
  191. switchcount++;
  192. } else {
  193. /* If no switching has been done AND the direction is "asc",
  194. set the direction to "desc" and run the while loop again. */
  195. if (switchcount == 0 && dir == "asc") {
  196. dir = "desc";
  197. switching = true;
  198. }
  199. }
  200. }
  201. }
  202. function serializeTableData(table, columns, objAlertPlaceholder) {
  203. var data = table.find('input:text, :input[type="number"], input:checkbox, input:hidden, select');
  204. var output = "";
  205. for (var i = 0; i < data.length; i += columns) {
  206. if (i > 0)
  207. output += "|";
  208. for (var j = 0; j < columns; j++) {
  209. if (j > 0)
  210. output += "|";
  211. var cell = $(data[i + j]);
  212. var cellValue;
  213. if (cell.attr("type") == "checkbox") {
  214. cellValue = cell.prop("checked").toString();
  215. }
  216. else {
  217. cellValue = cell.val();
  218. var optional = (cell.attr("data-optional") === "true");
  219. if ((cellValue === "") && !optional) {
  220. showAlert("warning", "Missing!", "Please enter a valid value in the text field in focus.", objAlertPlaceholder);
  221. cell.focus();
  222. return false;
  223. }
  224. if (cellValue.includes("|")) {
  225. showAlert("warning", "Invalid Character!", "Please edit the value in the text field in focus to remove '|' character.", objAlertPlaceholder);
  226. cell.focus();
  227. return false;
  228. }
  229. }
  230. output += htmlDecode(cellValue);
  231. }
  232. }
  233. return output;
  234. }
  235. function cleanTextList(text) {
  236. text = text.replace(/\n/g, ",");
  237. while (text.indexOf(",,") !== -1) {
  238. text = text.replace(/,,/g, ",");
  239. }
  240. if (text.startsWith(","))
  241. text = text.substr(1);
  242. if (text.endsWith(","))
  243. text = text.substr(0, text.length - 1);
  244. return text;
  245. }