Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 5030c46

Browse files
committed
Support binding to events
R=arv BUG= Review URL: https://codereview.appspot.com/45020044
1 parent 2f909f6 commit 5030c46

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/NodeBind.js

+39
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,46 @@
133133
};
134134
}
135135

136+
function isEventHandler(name) {
137+
return name[0] === 'o' &&
138+
name[1] === 'n' &&
139+
name[2] === '-';
140+
}
141+
142+
function eventBinding(el, name, value, oneTime) {
143+
var eventType = name.substring(3);
144+
if (oneTime) {
145+
el.addEventListener(eventType, value);
146+
return;
147+
}
148+
149+
var observable = value;
150+
unbind(el, name);
151+
function eventHandler() {
152+
var fn = observable.discardChanges();
153+
fn.apply(this, arguments);
154+
}
155+
156+
el.addEventListener(eventType, eventHandler);
157+
158+
var capturedClose = observable.close;
159+
observable.close = function() {
160+
if (!capturedClose)
161+
return;
162+
el.removeEventListener(eventType, eventHandler);
163+
164+
observable.close = capturedClose;
165+
observable.close();
166+
capturedClose = undefined;
167+
}
168+
169+
return el.bindings[name] = observable;
170+
}
171+
136172
Element.prototype.bind = function(name, value, oneTime) {
173+
if (isEventHandler(name))
174+
return eventBinding(this, name, value, oneTime);
175+
137176
var conditional = name[name.length - 1] == '?';
138177
if (conditional) {
139178
this.removeAttribute(name);

tests/tests.js

+60
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,66 @@ suite('Element attribute bindings', function() {
198198
});
199199
});
200200

201+
suite('Element event bindings', function() {
202+
test('Basic', function() {
203+
var element = testDiv.appendChild(document.createElement('div'));
204+
var fooCount = 0;
205+
var barCount = 0;
206+
var model = {
207+
fooHandler: function() {
208+
fooCount++;
209+
}
210+
};
211+
212+
var binding = element.bind('on-foo', new PathObserver(model, 'fooHandler'));
213+
Platform.performMicrotaskCheckpoint();
214+
dispatchEvent('foo', element);
215+
assert.strictEqual(fooCount, 1);
216+
assert.strictEqual(barCount, 0);
217+
218+
model.fooHandler = function() {
219+
barCount++;
220+
}
221+
222+
Platform.performMicrotaskCheckpoint();
223+
dispatchEvent('foo', element);
224+
assert.strictEqual(fooCount, 1);
225+
assert.strictEqual(barCount, 1);
226+
227+
binding.close();
228+
dispatchEvent('foo', element);
229+
assert.strictEqual(fooCount, 1);
230+
assert.strictEqual(barCount, 1);
231+
232+
});
233+
234+
test('Basic - oneTime', function() {
235+
var element = testDiv.appendChild(document.createElement('div'));
236+
var fooCount = 0;
237+
var barCount = 0;
238+
var model = {
239+
fooHandler: function() {
240+
fooCount++;
241+
}
242+
};
243+
244+
var binding = element.bind('on-foo', model.fooHandler, true);
245+
Platform.performMicrotaskCheckpoint();
246+
dispatchEvent('foo', element);
247+
assert.strictEqual(fooCount, 1);
248+
assert.strictEqual(barCount, 0);
249+
250+
model.fooHandler = function() {
251+
barCount++;
252+
}
253+
254+
Platform.performMicrotaskCheckpoint();
255+
dispatchEvent('foo', element);
256+
assert.strictEqual(fooCount, 2);
257+
assert.strictEqual(barCount, 0);
258+
});
259+
});
260+
201261
suite('Form Element Bindings', function() {
202262

203263
setup(doSetup);

0 commit comments

Comments
 (0)