PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/examples/web/terminal/static/js/jquery.terminal.js

https://bitbucket.org/prologic/circuits/
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+= "&nbsp;";
 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));