ngrok.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. var ngrok = angular.module("ngrok", []);
  2. ngrok.directive({
  3. "keyval": function() {
  4. return {
  5. scope: {
  6. title: "@",
  7. tuples: "=",
  8. },
  9. replace: true,
  10. restrict: "E",
  11. template: "" +
  12. '<div ng-show="hasKeys">' +
  13. '<h6>{{title}}</h6>' +
  14. '<table class="table params">' +
  15. '<tr ng-repeat="(key, value) in tuples">' +
  16. '<th>{{ key }}</th>' +
  17. '<td>{{ value }}</td>' +
  18. '</tr>' +
  19. '</table>' +
  20. '</div>',
  21. link: function($scope) {
  22. $scope.hasKeys = false;
  23. for (key in $scope.tuples) { $scope.hasKeys = true; break; }
  24. }
  25. };
  26. },
  27. "tabs": function() {
  28. return {
  29. scope: {
  30. "tabs": "@",
  31. "btn": "@",
  32. "onbtnclick": "&"
  33. },
  34. replace: true,
  35. template: '' +
  36. '<ul class="nav nav-pills">' +
  37. '<li ng-repeat="tab in tabNames" ng-class="{\'active\': isTab(tab)}">' +
  38. '<a ng-click="setTab(tab)" href="#">{{tab}}</a>' +
  39. '</li>' +
  40. '<li ng-show="!!btn" class="pull-right"> <button class="btn btn-primary" ng-click="onbtnclick()">{{btn}}</button></li>' +
  41. '</ul>',
  42. link: function postLink(scope, element, attrs) {
  43. scope.tabNames = attrs.tabs.split(",");
  44. scope.activeTab = scope.tabNames[0];
  45. scope.setTab = function(t) {
  46. scope.activeTab = t;
  47. };
  48. scope.$parent.isTab = scope.isTab = function(t) {
  49. return t == scope.activeTab;
  50. };
  51. },
  52. };
  53. },
  54. "body": function($timeout) {
  55. return {
  56. scope: {
  57. "body": "="
  58. },
  59. template: '' +
  60. '<h6 ng-show="hasBody">' +
  61. '{{ Body.Length }} bytes ' +
  62. '{{ Body.RawContentType }}' +
  63. '</h6>' +
  64. '' +
  65. '<div ng-show="!isForm">' +
  66. '<pre ng-show="hasBody"><code ng-class="syntaxClass">{{ Body.Text }}</code></pre>' +
  67. '</div>' +
  68. '' +
  69. '<div ng-show="isForm">' +
  70. '<keyval title="Form Params" tuples="Body.Form">' +
  71. '</div>' +
  72. '<div ng-show="hasError" class="alert">' +
  73. '{{ Body.Error }}' +
  74. '</div>',
  75. controller: function($scope) {
  76. var body = $scope.body;
  77. $scope.isForm = (body.ContentType == "application/x-www-form-urlencoded");
  78. $scope.hasBody = (body.Length > 0);
  79. $scope.hasError = !!body.Error;
  80. $scope.syntaxClass = {
  81. "text/xml": "xml",
  82. "application/xml": "xml",
  83. "text/html": "xml",
  84. "text/css": "css",
  85. "application/json": "json",
  86. "text/javascript": "javascript",
  87. "application/javascript": "javascript",
  88. }[body.ContentType];
  89. var transform = {
  90. "xml": "xml",
  91. "json": "json"
  92. }[$scope.syntaxClass];
  93. if (!$scope.hasError && !!transform) {
  94. try {
  95. body.Text = vkbeautify[transform](body.Text);
  96. } catch (e) {
  97. }
  98. }
  99. $scope.Body = body;
  100. },
  101. link: function($scope, $elem) {
  102. $timeout(function() {
  103. $code = $elem.find("code").get(0);
  104. hljs.highlightBlock($code);
  105. if ($scope.Body.ErrorOffset > -1) {
  106. var offset = $scope.Body.ErrorOffset;
  107. function textNodes(node) {
  108. var textNodes = [];
  109. function getTextNodes(node) {
  110. if (node.nodeType == 3) {
  111. textNodes.push(node);
  112. } else {
  113. for (var i = 0, len = node.childNodes.length; i < len; ++i) {
  114. getTextNodes(node.childNodes[i]);
  115. }
  116. }
  117. }
  118. getTextNodes(node);
  119. return textNodes;
  120. }
  121. var tNodes = textNodes($elem.find("code").get(0));
  122. for (var i=0; i<tNodes.length; i++) {
  123. offset -= tNodes[i].nodeValue.length;
  124. if (offset < 0) {
  125. $(tNodes[i]).parent().css("background-color", "orange");
  126. break;
  127. }
  128. }
  129. }
  130. });
  131. }
  132. };
  133. }
  134. });
  135. ngrok.controller({
  136. "HttpTxns": function($scope) {
  137. $scope.txns = window.txns;
  138. if (!!window.WebSocket) {
  139. var ws = new WebSocket("ws://localhost:4040/_ws");
  140. ws.onopen = function() {
  141. console.log("connected websocket for real-time updates");
  142. };
  143. ws.onmessage = function(message) {
  144. $scope.$apply(function() {
  145. $scope.txns.unshift(JSON.parse(message.data));
  146. });
  147. /*
  148. $("pre code").each(function(i, e) {
  149. hljs.highlightBlock(e)
  150. });
  151. */
  152. };
  153. ws.onerror = function(err) {
  154. console.log("Web socket error:" + err);
  155. };
  156. ws.onclose = function(cls) {
  157. console.log("Web socket closed:" + cls);
  158. };
  159. }
  160. },
  161. "HttpRequest": function($scope) {
  162. $scope.Req = $scope.txn.Req;
  163. $scope.replay = function() {
  164. $.ajax({
  165. type: "POST",
  166. url: "/http/in/replay",
  167. data: { txnid: $scope.txn.Id }
  168. });
  169. }
  170. },
  171. "HttpResponse": function($scope) {
  172. $scope.Resp = $scope.txn.Resp;
  173. $scope.statusClass = {
  174. '2': "text-info",
  175. '3': "muted",
  176. '4': "text-warning",
  177. '5': "text-error"
  178. }[$scope.Resp.Status[0]];
  179. }
  180. });