PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/static/js/shell.js

https://bitbucket.org/sdidit/rfhresult
JavaScript | 197 lines | 87 code | 23 blank | 87 comment | 35 complexity | 7c054e8982c790c554cee0c831e1ee15 MD5 | raw file
  1. // Copyright 2007 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview
  16. * Javascript code for the interactive AJAX shell.
  17. *
  18. * Part of http://code.google.com/p/google-app-engine-samples/.
  19. *
  20. * Includes a function (shell.runStatement) that sends the current python
  21. * statement in the shell prompt text box to the server, and a callback
  22. * (shell.done) that displays the results when the XmlHttpRequest returns.
  23. *
  24. * Also includes cross-browser code (shell.getXmlHttpRequest) to get an
  25. * XmlHttpRequest.
  26. */
  27. /**
  28. * Shell namespace.
  29. * @type {Object}
  30. */
  31. var shell = {}
  32. /**
  33. * The shell history. history is an array of strings, ordered oldest to
  34. * newest. historyCursor is the current history element that the user is on.
  35. *
  36. * The last history element is the statement that the user is currently
  37. * typing. When a statement is run, it's frozen in the history, a new history
  38. * element is added to the end of the array for the new statement, and
  39. * historyCursor is updated to point to the new element.
  40. *
  41. * @type {Array}
  42. */
  43. shell.history = [''];
  44. /**
  45. * See {shell.history}
  46. * @type {number}
  47. */
  48. shell.historyCursor = 0;
  49. /**
  50. * A constant for the XmlHttpRequest 'done' state.
  51. * @type Number
  52. */
  53. shell.DONE_STATE = 4;
  54. /**
  55. * A cross-browser function to get an XmlHttpRequest object.
  56. *
  57. * @return {XmlHttpRequest?} a new XmlHttpRequest
  58. */
  59. shell.getXmlHttpRequest = function () {
  60. if (window.XMLHttpRequest) {
  61. return new XMLHttpRequest();
  62. } else if (window.ActiveXObject) {
  63. try {
  64. return new ActiveXObject('Msxml2.XMLHTTP');
  65. } catch (e) {
  66. return new ActiveXObject('Microsoft.XMLHTTP');
  67. }
  68. }
  69. return null;
  70. };
  71. /**
  72. * This is the prompt textarea's onkeypress handler. Depending on the key that
  73. * was pressed, it will run the statement, navigate the history, or update the
  74. * current statement in the history.
  75. *
  76. * @param {Event} event the keypress event
  77. * @return {Boolean} false to tell the browser not to submit the form.
  78. */
  79. shell.onPromptKeyPress = function (event) {
  80. var statement = document.getElementById('statement');
  81. if (this.historyCursor == this.history.length - 1) {
  82. // we're on the current statement. update it in the history before doing
  83. // anything.
  84. this.history[this.historyCursor] = statement.value;
  85. }
  86. // should we pull something from the history?
  87. if (event.ctrlKey && event.keyCode == 38 /* up arrow */) {
  88. if (this.historyCursor > 0) {
  89. statement.value = this.history[--this.historyCursor];
  90. }
  91. return false;
  92. } else if (event.ctrlKey && event.keyCode == 40 /* down arrow */) {
  93. if (this.historyCursor < this.history.length - 1) {
  94. statement.value = this.history[++this.historyCursor];
  95. }
  96. return false;
  97. } else if (!event.altKey) {
  98. // probably changing the statement. update it in the history.
  99. this.historyCursor = this.history.length - 1;
  100. this.history[this.historyCursor] = statement.value;
  101. }
  102. // should we submit?
  103. var ctrlEnter = (document.getElementById('submit_key').value == 'ctrl-enter');
  104. if (event.keyCode == 13 /* enter */ && !event.altKey && !event.shiftKey &&
  105. event.ctrlKey == ctrlEnter) {
  106. return this.runStatement();
  107. }
  108. };
  109. /**
  110. * The XmlHttpRequest callback. If the request succeeds, it adds the command
  111. * and its resulting output to the shell history div.
  112. *
  113. * @param {XmlHttpRequest} req the XmlHttpRequest we used to send the current
  114. * statement to the server
  115. */
  116. shell.done = function (req) {
  117. if (req.readyState == this.DONE_STATE) {
  118. var statement = document.getElementById('statement')
  119. statement.className = 'prompt';
  120. // add the command to the shell output
  121. var output = document.getElementById('output');
  122. output.value += '\n>>> ' + statement.value;
  123. statement.value = '';
  124. // add a new history element
  125. this.history.push('');
  126. this.historyCursor = this.history.length - 1;
  127. // add the command's result
  128. var result = req.responseText.replace(/^\s*|\s*$/g, ''); // trim whitespace
  129. if (result != '')
  130. output.value += '\n' + result;
  131. // scroll to the bottom
  132. output.scrollTop = output.scrollHeight;
  133. if (output.createTextRange) {
  134. var range = output.createTextRange();
  135. range.collapse(false);
  136. range.select();
  137. }
  138. }
  139. };
  140. /**
  141. * This is the form's onsubmit handler. It sends the python statement to the
  142. * server, and registers shell.done() as the callback to run when it returns.
  143. *
  144. * @return {Boolean} false to tell the browser not to submit the form.
  145. */
  146. shell.runStatement = function () {
  147. var form = document.getElementById('form');
  148. // build a XmlHttpRequest
  149. var req = this.getXmlHttpRequest();
  150. if (!req) {
  151. document.getElementById('ajax-status').innerHTML =
  152. "<span class='error'>Your browser doesn't support AJAX. :(</span>";
  153. return false;
  154. }
  155. req.onreadystatechange = function () {
  156. shell.done(req);
  157. };
  158. // build the query parameter string
  159. var params = '';
  160. for (i = 0; i < form.elements.length; i++) {
  161. var elem = form.elements[i];
  162. if (elem.type != 'submit' && elem.type != 'button' && elem.id != 'caret') {
  163. var value = escape(elem.value).replace(/\+/g, '%2B'); // escape ignores +
  164. params += '&' + elem.name + '=' + value;
  165. }
  166. }
  167. // send the request and tell the user.
  168. document.getElementById('statement').className = 'prompt processing';
  169. req.open(form.method, form.action + '?' + params, true);
  170. req.setRequestHeader('Content-type',
  171. 'application/x-www-form-urlencoded;charset=UTF-8');
  172. req.send(null);
  173. return false;
  174. };