JavaScript Theory/Design Question
Posted: Thu Aug 10, 2006 7:43 am
I'm trying to take a MVC type of approach to designing a JavaScript application. This is responds to use commands (typed only) and displays various bits and pieces on the page.
The things that may change in the display are:
* The main window area (just a big DIV like a terminal window)
* The command prompt
* The line the user types on
* A status bar/box (notification of what's happening on the ajax side of things)
I've already broken my code into several classes on the client side like this:
* Input - exists as a single object, handles all user input, contains a buffer object
* Output - Handles the display (aspects shown above)
* Buffer - Keeps a log of command keyed by the user and allows iterating backwards and forward through them by pressing UP and DOWN (like a terminal)
I'm getting a bix mixed up with what's generating output however. For example, when an item is addded to the buffer, the buffer wants to update the diaply to remove the line of text the user typed so it generates a new Output(), sets the buffer contents empty then flushes it itself.
Now similarly, when the user presses UP or DOWN, Input() asks Buffer() to get the next or previous item and then Input() generates a new Output(), sets the buffer contents to the relevant item and calls flush().
Can I centralise my output any more than this? It seems I'm going to be genrating new Output() in several areas, although the specific logic for this output will be dealt with by the Output() class itself.
Input()
Buffer()
Output() -- so far
Thoughts?
EDIT | There's a test page up at http://www.w3style.co.uk/~d11wtq/PhpMyAjax/ if you're wondering what on earth I'm talking about. I'm only creating the skeleton for it at the moment, once the terminal functions I can do Request/Response.
The things that may change in the display are:
* The main window area (just a big DIV like a terminal window)
* The command prompt
* The line the user types on
* A status bar/box (notification of what's happening on the ajax side of things)
I've already broken my code into several classes on the client side like this:
* Input - exists as a single object, handles all user input, contains a buffer object
* Output - Handles the display (aspects shown above)
* Buffer - Keeps a log of command keyed by the user and allows iterating backwards and forward through them by pressing UP and DOWN (like a terminal)
I'm getting a bix mixed up with what's generating output however. For example, when an item is addded to the buffer, the buffer wants to update the diaply to remove the line of text the user typed so it generates a new Output(), sets the buffer contents empty then flushes it itself.
Now similarly, when the user presses UP or DOWN, Input() asks Buffer() to get the next or previous item and then Input() generates a new Output(), sets the buffer contents to the relevant item and calls flush().
Can I centralise my output any more than this? It seems I'm going to be genrating new Output() in several areas, although the specific logic for this output will be dealt with by the Output() class itself.
Input()
Code: Select all
/**
* @fileoverview Contains the Input handler class for processing what is typed.
* The input handler reads user input and either generate a particular output
* directly, or makes a new Request() to send to the server.
*
* @author Chris Corbyn <chris@w3style.co.uk>
* @version 0.1
*/
/**
* Constructor for the Input handler
* @class Input
* @constructor
*/
function Input()
{
/**
* The DOM element where the user is typing input
* @type Element
*/
var DOMElement = document.getElementById('phpmyajax_input');
/**
* The buffer keeps a log of what the user types so they can press
* UP and DOWN to repeat previous commands.
* @type Buffer
*/
var buffer = new Buffer();
/**
* Maps ascii key codes to callback functions
* @type Array
*/
var keyHandles = new Array();
keyHandles[38] = bufferGoBack; //UP arrow
keyHandles[40] = bufferGoForward; //DOWN arrow
keyHandles[13] = executeCommand; //ENTER key
/**
* The type of object this is (used for identification)
* @return {string} type
*/
this.getType = function()
{
return 'Input';
}
/**
* Takes a string of user input and either stores it as a partially completed string,
* makes a new request, or instantly asks Output() to do something.
* @param {int} command
*/
function process(str)
{
if (str == '\\clear')
{
buffer.clear();
}
else if (str.length) buffer.store(str);
}
/**
* Reads every single keypress from the user and fires actions
* upon certain keypresses
* @param {event} keypress
*/
this.readKey = function(e)
{
e = e || window.event;
if (typeof keyHandles[e.keyCode] != 'undefined')
{
callback = keyHandles[e.keyCode];
callback();
}
}
/**
* Work backwords through the buffer and get the previous command
* @throws Output
*/
function bufferGoBack()
{
if (!buffer.length) return;
if (buffer.prev())
{
var output = new Output();
output.setItem(buffer.getItem(), buffer.getType());
output.flush();
}
}
/**
* Work backwords through the buffer and get the previous command
* @throws Output
*/
function bufferGoForward()
{
if (!buffer.length) return;
if (buffer.next())
{
var output = new Output();
output.setItem(buffer.getItem(), buffer.getType());
output.flush();
}
}
/**
* Trigger the process() method
*/
function executeCommand()
{
process(DOMElement.value);
}
}
Code: Select all
/**
* @fileoverview Contains the command buffer class.
* The command buffer tracks what the user has typed and offers iterators to
* move backwards and forwards through the entries.
*
* @author Chris Corbyn <chris@w3style.co.uk>
* @version 0.1
*/
/**
* Constructor for the Buffer
* @class Buffer
* @constructor
*/
function Buffer()
{
/**
* Stack of entries in the buffer
* @type Array
*/
var items = new Array();
/**
* The last thing that was stored in the buffer
* @type string
*/
this.lastItem = null;
/**
* The current position in the entries
* @type int
*/
this.position = 0;
/**
* The size of the list of entries
* @type int
*/
this.length = 0;
/**
* Used for identification
* @return {string} type
*/
this.getType = function()
{
return 'Buffer';
}
/**
* Log an entry into the buffer
* @param {string} entry
*/
this.store = function(str)
{
if (str != this.lastItem && str.charAt(0) != '\\')
{
items[this.length] = str;
this.lastItem = str;
this.length++;
this.position = this.length; //Back to end
}
var output = new Output();
output.setItem('', this.getType());
output.flush();
}
/**
* Empty the buffer contents
*/
this.clear = function()
{
for (var i in items)
{
delete items[i];
}
this.lastItem = null;
this.length = 0;
this.position = 0;
var output = new Output();
output.setItem('', this.getType());
output.flush();
}
/**
* Retreive the item from the buffer at the current position
* @return {string} entry
*/
this.getItem = function()
{
return items[this.position];
}
/**
* Iterate forwards
*/
this.next = function()
{
if (this.position < this.length-1)
{
this.position++;
return true;
}
return false;
}
/**
* Iterate backwards
*/
this.prev = function()
{
if (this.position > 0)
{
this.position--;
return true;
}
return false;
}
}
Code: Select all
/**
* @fileoverview Contains the Output handler class for displaying data.
* The output handler is passed an item or several items and displays them
* when flush() is called.
*
* @author Chris Corbyn <chris@w3style.co.uk>
* @version 0.1
*/
/**
* Constructor for the Input handler
* @class Output
* @constructor
*/
function Output()
{
/**
* There are certain types of output (screen, input box, status bar, prompt)
* @type array
*/
var items = new Array();
/**
* The node where the user is typing
* @type element
*/
var DOMInputElement = document.getElementById('phpmyajax_input');
/**
* Add something to output
* @param {string} item
* @param {string} item type
*/
this.setItem = function(strItem, type)
{
items[type] = strItem;
}
/**
* Flush the output to the display
*/
this.flush = function()
{
for (var t in items)
{
switch(t)
{
case 'Buffer':
updateBuffer(items[t]);
break;
}
}
}
/**
* Change the contents of the input buffer
* @param {string}
*/
function updateBuffer(str)
{
DOMInputElement.value = str;
DOMInputElement.focus();
}
}
EDIT | There's a test page up at http://www.w3style.co.uk/~d11wtq/PhpMyAjax/ if you're wondering what on earth I'm talking about. I'm only creating the skeleton for it at the moment, once the terminal functions I can do Request/Response.