codekingpro/portable-devtools
114k
1// Urwid web (CGI/Asynchronous Javascript) display module2// Copyright (C) 2004-2005 Ian Ward3//4// This library is free software; you can redistribute it and/or5// modify it under the terms of the GNU Lesser General Public6// License as published by the Free Software Foundation; either7// version 2.1 of the License, or (at your option) any later version.8//9// This library is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12// Lesser General Public License for more details.13//14// You should have received a copy of the GNU Lesser General Public15// License along with this library; if not, write to the Free Software16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA17//18// Urwid web site: https://urwid.org/19 20colours = new Object();21colours = {22 '0': "black",23 '1': "#c00000",24 '2': "green",25 '3': "#804000",26 '4': "#0000c0",27 '5': "#c000c0",28 '6': "teal",29 '7': "silver",30 '8': "gray",31 '9': "#ff6060",32 'A': "lime",33 'B': "yellow",34 'C': "#8080ff",35 'D': "#ff40ff",36 'E': "aqua",37 'F': "white"38};39 40keycodes = new Object();41keycodes = {42 8: "backspace", 9: "tab", 13: "enter", 27: "esc",43 33: "page up", 34: "page down", 35: "end", 36: "home",44 37: "left", 38: "up", 39: "right", 40: "down",45 45: "insert", 46: "delete",46 112: "f1", 113: "f2", 114: "f3", 115: "f4",47 116: "f5", 117: "f6", 118: "f7", 119: "f8",48 120: "f9", 121: "f10", 122: "f11", 123: "f12"49 };50 51var conn = null;52var char_width = null;53var char_height = null;54var screen_x = null;55var screen_y = null;56 57var urwid_id = null;58var send_conn = null;59var send_queue_max = 32;60var send_queue = new Array(send_queue_max);61var send_queue_in = 0;62var send_queue_out = 0;63 64var check_font_delay = 1000;65var send_more_delay = 100;66var poll_again_delay = 500;67 68var document_location = null;69 70var update_method = "multipart";71 72var sending = false;73var lastkeydown = null;74 75function setup_connection() {76 if (window.XMLHttpRequest) {77 conn = new XMLHttpRequest();78 } else if (window.ActiveXObject) {79 conn = new ActiveXObject("Microsoft.XMLHTTP");80 }81 82 if (conn == null) {83 set_status("Connection Failed");84 alert( "Can't figure out how to send request." );85 return;86 }87 try{88 conn.multipart = true;89 }catch(e){90 update_method = "polling";91 }92 conn.onreadystatechange = handle_recv;93 conn.open("POST", document_location, true);94 conn.setRequestHeader("X-Urwid-Method",update_method);95 conn.setRequestHeader("Content-type","text/plain");96 conn.send("window resize " +screen_x+" "+screen_y+"\n");97}98 99function do_poll() {100 if (urwid_id == null){101 alert("that's unpossible!");102 return;103 }104 if (window.XMLHttpRequest) {105 conn = new XMLHttpRequest();106 } else if (window.ActiveXObject) {107 conn = new ActiveXObject("Microsoft.XMLHTTP");108 }109 conn.onreadystatechange = handle_recv;110 conn.open("POST", document_location, true);111 conn.setRequestHeader("X-Urwid-Method","polling");112 conn.setRequestHeader("X-Urwid-ID",urwid_id);113 conn.setRequestHeader("Content-type","text/plain");114 conn.send("eh?");115}116 117function handle_recv() {118 if( ! conn ){ return;}119 if( conn.readyState != 4) {120 return;121 }122 if( conn.status == 404 && urwid_id != null) {123 set_status("Connection Closed");124 return;125 }126 if( conn.status == 403 && update_method == "polling" ) {127 set_status("Server Refused Connection");128 alert("This server does not allow polling clients.\n\n" +129 "Please use a web browser with multipart support " +130 "such as Mozilla Firefox");131 return;132 }133 if( conn.status == 503 ) {134 set_status("Connection Failed");135 alert("The server has reached its maximum number of "+136 "connections.\n\nPlease try again later.");137 return;138 }139 if( conn.status != 200) {140 set_status("Connection Failed");141 alert("Error from server: "+conn.statusText);142 return;143 }144 if( urwid_id == null ){145 urwid_id = conn.getResponseHeader("X-Urwid-ID");146 if( send_queue_in != send_queue_out ){147 // keys waiting148 do_send();149 }150 if(update_method=="polling"){151 set_status("Polling");152 }else if(update_method=="multipart"){153 set_status("Connected");154 }155 156 }157 158 if( conn.responseText == "" ){159 if(update_method=="polling"){160 poll_again();161 }162 return; // keepalive163 }164 if( conn.responseText == "Z" ){165 set_status("Connection Closed");166 update_method = null;167 return;168 }169 170 var text = document.getElementById('text');171 172 var last_screen = Array(text.childNodes.length);173 for( var i=0; i<text.childNodes.length; i++ ){174 last_screen[i] = text.childNodes[i];175 }176 177 var frags = conn.responseText.split("\n");178 var ln = document.createElement('span');179 var k = 0;180 for( var i=0; i<frags.length; i++ ){181 var f = frags[i];182 if( f == "" ){183 var br = document.getElementById('br').cloneNode(true);184 ln.appendChild( br );185 if( text.childNodes.length > k ){186 text.replaceChild(ln, text.childNodes[k]);187 }else{188 text.appendChild(ln);189 }190 k = k+1;191 ln = document.createElement('span');192 }else if( f.charAt(0) == "<" ){193 line_number = parseInt(f.substr(1));194 if( line_number == k ){195 k = k +1;196 continue;197 }198 var clone = last_screen[line_number].cloneNode(true);199 if( text.childNodes.length > k ){200 text.replaceChild(clone, text.childNodes[k]);201 }else{202 text.appendChild(clone);203 }204 k = k+1;205 }else{206 var span=make_span(f.substr(2),f.charAt(0),f.charAt(1));207 ln.appendChild( span );208 }209 }210 for( var i=k; i < text.childNodes.length; i++ ){211 text.removeChild(last_screen[i]);212 }213 214 if(update_method=="polling"){215 poll_again();216 }217}218 219function poll_again(){220 if(conn.status == 200){221 setTimeout("do_poll();",poll_again_delay);222 }223}224 225 226function load_web_display(){227 if( document.documentURI ){228 document_location = document.documentURI;229 }else{230 document_location = document.location;231 }232 233 document.onkeypress = body_keypress;234 document.onkeydown = body_keydown;235 document.onresize = body_resize;236 237 body_resize();238 send_queue_out = send_queue_in; // don't queue the first resize239 240 set_status("Connecting");241 setup_connection();242 243 setTimeout("check_fontsize();",check_font_delay);244}245 246function set_status( status ){247 var s = document.getElementById('status');248 var t = document.createTextNode(status);249 s.replaceChild(t, s.firstChild);250}251 252function make_span(s, fg, bg){253 d = document.createElement('span');254 d.style.backgroundColor = colours[bg];255 d.style.color = colours[fg];256 d.appendChild(document.createTextNode(s));257 258 return d;259}260 261function body_keydown(e){262 if (conn == null){263 return;264 }265 if (!e) var e = window.event;266 if (e.keyCode) code = e.keyCode;267 else if (e.which) code = e.which;268 269 var mod = "";270 var key;271 272 if( e.ctrlKey ){ mod = "ctrl " + mod; }273 if( e.altKey || e.metaKey ){ mod = "meta " + mod; }274 if( e.shiftKey && e.charCode == 0 ){ mod = "shift " + mod; }275 276 key = keycodes[code];277 278 if( key != undefined ){279 lastkeydown = key;280 send_key( mod + key );281 stop_key_event(e);282 return false;283 }284}285 286function body_keypress(e){287 if (conn == null){288 return;289 }290 291 if (!e) var e = window.event;292 if (e.keyCode) code = e.keyCode;293 else if (e.which) code = e.which;294 295 var mod = "";296 var key;297 298 if( e.ctrlKey ){ mod = "ctrl " + mod; }299 if( e.altKey || e.metaKey ){ mod = "meta " + mod; }300 if( e.shiftKey && e.charCode == 0 ){ mod = "shift " + mod; }301 302 if( e.charCode != null && e.charCode != 0 ){303 key = String.fromCharCode(e.charCode);304 }else if( e.charCode == null ){305 key = String.fromCharCode(code);306 }else{307 key = keycodes[code];308 if( key == undefined || lastkeydown == key ){309 lastkeydown = null;310 stop_key_event(e);311 return false;312 }313 }314 315 send_key( mod + key );316 stop_key_event(e);317 return false;318}319 320function stop_key_event(e){321 e.cancelBubble = true;322 if( e.stopPropagation ){323 e.stopPropagation();324 }325 if( e.preventDefault ){326 e.preventDefault();327 }328}329 330function send_key( key ){331 if( (send_queue_in+1)%send_queue_max == send_queue_out ){332 // buffer overrun333 return;334 }335 send_queue[send_queue_in] = key;336 send_queue_in = (send_queue_in+1)%send_queue_max;337 338 if( urwid_id != null ){339 if (send_conn == undefined || send_conn.ready_state != 4 ){340 send_more();341 return;342 }343 do_send();344 }345}346 347function do_send() {348 if( ! urwid_id ){ return; }349 if( ! update_method ){ return; } // connection closed350 if( send_queue_in == send_queue_out ){ return; }351 if( sending ){352 //var queue_delta = send_queue_in - send_queue_out;353 //if( queue_delta < 0 ){ queue_delta += send_queue_max; }354 //set_status("Sending (queued "+queue_delta+")");355 return;356 }357 try{358 sending = true;359 //set_status("starting send");360 if( send_conn == null ){361 if (window.XMLHttpRequest) {362 send_conn = new XMLHttpRequest();363 } else if (window.ActiveXObject) {364 send_conn = new ActiveXObject("Microsoft.XMLHTTP");365 }366 }else if( send_conn.status != 200) {367 alert("Error from server: "+send_conn.statusText);368 return;369 }else if(send_conn.readyState != 4 ){370 alert("not ready on send connection");371 return;372 }373 } catch(e) {374 alert(e);375 sending = false;376 return;377 }378 send_conn.open("POST", document_location, true);379 send_conn.onreadystatechange = send_handle_recv;380 send_conn.setRequestHeader("Content-type","text/plain");381 send_conn.setRequestHeader("X-Urwid-ID",urwid_id);382 var tmp_send_queue_in = send_queue_in;383 var out = null;384 if( send_queue_out > tmp_send_queue_in ){385 out = send_queue.slice(send_queue_out).join("\n")386 if( tmp_send_queue_in > 0 ){387 out += "\n" + send_queue.slice(0,tmp_send_queue_in).join("\n");388 }389 }else{390 out = send_queue.slice(send_queue_out,391 tmp_send_queue_in).join("\n");392 }393 send_queue_out = tmp_send_queue_in;394 //set_status("Sending");395 send_conn.send( out +"\n" );396}397 398function send_handle_recv() {399 if( send_conn.readyState != 4) {400 return;401 }402 if( send_conn.status == 404) {403 set_status("Connection Closed");404 update_method = null;405 return;406 }407 if( send_conn.status != 200) {408 alert("Error from server: "+send_conn.statusText);409 return;410 }411 412 sending = false;413 414 if( send_queue_out != send_queue_in ){415 send_more();416 }417}418 419function send_more(){420 setTimeout("do_send();",send_more_delay);421}422 423function check_fontsize(){424 body_resize()425 setTimeout("check_fontsize();",check_font_delay);426}427 428function body_resize(){429 var t = document.getElementById('testchar');430 var t2 = document.getElementById('testchar2');431 var text = document.getElementById('text');432 433 var window_width;434 var window_height;435 if (window.innerHeight) {436 window_width = window.innerWidth;437 window_height = window.innerHeight;438 }else{439 window_width = document.documentElement.clientWidth;440 window_height = document.documentElement.clientHeight;441 //var z = "CI:"; for(var i in bod){z = z + " " + i;} alert(z);442 }443 444 char_width = t.offsetLeft / 44;445 var avail_width = window_width-18;446 var avail_width_mod = avail_width % char_width;447 var x_size = (avail_width - avail_width_mod)/char_width;448 449 char_height = t2.offsetTop - t.offsetTop;450 var avail_height = window_height-text.offsetTop-10;451 var avail_height_mod = avail_height % char_height;452 var y_size = (avail_height - avail_height_mod)/char_height;453 454 text.style.width = x_size*char_width+"px";455 text.style.height = y_size*char_height+"px";456 457 if( screen_x != x_size || screen_y != y_size ){458 send_key("window resize "+x_size+" "+y_size);459 }460 screen_x = x_size;461 screen_y = y_size;462}463 