megous / ajax-todo-list

Simple "host it yourself" todo list. An example of simple Prototype JS based client side MVC design.

ajax-todo-list / global.js
100644 84 lines (75 sloc) 1.946 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
var X = {};
 
function log(str)
{
  try { console.log(str); } catch(e) { }
}
 
X.Signals =
{
  /** Connect the signal handler.
*
* name: name of the signal
* func: signal handler
* ctx: context in which the signal handler should run (this)
* args...: additional arguments
*
* Example:
* this.name = 'c';
* someobj.connect('changed', function(msg1, msg2) { alert(msg1 + msg2 + this.name); }, this, 'a');
* someobj.emit('changed', 'b');
*
* This would result in message box popping up with a string 'a b c'.
*/
  connect: function(name, func)
  {
    if (!Object.isArray(this._signals))
      this._signals = [];
    if (!Object.isArray(this._signals[name]))
      this._signals[name] = [];
    if (arguments.length > 2)
      func = func.bind.apply(func, $A(arguments).slice(2));
    this._signals[name].push(func);
  },
 
  emit: function(name)
  {
    if (!this._signals_freezed)
    {
      var self = this, args = $A(arguments).slice(1);
      if (!Object.isArray(this._signals))
        this._signals = [];
      return (this._signals[name] || []).collect(function(func) { return func.apply(self, args); });
    }
  },
 
  freezeSignals: function()
  {
    this._signals_freezed = true;
  },
 
  thawSignals: function()
  {
    this._signals_freezed = false;
  }
};
 
X.RPC = Class.create(X.Signals,
{
  initialize: function(url)
  {
    this.url = url;
  },
  
  call: function(method, cb)
  {
    new Ajax.Request(this.url, {
      method: 'post',
      contentType: 'application/json',
      requestHeaders: { Accept: 'application/json' },
      postBody: Object.toJSON({version: '1.1', method: method, params: $A(arguments).slice(2)}),
      onSuccess: this.callFinish.bind(this, cb)
    });
  },
 
  callFinish: function(cb, request)
  {
    var response = request.responseJSON;
    if (response.error)
      this.emit('error', response.error);
    else
      cb(response.result, response.error);
  }
});