/examples/web/terminal/static/js/jquery.terminal.js
JavaScript | 234 lines | 180 code | 36 blank | 18 comment | 28 complexity | 3d22a03456008ac7e796ac73b0a64599 MD5 | raw file
1/* 2 * AJAX Terminal (0.1) 3 * by Sagie Maoz (n0nick.net) 4 * n0nick@php.net 5 * 6 * jQuery plugin to create a web-based console-like behavior that posts user 7 * input commands to an AJAX server, and prints the result text. 8 * Designed to be utterly simple and highly customizable. 9 * 10 * Copyright (c) 2009 Sagie Maoz <n0nick@php.net> 11 * Licensed under the GPL license, see http://www.gnu.org/licenses/gpl-3.0.html 12 * 13 * 14 * NOTE: This script requires jQuery to work. Download jQuery at www.jquery.com 15 * 16 */ 17 18(function($) { 19 20 $.fn.terminal = function(url, options) { 21 22 settings = $.extend({ 23 'max_height' : '100%', 24 'form_method' : 'POST', 25 'input_name' : 'input', 26 'post_vars' : {}, 27 'custom_prompt' : false, 28 'focus_on_load' : true, 29 'submit_on_load' : false, 30 'grab_focus_on_click' : true, 31 'hello_message' : false, 32 'unix_theme' : true, 33 'allow_empty_input' : false, 34 'tab_width' : 4, 35 'disable_input' : false, 36 'onload' : null, 37 }, options); 38 39 if (settings.custom_prompt) 40 { 41 settings.custom_prompt = $.trim(settings.custom_prompt) + ' '; 42 } 43 44 return this.each(function() 45 { 46 var terminal_container = $(this); 47 48 terminal_container.append('<div></div>'); 49 var terminal = terminal_container.find('div:last'); 50 51 if (settings.max_height == '100%') 52 { 53 settings.max_height = terminal_container.innerHeight(); 54 } 55 56 terminal.css({ 57 'display' : 'block', 58 'overflow-x' : 'none', 59 'overflow-y' : 'auto', 60 'padding' : '0', 61 'max-height' : settings.max_height + 'px', 62 }); 63 64 terminal.append('<span></span'); 65 var terminal_output = terminal.find('span:last'); 66 67 terminal.append('<form method="'+settings.form_method+'" action="'+url+'"></form>'); 68 var terminal_form = $(this).find('form:last'); 69 70 if (settings.custom_prompt) 71 { 72 terminal_form.append('<span>' + settings.custom_prompt + '</span>'); 73 } 74 75 terminal_form.css('display', 'inline'); 76 terminal_form.attr('onsubmit', 'return false;'); 77 78 var tabString = ""; 79 for (var i=0; i<settings.tab_width; i++) 80 tabString+= " "; 81 82 var terminal_append = function(data) 83 { 84 var formattedData = $('<span></span>').text(data); 85 var dataRows = formattedData.html().split(/\n/); 86 data = ''; 87 for (row in dataRows) 88 { 89 data += '<span>' + dataRows[row].replace(/\t/g, tabString); 90 if (!(row == dataRows.length-1 && (!dataRows[row] || !settings.custom_prompt))) 91 data+= '<br />'; 92 data += '</span>'; 93 } 94 95 terminal_output.append('<span>' + data + '</span>'); 96 97 terminal_form.show(); 98 terminal_input.val('').focus(); 99 100 // if input is disabled, we trick a focus so the scrolling will be ok 101 if (settings.disable_input) 102 { 103 terminal_input.removeAttr('disabled').focus().attr('disabled', 'disabled'); 104 } 105 } 106 // outsource this function for misc. implementations 107 terminal_container[0].append = terminal_append; 108 109 var terminal_command = function(first) 110 { 111 var first = first || false; 112 var val = $.trim(terminal_input.val()); 113 114 if ("" == val && !first) 115 { 116 if (!settings.allow_empty_input) 117 return; 118 } 119 120 terminal_form.hide(); 121 if ("" != val || settings.allow_empty_input) 122 { 123 var last_command = '<span>'; 124 last_command+= settings.custom_prompt? settings.custom_prompt : ''; 125 last_command+= val + '<br />'; 126 terminal_output.append(last_command); 127 } 128 129 post_vars = settings.post_vars; 130 post_vars[settings.input_name] = val; 131 132 function terminal_command_success(data) 133 { 134 return terminal_append(data); 135 } 136 137 function terminal_command_error(x, tStatus) 138 { 139 var out = 'ERROR: '; 140 switch(tStatus) 141 { 142 case 'timeout': 143 out+= 'Server timeout. Try again later.'; 144 break; 145 case 'notmodified': 146 out+= 'Server did not response properly. Try again.'; 147 break; 148 case 'parsererror': 149 out+= 'Client error. Try again.'; 150 break; 151 default: 152 case 'error': 153 out+= 'A server error has occured. Check your command.'; 154 break; 155 } 156 return terminal_command_success(out); 157 } 158 159 $.ajax({ 160 'type' : terminal_form.attr('method'), 161 'url' : terminal_form.attr('action'), 162 'cache' : false, 163 'data' : post_vars, 164 'dataType' : 'text', 165 'success' : terminal_command_success, 166 'error' : terminal_command_error, 167 }); 168 169 } 170 terminal_form.submit(terminal_command); 171 172 terminal_form.append('<input type="text" name="'+settings.input_name+'" />'); 173 var terminal_input = terminal_form.find('input:last'); 174 terminal_input.css('width', '80%'); 175 terminal_input.attr('autocomplete', 'off'); 176 177 if (settings.unix_theme) 178 { 179 terminal_container.css({ 180 'border' : 'none', 181 'background-color' : 'black', 182 }); 183 terminal_form.css({ 184 'padding' : '0', 185 'margin' : '0', 186 }); 187 terminal_input.css({ 188 'border' : 'none', 189 'background-color' : 'black', 190 'padding' : '0', 191 'margin' : '0', 192 }); 193 terminal_container.find('input, span').css({ 194 'color' : 'lightgrey', 195 'font-family' : 'monospace', 196 'font-size' : '1em', 197 'line-height' : '1.3em', 198 }); 199 } 200 201 $(document).ready(function() 202 { 203 if (settings.grab_focus_on_click) 204 { 205 terminal_container.mouseup(function() 206 { 207 if ("" == document.getSelection()) 208 { 209 $(terminal_input.focus()); 210 } 211 }); 212 } 213 214 if (settings.hello_message) 215 terminal_output.append('<span>' + settings.hello_message + '<br /></span>'); 216 217 if (settings.submit_on_load) 218 terminal_command(true); 219 220 if (settings.focus_on_load) 221 terminal_input.focus(); 222 223 if (settings.disable_input) 224 terminal_input.attr('disabled', 'disabled'); 225 226 if (settings.onload) 227 settings.onload(); 228 229 }); 230 }); 231 232 } 233 234}(jQuery));