Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tal committed Jan 2, 2015
0 parents commit 43df3dd
Show file tree
Hide file tree
Showing 10 changed files with 780 additions and 0 deletions.
Empty file added .gitignore
Empty file.
87 changes: 87 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
// JSHint Default Configuration File (as on JSHint website)
// See http://jshint.com/docs/ for more details

"maxerr" : 50, // {int} Maximum error before stopping

// Enforcing
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : false, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc.
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : false, // true: Require variables/functions to be defined before being used
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters.
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : false, // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // true: Require all defined variables be used
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : false, // {int} Max number of characters per line

// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : true, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : true, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements
"globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"noyield" : false, // true: Tolerate generator functions with no yield statement in them.
"notypeof" : false, // true: Tolerate invalid typeof operator values
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function

// Environments
"browser" : false, // Web Browser (window, document, etc)
"browserify" : false, // Browserify (node.js code in the browser)
"couch" : false, // CouchDB
"devel" : true, // Development/debugging (alert, confirm, etc)
"dojo" : false, // Dojo Toolkit
"jasmine" : false, // Jasmine
"jquery" : false, // jQuery
"mocha" : false, // Mocha
"mootools" : false, // MooTools
"node" : true, // Node.js
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
"prototypejs" : false, // Prototype and Scriptaculous
"qunit" : false, // QUnit
"rhino" : false, // Rhino
"shelljs" : false, // ShellJS
"worker" : false, // Web Workers
"wsh" : false, // Windows Scripting Host
"yui" : false, // Yahoo User Interface

// Custom Globals
"globals" : {} // additional predefined global variables
}
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

var Session = require('./lib/session');

module.exports = Session;
79 changes: 79 additions & 0 deletions lib/channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use strict';

var _ = require('lodash');

var Event = require('./event');

var formatMessage = require('./util/format-message.js');

function Channel(session, name) {
this.session = session;

var names = _.isArray(name) ? name : [name];

this.channelNames = names;

this.handlers = [];

_.bindAll(this, 'testMessage');
}

Channel.prototype = {
send: function() {
this.sendMessage.apply(this, arguments);
},

eachChannelName: function(cb) {
_.each(this.channelNames, cb, this);
},

sendMessage: function(msg) {
msg = formatMessage(msg);

if (msg.channel) {
this.session.sendMessage(msg);
} else {
this.eachChannelName(function(channelName) {
var msgToSend = _.clone(msg);

msgToSend.channel = channelName;

this.session.sendMessage(msgToSend);
});
}
},

on: function(selector, callback) {
if (callback) {
this.handlers.push(new Event(this, selector, callback));
} else {
for (var key in selector) {
if (selector.hasOwnProperty(key)) {
this.on(key, selector[key]);
}
}
}
},

testMessage: function(message) {
for (var i = this.handlers.length - 1; i >= 0; i--) {
this.handlers[i].match(message);
}
},

setChannels: function() {
this.channels = {};

_.each(this.channelNames, function(channelName) {
var data = this.session.channelData(channelName);
this.channels[channelName] = data;

this.session.onChannelMessage(channelName, this.testMessage);
}, this);
}
};

Object.defineProperties(Channel.prototype, {
});

module.exports = Channel;
191 changes: 191 additions & 0 deletions lib/event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
'use strict';

var Message = require('./message');

var regExRegEx = /^\/(.+)\/([gimy]*)$/;

function Event(session, selector, callback) {
this.session = session;
this.selector = selector;
this.callback = callback;
}

Event.prototype = {
get selector() {
return this._selector;
},

set selector(selector) {
var type;

Object.defineProperty(this, '_selector', {
value: selector,
writeable: false,
configurable: true,
enumerable: false
});

var match;

if (selector instanceof RegExp) {
type = 'regex';

Object.defineProperty(this, 'regex', {
value: selector,
writeable: false,
configurable: false,
enumerable: true
});
} else {
match = selector.match(regExRegEx);
}

if (match) {
type = 'regex';

Object.defineProperty(this, 'regex', {
value: new RegExp(match[1], match[2]),
writeable: false,
configurable: false,
enumerable: true
});
} else if (selector[selector.length - 1] === '*') {

if (selector[0] === '*') {
type = 'stringAnywhere';

Object.defineProperty(this, 'stringAnywhere', {
value: selector.slice(0, -1),
writeable: false,
configurable: false,
enumerable: true
});
} else {
type = 'prefix';

Object.defineProperty(this, 'prefix', {
value: selector.slice(0, -1),
writeable: false,
configurable: false,
enumerable: true
});
}
} else if (!type) {
type = 'text';
}

this.type = type;
},

get type() {
return this._type;
},

set type(type) {
Object.defineProperty(this, '_type', {
value: type,
writeable: false,
configurable: true,
enumerable: false
});

var matcher;

switch (type) {
case 'text':
matcher = matchText;
break;
case 'prefix':
matcher = prefixMatch;
break;
case 'stringAnywhere':
matcher = stringAnyWhereMatch;
break;
case 'regex':
matcher = regexMatch;
break;
default:
matcher = function() {};
}

Object.defineProperty(this, 'match', {
value: matcher,
writeable: false,
configurable: true,
enumerable: true
});
}
};

function matchText(message) {
/*jshint validthis:true */

if (!(message && message.text)) {
return;
}

var matched = message.text === this.selector;

if (matched) {
var msg = new Message(this.session, message);
this.callback(msg, this.selector);
}

return matched;
}

function prefixMatch(message) {
/*jshint validthis:true */

if (!(message && message.text)) {
return;
}

var matched = message.text.indexOf(this.prefix) === 0;

if (matched) {
var rest = message.text.slice(this.prefix.length);

var msg = new Message(this.session, message);
this.callback(msg, this.prefix, rest);
}

return matched;
}

function stringAnyWhereMatch(message) {
/*jshint validthis:true */

if (!(message && message.text)) {
return;
}

var matched = message.text.indexOf(this.stringAnywhere) >= 0;

if (matched) {
var msg = new Message(this.session, message);
this.callback(msg, this.selector);
}

return matched;
}

function regexMatch(message) {
/*jshint validthis:true */

if (!(message && message.text)) {
return;
}

var match = message.text.match(this.regex);

if (match) {
var msg = new Message(this.session, message);

this.callback(msg, match);
}

return !!match;
}

module.exports = Event;
Loading

0 comments on commit 43df3dd

Please sign in to comment.