Skip to content

Instantly share code, notes, and snippets.

@lavelle
Created July 29, 2013 20:41
Show Gist options
  • Save lavelle/6107625 to your computer and use it in GitHub Desktop.
Save lavelle/6107625 to your computer and use it in GitHub Desktop.
jQuery console diff
diff --git a/jquery.console.js b/../doppio/vendor/jquery.console.js
index 10e893e..7db1f1c 100644
--- a/jquery.console.js
+++ b/../doppio/vendor/jquery.console.js
@@ -38,9 +38,12 @@
// Google Chrome 5.0.375.55 (Mac)
(function($){
- var isWebkit = !!~navigator.userAgent.indexOf(' AppleWebKit/');
-
$.fn.console = function(config){
+ if (config === undefined) config = {};
+
+ // External exports object
+ var extern = {};
+
////////////////////////////////////////////////////////////////////////
// Constants
// Some are enums, data types, others just for optimisation
@@ -55,6 +58,8 @@
40: nextHistory,
// backspace
8: backDelete,
+ // tab
+ 9: tabComplete,
// delete
46: forwardDelete,
// end
@@ -63,18 +68,16 @@
36: moveToStart,
// return
13: commandTrigger,
- // tab
- 18: doNothing,
- // tab
- 9: doComplete
+ // alt
+ 18: doNothing
};
var ctrlCodes = {
// C-a
65: moveToStart,
- // C-e
- 69: moveToEnd,
// C-d
68: forwardDelete,
+ // C-e
+ 69: moveToEnd,
// C-n
78: nextHistory,
// C-p
@@ -86,9 +89,6 @@
// C-k
75: deleteUntilEnd
};
- if(config.ctrlCodes) {
- $.extend(ctrlCodes, config.ctrlCodes);
- }
var altCodes = {
// M-f
70: moveToNextWord,
@@ -102,23 +102,33 @@
////////////////////////////////////////////////////////////////////////
// Globals
var container = $(this);
- var inner = $('<div class="jquery-console-inner"></div>');
+ var inner = $('<pre class="jquery-console-inner"></pre>');
// erjiang: changed this from a text input to a textarea so we
// can get pasted newlines
var typer = $('<textarea class="jquery-console-typer"></textarea>');
// Prompt
var promptBox;
var prompt;
- var promptLabel = config && config.promptLabel? config.promptLabel : "> ";
- var continuedPromptLabel = config && config.continuedPromptLabel?
+ extern.promptLabel = config.promptLabel ? config.promptLabel : "> ";
+ extern.continuedPromptLabel = config.continuedPromptLabel ?
config.continuedPromptLabel : "> ";
var column = 0;
var promptText = '';
var restoreText = '';
var continuedText = '';
+
// Prompt history stack
var history = [];
var ringn = 0;
+ if (window.localStorage && window.localStorage.history) {
+ try {
+ history = JSON.parse(localStorage.history);
+ }
+ catch (e) {
+ console.error('Previous history is not a valid JSON object.');
+ }
+ }
+
// For reasons unknown to The Sword of Michael himself, Opera
// triggers and sends a key character when you hit various
// keys like PgUp, End, etc. So there is no way of knowing
@@ -131,9 +141,8 @@
var acceptInput = true;
// When this value is true, the command has been canceled
var cancelCommand = false;
-
- // External exports object
- var extern = {};
+ extern.commandHandle = config.commandHandle;
+ var lastMsg = null;
////////////////////////////////////////////////////////////////////////
// Main entry point
@@ -208,19 +217,32 @@
////////////////////////////////////////////////////////////////////////
// Make a new prompt box
function newPromptBox() {
+ if (typeof extern.onreprompt === 'function')
+ extern.onreprompt();
column = 0;
promptText = '';
ringn = 0; // Reset the position of the history ring
enableInput();
promptBox = $('<div class="jquery-console-prompt-box"></div>');
var label = $('<span class="jquery-console-prompt-label"></span>');
- var labelText = extern.continuedPrompt? continuedPromptLabel : promptLabel;
+ var labelText = extern.continuedPrompt ? extern.continuedPromptLabel :
+ extern.promptLabel;
+ if (lastMsg) {
+ var text = lastMsg.text();
+ if (_.last(text) !== '\n') {
+ var lines = text.split('\n');
+ labelText = _.last(lines) + labelText;
+ lines.length--;
+ lastMsg.text(lines.join('\n'));
+ }
+ }
promptBox.append(label.text(labelText).show());
label.html(label.html().replace(' ','&nbsp;'));
prompt = $('<span class="jquery-console-prompt"></span>');
promptBox.append(prompt);
inner.append(promptBox);
updatePromptDisplay();
+ lastMsg = null;
};
////////////////////////////////////////////////////////////////////////
@@ -228,11 +250,7 @@
container.click(function(){
inner.addClass('jquery-console-focus');
inner.removeClass('jquery-console-nofocus');
- if (isWebkit) {
- typer.focusWithoutScrolling();
- } else {
- typer.css('position', 'fixed').focus();
- }
+ typer.focus();
scrollToBottom();
return false;
});
@@ -295,28 +313,24 @@
if (isIgnorableKey(e)) {
return false;
}
- // C-v: don't insert on paste event
- if ((e.ctrlKey || e.metaKey) && String.fromCharCode(keyCode).toLowerCase() == 'v') {
+ // // C-v: don't insert on paste event
+ if (e.ctrlKey && String.fromCharCode(keyCode).toLowerCase() == 'v') {
return true;
}
if (acceptInput && cancelKeyPress != keyCode && keyCode >= 32){
if (cancelKeyPress) return false;
- if (
- typeof config.charInsertTrigger == 'undefined' || (
- typeof config.charInsertTrigger == 'function' &&
- config.charInsertTrigger(keyCode,promptText)
- )
- ){
+ if (typeof config.charInsertTrigger == 'undefined' ||
+ (typeof config.charInsertTrigger == 'function' &&
+ config.charInsertTrigger(keyCode,promptText)))
typer.consoleInsert(keyCode);
}
- }
- if (isWebkit) return false;
+ if ($.browser.webkit || $.browser.opera) return false;
});
function isIgnorableKey(e) {
// for now just filter alt+tab that we receive on some platforms when
// user switches windows (goes away from the browser)
- return ((e.keyCode == keyCodes.tab || e.keyCode == 192) && e.altKey);
+ return ((e.keyCode == 9 || e.keyCode == 192) && e.altKey);
};
////////////////////////////////////////////////////////////////////////
@@ -355,6 +369,9 @@
// Add something to the history ring
function addToHistory(line){
history.push(line);
+ if (window.localStorage) {
+ localStorage.history = JSON.stringify(history);
+ }
restoreText = '';
};
@@ -377,9 +394,12 @@
};
function forwardDelete() {
- if (deleteCharAtPos()){
- updatePromptDisplay();
+ if (promptText.length == 0) {
+ if (extern.commandHandle)
+ extern.commandHandle('\0');
}
+ else if (deleteCharAtPos())
+ updatePromptDisplay();
};
function deleteUntilEnd() {
@@ -392,18 +412,14 @@
// A word is defined within this context as a series of alphanumeric
// characters.
// Delete up to the next alphanumeric character
- while(
- column < promptText.length &&
- !isCharAlphanumeric(promptText[column])
- ) {
+ while(column < promptText.length &&
+ !isCharAlphanumeric(promptText[column])) {
deleteCharAtPos();
updatePromptDisplay();
}
// Then, delete until the next non-alphanumeric character
- while(
- column < promptText.length &&
- isCharAlphanumeric(promptText[column])
- ) {
+ while(column < promptText.length &&
+ isCharAlphanumeric(promptText[column])) {
deleteCharAtPos();
updatePromptDisplay();
}
@@ -429,12 +445,7 @@
// Scroll to the bottom of the view
function scrollToBottom() {
- var version = jQuery.fn.jquery.split('.');
- var major = parseInt(version[0]);
- var minor = parseInt(version[1]);
-
- // check if we're using jquery > 1.6
- if ((major == 1 && minor > 6) || major > 1) {
+ if (jQuery.fn.jquery > "1.6") {
inner.prop({ scrollTop: inner.prop("scrollHeight") });
}
else {
@@ -451,7 +462,7 @@
////////////////////////////////////////////////////////////////////////
// Handle a command
function handleCommand() {
- if (typeof config.commandHandle == 'function') {
+ if (typeof extern.commandHandle == 'function') {
disableInput();
addToHistory(promptText);
var text = promptText;
@@ -461,20 +472,19 @@
else continuedText = promptText;
} else continuedText = undefined;
if (continuedText) text = continuedText;
- var ret = config.commandHandle(text,function(msgs){
- commandResult(msgs);
- });
+ var ret = extern.commandHandle(text);
if (extern.continuedPrompt && !continuedText)
continuedText = promptText;
- if (typeof ret == 'boolean') {
+ if (ret === null) {
+ // assume that we don't want to reprompt
+ return;
+ } else if (typeof ret == 'boolean') {
if (ret) {
// Command succeeded without a result.
commandResult();
} else {
- commandResult(
- 'Command failed.',
- "jquery-console-message-error"
- );
+ commandResult('Command failed.',
+ "jquery-console-message-error");
}
} else if (typeof ret == "string") {
commandResult(ret,"jquery-console-message-success");
@@ -490,39 +500,64 @@
// Disable input
function disableInput() {
acceptInput = false;
+ $('span.jquery-console-cursor').addClass('jquery-console-cursor-busy');
+ $('#consoleUnderlay').addClass('consoleUnderlayBusy');
};
// Enable input
function enableInput() {
acceptInput = true;
+ $('span.jquery-console-cursor').removeClass('jquery-console-cursor-busy');
+ $('#consoleUnderlay').removeClass('consoleUnderlayBusy');
}
+ var type2css = {
+ success: 'jquery-console-message-success',
+ error: 'jquery-console-message-error'
+ };
+
////////////////////////////////////////////////////////////////////////
// Reset the prompt in invalid command
- function commandResult(msg,className) {
+ function commandResult(msg,className,noreprompt) {
column = -1;
updatePromptDisplay();
if (typeof msg == 'string') {
- message(msg,className);
+ message(msg,className,noreprompt);
} else if ($.isArray(msg)) {
- for (var x in msg) {
- var ret = msg[x];
- message(ret.msg,ret.className);
- }
+ message(msg[0],type2css[msg[1]]);
} else { // Assume it's a DOM node or jQuery object.
inner.append(msg);
}
+ if (!noreprompt) {
newPromptBox();
+ }
};
+ extern.message = function (msg, type, noreprompt) {
+ commandResult(msg, type2css[type], noreprompt);
+ }
+ extern.reprompt = function() { commandResult(); }
+
////////////////////////////////////////////////////////////////////////
// Display a message
- function message(msg,className) {
- var mesg = $('<div class="jquery-console-message"></div>');
+ function message(msg,className,noreprompt) {
+ if (!noreprompt) {
+ mesg = $('<div class="jquery-console-message"></div>');
if (className) mesg.addClass(className);
- mesg.filledText(msg).hide();
+ mesg.text(msg)
+ mesg.hide();
inner.append(mesg);
mesg.show();
+ }
+ else {
+ if (!lastMsg)
+ lastMsg = $('<div class="jquery-console-message"></div>');
+ lastMsg.text(lastMsg.text() + msg)
+ lastMsg.hide();
+ inner.append(lastMsg);
+ lastMsg.show();
+ }
+ scrollToBottom();
};
////////////////////////////////////////////////////////////////////////
@@ -577,31 +612,27 @@
};
function moveToNextWord() {
- while(
- column < promptText.length &&
+ while(column < promptText.length &&
!isCharAlphanumeric(promptText[column]) &&
- moveForward()
- ) {}
- while(
- column < promptText.length &&
+ moveForward()) {
+ }
+ while(column < promptText.length &&
isCharAlphanumeric(promptText[column]) &&
- moveForward()
- ) {}
+ moveForward()) {
+ }
};
function moveToPreviousWord() {
// Move backward until we find the first alphanumeric
- while(
- column -1 >= 0 &&
+ while(column -1 >= 0 &&
!isCharAlphanumeric(promptText[column-1]) &&
- moveBackward()
- ) {}
+ moveBackward()) {
+ }
// Move until we find the first non-alphanumeric
- while(
- column -1 >= 0 &&
+ while(column -1 >= 0 &&
isCharAlphanumeric(promptText[column-1]) &&
- moveBackward()
- ) {}
+ moveBackward()) {
+ }
};
function isCharAlphanumeric(charToTest) {
@@ -614,44 +645,15 @@
return false;
};
- function doComplete() {
- if(typeof config.completeHandle == 'function') {
- var completions = config.completeHandle(promptText);
- var len = completions.length;
- if (len === 1) {
- extern.promptText(promptText + completions[0]);
- } else if (len > 1 && config.cols) {
- var prompt = promptText;
- // Compute the number of rows that will fit in the width
- var max = 0;
- for (var i = 0;i < len;i++) {
- max = Math.max(max, completions[i].length);
- }
- max += 2;
- var n = Math.floor(config.cols / max);
- var buffer = "";
- var col = 0;
- for (i = 0;i < len;i++) {
- var completion = completions[i];
- buffer += completions[i];
- for (var j = completion.length;j < max;j++) {
- buffer += " ";
- }
- if (++col >= n) {
- buffer += "\n";
- col = 0;
- }
- }
- commandResult(buffer,"jquery-console-message-value");
- extern.promptText(prompt);
- }
- }
- };
-
function doNothing() {};
+ function tabComplete() {
+ if (config.tabComplete)
+ return config.tabComplete();
+ }
+
extern.promptText = function(text){
- if (typeof text === 'string') {
+ if (text) {
promptText = text;
column = promptText.length;
updatePromptDisplay();
@@ -705,17 +707,4 @@
return extern;
};
- // Simple utility for printing messages
- $.fn.filledText = function(txt){
- $(this).text(txt);
- $(this).html($(this).html().replace(/\n/g,'<br/>'));
- return this;
- };
-
- // Alternative method for focus without scrolling
- $.fn.focusWithoutScrolling = function(){
- var x = window.scrollX, y = window.scrollY;
- $(this).focus();
- window.scrollTo(x, y);
- };
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment