Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.js -crlf
*.coffee -crlf
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
spec/*.spec.js
spec/*.spec.js
.c9
180 changes: 111 additions & 69 deletions dist/backbone.eventstreams.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,121 @@
(function() {
var __slice = [].slice;
var Backbone, Bacon, init,
__slice = [].slice;

Backbone.EventStream = {
listenToEventStream: function(eventTarget, eventName, eventTransformer) {
var listener;
if (eventTransformer == null) {
eventTransformer = _.identity;
init = function(Bacon, Backbone) {
var ReactiveView, _undelegate;
Backbone.EventStream = {
listenToEventStream: function(eventTarget, eventName, eventTransformer) {
var listener;
if (eventTransformer == null) {
eventTransformer = _.identity;
}
listener = this;
return Bacon.fromBinder(function(sink) {
var handler, unbind;
handler = function() {
var args, reply;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
reply = sink(new Bacon.Next(eventTransformer.apply(null, args)));
if (reply === Bacon.noMore) {
return unbind();
}
};
unbind = function() {
return listener.stopListening(eventTarget, eventName, handler);
};
listener.listenTo(eventTarget, eventName, handler);
return unbind;
});
},
asEventStream: function(eventName, eventTransformer) {
var eventTarget;
if (eventTransformer == null) {
eventTransformer = _.identity;
}
eventTarget = this;
return Bacon.fromBinder(function(sink) {
var handler, unbind;
handler = function() {
var args, reply;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
reply = sink(new Bacon.Next(eventTransformer.apply(null, args)));
if (reply === Bacon.noMore) {
return unbind();
}
};
unbind = function() {
return eventTarget.off(eventName, handler);
};
eventTarget.on(eventName, handler, this);
return unbind;
});
}
listener = this;
return new Bacon.EventStream(function(sink) {
var handler, unbind;
handler = function() {
var args, reply;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
reply = sink(new Bacon.Next(eventTransformer.apply(null, args)));
if (reply === Bacon.noMore) {
return unbind();
}
};
_.extend(Backbone, Backbone.EventStream);
_.extend(Backbone.Model.prototype, Backbone.EventStream);
_.extend(Backbone.Collection.prototype, Backbone.EventStream);
_.extend(Backbone.Router.prototype, Backbone.EventStream);
_.extend(Backbone.History.prototype, Backbone.EventStream);
_.extend(Backbone.View.prototype, Backbone.EventStream);
Backbone.BaconProperty = {
toModel: function() {
var handler, model;
model = new Backbone.Model(this.take(1));
handler = function(value) {
return model.set(value);
};
unbind = function() {
return listener.stopListening(eventTarget, eventName, handler);
};
listener.listenTo(eventTarget, eventName, handler);
return unbind;
});
},
asEventStream: function(eventName, eventTransformer) {
var eventTarget;
if (eventTransformer == null) {
eventTransformer = _.identity;
this.onValue(handler);
return model;
}
eventTarget = this;
return new Bacon.EventStream(function(sink) {
var handler, unbind;
handler = function() {
var args, reply;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
reply = sink(new Bacon.Next(eventTransformer.apply(null, args)));
if (reply === Bacon.noMore) {
return unbind();
}
};
unbind = function() {
return eventTarget.off(eventName, handler);
};
eventTarget.on(eventName, handler, this);
return unbind;
});
}
};

_.extend(Backbone, Backbone.EventStream);

_.extend(Backbone.Model.prototype, Backbone.EventStream);

_.extend(Backbone.Collection.prototype, Backbone.EventStream);

_.extend(Backbone.Router.prototype, Backbone.EventStream);

_.extend(Backbone.History.prototype, Backbone.EventStream);

_.extend(Backbone.View.prototype, Backbone.EventStream);

Backbone.BaconProperty = {
toModel: function() {
var handler, model;
model = new Backbone.Model(this.take(1));
handler = function(value) {
return model.set(value);
};
_.extend(Bacon.Property.prototype, Backbone.BaconProperty);
(function(proto) {
return proto.matches = proto.matchesSelector = proto.matches || proto.matchesSelector || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || function(selector) {
var i, nodes;
nodes = (this.parentNode || this.document).querySelectorAll(selector);
i = -1;
while (nodes[++i] && nodes[i] !== this) {}
return !!nodes[i];
};
this.onValue(handler);
return model;
}
})(Element.prototype);
_undelegate = Backbone.View.prototype.undelegateEvents;
ReactiveView = {
onEvent: function(eventName, selector, eventTransformer) {
var stream, _ref;
if ((_ref = this.bus) == null) {
this.bus = new Bacon.Bus();
}
stream = this.$el.asEventStream(eventName, selector, eventTransformer);
this.bus.plug(stream);
return this.bus.filter(function(x) {
return x instanceof $.Event && x.type === eventName && (!(selector != null) || x.currentTarget.matches(selector));
});
},
undelegateEvents: function() {
var args, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
_undelegate.apply(this, args);
if ((_ref = this.bus) != null) {
_ref.end();
}
return this;
}
};
_.extend(Backbone.View.prototype, ReactiveView);
return Backbone;
};

_.extend(Bacon.Property.prototype, Backbone.BaconProperty);
if (typeof module !== "undefined" && module !== null) {
Bacon = require("baconjs");
Backbone = require("backbone");
module.exports = init(Bacon, Backbone);
} else {
if (typeof define === "function" && define.amd) {
define(["bacon", "backbone"], init);
} else {
init(this.Bacon, this.Backbone);
}
}

}).call(this);
6 changes: 3 additions & 3 deletions dist/backbone.eventstreams.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions grunt.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ module.exports = function(grunt) {
grunt.registerTask('test', ['coffee', 'jasmine']);

};

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Backbone.EventStreams",
"version": "0.1.0",
"main": "dist/bacbone.eventstreams.js",
"main": "dist/backbone.eventstreams.js",
"description": "Backbone events as Bacon.js EventStreams",
"homepage": "https://github.com/pyykkis/Backbone.EventStreams",
"repository": {
Expand Down
130 changes: 88 additions & 42 deletions src/backbone.eventstreams.coffee
Original file line number Diff line number Diff line change
@@ -1,42 +1,88 @@
Backbone.EventStream =
listenToEventStream: (eventTarget, eventName, eventTransformer = _.identity) ->
listener = this
new Bacon.EventStream (sink) ->
handler = (args...) ->
reply = sink(new Bacon.Next(eventTransformer args...))
if reply == Bacon.noMore
unbind()

unbind = -> listener.stopListening(eventTarget, eventName, handler)
listener.listenTo(eventTarget, eventName, handler)
unbind

asEventStream: (eventName, eventTransformer = _.identity) ->
eventTarget = this
new Bacon.EventStream (sink) ->
handler = (args...) ->
reply = sink(new Bacon.Next(eventTransformer args...))
if reply == Bacon.noMore
unbind()

unbind = -> eventTarget.off(eventName, handler)
eventTarget.on(eventName, handler, this)
unbind

_.extend Backbone, Backbone.EventStream
_.extend Backbone.Model.prototype, Backbone.EventStream
_.extend Backbone.Collection.prototype, Backbone.EventStream
_.extend Backbone.Router.prototype, Backbone.EventStream
_.extend Backbone.History.prototype, Backbone.EventStream
_.extend Backbone.View.prototype, Backbone.EventStream

Backbone.BaconProperty =
toModel: ->
model = new Backbone.Model(this.take(1))
handler = (value) ->
model.set value
this.onValue(handler)
model


_.extend Bacon.Property.prototype, Backbone.BaconProperty
init = (Bacon, Backbone) ->
Backbone.EventStream =
listenToEventStream: (eventTarget, eventName, eventTransformer = _.identity) ->
listener = this
Bacon.fromBinder (sink) ->
handler = (args...) ->
reply = sink(new Bacon.Next(eventTransformer args...))
if reply == Bacon.noMore
unbind()

unbind = -> listener.stopListening(eventTarget, eventName, handler)
listener.listenTo(eventTarget, eventName, handler)
unbind

asEventStream: (eventName, eventTransformer = _.identity) ->
eventTarget = this
Bacon.fromBinder (sink) ->
handler = (args...) ->
reply = sink(new Bacon.Next(eventTransformer args...))
if reply == Bacon.noMore
unbind()

unbind = -> eventTarget.off(eventName, handler)
eventTarget.on(eventName, handler, this)
unbind

_.extend Backbone, Backbone.EventStream
_.extend Backbone.Model.prototype, Backbone.EventStream
_.extend Backbone.Collection.prototype, Backbone.EventStream
_.extend Backbone.Router.prototype, Backbone.EventStream
_.extend Backbone.History.prototype, Backbone.EventStream
_.extend Backbone.View.prototype, Backbone.EventStream

Backbone.BaconProperty =
toModel: ->
model = new Backbone.Model(this.take(1))
handler = (value) ->
model.set value
this.onValue(handler)
model


_.extend Bacon.Property.prototype, Backbone.BaconProperty

((proto) ->
proto.matches = proto.matchesSelector = proto.matches ||
proto.matchesSelector ||
proto.webkitMatchesSelector ||
proto.mozMatchesSelector ||
proto.msMatchesSelector ||
proto.oMatchesSelector ||
(selector) ->
nodes = (@parentNode || @document).querySelectorAll(selector)
i = -1
while (nodes[++i] && nodes[i] isnt @) then
!!nodes[i]
)(Element::)


_undelegate = Backbone.View::undelegateEvents

ReactiveView =
onEvent: (eventName, selector, eventTransformer) ->
@bus ?= new Bacon.Bus()
stream = @$el.asEventStream(eventName, selector, eventTransformer)
@bus.plug stream
@bus.filter (x) ->
x instanceof $.Event &&
x.type is eventName &&
(!selector? || x.currentTarget.matches(selector))

undelegateEvents: (args...) ->
_undelegate.apply(@, args)
@bus?.end()
@

_.extend Backbone.View.prototype, ReactiveView
Backbone

if module?
Bacon = require("baconjs")
Backbone = require("backbone")
module.exports = init(Bacon, Backbone)
else
if typeof define == "function" and define.amd
define ["bacon", "backbone"], init
else
init(this.Bacon, this.Backbone)