input.js (9239B)
1 /** 2 * The input service 3 * @return {Object} 4 */ 5 window.FakeTerminal.input = function (instance) { 6 7 /** 8 * Avoid scope issues by using `base` instead of `this` 9 * @type {Object} 10 */ 11 var base = this; 12 13 // -------------------------------------------------------------------------- 14 15 /** 16 * The input box the user can type into 17 * @type {Object} 18 */ 19 base.$input = null; 20 21 /** 22 * The input box the user can type into when requesting input 23 * @type {Object} 24 */ 25 base.$request = null; 26 27 /** 28 * The command line container 29 * @type {Object} 30 */ 31 base.$commandLine = null; 32 33 /** 34 * The input request container 35 * @type {Object} 36 */ 37 base.$inputRequest = null; 38 39 // -------------------------------------------------------------------------- 40 41 /** 42 * Constructs window.FakeTerminal.input 43 * @returns {Object} 44 * @private 45 */ 46 base.__construct = function () { 47 48 base.$prompt = $('<div>') 49 .addClass('faketerminal__prompt') 50 .attr('autocorrect', 'off') 51 .attr('autocapitalize', 'none') 52 .html(instance.getPrompt()); 53 54 base.$input = $('<input>') 55 .on('keyup', function (e) { 56 switch (e.which) { 57 case instance.keymap.ENTER: 58 instance.exec(base.read()) 59 .done(function () { 60 // Update the prompt, it may have been altered 61 base.$prompt.html(instance.getPrompt()); 62 }); 63 break; 64 65 case instance.keymap.UP: 66 case instance.keymap.DOWN: 67 base.set(instance.history.browse(e.which)); 68 break; 69 } 70 }); 71 72 base.$commandLine = $('<div>') 73 .addClass('faketerminal__commandline'); 74 75 // -------------------------------------------------------------------------- 76 77 base.$request = $('<input>'); 78 base.$inputRequest = $('<div>') 79 .addClass('faketerminal__commandline faketerminal__commandline--request'); 80 81 // -------------------------------------------------------------------------- 82 83 instance.$el 84 .append( 85 base.$commandLine 86 .append(base.$prompt) 87 .append(base.$input) 88 ) 89 .append( 90 base.$inputRequest 91 .append(base.$request) 92 ); 93 94 // -------------------------------------------------------------------------- 95 96 base.enable(); 97 base.disableRequest(); 98 99 return base; 100 }; 101 102 // -------------------------------------------------------------------------- 103 104 /** 105 * Reads the value of base.$input and clears immediately after 106 * @returns {String} 107 */ 108 base.read = function () { 109 var value = base.$input.val(); 110 base.$input.val(''); 111 return value; 112 }; 113 114 // -------------------------------------------------------------------------- 115 116 /** 117 * Requests user input from the user 118 * @param {String} type The type of request; boolean 119 * @returns {$.Deferred} 120 */ 121 base.request = function (type) { 122 123 type = type || 'TEXT'; 124 type = type.toUpperCase(); 125 126 switch (type) { 127 case 'TEXT': 128 return base.requestText(); 129 break; 130 case 'BOOL': 131 case 'BOOLEAN': 132 return base.requestBool(); 133 break; 134 case 'PASSWORD': 135 return base.requestPassword(); 136 break; 137 default: 138 throw 'Invalid request type'; 139 break; 140 } 141 }; 142 143 // -------------------------------------------------------------------------- 144 145 /** 146 * Requests text input from the user 147 * @param {Boolean} muteOutput Whether to print what the user typed to the output or not 148 * @returns {$.Deferred} 149 */ 150 base.requestText = function (muteOutput) { 151 152 var deferred = new $.Deferred(); 153 154 base.enableRequest(); 155 base.$request 156 .on('keyup', function (e) { 157 if (e.which === instance.keymap.ENTER) { 158 var value = $.trim(base.$request.val()); 159 if (!muteOutput) { 160 instance.output.write(value); 161 } 162 deferred.resolve(value); 163 instance.$el.trigger('ft:command', [instance, value]); 164 } 165 }); 166 167 deferred.always(function () { 168 base.disableRequest(); 169 base.$request.off('keyup'); 170 }); 171 172 return deferred.promise(); 173 }; 174 175 // -------------------------------------------------------------------------- 176 177 /** 178 * Requests a boolean input from the user 179 * @returns {$.Deferred} 180 */ 181 base.requestBool = function () { 182 183 var deferred = new $.Deferred(); 184 185 base.requestText() 186 .done(function(value) { 187 188 value = $.trim(String(value).toLowerCase()); 189 190 if (['1', 'true', 'yes', 'y', 'ok'].indexOf(value) !== -1) { 191 deferred.resolve(); 192 } else { 193 deferred.reject(); 194 } 195 }); 196 197 return deferred.promise(); 198 }; 199 200 // -------------------------------------------------------------------------- 201 202 /** 203 * Requests text input from the user, but hides it from screen and does not print to the output 204 * @returns {$.Deferred} 205 */ 206 base.requestPassword = function () { 207 208 var deferred = new $.Deferred(); 209 210 base.$request.addClass('is-password'); 211 instance.output.write('Password:'); 212 base.requestText(true) 213 .done(function(value) { 214 base.$request.removeClass('is-password'); 215 deferred.resolve(value); 216 }); 217 218 return deferred.promise(); 219 }; 220 221 // -------------------------------------------------------------------------- 222 223 /** 224 * Sets the value of base.$input 225 * @param {String} command The command to set 226 */ 227 base.set = function (command) { 228 base.$input.val(command); 229 }; 230 231 // -------------------------------------------------------------------------- 232 233 /** 234 * Focuses base.$input 235 * @returns {Object} 236 */ 237 base.focus = function () { 238 if (base.$input.is(':visible')) { 239 base.$input.focus(); 240 } else if (base.$request.is(':visible')) { 241 base.$request.focus(); 242 } 243 return base; 244 }; 245 246 // -------------------------------------------------------------------------- 247 248 /** 249 * Shows base.$commandLine 250 * @returns {Object} 251 */ 252 base.enable = function () { 253 base.$commandLine.show(); 254 base.focus(); 255 return base; 256 }; 257 258 // -------------------------------------------------------------------------- 259 260 /** 261 * Hides base.$commandLine 262 * @returns {Object} 263 */ 264 base.disable = function () { 265 base.$commandLine.hide(); 266 base.$input.val(''); 267 return base; 268 }; 269 270 // -------------------------------------------------------------------------- 271 272 /** 273 * Shows base.$inputRequest 274 * @returns {Object} 275 */ 276 base.enableRequest = function () { 277 base.$inputRequest.show(); 278 base.focus(); 279 return base; 280 }; 281 282 // -------------------------------------------------------------------------- 283 284 /** 285 * Hides base.$inputRequest 286 * @returns {Object} 287 */ 288 base.disableRequest = function () { 289 base.$inputRequest.hide(); 290 base.$request.val(''); 291 return base; 292 }; 293 294 // -------------------------------------------------------------------------- 295 296 /** 297 * Exits out of any running task 298 * @return {Object} 299 */ 300 base.ctrlC = function () { 301 302 /** 303 * If a command is executing reject it and show some feedback; if not 304 * just repeat the prompt 305 */ 306 307 if (instance.executingCommand.instance) { 308 instance.executingCommand.instance.terminate(); 309 instance.executingCommand.instance = null; 310 instance.executingCommand.deferred = null; 311 instance.output.write('^C', true); 312 } else { 313 var value = base.read(); 314 if (value.length) { 315 instance.output.write(value, true); 316 instance.output.write('^C', true); 317 } 318 instance.output.write('', true); 319 } 320 321 // Focus the command prompt 322 base.disableRequest(); 323 base.focus(); 324 325 return base; 326 }; 327 328 // -------------------------------------------------------------------------- 329 330 /** 331 * Resets the command input 332 * @return {Object} 333 */ 334 base.ctrlU = function () { 335 base.$input.val(''); 336 return base; 337 }; 338 339 // -------------------------------------------------------------------------- 340 341 return base.__construct(); 342 };