| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 | // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.// // 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.// ┌────────────────────────────────────────────────────────────┐ \\// │ Eve 0.5.0 - JavaScript Events Library                      │ \\// ├────────────────────────────────────────────────────────────┤ \\// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\// └────────────────────────────────────────────────────────────┘ \\(function (glob) {    var version = "0.5.0",        has = "hasOwnProperty",        separator = /[\.\/]/,        comaseparator = /\s*,\s*/,        wildcard = "*",        fun = function () {},        numsort = function (a, b) {            return a - b;        },        current_event,        stop,        events = {n: {}},        firstDefined = function () {            for (var i = 0, ii = this.length; i < ii; i++) {                if (typeof this[i] != "undefined") {                    return this[i];                }            }        },        lastDefined = function () {            var i = this.length;            while (--i) {                if (typeof this[i] != "undefined") {                    return this[i];                }            }        },        objtos = Object.prototype.toString,        Str = String,        isArray = Array.isArray || function (ar) {            return ar instanceof Array || objtos.call(ar) == "[object Array]";        };    /*\     * eve     [ method ]     * Fires event with given `name`, given scope and other parameters.     > Arguments     - name (string) name of the *event*, dot (`.`) or slash (`/`) separated     - scope (object) context for the event handlers     - varargs (...) the rest of arguments will be sent to event handlers     = (object) array of returned values from the listeners. Array has two methods `.firstDefined()` and `.lastDefined()` to get first or last not `undefined` value.    \*/        eve = function (name, scope) {            var e = events,                oldstop = stop,                args = Array.prototype.slice.call(arguments, 2),                listeners = eve.listeners(name),                z = 0,                f = false,                l,                indexed = [],                queue = {},                out = [],                ce = current_event,                errors = [];            out.firstDefined = firstDefined;            out.lastDefined = lastDefined;            current_event = name;            stop = 0;            for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {                indexed.push(listeners[i].zIndex);                if (listeners[i].zIndex < 0) {                    queue[listeners[i].zIndex] = listeners[i];                }            }            indexed.sort(numsort);            while (indexed[z] < 0) {                l = queue[indexed[z++]];                out.push(l.apply(scope, args));                if (stop) {                    stop = oldstop;                    return out;                }            }            for (i = 0; i < ii; i++) {                l = listeners[i];                if ("zIndex" in l) {                    if (l.zIndex == indexed[z]) {                        out.push(l.apply(scope, args));                        if (stop) {                            break;                        }                        do {                            z++;                            l = queue[indexed[z]];                            l && out.push(l.apply(scope, args));                            if (stop) {                                break;                            }                        } while (l)                    } else {                        queue[l.zIndex] = l;                    }                } else {                    out.push(l.apply(scope, args));                    if (stop) {                        break;                    }                }            }            stop = oldstop;            current_event = ce;            return out;        };        // Undocumented. Debug only.        eve._events = events;    /*\     * eve.listeners     [ method ]     * Internal method which gives you array of all event handlers that will be triggered by the given `name`.     > Arguments     - name (string) name of the event, dot (`.`) or slash (`/`) separated     = (array) array of event handlers    \*/    eve.listeners = function (name) {        var names = isArray(name) ? name : name.split(separator),            e = events,            item,            items,            k,            i,            ii,            j,            jj,            nes,            es = [e],            out = [];        for (i = 0, ii = names.length; i < ii; i++) {            nes = [];            for (j = 0, jj = es.length; j < jj; j++) {                e = es[j].n;                items = [e[names[i]], e[wildcard]];                k = 2;                while (k--) {                    item = items[k];                    if (item) {                        nes.push(item);                        out = out.concat(item.f || []);                    }                }            }            es = nes;        }        return out;    };    /*\     * eve.separator     [ method ]     * If for some reasons you don’t like default separators (`.` or `/`) you can specify yours     * here. Be aware that if you pass a string longer than one character it will be treated as     * a list of characters.     - separator (string) new separator. Empty string resets to default: `.` or `/`.    \*/    eve.separator = function (sep) {        if (sep) {            sep = Str(sep).replace(/(?=[\.\^\]\[\-])/g, "\\");            sep = "[" + sep + "]";            separator = new RegExp(sep);        } else {            separator = /[\.\/]/;        }    };    /*\     * eve.on     [ method ]     **     * Binds given event handler with a given name. You can use wildcards “`*`” for the names:     | eve.on("*.under.*", f);     | eve("mouse.under.floor"); // triggers f     * Use @eve to trigger the listener.     **     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards     - f (function) event handler function     **     - name (array) if you don’t want to use separators, you can use array of strings     - f (function) event handler function     **     = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment.      > Example:     | eve.on("mouse", eatIt)(2);     | eve.on("mouse", scream);     | eve.on("mouse", catchIt)(1);     * This will ensure that `catchIt` function will be called before `eatIt`.     *     * If you want to put your handler before non-indexed handlers, specify a negative value.     * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.    \*/    eve.on = function (name, f) {        if (typeof f != "function") {            return function () {};        }        var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator);        for (var i = 0, ii = names.length; i < ii; i++) {            (function (name) {                var names = isArray(name) ? name : Str(name).split(separator),                    e = events,                    exist;                for (var i = 0, ii = names.length; i < ii; i++) {                    e = e.n;                    e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});                }                e.f = e.f || [];                for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {                    exist = true;                    break;                }                !exist && e.f.push(f);            }(names[i]));        }        return function (zIndex) {            if (+zIndex == +zIndex) {                f.zIndex = +zIndex;            }        };    };    /*\     * eve.f     [ method ]     **     * Returns function that will fire given event with optional arguments.     * Arguments that will be passed to the result function will be also     * concated to the list of final arguments.     | el.onclick = eve.f("click", 1, 2);     | eve.on("click", function (a, b, c) {     |     console.log(a, b, c); // 1, 2, [event object]     | });     > Arguments     - event (string) event name     - varargs (…) and any other arguments     = (function) possible event handler function    \*/    eve.f = function (event) {        var attrs = [].slice.call(arguments, 1);        return function () {            eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));        };    };    /*\     * eve.stop     [ method ]     **     * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.    \*/    eve.stop = function () {        stop = 1;    };    /*\     * eve.nt     [ method ]     **     * Could be used inside event handler to figure out actual name of the event.     **     > Arguments     **     - subname (string) #optional subname of the event     **     = (string) name of the event, if `subname` is not specified     * or     = (boolean) `true`, if current event’s name contains `subname`    \*/    eve.nt = function (subname) {        var cur = isArray(current_event) ? current_event.join(".") : current_event;        if (subname) {            return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(cur);        }        return cur;    };    /*\     * eve.nts     [ method ]     **     * Could be used inside event handler to figure out actual name of the event.     **     **     = (array) names of the event    \*/    eve.nts = function () {        return isArray(current_event) ? current_event : current_event.split(separator);    };    /*\     * eve.off     [ method ]     **     * Removes given function from the list of event listeners assigned to given name.     * If no arguments specified all the events will be cleared.     **     > Arguments     **     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards     - f (function) event handler function    \*/    /*\     * eve.unbind     [ method ]     **     * See @eve.off    \*/    eve.off = eve.unbind = function (name, f) {        if (!name) {            eve._events = events = {n: {}};            return;        }        var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator);        if (names.length > 1) {            for (var i = 0, ii = names.length; i < ii; i++) {                eve.off(names[i], f);            }            return;        }        names = isArray(name) ? name : Str(name).split(separator);        var e,            key,            splice,            i, ii, j, jj,            cur = [events];        for (i = 0, ii = names.length; i < ii; i++) {            for (j = 0; j < cur.length; j += splice.length - 2) {                splice = [j, 1];                e = cur[j].n;                if (names[i] != wildcard) {                    if (e[names[i]]) {                        splice.push(e[names[i]]);                    }                } else {                    for (key in e) if (e[has](key)) {                        splice.push(e[key]);                    }                }                cur.splice.apply(cur, splice);            }        }        for (i = 0, ii = cur.length; i < ii; i++) {            e = cur[i];            while (e.n) {                if (f) {                    if (e.f) {                        for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {                            e.f.splice(j, 1);                            break;                        }                        !e.f.length && delete e.f;                    }                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {                        var funcs = e.n[key].f;                        for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {                            funcs.splice(j, 1);                            break;                        }                        !funcs.length && delete e.n[key].f;                    }                } else {                    delete e.f;                    for (key in e.n) if (e.n[has](key) && e.n[key].f) {                        delete e.n[key].f;                    }                }                e = e.n;            }        }    };    /*\     * eve.once     [ method ]     **     * Binds given event handler with a given name to only run once then unbind itself.     | eve.once("login", f);     | eve("login"); // triggers f     | eve("login"); // no listeners     * Use @eve to trigger the listener.     **     > Arguments     **     - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards     - f (function) event handler function     **     = (function) same return function as @eve.on    \*/    eve.once = function (name, f) {        var f2 = function () {            eve.off(name, f2);            return f.apply(this, arguments);        };        return eve.on(name, f2);    };    /*\     * eve.version     [ property (string) ]     **     * Current version of the library.    \*/    eve.version = version;    eve.toString = function () {        return "You are running Eve " + version;    };    (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define === "function" && define.amd ? (define("eve", [], function() { return eve; })) : (glob.eve = eve));})(this);
 |