diff options
Diffstat (limited to 'webchat/public')
| -rw-r--r-- | webchat/public/client.js | 123 | ||||
| -rw-r--r-- | webchat/public/functions.js | 54 | ||||
| -rw-r--r-- | webchat/public/krebs.png | bin | 956 -> 2583 bytes | |||
| -rw-r--r-- | webchat/public/reset.css | 23 | ||||
| -rw-r--r-- | webchat/public/rpc.js | 99 | ||||
| -rw-r--r-- | webchat/public/sockjs_client_transport.js | 25 | 
6 files changed, 242 insertions, 82 deletions
| diff --git a/webchat/public/client.js b/webchat/public/client.js index ca71b537..54ccfe34 100644 --- a/webchat/public/client.js +++ b/webchat/public/client.js @@ -1,34 +1,50 @@ -function replaceURLWithHTMLLinks (text) { -  var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; -  return text.replace(exp,"<a href='$1'>$1</a>"); -} -function setMaybeNick (input) { -  var match = /^\/nick\s+(.+)$/.exec(input); -  if (match) { -    nick = match[1]; -    $('#nick').html(nick); -  } -} +var settings = {} +settings.sock = new SockJS('/echo'); +settings.waiting_callbacks = {} -function getCurTime () { -  date = new Date; -  h = date.getHours(); -  if(h<10) -  { -    h = "0"+h; -  } -  m = date.getMinutes(); -  if(m<10) -  { -    m = "0"+m; -  } -  s = date.getSeconds(); -  if(s<10) -  { -    s = "0"+s; +var transport = make_sockjs_client_transport(settings.sock) +settings.rpc = new RPC(transport) + +settings.rpc.register('msg', {type: 'string', nick: 'string', msg: 'string'}, function(params, callback) { +  var safe_message = $('<div/>').text(params.msg).html(); +  safe_message = replaceURLWithHTMLLinks(safe_message); +  var safe_from = $('<div/>').text(params.nick).html(); +  chatboxAppend(safe_from, safe_message, 'web_msg') +  return callback(null) +}) +settings.rpc.register('nick', {type: 'string', newnick: 'string', oldnick: 'string'}, function(params, callback) { +  var safe_oldnick = $('<div/>').text(params.oldnick).html(); +  var safe_newnick = $('<div/>').text(params.newnick).html(); +  var safe_type = $('<div/>').text(params.type).html(); +  if (safe_oldnick === settings.nick){ +    settings.nick = safe_newnick +    $('#nick').html(settings.nick)    } -  return ''+h+':'+m+':'+s; -}; +  $(getNicklistElement(safe_oldnick,safe_type)).remove(); +  $('#nicklist').append('<div class="'+safe_type+'_name">' + safe_newnick + '</div>') ; +  chatboxAppend(safe_oldnick, 'is now known as ' + safe_newnick, 'nick'); +  return callback(null) +}) +settings.rpc.register('your_nick', {nick: 'string'}, function(params, callback) { +  var safe_nick = $('<div/>').text(params.nick).html(); +  settings.nick = safe_nick +  $('#nick').html(settings.nick) +  return callback(null) +}) +settings.rpc.register('join', {type: 'string', nick: 'string'}, function(params, callback) { +  var safe_nick = $('<div/>').text(params.nick).html(); +  var safe_type = $('<div/>').text(params.type).html(); +  $('#nicklist').append('<div class="'+safe_type+'_name">' + safe_nick + '</div>') ; +  chatboxAppend(safe_nick, 'has joined'); +  return callback(null) +}) +settings.rpc.register('part', {type: 'string', nick: 'string'}, function(params, callback) { +  var safe_nick = $('<div/>').text(params.nick).html(); +  var safe_type = $('<div/>').text(params.type).html(); +  $(getNicklistElement(safe_nick,safe_type)).remove(); +  chatboxAppend(safe_nick, 'has parted'); +  return callback(null) +})  $(function updateTime () {    $('#time').html(getCurTime()); @@ -36,59 +52,18 @@ $(function updateTime () {    return true;  }); -var nick; - -$(function connect() { -  sock = new SockJS('/echo'); - -  sock.onopen = function() { -    console.log('open'); -    sock.send('open'); -  }; -  sock.onmessage = function(e) { -    console.log('message', e.data); -    try { -      var object = JSON.parse(e.data); -      console.log(object.message); -      var safe_message = $('<div/>').text(object.message).html(); -      safe_message = replaceURLWithHTMLLinks(safe_message); -      var safe_from = $('<div/>').text(object.from).html(); -      $('<tr><td class="chat_date">'+getCurTime()+'</td><td class="chat_from">'+safe_from+'</td><td class="chat_msg">'+safe_message+'</td></tr>').insertBefore('#foot'); -      var elem = document.getElementById('chatter'); -      elem.scrollTop = elem.scrollHeight; - -    } catch (error) { -      console.log(error); -    } -  }; -  sock.onclose = function(event) { -    console.log('close'); -    switch (event.code) { -      case 1006: //abnormal closure -        return setTimeout(connect, 1000); -    }; -  }; - -});  $(function() {    $('#input').keydown(function(e) {      if (e.keyCode === 13) {        e.preventDefault();        e.stopPropagation();        e.stopImmediatePropagation(); -      setMaybeNick($('#input').val()); -      var sendObj = { -        message: $('#input').val(), -      }; - -      if (typeof nick === 'string') { -        sendObj.nick = nick; -      }; +      var input = ($('#input').val()); +      $('#input').val('') -      sock.send(JSON.stringify(sendObj)); -      $('#input').val(''); -      return; +      var command = inputParser(input) +      return (commands[command.method] || commands.badcommand)(settings, command.params)      }    }); diff --git a/webchat/public/functions.js b/webchat/public/functions.js new file mode 100644 index 00000000..781fafce --- /dev/null +++ b/webchat/public/functions.js @@ -0,0 +1,54 @@ +function inputParser (str) { +  var match = /^\/([a-z]+)(?:\s+(.*\S))?\s*$/.exec(str) +  if (match) { +    return { method: match[1], params: match[2] } +  } else { +    return { method: 'msg', params: str } +  } +} + +function replaceURLWithHTMLLinks (text) { +  var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; +  return text.replace(exp,"<a class=chat_link href='$1'>$1</a>"); +} + +function getNicklistElement(name, type) {  +  var el; +  $('.'+type+'_name').each(function (i,e) { +    if (e.innerHTML === name) { +      if (typeof el !== 'undefined') { +        throw new Error('duplicate name: ' + name); +      }; +      el = e; +    }; +  }); +  return el; +} + +function chatboxAppend (chat_from, chat_msg, type) { +  type = type||'msg' +  $('<tr><td class="date '+type+'_date">'+getCurTime()+'</td><td class="from '+type+'_from">'+chat_from+'</td><td class="msg '+type+'_msg">'+chat_msg+'</td></tr>').insertBefore('#foot'); + +  var elem = document.getElementById('chatter'); +  elem.scrollTop = elem.scrollHeight; +}; + +function getCurTime () { +  date = new Date; +  h = date.getHours(); +  if(h<10) +  { +    h = "0"+h; +  } +  m = date.getMinutes(); +  if(m<10) +  { +    m = "0"+m; +  } +  s = date.getSeconds(); +  if(s<10) +  { +    s = "0"+s; +  } +  return ''+h+':'+m+':'+s; +}; diff --git a/webchat/public/krebs.png b/webchat/public/krebs.pngBinary files differ index 263d5b1c..5762e7f4 100644 --- a/webchat/public/krebs.png +++ b/webchat/public/krebs.png diff --git a/webchat/public/reset.css b/webchat/public/reset.css index 65f68058..d369bc86 100644 --- a/webchat/public/reset.css +++ b/webchat/public/reset.css @@ -21,7 +21,6 @@ time, mark, audio, video {    border: 0;    font-size: 100%;    font: inherit; -  font-family: monospace;    vertical-align: baseline;  }  /* HTML5 display-role reset for older browsers */ @@ -33,6 +32,7 @@ body {    line-height: 1;    background-color: black;    color: white; +  font-family: monospace;  }  ol, ul {    list-style: none; @@ -54,17 +54,18 @@ q:before, q:after {  }  #input{    width: 100%; -  background-color: #555555; +  background-color: #221111;    border: 1px solid black;    color: white;  } -.chat_from { +.from {    color:grey;    font-weight: bold;    text-align: right;    font-size:12px; +  white-space: nowrap;  } -.chat_from:after { +.from:after {    content: ":";    padding-right: 6px;  } @@ -87,16 +88,16 @@ q:before, q:after {  }  .chat_date,.chat_from,.chat_msg{  } -.chat_msg{ +.msg{    width: 100%;  }  a {    color: red;  } -.chat_date { +.date {    color: green;  } -.chat_date:after { +.date:after {    content: "";    padding-right: 4px;  } @@ -116,4 +117,10 @@ a {    font-size: 14px;    position: absolute;    bottom: 5px; -}
\ No newline at end of file +} +.join_msg { +  color: #00FF00; +} +.quit_msg { +  color: #FF0000; +} diff --git a/webchat/public/rpc.js b/webchat/public/rpc.js new file mode 100644 index 00000000..8e911e1d --- /dev/null +++ b/webchat/public/rpc.js @@ -0,0 +1,99 @@ +try { +  module.exports = RPC +} +catch(e){ +} + +function RPC (transport) { +  this._id = 0 +  this._waiting_callbacks = {} +  this._methods = {} +  this._transport = transport + +  transport.onmessage = this.onmessage.bind(this) +} + +RPC.prototype.register = function (method, params, callback) { +  this._methods[method] = callback +} + +RPC.prototype.send = function (method, params, callback) { +  var message = { +    method: method, +    params: params, +  } +  if (callback) { +    var id = ++this._id +    this._waiting_callbacks[id] = callback +    message.id = id +  } +  return this._transport.send(message) +} + +function _is_request (message) { +  return typeof message.method === 'string' +} + +function _is_response (message) { +  return message.hasOwnProperty('result') +      || message.hasOwnProperty('error') +} + +RPC.prototype.onmessage = function (message) { +  console.log('RPC message:', message) +  if (_is_request(message)) { +    return this._on_request(message) +  } +  if (_is_response(message)) { +    return this._on_response(message) +  } +  return this._on_bad_message(message) +} + +RPC.prototype._on_request = function (request) { +  var method = this._methods[request.method] || function(){ +    console.log('method not found', request.method) +  } +  var params = request.params +  var id = request.id + +  var transport = this._transport + +  if (typeof id === 'string' || typeof id === 'number' || id === null) { +    return method(params, function (error, result) { +      var response = { +        id: id, +      } +      if (error) { +        response.error = error +      } else { +        response.result = result +      } +      console.log('request:', request, '->', response) +      return transport.send(response) +    }) +  } else { +    return method(params, function (error, result) { +      var response = { +        id: id, +      } +      if (error) { +        response.error = error +      } else { +        response.result = result +      } +      console.log('notification:', request, '->', response) +    }) +  } +} + +RPC.prototype._on_response = function (response) { +  var result = response.result +  var error = response.error +  var id = response.id + +  var callback = this._waiting_callbacks[id] +  delete this._waiting_callbacks[id] + +  return callback(result, error) +} diff --git a/webchat/public/sockjs_client_transport.js b/webchat/public/sockjs_client_transport.js new file mode 100644 index 00000000..a7b76af3 --- /dev/null +++ b/webchat/public/sockjs_client_transport.js @@ -0,0 +1,25 @@ + +function make_sockjs_client_transport (sock) { +  var transport = {} + +  sock.onmessage = function (data) { +    console.log('sockjs parse', data) +    try { +      var message = JSON.parse(data.data) +    } catch (error) { +      return console.log('error', error) +    } +    transport.onmessage(message) +  } + +  transport.send = function (message) { +    try { +      var data = JSON.stringify(message) +    } catch (error) { +      return console.log('sockjs transport send error:', error) +    } +    sock.send(data) +  } + +  return transport +} | 
