Created
October 15, 2013 19:34
-
-
Save frostney/6997374 to your computer and use it in GitHub Desktop.
Example of mixing EventMap into a new constructor object with prototypes and direct objects being bound seperately
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
var exportObject, hasModule, isObject, | |
__hasProp = {}.hasOwnProperty; | |
(function() { | |
var _ref; | |
return (_ref = Array.isArray) != null ? _ref : Array.isArray = function(a) { | |
return a.push === Array.prototype.push && (a.length != null); | |
}; | |
})(); | |
hasModule = !!((typeof module !== "undefined" && module !== null) && module.exports); | |
exportObject = {}; | |
isObject = function(obj) { | |
return typeof obj === 'object' && !Array.isArray(obj); | |
}; | |
(function(root) { | |
var loadModule, platform, platforms, resolveModule, udefine; | |
platforms = ['commonjs', 'globals']; | |
platform = hasModule ? 'commonjs' : 'globals'; | |
resolveModule = function(factory, deps) { | |
if (typeof factory === 'function') { | |
return factory.apply(this, deps); | |
} else { | |
return factory; | |
} | |
}; | |
loadModule = function(name, type) { | |
var path, prePath; | |
if (hasModule && typeof udefine.modules[type][name] === 'string') { | |
path = require('path'); | |
prePath = (function() { | |
if (udefine.paths[type].base) { | |
return udefine.paths[type].base; | |
} else { | |
return ''; | |
} | |
})(); | |
return require(path.join(process.cwd(), prePath, udefine.modules[type][name])); | |
} else { | |
return udefine.modules[type][name]; | |
} | |
}; | |
udefine = function(name, deps, factory) { | |
var dep, depArr, ignoreName, injectName, injectObject, injectRoot, result, _ref; | |
if (name == null) { | |
throw new Error('A udefine module needs to have a name'); | |
} | |
if (name !== name.toLowerCase()) { | |
console.warn('A module should be all lowercase'); | |
} | |
if (typeof deps === 'function' || isObject(deps)) { | |
_ref = [name, [], deps], name = _ref[0], deps = _ref[1], factory = _ref[2]; | |
} | |
if (typeof define !== "undefined" && define !== null) { | |
if (define.amd || define.umd) { | |
result = define.apply(this, arguments); | |
} | |
} else { | |
depArr = (function() { | |
var _i, _len, _results; | |
_results = []; | |
for (_i = 0, _len = deps.length; _i < _len; _i++) { | |
dep = deps[_i]; | |
_results.push(loadModule(dep, platform)); | |
} | |
return _results; | |
})(); | |
result = resolveModule(factory, depArr); | |
if (!Object.hasOwnProperty.call(udefine.modules[platform], name)) { | |
udefine.modules[platform][name] = result; | |
} | |
} | |
if (!Object.hasOwnProperty.call(udefine.inject.modules, name)) { | |
if (udefine.autoInject) { | |
if (udefine.env.globals) { | |
udefine.inject.add(name, { | |
root: root, | |
name: name | |
}); | |
} | |
/* | |
if udefine.env.commonjs | |
udefine.inject.add name, | |
root: module.exports | |
name: name | |
ignoreName: true | |
*/ | |
} | |
} | |
if (Object.hasOwnProperty.call(udefine.inject.modules, name)) { | |
injectObject = udefine.inject.modules[name]; | |
injectRoot = injectObject.root, injectName = injectObject.name, ignoreName = injectObject.ignoreName; | |
udefine.inject(injectRoot, injectName, ignoreName)(result); | |
} | |
return result; | |
}; | |
udefine.autoInject = true; | |
udefine.inject = function(obj, name, ignoreName) { | |
return function(res) { | |
if (!((obj != null) && (name != null))) { | |
return; | |
} | |
if (ignoreName) { | |
return obj || (obj = res); | |
} else { | |
return obj[name] || (obj[name] = res); | |
} | |
}; | |
}; | |
udefine.inject.modules = {}; | |
udefine.inject.add = function(name, value) { | |
if (name == null) { | |
return; | |
} | |
if (value == null) { | |
value = {}; | |
} | |
if (value.root == null) { | |
value.root = root; | |
} | |
if (value.name == null) { | |
value.name = name; | |
} | |
udefine.inject.modules[name] = value; | |
return this; | |
}; | |
udefine.inject.remove = function(name) { | |
delete udefine.inject.modules[name]; | |
return this; | |
}; | |
udefine.inject.clear = function() { | |
udefine.inject.modules = {}; | |
return this; | |
}; | |
udefine.modules = { | |
globals: {}, | |
commonjs: {}, | |
add: function(name, value) { | |
var key, v, val, _i, _len; | |
if (typeof name === 'object') { | |
for (key in name) { | |
val = name[key]; | |
this.add(key, val); | |
} | |
} else { | |
if (value) { | |
if (Array.isArray(value)) { | |
for (_i = 0, _len = value.length; _i < _len; _i++) { | |
v = value[_i]; | |
udefine.modules[v][name] = void 0; | |
} | |
} else { | |
udefine.modules.set(name, value); | |
} | |
} else { | |
udefine.modules[platform][name] = void 0; | |
} | |
} | |
return this; | |
}, | |
remove: function(name) { | |
var p, _i, _len; | |
for (_i = 0, _len = platforms.length; _i < _len; _i++) { | |
p = platforms[_i]; | |
if (Object.hasOwnProperty.call(udefine.modules[p], name)) { | |
delete udefine.modules[p][name]; | |
} | |
} | |
return this; | |
}, | |
get: function(name) { | |
return udefine.modules[platform][name]; | |
}, | |
set: function(name, value) { | |
var k, v; | |
if (typeof value === 'object') { | |
for (k in value) { | |
v = value[k]; | |
udefine.modules[k][name] = v; | |
} | |
} else { | |
udefine.modules[platform][name] = value; | |
} | |
return this; | |
}, | |
clear: function() { | |
var p, _i, _len; | |
for (_i = 0, _len = platforms.length; _i < _len; _i++) { | |
p = platforms[_i]; | |
udefine.modules[p] = {}; | |
} | |
return this; | |
} | |
}; | |
udefine.env || (udefine.env = { | |
amd: (function() { | |
return (typeof define !== "undefined" && define !== null) && (define.amd || define.umd); | |
})(), | |
commonjs: hasModule, | |
browser: !hasModule, | |
globals: !hasModule && !udefine.amd | |
}); | |
udefine.paths = { | |
commonjs: { | |
base: void 0 | |
} | |
}; | |
udefine.require = function(name, callback) { | |
var n, reqDeps; | |
if (!Array.isArray(name)) { | |
name = [name]; | |
} | |
reqDeps = (function() { | |
var _i, _len, _results; | |
_results = []; | |
for (_i = 0, _len = name.length; _i < _len; _i++) { | |
n = name[_i]; | |
_results.push(udefine.modules.get(n)); | |
} | |
return _results; | |
})(); | |
return callback.apply(this, reqDeps); | |
}; | |
udefine.defaultConfig = function() { | |
udefine.modules.commonjs.root = root; | |
udefine.modules.globals.root = root; | |
if (root.define != null) { | |
return define('root', function() { | |
return root; | |
}); | |
} | |
}; | |
udefine.defaultConfig(); | |
udefine.configure = function(configFunc) { | |
var context, e, _ref, | |
_this = this; | |
context = {}; | |
_ref = udefine.env; | |
for (e in _ref) { | |
if (!__hasProp.call(_ref, e)) continue; | |
context[e] = function(platformDef) { | |
if (udefine.env[e]) { | |
return platformDef.call(_this); | |
} | |
}; | |
} | |
return configFunc.apply(context, [root, udefine]); | |
}; | |
if (hasModule) { | |
return module.exports = udefine; | |
} else { | |
return root.udefine = udefine; | |
} | |
})(hasModule ? {} : this); | |
}).call(this); | |
(function() { | |
(function(name) { | |
return udefine.configure(function(root) { | |
return this.globals(function() { | |
return udefine.inject.add(name.toLowerCase(), { | |
name: name, | |
root: root | |
}); | |
}); | |
}); | |
})('EventMap'); | |
}).call(this); | |
(function() { | |
'use strict'; | |
var defaults, flatten, hasProp, | |
__slice = [].slice; | |
(function() { | |
return Array.isArray != null ? Array.isArray : Array.isArray = function(a) { | |
return a.push === Array.prototype.push && (a.length != null); | |
}; | |
})(); | |
hasProp = {}.hasOwnProperty; | |
defaults = function(opts, defOpts) { | |
var key, value; | |
if (opts == null) { | |
opts = {}; | |
} | |
for (key in defOpts) { | |
value = defOpts[key]; | |
if (!hasProp.call(opts, key)) { | |
if (typeof value === 'object') { | |
opts[key] = {}; | |
defaults(opts[key], value); | |
} else { | |
opts[key] = value; | |
} | |
} | |
} | |
return opts; | |
}; | |
flatten = function(arr) { | |
return [].concat.call([], arr); | |
}; | |
udefine('eventmap', ['root'], function(root) { | |
var EventMap; | |
return EventMap = (function() { | |
function EventMap(options) { | |
options = defaults(options, { | |
shorthandFunctions: { | |
enabled: true, | |
separator: '/' | |
} | |
}); | |
this.sender = null; | |
this.events = {}; | |
this.validEvents = []; | |
this.options = options; | |
} | |
EventMap.prototype.serialize = function() { | |
var err, result; | |
try { | |
result = JSON.stringify(this.events, function(key, value) { | |
if (typeof value === 'function') { | |
value = value.toString(); | |
} | |
return value; | |
}); | |
} catch (_error) { | |
err = _error; | |
console.error("Error while serializing eventmap: " + err); | |
} | |
return result; | |
}; | |
EventMap.prototype.deserialize = function(string) { | |
var err, events; | |
try { | |
events = JSON.parse(string, function(key, value) { | |
if (value.indexOf('function') === 0) { | |
value = new Function(value)(); | |
} | |
return value; | |
}); | |
} catch (_error) { | |
err = _error; | |
console.error("Error while deserializing eventmap: " + err); | |
return false; | |
} | |
this.events = events; | |
return true; | |
}; | |
EventMap.prototype.bind = function(eventName, context) { | |
var bindSingleEvent, e, _i, _len, | |
_this = this; | |
if (context == null) { | |
context = this; | |
} | |
if (!this.options.shorthandFunctions.enabled) { | |
return; | |
} | |
if (!Array.isArray(eventName)) { | |
eventName = [eventName]; | |
} | |
bindSingleEvent = function(evName) { | |
if (!hasProp.call(context, evName)) { | |
return context[evName] = function() { | |
var args; | |
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |
return this.trigger.apply(this, flatten([evName, args])); | |
}; | |
} | |
}; | |
for (_i = 0, _len = eventName.length; _i < _len; _i++) { | |
e = eventName[_i]; | |
bindSingleEvent(e); | |
} | |
return this; | |
}; | |
EventMap.prototype.on = function(eventName, eventFunction) { | |
var _base, _base1; | |
if (!eventFunction) { | |
return; | |
} | |
if (this.validEvents.length > 0) { | |
if (this.validEvents.indexOf(eventName) === -1) { | |
return; | |
} | |
} | |
(_base = this.events)[eventName] || (_base[eventName] = { | |
id: -1, | |
type: '' | |
}); | |
(_base1 = this.events[eventName])['now'] || (_base1['now'] = []); | |
this.events[eventName]['now'].push(eventFunction); | |
this.bind(eventName); | |
return this; | |
}; | |
EventMap.prototype.off = function(eventName) { | |
var id, type, _ref; | |
if (eventName && this.events[eventName]) { | |
_ref = this.events[eventName], id = _ref.id, type = _ref.type; | |
if (type === 'once' || type === 'repeat') { | |
if (type === 'repeat') { | |
root.clearInterval(id); | |
} | |
if (type === 'once') { | |
root.clearTimeout(id); | |
} | |
} | |
if (this.events[eventName]) { | |
delete this.events[eventName]; | |
} | |
} else { | |
return; | |
} | |
return this; | |
}; | |
EventMap.prototype.before = function(eventName, eventFunction) { | |
var _base, _base1; | |
if (!eventFunction) { | |
return; | |
} | |
(_base = this.events)[eventName] || (_base[eventName] = {}); | |
(_base1 = this.events[eventName])['before'] || (_base1['before'] = []); | |
this.events[eventName]['before'].push(eventFunction); | |
return this; | |
}; | |
EventMap.prototype.after = function(eventName, eventFunction) { | |
var _base, _base1; | |
if (!eventFunction) { | |
return; | |
} | |
(_base = this.events)[eventName] || (_base[eventName] = {}); | |
(_base1 = this.events[eventName])['after'] || (_base1['after'] = []); | |
this.events[eventName]['after'].push(eventFunction); | |
return this; | |
}; | |
EventMap.prototype.clear = function() { | |
this.events = {}; | |
this.validEvents = []; | |
return this; | |
}; | |
EventMap.prototype.trigger = function() { | |
var args, context, delay, e, ev, eventName, interval, name, repeat, sender, timeoutId, triggerEvent, triggerFunction, _i, _len, _ref, | |
_this = this; | |
eventName = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; | |
if (eventName == null) { | |
return; | |
} | |
if (Array.isArray(eventName)) { | |
for (_i = 0, _len = eventName.length; _i < _len; _i++) { | |
e = eventName[_i]; | |
this.trigger(e, args); | |
} | |
} | |
if (typeof eventName === 'object') { | |
name = eventName.name, interval = eventName.interval, repeat = eventName.repeat, context = eventName.context, delay = eventName.delay, sender = eventName.sender; | |
} else { | |
name = eventName; | |
} | |
if (((_ref = this.events[name]) != null ? _ref['now'] : void 0) == null) { | |
return; | |
} | |
if (interval == null) { | |
interval = 0; | |
} | |
if (repeat == null) { | |
repeat = false; | |
} | |
if (context == null) { | |
context = {}; | |
} | |
if (delay == null) { | |
delay = 0; | |
} | |
if (sender == null) { | |
sender = this.sender; | |
} | |
if (sender == null) { | |
context.sender = sender; | |
} | |
triggerFunction = function() { | |
var afterArr, beforeArr, callEvents, nowArr; | |
nowArr = _this.events[name]['now'] || []; | |
beforeArr = _this.events[name]['before'] || []; | |
afterArr = _this.events[name]['after'] || []; | |
callEvents = function(eventArr) { | |
var _j, _len1; | |
if (eventArr != null) { | |
for (_j = 0, _len1 = eventArr.length; _j < _len1; _j++) { | |
e = eventArr[_j]; | |
e.apply(context, args); | |
} | |
} | |
return null; | |
}; | |
callEvents(beforeArr); | |
callEvents(nowArr); | |
return callEvents(afterArr); | |
}; | |
ev = this.events[name]; | |
triggerEvent = function() { | |
if (interval) { | |
if (repeat) { | |
ev.type = 'repeat'; | |
ev.id = root.setInterval((function() { | |
return triggerFunction.call(this); | |
}), interval); | |
} else { | |
ev.type = 'once'; | |
ev.id = root.setTimeout((function() { | |
return triggerFunction.call(this); | |
}), interval); | |
} | |
} else { | |
ev.type = 'direct'; | |
triggerFunction.call(this); | |
} | |
return null; | |
}; | |
if (delay) { | |
timeoutId = root.setTimeout((function() { | |
triggerEvent.call(this); | |
return root.clearTimeout(timeoutId); | |
}), delay); | |
} else { | |
triggerEvent.call(this); | |
} | |
return this; | |
}; | |
return EventMap; | |
})(); | |
}); | |
if (udefine.env.commonjs) { | |
udefine.require('eventmap', function(EventMap) { | |
return module.exports = EventMap; | |
}); | |
} | |
}).call(this); | |
(function() { | |
(function(name) { | |
return udefine.configure(function(root) { | |
return udefine.inject.add(name); | |
}); | |
})('mixer'); | |
}).call(this); | |
(function() { | |
var ownProp, | |
__slice = [].slice; | |
ownProp = Object.hasOwnProperty; | |
udefine('mixer', function() { | |
var mixer, mixinList; | |
mixinList = {}; | |
mixer = function() { | |
var mixFunction, mixObject, n, name, params, target, _i, _len; | |
target = arguments[0], name = arguments[1], params = 3 <= arguments.length ? __slice.call(arguments, 2) : []; | |
if (target == null) { | |
return; | |
} | |
mixObject = function(target, obj) { | |
var key, splitObject, splitted, value; | |
splitObject = function(obj) { | |
var directObj, keys, protoObj; | |
keys = Object.keys(obj); | |
directObj = (function() { | |
var key, result, _i, _len; | |
result = {}; | |
for (_i = 0, _len = keys.length; _i < _len; _i++) { | |
key = keys[_i]; | |
result[key] = obj[key]; | |
} | |
return result; | |
})(); | |
protoObj = Object.getPrototypeOf(obj); | |
return [directObj, protoObj]; | |
}; | |
if (Array.isArray(target)) { | |
splitted = splitObject(obj); | |
mixObject(target[0], splitted[0]); | |
mixObject(target[1], splitted[1]); | |
} else { | |
for (key in obj) { | |
value = obj[key]; | |
if (!ownProp.call(target, key)) { | |
target[key] = value; | |
} | |
} | |
} | |
return null; | |
}; | |
mixFunction = function(target, func, params) { | |
return func.apply(target, params); | |
}; | |
if (Array.isArray(name)) { | |
for (_i = 0, _len = name.length; _i < _len; _i++) { | |
n = name[_i]; | |
mixer(target, n, params); | |
} | |
} | |
if (typeof name === 'string' && ownProp.call(mixinList, name)) { | |
if (typeof mixinList[name] === 'function') { | |
mixFunction(target, mixinList[name], params); | |
} else { | |
mixObject(target, mixinList[name]); | |
} | |
} else { | |
if (typeof name === 'function') { | |
mixFunction(target, name, params); | |
} else { | |
mixObject(target, name); | |
} | |
} | |
return null; | |
}; | |
mixer.define = function(name, definition) { | |
if (!((name != null) || (definition != null))) { | |
return; | |
} | |
if (mixinList[name] != null) { | |
return; | |
} | |
mixinList[name] = definition; | |
return null; | |
}; | |
mixer.remove = function(name) { | |
if ((name != null) && (mixinList[name] != null)) { | |
delete mixinList[name]; | |
} | |
return null; | |
}; | |
mixer.exists = function(name) { | |
return ownProp.call(mixinList, name); | |
}; | |
return mixer; | |
}); | |
}).call(this); | |
var MyBlubb = (function() { | |
var MyBlubb = function() { | |
mixer([this, MyBlubb.prototype], new EventMap()) | |
this.a = 5; | |
}; | |
MyBlubb.prototype.t = function() {}; | |
return MyBlubb; | |
})(); | |
var blubb = new MyBlubb(); | |
blubb.on('test', function() { | |
console.log('test'); | |
}); | |
blubb.trigger('test'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment