| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /**
- * Durandal 2.1.0 Copyright (c) 2012 Blue Spire Consulting, Inc. All Rights Reserved.
- * Available via the MIT license.
- * see: http://durandaljs.com or https://github.com/BlueSpire/Durandal for details.
- */
- /**
- * Durandal events originate from backbone.js but also combine some ideas from signals.js as well as some additional improvements.
- * Events can be installed into any object and are installed into the `app` module by default for convenient app-wide eventing.
- * @module events
- * @requires system
- */
- define(['durandal/system'], function (system) {
- var eventSplitter = /\s+/;
- var Events = function() { };
- /**
- * Represents an event subscription.
- * @class Subscription
- */
- var Subscription = function(owner, events) {
- this.owner = owner;
- this.events = events;
- };
- /**
- * Attaches a callback to the event subscription.
- * @method then
- * @param {function} callback The callback function to invoke when the event is triggered.
- * @param {object} [context] An object to use as `this` when invoking the `callback`.
- * @chainable
- */
- Subscription.prototype.then = function (callback, context) {
- this.callback = callback || this.callback;
- this.context = context || this.context;
-
- if (!this.callback) {
- return this;
- }
- this.owner.on(this.events, this.callback, this.context);
- return this;
- };
- /**
- * Attaches a callback to the event subscription.
- * @method on
- * @param {function} [callback] The callback function to invoke when the event is triggered. If `callback` is not provided, the previous callback will be re-activated.
- * @param {object} [context] An object to use as `this` when invoking the `callback`.
- * @chainable
- */
- Subscription.prototype.on = Subscription.prototype.then;
- /**
- * Cancels the subscription.
- * @method off
- * @chainable
- */
- Subscription.prototype.off = function () {
- this.owner.off(this.events, this.callback, this.context);
- return this;
- };
- /**
- * Creates an object with eventing capabilities.
- * @class Events
- */
- /**
- * Creates a subscription or registers a callback for the specified event.
- * @method on
- * @param {string} events One or more events, separated by white space.
- * @param {function} [callback] The callback function to invoke when the event is triggered. If `callback` is not provided, a subscription instance is returned.
- * @param {object} [context] An object to use as `this` when invoking the `callback`.
- * @return {Subscription|Events} A subscription is returned if no callback is supplied, otherwise the events object is returned for chaining.
- */
- Events.prototype.on = function(events, callback, context) {
- var calls, event, list;
- if (!callback) {
- return new Subscription(this, events);
- } else {
- calls = this.callbacks || (this.callbacks = {});
- events = events.split(eventSplitter);
- while (event = events.shift()) {
- list = calls[event] || (calls[event] = []);
- list.push(callback, context);
- }
- return this;
- }
- };
- /**
- * Removes the callbacks for the specified events.
- * @method off
- * @param {string} [events] One or more events, separated by white space to turn off. If no events are specified, then the callbacks will be removed.
- * @param {function} [callback] The callback function to remove. If `callback` is not provided, all callbacks for the specified events will be removed.
- * @param {object} [context] The object that was used as `this`. Callbacks with this context will be removed.
- * @chainable
- */
- Events.prototype.off = function(events, callback, context) {
- var event, calls, list, i;
- // No events
- if (!(calls = this.callbacks)) {
- return this;
- }
- //removing all
- if (!(events || callback || context)) {
- delete this.callbacks;
- return this;
- }
- events = events ? events.split(eventSplitter) : system.keys(calls);
- // Loop through the callback list, splicing where appropriate.
- while (event = events.shift()) {
- if (!(list = calls[event]) || !(callback || context)) {
- delete calls[event];
- continue;
- }
- for (i = list.length - 2; i >= 0; i -= 2) {
- if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
- list.splice(i, 2);
- }
- }
- }
- return this;
- };
- /**
- * Triggers the specified events.
- * @method trigger
- * @param {string} [events] One or more events, separated by white space to trigger.
- * @chainable
- */
- Events.prototype.trigger = function(events) {
- var event, calls, list, i, length, args, all, rest;
- if (!(calls = this.callbacks)) {
- return this;
- }
- rest = [];
- events = events.split(eventSplitter);
- for (i = 1, length = arguments.length; i < length; i++) {
- rest[i - 1] = arguments[i];
- }
- // For each event, walk through the list of callbacks twice, first to
- // trigger the event, then to trigger any `"all"` callbacks.
- while (event = events.shift()) {
- // Copy callback lists to prevent modification.
- if (all = calls.all) {
- all = all.slice();
- }
- if (list = calls[event]) {
- list = list.slice();
- }
- // Execute event callbacks.
- if (list) {
- for (i = 0, length = list.length; i < length; i += 2) {
- list[i].apply(list[i + 1] || this, rest);
- }
- }
- // Execute "all" callbacks.
- if (all) {
- args = [event].concat(rest);
- for (i = 0, length = all.length; i < length; i += 2) {
- all[i].apply(all[i + 1] || this, args);
- }
- }
- }
- return this;
- };
- /**
- * Creates a function that will trigger the specified events when called. Simplifies proxying jQuery (or other) events through to the events object.
- * @method proxy
- * @param {string} events One or more events, separated by white space to trigger by invoking the returned function.
- * @return {function} Calling the function will invoke the previously specified events on the events object.
- */
- Events.prototype.proxy = function(events) {
- var that = this;
- return (function(arg) {
- that.trigger(events, arg);
- });
- };
- /**
- * Creates an object with eventing capabilities.
- * @class EventsModule
- * @static
- */
- /**
- * Adds eventing capabilities to the specified object.
- * @method includeIn
- * @param {object} targetObject The object to add eventing capabilities to.
- */
- Events.includeIn = function(targetObject) {
- targetObject.on = Events.prototype.on;
- targetObject.off = Events.prototype.off;
- targetObject.trigger = Events.prototype.trigger;
- targetObject.proxy = Events.prototype.proxy;
- };
- return Events;
- });
|