server_list.htm 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <%#
  2. Copyright 2018-2019 Lienol <[email protected]>
  3. Licensed to the public under the Apache License 2.0.
  4. -%>
  5. <script type="text/javascript">
  6. //<![CDATA[
  7. window.addEventListener('load', function () {
  8. const doms = document.getElementsByClassName('pingtime');
  9. const ports = document.getElementsByClassName("socket-connected");
  10. const transports = document.getElementsByClassName("transport");
  11. const wsPaths = document.getElementsByClassName("wsPath");
  12. const tlss = document.getElementsByClassName("tls");
  13. const xhr = (index) => {
  14. return new Promise((res) => {
  15. const dom = doms[index];
  16. const port = ports[index];
  17. const transport = transports[index];
  18. const wsPath = wsPaths[index];
  19. const tls = tlss[index];
  20. if (!dom) res();
  21. port.innerHTML = '<font style=\"color:#0072c3\">connect</font>';
  22. XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', {
  23. index,
  24. domain: dom.getAttribute("hint"),
  25. port: port.getAttribute("hint"),
  26. transport: transport.getAttribute("hint"),
  27. wsPath: wsPath.getAttribute("hint"),
  28. tls: tls.getAttribute("hint")
  29. },
  30. (x, result) => {
  31. let col = '#ff0000';
  32. if (result.ping) {
  33. if (result.ping < 300) col = '#ff3300';
  34. if (result.ping < 200) col = '#ff7700';
  35. if (result.ping < 100) col = '#249400';
  36. }
  37. dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>`;
  38. if (result.socket) {
  39. port.innerHTML = '<font style=\"color:#249400\">ok</font>';
  40. } else {
  41. port.innerHTML = '<font style=\"color:#ff0000\">fail</font>';
  42. }
  43. res();
  44. });
  45. });
  46. };
  47. let task = -1;
  48. const thread = () => {
  49. task = task + 1;
  50. if (doms[task]) {
  51. xhr(task).then(thread);
  52. }
  53. };
  54. for (let i = 0; i < 20; i++) {
  55. thread();
  56. }
  57. });
  58. function cbi_row_drop(fromId, toId, store, isToBottom) {
  59. var fromNode = document.getElementById(fromId);
  60. var toNode = document.getElementById(toId);
  61. if (!fromNode || !toNode) return false;
  62. var table = fromNode.parentNode;
  63. while (table && table.nodeName.toLowerCase() != "table")
  64. table = table.parentNode;
  65. if (!table) return false;
  66. var ids = [];
  67. if (isToBottom) {
  68. toNode.parentNode.appendChild(fromNode);
  69. } else {
  70. fromNode.parentNode.insertBefore(fromNode, toNode);
  71. }
  72. for (var idx = 2; idx < table.rows.length; idx++) {
  73. table.rows[idx].className = table.rows[idx].className.replace(
  74. /cbi-rowstyle-[12]/,
  75. "cbi-rowstyle-" + (1 + (idx % 2))
  76. );
  77. if (table.rows[idx].id && table.rows[idx].id.match(/-([^\-]+)$/))
  78. ids.push(RegExp.$1);
  79. }
  80. var input = document.getElementById(store);
  81. if (input) input.value = ids.join(" ");
  82. return false;
  83. }
  84. // set tr draggable
  85. function enableDragForTable(table_selecter, store) {
  86. var trs = document.querySelectorAll(table_selecter + " tr");
  87. if (!trs || trs.length.length < 3) {
  88. return;
  89. }
  90. function ondragstart(ev) {
  91. ev.dataTransfer.setData("Text", ev.target.id);
  92. }
  93. function ondrop(ev) {
  94. var from = ev.dataTransfer.getData("Text");
  95. cbi_row_drop(from, this.id, store);
  96. }
  97. function ondragover(ev) {
  98. ev.preventDefault();
  99. ev.dataTransfer.dropEffect = "move";
  100. }
  101. function moveToTop(id) {
  102. var top = document.querySelectorAll(table_selecter + " tr")[2];
  103. cbi_row_drop(id, top.id, store);
  104. }
  105. function moveToBottom(id) {
  106. console.log('moveToBottom:', id);
  107. var trList = document.querySelectorAll(table_selecter + " tr");
  108. var bottom = trList[trList.length - 1];
  109. cbi_row_drop(id, bottom.id, store, true);
  110. }
  111. for (let index = 2; index < trs.length; index++) {
  112. const el = trs[index];
  113. el.setAttribute("draggable", true);
  114. el.ondragstart = ondragstart;
  115. el.ondrop = ondrop;
  116. el.ondragover = ondragover;
  117. // reset the behaviors of the btns
  118. var upBtns = el.querySelectorAll(".cbi-button.cbi-button-up");
  119. if (upBtns && upBtns.length > 0) {
  120. upBtns.forEach(function (_el) {
  121. _el.onclick = function () {
  122. moveToTop(el.id);
  123. };
  124. });
  125. }
  126. var downBtns = el.querySelectorAll(".cbi-button.cbi-button-down");
  127. if (downBtns && downBtns.length > 0) {
  128. downBtns.forEach(function (_el) {
  129. _el.onclick = function () {
  130. moveToBottom(el.id);
  131. };
  132. });
  133. }
  134. }
  135. }
  136. // enable
  137. enableDragForTable(
  138. "#cbi-shadowsocksr-servers table",
  139. "cbi.sts.shadowsocksr.servers"
  140. );
  141. //]]>
  142. </script>