All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tajin.tajin.event.js Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2011 Ovea 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*jslint white: true, browser: true, devel: false, indent: 4, plusplus: true */
/*global window, jQuery, console*/
(function (w, $) {
    "use strict";
    var EventModule = function () {
        var e_uid = 1,
            e_cb_uid = 1,
            events = {},
            t_add = function (opts) {
                if ($.type(opts) === 'string') {
                    opts = {
                        id: opts
                    };
                }
                if (!$.isPlainObject(opts)) {
                    opts = {};
                }
                if ($.type(opts.id) !== 'string') {
                    opts.id = 'anon-' + e_uid++;
                }
                if (events[opts.id]) {
                    throw new Error('Duplicate event: ' + opts.id);
                }
                var listeners = [];
                events[opts.id] = {
                    context: opts.context,
                    id: opts.id,
                    stateful: opts.state || opts.stateful || false,
                    remote: opts.remote || false,
                    data: undefined,
                    time: undefined,
                    toString: function () {
                        return 'Event(id=' + this.id + ', stateful=' + this.stateful + ', remote=' + this.remote + ', time=' + this.time + ')';
                    },
                    fire: function (data) {
                        if (this.stateful && this.data !== undefined) {
                            throw new Error('fire() cannot be called again on a stateful event. If needed, reset() must be called before or stateful flag must be removed.');
                        }
                        if (arguments.length > 1) {
                            throw new Error('fire() only accept at most one argument');
                        }
                        if (data === undefined) {
                            data = null;
                        }
                        if (this.stateful) {
                            this.data = data;
                        }
                        var i;
                        this.time = (new Date()).getTime();
                        for (i = 0; i < listeners.length; i++) {
                            listeners[i].call(this, data);
                        }
                    },
                    listen: function (cb) {
                        var added = false;
                        if ($.isFunction(cb)) {
                            if (!cb.tajin_cb_uid) {
                                cb.tajin_cb_uid = e_cb_uid++;
                                listeners.push(cb);
                                added = true;
                            } else if (!$.grep(listeners,function (l) {
                                return l.tajin_cb_uid === cb.tajin_cb_uid;
                            }).length) {
                                listeners.push(cb);
                                added = true;
                            }
                            if (added && this.stateful && this.data !== undefined) {
                                cb.call(this, this.data);
                            }
                        }
                        return added;
                    },
                    once: function (cb) {
                        if ($.isFunction(cb)) {
                            var self = this, f = function (data) {
                                self.remove(f);
                                cb.call(this, data);
                            };
                            self.listen(f);
                        }
                    },
                    remove: function (cb) {
                        if (cb.tajin_cb_uid) {
                            var i;
                            for (i = 0; i < listeners.length; i++) {
                                if (listeners[i].tajin_cb_uid === cb.tajin_cb_uid) {
                                    listeners.splice(i, 1);
                                    return true;
                                }
                            }
                        }
                        return false;
                    },
                    destroy: function () {
                        this.reset();
                        listeners = [];
                        delete events[this.id];
                    },
                    reset: function () {
                        this.data = undefined;
                        this.time = undefined;
                    }
                };
                return events[opts.id];
            },
            toEventList = function (events) {
                var syncf = function (call, cb) {
                    var m = events.length, i, args = [], triggered = {}, f = function (idx) {
                        events[i][call](function (arg) {
                            args[idx] = arg;
                            triggered[idx] = true;
                            var j;
                            for (j = 0; j < m; j++) {
                                if (!triggered[j]) {
                                    return;
                                }
                            }
                            cb.apply(events, args);
                        });
                    };
                    for (i = 0; i < m; i++) {
                        f(i);
                    }
                };
                $.extend(events, {
                    toString: function () {
                        var s = 'EventList(', i;
                        for (i = 0; i < events.length; i++) {
                            s += events[i].id + (i === events.length - 1 ? '' : ',');
                        }
                        return s + ')';
                    },
                    fire: function (data) {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].fire(data);
                        }
                    },
                    listen: function (cb) {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].listen(cb);
                        }
                    },
                    once: function (cb) {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].once(cb);
                        }
                    },
                    remove: function (cb) {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].remove(cb);
                        }
                    },
                    destroy: function () {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].destroy();
                        }
                    },
                    reset: function () {
                        var i;
                        for (i = 0; i < events.length; i++) {
                            events[i].reset();
                        }
                    },
                    sync: function (cb) {
                        syncf('listen', cb);
                    },
                    syncOnce: function (cb) {
                        syncf('once', cb);
                    }
                });
                return events;
            };
        this.name = 'event';
        this.oninstall = function (tajin) {
            var ready = t_add({
                id: 'tajin/ready',
                state: true
            });
            tajin.ready(function () {
                ready.fire();
            });
        };
        this.onconfigure = function (next, opts, tajin) {
            //TODO MATHIEU - add remote features here with cometd if opts.remote
            next();
        };
        this.exports = {
            get: function (id, opts) {
                if (!events[id]) {
                    this.add($.extend({}, opts, {
                        id: id
                    }));
                }
                return events[id];
            },
            getAll: function () {
                var i, m, events = [], g_opts = arguments[arguments.length - 1];
                if (!$.isPlainObject(g_opts)) {
                    g_opts = undefined;
                }
                for (i = 0, m = g_opts ? arguments.length - 1 : arguments.length; i < m; i++) {
                    events.push(this.get(arguments[i], g_opts));
                }
                return toEventList(events);
            },
            has: function (id) {
                return !!events[id];
            },
            addAll: function () {
                if (arguments.length <= 1) {
                    return t_add.apply(this, arguments);
                }
                var i, m, o, events = [], g_opts = arguments[arguments.length - 1];
                if (!$.isPlainObject(g_opts)) {
                    g_opts = undefined;
                }
                for (i = 0, m = g_opts ? arguments.length - 1 : arguments.length; i < m; i++) {
                    o = arguments[i];
                    if (typeof o === 'string') {
                        o = {
                            id: o
                        };
                    }
                    events.push(t_add($.extend({}, g_opts || {}, o)));
                }
                return toEventList(events);
            },
            add: t_add,
            reset: function (id) {
                this.get(id).reset();
            },
            destroy: function (id) {
                this.get(id).destroy();
            }
        };
    };
    w.tajin.install(new EventModule());
}(window, jQuery));




© 2015 - 2024 Weber Informatics LLC | Privacy Policy