Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #1023 from braddunbar/events

Clean up `Backbone.Events`.
  • Loading branch information...
commit 4de073ca142a4ae9c00c01d28c16c1014ece213e 2 parents c8cbde2 + f92fa9a
Jeremy Ashkenas authored February 18, 2012

Showing 1 changed file with 44 additions and 39 deletions. Show diff stats Hide diff stats

  1. 83  backbone.js
83  backbone.js
@@ -82,71 +82,76 @@
82 82
   //
83 83
   Backbone.Events = {
84 84
 
85  
-    // Bind an event, specified by a string name, `ev`, to a `callback`
  85
+    // Bind one or more space separated events, `events`, to a `callback`
86 86
     // function. Passing `"all"` will bind the callback to all events fired.
87 87
     on: function(events, callback, context) {
88  
-      var ev;
  88
+      var calls, event, node, tail, list;
89 89
       if (!callback) return this;
90 90
       events = events.split(/\s+/);
91  
-      var calls = this._callbacks || (this._callbacks = {});
92  
-      while (ev = events.shift()) {
  91
+      calls = this._callbacks || (this._callbacks = {});
  92
+      while (event = events.shift()) {
93 93
         // Create an immutable callback list, allowing traversal during
94 94
         // modification.  The tail is an empty object that will always be used
95 95
         // as the next node.
96  
-        var list  = calls[ev] || (calls[ev] = {});
97  
-        var tail = list.tail || (list.tail = list.next = {});
98  
-        tail.callback = callback;
99  
-        tail.context = context;
100  
-        list.tail = tail.next = {};
  96
+        list = calls[event];
  97
+        node = list ? list.tail : {};
  98
+        node.next = tail = {};
  99
+        node.context = context;
  100
+        node.callback = callback;
  101
+        calls[event] = {tail: tail, next: list ? list.next : node};
101 102
       }
102 103
       return this;
103 104
     },
104 105
 
105 106
     // Remove one or many callbacks. If `context` is null, removes all callbacks
106 107
     // with that function. If `callback` is null, removes all callbacks for the
107  
-    // event. If `ev` is null, removes all bound callbacks for all events.
  108
+    // event. If `events` is null, removes all bound callbacks for all events.
108 109
     off: function(events, callback, context) {
109  
-      var ev, calls, node;
  110
+      var event, calls, node, tail, cb, ctx;
110 111
       if (!events) {
111 112
         delete this._callbacks;
112 113
       } else if (calls = this._callbacks) {
113 114
         events = events.split(/\s+/);
114  
-        while (ev = events.shift()) {
115  
-          node = calls[ev];
116  
-          delete calls[ev];
  115
+        while (event = events.shift()) {
  116
+          node = calls[event];
  117
+          delete calls[event];
117 118
           if (!callback || !node) continue;
118  
-          // Create a new list, omitting the indicated event/context pairs.
119  
-          while ((node = node.next) && node.next) {
120  
-            if (node.callback === callback &&
121  
-              (!context || node.context === context)) continue;
122  
-            this.on(ev, node.callback, node.context);
  119
+          // Create a new list, omitting the indicated callbacks.
  120
+          tail = node.tail;
  121
+          while ((node = node.next) !== tail) {
  122
+            cb = node.callback;
  123
+            ctx = node.context;
  124
+            if (cb !== callback || (context && ctx !== context)) {
  125
+              this.on(event, cb, ctx);
  126
+            }
123 127
           }
124 128
         }
125 129
       }
126 130
       return this;
127 131
     },
128 132
 
129  
-    // Trigger an event, firing all bound callbacks. Callbacks are passed the
130  
-    // same arguments as `trigger` is, apart from the event name.
  133
+    // Trigger one more many events, firing all bound callbacks. Callbacks are
  134
+    // passed the same arguments as `trigger` is, apart from the event name.
131 135
     // Listening for `"all"` passes the true event name as the first argument.
132 136
     trigger: function(events) {
133 137
       var event, node, calls, tail, args, all, rest;
134 138
       if (!(calls = this._callbacks)) return this;
135  
-      all = calls['all'];
136  
-      (events = events.split(/\s+/)).push(null);
137  
-      // Save references to the current heads & tails.
138  
-      while (event = events.shift()) {
139  
-        if (all) events.push({next: all.next, tail: all.tail, event: event});
140  
-        if (!(node = calls[event])) continue;
141  
-        events.push({next: node.next, tail: node.tail});
142  
-      }
143  
-      // Traverse each list, stopping when the saved tail is reached.
  139
+      all = calls.all;
  140
+      events = events.split(/\s+/);
144 141
       rest = slice.call(arguments, 1);
145  
-      while (node = events.pop()) {
146  
-        tail = node.tail;
147  
-        args = node.event ? [node.event].concat(rest) : rest;
148  
-        while ((node = node.next) !== tail) {
149  
-          node.callback.apply(node.context || this, args);
  142
+      while (event = events.shift()) {
  143
+        if (node = calls[event]) {
  144
+          tail = node.tail;
  145
+          while ((node = node.next) !== tail) {
  146
+            node.callback.apply(node.context || this, rest);
  147
+          }
  148
+        }
  149
+        if (node = all) {
  150
+          tail = node.tail;
  151
+          args = [event].concat(rest);
  152
+          while ((node = node.next) !== tail) {
  153
+            node.callback.apply(node.context || this, args);
  154
+          }
150 155
         }
151 156
       }
152 157
       return this;
@@ -766,12 +771,12 @@
766 771
     // Sets need to update their indexes when models change ids. All other
767 772
     // events simply proxy through. "add" and "remove" events that originate
768 773
     // in other collections are ignored.
769  
-    _onModelEvent: function(ev, model, collection, options) {
770  
-      if ((ev == 'add' || ev == 'remove') && collection != this) return;
771  
-      if (ev == 'destroy') {
  774
+    _onModelEvent: function(event, model, collection, options) {
  775
+      if ((event == 'add' || event == 'remove') && collection != this) return;
  776
+      if (event == 'destroy') {
772 777
         this.remove(model, options);
773 778
       }
774  
-      if (model && ev === 'change:' + model.idAttribute) {
  779
+      if (model && event === 'change:' + model.idAttribute) {
775 780
         delete this._byId[model.previous(model.idAttribute)];
776 781
         this._byId[model.id] = model;
777 782
       }

0 notes on commit 4de073c

Please sign in to comment.
Something went wrong with that request. Please try again.