Extends the Chrome Developer Tools, adding a new Network Panel in the Developer Tools window with better searching and response previews. https://leviolson.com/posts/chrome-ext-better-network-panel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
9.5 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
1 year ago
  1. var BNPChrome = angular
  2. .module("BNPChrome", [])
  3. .factory("parse", function () {
  4. function convertToJSON(input) {
  5. let jsonString;
  6. // Try to parse the input as JSON
  7. try {
  8. jsonString = JSON.parse(input);
  9. return jsonString;
  10. } catch (error) {
  11. // Parsing failed, assume input is a query string
  12. }
  13. // Decode URL-encoded string n times until no more encoding is found
  14. let decodedInput = decodeURIComponent(input);
  15. while (decodedInput !== input) {
  16. input = decodedInput;
  17. decodedInput = decodeURIComponent(input);
  18. }
  19. // Convert the query string to a JSON object
  20. const keyValuePairs = input.split('&');
  21. const jsonObject = {};
  22. keyValuePairs.forEach(keyValuePair => {
  23. const [key, value] = keyValuePair.split('=');
  24. jsonObject[key] = value;
  25. });
  26. return jsonObject;
  27. }
  28. function queryStringToJson(queryString) {
  29. let decoded = decodeURIComponent(queryString);
  30. let pairs = decoded.split('&');
  31. let result = {};
  32. pairs.forEach(function(pair) {
  33. pair = pair.split('=');
  34. let name = pair[0];
  35. let value = pair[1];
  36. if (name.length > 0) {
  37. name = name.replace(/\[([^\]]*)\]/g, function($0, $1) {
  38. if ($1.length > 0) {
  39. return "." + $1;
  40. } else {
  41. return "";
  42. }
  43. });
  44. try {
  45. value = decodeURIComponent(value);
  46. } catch (e) {
  47. // Do nothing, use the original value instead
  48. }
  49. let keys = name.split('.');
  50. let obj = result;
  51. let key;
  52. while ((key = keys.shift())) {
  53. if (keys.length === 0) {
  54. if (obj[key] === undefined) {
  55. obj[key] = value;
  56. } else if (Array.isArray(obj[key])) {
  57. obj[key].push(value);
  58. } else {
  59. obj[key] = [obj[key], value];
  60. }
  61. } else {
  62. if (obj[key] === undefined) {
  63. obj[key] = {};
  64. }
  65. obj = obj[key];
  66. }
  67. }
  68. }
  69. });
  70. return result;
  71. }
  72. const parseQueryParams = function(queryString) {
  73. // Extract query params using a regular expression
  74. const params = queryString.split('&');
  75. if (params.length == 0) return queryString;
  76. const queryParams = {};
  77. for (let i = 0; i < params.length; i++) {
  78. let [key, value] = params[i].split('=');
  79. let decodedInput = decodeURIComponent(value);
  80. while (decodedInput !== value) {
  81. value = decodedInput;
  82. decodedInput = decodeURIComponent(value);
  83. }
  84. queryParams[key] = decodedInput;
  85. }
  86. return queryParams;
  87. };
  88. const parser = function (input, depth, maxDepth) {
  89. // If the input is a string, try to parse it as JSON
  90. if (typeof input === 'string') {
  91. try {
  92. return parser(JSON.parse(input), depth + 1, maxDepth);
  93. } catch (err) {
  94. // If the input is not valid JSON return the input
  95. return input
  96. }
  97. }
  98. // If the input is an array, recursively parse each item in the array
  99. if (Array.isArray(input)) {
  100. return input.map(item => parser(item, depth + 1, maxDepth));
  101. }
  102. // If the input is an object, recursively parse each value in the object
  103. if (typeof input === 'object') {
  104. const parsedJson = {};
  105. for (const [key, value] of Object.entries(input)) {
  106. if (typeof value === 'string') {
  107. // If the value is a string, then it might be a serialized JSON string, so try to parse it
  108. try {
  109. parsedJson[key] = parser(JSON.parse(value), depth + 1, maxDepth);
  110. } catch (err) {
  111. if (value.includes("&") && value.includes("="))
  112. parsedJson[key] = parser(convertToJSON(value), depth + 1, maxDepth);
  113. else
  114. parsedJson[key] = value;
  115. }
  116. } else {
  117. // If the value is not a string, recursively parse it
  118. parsedJson[key] = parser(value, depth + 1, maxDepth);
  119. }
  120. }
  121. return parsedJson;
  122. }
  123. // If the input is not a string, array, or object, return it unchanged
  124. return input;
  125. };
  126. return parser;
  127. })
  128. .directive("prettyPrint", function (parse) {
  129. return {
  130. restrict: "E",
  131. replace: true,
  132. transclude: false,
  133. scope: { data: "=data" },
  134. link: function (scope, element, attrs) {
  135. let data = scope.data;
  136. let $el = $("<div></div>");
  137. if (data === true) {
  138. data = "<i>true</i>";
  139. } else if (data === false) {
  140. data = "<i>false</i>";
  141. } else if (data === undefined) {
  142. data = "<i>undefined</i>";
  143. } else if (data === null) {
  144. data = "<i>null</i>";
  145. } else if (typeof data === "number") {
  146. // skip (i.e. do default)
  147. } else if (typeof data === "string" && (data[0] === "{" || data[0] === "[")) {
  148. $el = $("<pre></pre>");
  149. data = JSON.stringify(parse(data, 0), null, 4);
  150. } else if (typeof data === "string") {
  151. // i.e. a string but not a JSON stringified string
  152. data = $("<div>").text(data).html();
  153. }
  154. $el.html(data);
  155. element.replaceWith($el);
  156. }
  157. };
  158. })
  159. .directive("resizableColumns", function () {
  160. return {
  161. link: function (scope, element, attrs) {
  162. const options = { minWidth: 5 };
  163. if ($(element).data("resizable-columns-sync")) {
  164. var $target = $($(element).data("resizable-columns-sync"));
  165. $(element).on("column:resize", function (
  166. event,
  167. resizable,
  168. $leftColumn,
  169. $rightColumn,
  170. widthLeft,
  171. widthRight
  172. ) {
  173. var leftColumnIndex = resizable.$table
  174. .find(".rc-column-resizing")
  175. .parent()
  176. .find("td, th")
  177. .index($leftColumn);
  178. var $targetFirstRow = $target.find("tr:first");
  179. $($targetFirstRow.find("td, th").get(leftColumnIndex)).css("width", widthLeft + "%");
  180. $($targetFirstRow.find("td, th").get(leftColumnIndex + 1)).css("width", widthRight + "%");
  181. $target.data("resizableColumns").syncHandleWidths();
  182. $target.data("resizableColumns").saveColumnWidths();
  183. });
  184. // $(window).on("resize", function () {
  185. // // console.log('resize event');
  186. // // var $target = $($(element).data("resizable-columns-sync"));
  187. // // $target.data("resizableColumns").refreshHeaders();
  188. // // $(element).resizableColumns(options);
  189. // })
  190. }
  191. $(element).resizableColumns(options);
  192. }
  193. };
  194. })
  195. .directive("scrollToNew", function () {
  196. return function (scope, element, attrs) {
  197. if (scope.scrollToNew && scope.$last) {
  198. const $container = $(element).parents(".data-container").first();
  199. const $parent = $(element).parent();
  200. $container.scrollTop($parent.height());
  201. }
  202. };
  203. }).directive('onSearch', function () {
  204. return function (scope, element, attrs) {
  205. element.bind("keypress", function (event) {
  206. if((event.shiftKey && event.which === 220) || event.which === 13 || event.which === 44 || event.which === 124) {
  207. scope.$apply(function (){
  208. scope.$eval(attrs.onSearch);
  209. });
  210. event.preventDefault();
  211. }
  212. });
  213. };
  214. }).directive('ngRightClick', function() {
  215. return function(scope, element, attrs) {
  216. element.bind('contextmenu', function(event) {
  217. scope.$apply(function() {
  218. scope.$eval(attrs.ngRightClick);
  219. });
  220. event.preventDefault();
  221. });
  222. };
  223. });