Skip to content

Instantly share code, notes, and snippets.

@frostney
Created October 15, 2013 19:34
Show Gist options
  • Save frostney/6997374 to your computer and use it in GitHub Desktop.
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
(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