View Single Post
  #5 (permalink)  
Old 05-04-08, 11:22 PM
job0107's Avatar
job0107 job0107 is offline
Community Liaison
 
Join Date: Dec 2006
Location: Tacoma, Washington USA
Posts: 3,454
Thanks: 0
Thanked 140 Times in 137 Posts
Ok UnrealEd,
I believe I have a solution for you.
I took the scroll feature out of the proceed() function and put it in the toggleCursor() function.
This seems to give it enough time to update the scroll position.
I have tested it in both FireFox and IE.

Javascript Code:
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  6. <title>Untitled Document</title>
  7. <script language="javascript" type="text/javascript">
  8. // <![CDATA[
  9.  
  10. // Stores specific hotKeyEvents. Certain keys need to be assigned to a different function
  11. // rather than the function that simply outputs the data to the cmdLineDiv div.
  12. // For instance the <enter> key also needs to continue the requests, as well as starting
  13. // a new line
  14. var hotKeyEvents = new Array();
  15. hotKeyEvents[10] = proceed;
  16. hotKeyEvents[13] = proceed;
  17. //hotKeyEvents[13]= function(cmdLineDiv.scrollTop = scrollHeight;)
  18. hotKeyEvents[127] = removeInputIfNecessary;
  19. // De page that need to be accessed via AJAX for processing the input of the cmd
  20. // line
  21. var ajaxRequestPage = 'ajax_install_test_div.php';
  22. // Defines the starting characters of a new cmd line (cf. C:\ on a windows cmd line)
  23. var CMDNL = '>>> ';
  24. // Contains the height of 1 line of text in the cmd (in px)
  25. var LINE_HEIGHT = 12;
  26. // Contains the height of the cmd itself (in px)
  27. var CMD_DIV_HEIGHT = 250;
  28. // contains the maximum amount of lines that can be displayed without having to use
  29. // scrollbars
  30. var MAX_CMD_LINES = Math.round(CMD_DIV_HEIGHT / LINE_HEIGHT);
  31. // When set to true, an additional textarea will be outputted at the bottom of the screen
  32. // with some debug information
  33. var debug = false;
  34.  
  35. // Contains a reference to the cmdLineDiv div in the HTML document
  36. var cmdLineDiv = null;
  37. // Contains the first occurence (backwards) that need to be found so that no contents
  38. // gets deleted after that point (sounds crazy, but is actually very logical)
  39. // In cmd on Windows, for instance, you can't delete the "C:\ " character at the beginning
  40. // of each line. The prevent a user from deleting these lines here, I had to make a copy
  41. // of the string that can't be deleted (">>> " in this case, or when a question is asked)
  42. var noEditLine = null;
  43. // Contains the XMLHttpRequest object in case XMLHttpRequest is available, otherwise
  44. // an ActiveXObject
  45. var ajaxRequestObject = null;
  46. // Contains a question that need to be answered. This question was send from the
  47. // ajaxRequestPage
  48. var cmdQuestion = null;
  49. // Contains the answer, filled in by the user, to the question last asked
  50. var cmdAnswer = null;
  51.  
  52. var newLines = 0;
  53.  
  54. /**
  55. * This function is called whenever a key is pressed inside the cmdLineDiv div.
  56. * It will check the key pressed, and then decides what to do with the event. By
  57. * default it will simply display the character in the cmdLineDiv div, unless a
  58. * hotKeyEvent was stored in the hotKeyEvents Array
  59. *
  60. * @param object An event object containing all information about the event
  61. */
  62. function onKeyPressEvent (event) {
  63.     event = event? event : (window.event? window.event : null);
  64.     if (event != null) {
  65.         var charCode = event.charCode? event.charCode : (event.which? event.which : event.keyCode);
  66.         if (debug) alertT (charCode + " = '" + String.fromCharCode(charCode) + "'");
  67.         if (charCode in hotKeyEvents)
  68.             hotKeyEvents[charCode]();
  69.         else if (charCode > 31 && charCode < 127)
  70.             insertChar (charCode);
  71.         else if (charCode > 160 && charCode <255)
  72.             insertHtmlChar (charCode);
  73.     }
  74. }
  75.  
  76. /**
  77. * Adds HTML text to the cmdLineDiv.
  78. * It will first remove the fake cursor, otherwise an unecessary underscore will
  79. * be placed on the cmdLineDiv div as well
  80. *
  81. * @param string The text that need to be displayed to the user on the cmdLineDiv div
  82. */
  83. function addHtmlText (text) {
  84.     removeCursor ();
  85.     cmdLineDiv.innerHTML += text;
  86. }
  87.  
  88. /**
  89. * This function is called whenever te <enter> key was pressed on your keyboard
  90. * If a question was asked during the previous cmd output, the answer is searched
  91. * for first. Next it will call the proceedWithRequests function to continue sending
  92. * requests to the ajaxRequestPage
  93. */
  94.  
  95. function proceed () {
  96.      //if (toScroll > CMD_DIV_HEIGHT)
  97.         //cmdLineDiv.scrollTop = scrollHeight;
  98.     if (debug) alertT ("proceed:");
  99.     if (cmdQuestion != null) {
  100.         removeCursor ();
  101.         cmdAnswer = cmdLineDiv.innerHTML.substring (cmdLineDiv.innerHTML.lastIndexOf (cmdQuestion) + cmdQuestion.length + 1);
  102.         cmdAnswer = (cmdAnswer == "" || cmdAnswer == " ")? null : cmdAnswer;
  103.         if (debug) alertT ("\tcmdAnswer: " + cmdAnswer);
  104.     }
  105.     //alert (cmdLineDiv.scrollHeight + " - " + cmdLineDiv.scrollTop);
  106.     proceedWithRequests ();
  107.     alertT (newLines);
  108.     alertT ("scrollH - scrollT = " + cmdLineDiv.scrollHeight + " - " + cmdLineDiv.scrollTop);
  109.     addHtmlText ("<br />\r\n" + CMDNL);
  110.     noEditLine = CMDNL;
  111.     cmdLineDiv.focus();
  112. }
  113. /**
  114. * Whenever the user hits the ctrl+backspace key combination on the keyboard
  115. * The text needs to be removed from the cmdLineDiv div. This function is called
  116. * everytime the user hits this combination, or keeps it down
  117. * Since I couldn't simply catch the backspace key-press, I had to use the
  118. * ctrl+backspace key combination
  119. */
  120. function removeInputIfNecessary () {
  121.     removeCursor ();
  122.     var cur = cmdLineDiv.innerText.substring (cmdLineDiv.innerText.length - noEditLine.length)
  123.     if (debug) alertT ("removeInputIfNecessary: " + cur + " vs. " + noEditLine + " = " + (cur == noEditLine? 'no-change' : 'remove'));
  124.     if (cur != noEditLine) {
  125.         cmdLineDiv.innerHTML = cmdLineDiv.innerHTML.substring (0, cmdLineDiv.innerHTML.length-1);
  126.     }
  127. }
  128.  
  129. /**
  130. * Inserts the character referring to the key that was pressed on your keyboard
  131. * into the cmdLineDiv div
  132. *
  133. * @param string The character code that refers to a certain character
  134. */
  135. function insertChar (char) {
  136.     if (debug) alertT ("insertChar: " + String.fromCharCode (char));
  137.     addHtmlText (String.fromCharCode (char));
  138. }
  139.  
  140. /**
  141. * When extended ASCII characters, such as ù, are typed, the HTML equivalent needs
  142. * to be inserted into the cmdLineDiv div.
  143. *
  144. * @param string The character code of a certain extended ASCII character. Eventually
  145. *            the &#-char-; string is inserted into the cmdLineDiv div
  146. */
  147. function insertHtmlChar (char) {
  148.     if (debug) alertT ("insertHtmlChar: " + String.fromCharCode(char));
  149.     addHtmlText ("&#" + parseInt (char) + ";");
  150. }
  151.  
  152. /**
  153. * This function is called to initiate all startup variables and functions
  154. */
  155. function __init__ () {
  156.     if (debug) createDebugOutputField ();
  157.     cmdLineDiv = document.getElementById('cmdLineDiv');
  158.     cmdLineDiv.focus();
  159.     noEditLine = CMDNL;
  160.     createAjaxObject ();
  161.     toggleCursor ();
  162. }
  163.  
  164. /**
  165. * This function makes a cursor flash inside the cmdLineDiv div.
  166. * It uses the setTimeout function that redirects to itself with an interval of
  167. * 0.5 seconds
  168. */
  169. function toggleCursor () {
  170.     if (cmdLineDiv.innerHTML.substring (cmdLineDiv.innerHTML.length-1) == '_')
  171.         {cmdLineDiv.innerHTML = cmdLineDiv.innerHTML.substring (0, cmdLineDiv.innerHTML.length-1);
  172.         cmdLineDiv.scrollTop = cmdLineDiv.scrollHeight;}
  173.     else
  174.         {cmdLineDiv.innerHTML += '_';
  175.         cmdLineDiv.scrollTop = cmdLineDiv.scrollHeight;}
  176.     setTimeout (toggleCursor, 500)
  177. }
  178.  
  179. /**
  180. * Removes the cursor from the cmdLineDiv div whenever text needs to be added to the div
  181. */
  182. function removeCursor () {
  183.     if (cmdLineDiv.innerHTML.substring (cmdLineDiv.innerHTML.length-1) == '_')
  184.         cmdLineDiv.innerHTML = cmdLineDiv.innerHTML.substring (0, cmdLineDiv.innerHTML.length-1);
  185. }
  186.  
  187. /**
  188. * Creates the XMLHttpRequest object or an ActiveXObject, depending on the browser
  189. */
  190. function createAjaxObject () {
  191.     if (window.XMLHttpRequest) {
  192.         ajaxRequestObject = new XMLHttpRequest();
  193.         return true;
  194.     } else if (window.ActiveXObject) {
  195.         var aVersions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", "Microsoft.XMLHttp"];
  196.         for (var i=0; i<aVersions.length; i++) {
  197.             try {
  198.                 ajaxRequestObject = new ActiveXObject (aVersions[i]);
  199.                 return true;
  200.             } catch (e) {}
  201.         }
  202.     } else {
  203.         alertT("Your browser doesn't support AJAX, please switch to Opera, Netscape, Firefox or IE");
  204.         return false;
  205.     }
  206. }
  207.  
  208. /**
  209. * Keeps on sending requests to the ajaxRequestPage whenever the user hits the <enter>
  210. * key on his keyboard
  211. */
  212. function proceedWithRequests () {
  213.     if (ajaxRequestObject != null) {
  214.         if (debug) alertT ("proceedWithRequests:");
  215.         ajaxRequestObject.open ('POST', ajaxRequestPage);
  216.         ajaxRequestObject.setRequestHeader ('Content-type', 'application/x-www-form-urlencoded');
  217.         ajaxRequestObject.onreadystatechange = function () {
  218.             if (ajaxRequestObject.readyState == 4 && ajaxRequestObject.status == 200) {
  219.                 var xml = ajaxRequestObject.responseXML;
  220.                 var status = parseInt(xml.getElementsByTagName ('status')[0].firstChild.nodeValue);
  221.                 if (debug) alertT ("\tstatus: " + status);
  222.                 if (status == 0) {
  223.                     var cmdText = new Array();
  224.                     var a = xml.getElementsByTagName ('cmdText')
  225.                     for (var i=0; i<a.length;i++)
  226.                         if (a[i].firstChild.nodeValue != "") cmdText.push (a[i].firstChild.nodeValue);
  227.                     try {
  228.                         cmdQuestion = xml.getElementsByTagName ('cmdQuestion')[0].firstChild.nodeValue;
  229.                     } catch (e) {
  230.                         cmdQuestion = null;
  231.                     }
  232.                     updateCmdLineDiv (cmdText, cmdQuestion);
  233.                     newLines = parseInt(cmdText.length + (cmdQuestion == null? 0 : 1));
  234.                     alertT("newLines in proceedWithRequests: " + newLines);
  235.                 } else {
  236.                     updateCmdLineDiv (new Array ('<span style="color:red">Error(' + status + '): The installation could not be completed</span>'), null);
  237.                     newLines = 1;
  238.                 }
  239.             } else {
  240.                 try {
  241.                     if (debug) alertT ("\tSomething went wrong during the ajax request:\n\tstatus: " + ajaxRequestObject.status + "\n\treadyState: " + ajaxRequestObject.readyState);
  242.                 } catch (e) {}
  243.                 newLines = 0;
  244.             }
  245.         };
  246.         if (cmdAnswer != null)
  247.             ajaxRequestObject.send ("sectionId=3&cmdAnwser=" + cmdAnswer);
  248.         else
  249.             ajaxRequestObject.send ("sectionId=1");
  250.     }
  251.  
  252.     return 0;
  253. }
  254.  
  255. /**
  256. * Processes the list of text that needs to be added to the cmdLineDiv div
  257. */
  258. function updateCmdLineDiv (cmdText, cmdQuestion) {
  259.     if (debug) alertT ("updateCmdLineDiv: cmdText(length):" + cmdText.length + ";cmdQuestion:" + cmdQuestion);
  260.     for (var i=0; i<cmdText.length; i++) {
  261.         addHtmlText (cmdText[i] + "<br/>\r\n");
  262.     }
  263.     if (cmdQuestion != null) {
  264.         addHtmlText (CMDNL + cmdQuestion + " ");
  265.         noEditLine = cmdQuestion + " ";
  266.     } else {
  267.         addHtmlText (CMDNL);
  268.         noEditLine = CMDNL;
  269.     }
  270. }
  271.  
  272. /**
  273. * Creates the textarea in which the debug-output will be placed
  274. */
  275. function createDebugOutputField () {
  276.     var textarea = document.createElement ('textarea');
  277.     try {
  278.         textarea.className = 'debugField';
  279.         textarea.id = 'debugField';
  280.     } catch (e) {
  281.         textarea.setAttribute ('class', 'debugField');
  282.         textarea.setAttribute ('id', 'debugField');
  283.     }
  284.     document.body.appendChild (textarea);
  285. }
  286.  
  287. /**
  288. * A variant of the built-in alert function, except this one simply outputs the
  289. * text to the debug field
  290. */
  291. function alertT (text) {
  292.     document.getElementById ('debugField').value += text + '\n';
  293. }
  294. // ]]>
  295. </script>
  296. <style type="text/css" media="screen">
  297. /* <![CDATA[ */
  298. textarea.debugField {
  299.     width:90%;
  300.     height:150px;
  301. }
  302.  
  303. div.cmdLine {
  304.     border:2px solid #AAAAAA;
  305.     height:250px;
  306.     width:90%;
  307.     font-family:"Lucida Console";
  308.     font-size:12px;
  309.     color:rgb(192,192,192);
  310.     background-color:#000000;
  311.     overflow:auto;
  312.     padding:2px;
  313. }
  314. /* ]]> */
  315. </style>
  316. </head>
  317.  
  318. <body onload="__init__(); createDebugOutputField()">
  319. <h3>Even wat zever zetten</h3>
  320. <button id="installbtn" type="button">Install!</button><br/>
  321. <br/>
  322. <div class="cmdLine" id="cmdLineDiv" onkeypress="onKeyPressEvent(event)">>>> </div>
  323. </body>
  324. </html>
__________________
Jerry Broughton
Reply With Quote