Browse Source

Updates to chat, homepage

Former-commit-id: 9428ec0cae6bfc600ece09c8fdc9f9a6e8ccb4d9
Former-commit-id: 8e3955beec38879e4399a48a751bc73efadd81fc
beta
jlukic 11 years ago
parent
commit
fe6810ae66
  1. 766
      build/minified/modules/chatroom.js
  2. 2
      build/minified/modules/dropdown.js
  3. 358
      build/minified/modules/rating.js
  4. 766
      build/packaged/modules/chatroom.js
  5. 2
      build/packaged/modules/dropdown.js
  6. 358
      build/packaged/modules/rating.js
  7. 2
      build/uncompressed/elements/segment.css
  8. 242
      build/uncompressed/modules/chatroom.css
  9. 766
      build/uncompressed/modules/chatroom.js
  10. 2
      build/uncompressed/modules/dropdown.js
  11. 120
      build/uncompressed/modules/rating.css
  12. 358
      build/uncompressed/modules/rating.js
  13. 2
      node/src/documents/modules/chat.html
  14. 2
      node/src/files/components/semantic/elements/segment.css
  15. 25
      node/src/files/components/semantic/modules/chatroom.css
  16. 166
      node/src/files/components/semantic/modules/chatroom.js
  17. 2
      node/src/files/components/semantic/modules/dropdown.js
  18. 1
      node/src/files/javascript/semantic.js
  19. 84
      node/src/files/stylesheets/semantic.css
  20. 2
      src/elements/segment.less
  21. 766
      src/modules/chatroom.js
  22. 271
      src/modules/chatroom.less
  23. 2
      src/modules/dropdown.js
  24. 358
      src/modules/rating.js
  25. 151
      src/modules/rating.less

766
build/minified/modules/chatroom.js

@ -0,0 +1,766 @@
/* ******************************
Module - Chat Room
Author: Jack Lukic
Notes: First Commit Aug 8, 2012
Designed as a simple modular chat component
****************************** */
;(function ($, window, document, undefined) {
$.fn.chatroom = function(parameters) {
var
settings = $.extend(true, {}, $.fn.chatroom.settings, parameters),
className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
// hoist arguments
moduleArguments = arguments || false
;
$(this)
.each(function() {
var
$module = $(this),
$expandButton = $module.find(selector.expandButton),
$userListButton = $module.find(selector.userListButton),
$userList = $module.find(selector.userList),
$room = $module.find(selector.room),
$userCount = $module.find(selector.userCount),
$log = $module.find(selector.log),
$message = $module.find(selector.message),
$messageInput = $module.find(selector.messageInput),
$messageButton = $module.find(selector.messageButton),
instance = $module.data('module'),
html = '',
users = {},
channel,
loggedInUser,
message,
count,
height,
pusher,
module
;
module = {
width: {
log : $log.width(),
userList : $userList.outerWidth()
},
initialize: function() {
// check error conditions
if(Pusher === undefined) {
module.error(error.pusher);
}
if(settings.key === undefined || settings.channelName === undefined) {
module.error(error.key);
return false;
}
else if( !(settings.endpoint.message || settings.endpoint.authentication) ) {
module.error(error.endpoint);
return false;
}
// define pusher
pusher = new Pusher(settings.key);
Pusher.channel_auth_endpoint = settings.endpoint.authentication;
channel = pusher.subscribe(settings.channelName);
channel.bind('pusher:subscription_succeeded', module.user.list.create);
channel.bind('pusher:subscription_error', module.error);
channel.bind('pusher:member_added', module.user.joined);
channel.bind('pusher:member_removed', module.user.left);
channel.bind('update_messages', module.message.receive);
$.each(settings.customEvents, function(label, value) {
channel.bind(label, value);
});
// bind module events
$userListButton
.on('click.' + namespace, module.event.toggleUserList)
;
$expandButton
.on('click.' + namespace, module.event.toggleExpand)
;
$messageInput
.on('keydown.' + namespace, module.event.input.keydown)
.on('keyup.' + namespace, module.event.input.keyup)
;
$messageButton
.on('mouseenter.' + namespace, module.event.hover)
.on('mouseleave.' + namespace, module.event.hover)
.on('click.' + namespace, module.event.submit)
;
// scroll to bottom of chat log
$log
.animate({
scrollTop: $log.prop('scrollHeight')
}, 400)
;
$module
.data('module', module)
.addClass(className.loading)
;
},
// refresh module
refresh: function() {
// reset width calculations
$userListButton
.removeClass(className.active)
;
module.width = {
log : $log.width(),
userList : $userList.outerWidth()
};
if( $userListButton.hasClass(className.active) ) {
module.user.list.hide();
}
$module.data('module', module);
},
user: {
updateCount: function() {
if(settings.userCount) {
users = $module.data('users');
count = 0;
$.each(users, function() {
count++;
});
$userCount
.html( settings.templates.userCount(count) )
;
}
},
// add user to user list
joined: function(member) {
users = $module.data('users');
if(member.id != 'anonymous' && users[ member.id ] === undefined ) {
users[ member.id ] = member.info;
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
html = settings.templates.userList(member.info);
if(member.info.isAdmin) {
$(html)
.prependTo($userList)
;
}
else {
$(html)
.appendTo($userList)
;
}
if(settings.partingMessages) {
$log
.append( settings.templates.joined(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
// remove user from user list
left: function(member) {
users = $module.data('users');
if(member !== undefined && member.id !== 'anonymous') {
delete users[ member.id ];
$module
.data('users', users)
;
$userList
.find('[data-id='+ member.id + ']')
.remove()
;
if(settings.partingMessages) {
$log
.append( settings.templates.left(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
list: {
// receives list of members and generates user list
create: function(members) {
users = {};
members.each(function(member) {
if(member.id !== 'anonymous' && member.id !== 'undefined') {
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
// sort list with admin first
html = (member.info.isAdmin)
? settings.templates.userList(member.info) + html
: html + settings.templates.userList(member.info)
;
users[ member.id ] = member.info;
}
});
$module
.data('users', users)
.data('user', users[members.me.id] )
.removeClass(className.loading)
;
$userList
.html(html)
;
module.user.updateCount();
$.proxy(settings.onJoin, $userList.children())();
},
// shows user list
show: function() {
$log
.animate({
width: (module.width.log - module.width.userList)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
},
// hides user list
hide: function() {
$log
.stop()
.animate({
width: (module.width.log)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
}
}
},
message: {
// handles scrolling of chat log
scroll: {
test: function() {
height = $log.prop('scrollHeight') - $log.height();
if( Math.abs($log.scrollTop() - height) < settings.scrollArea) {
module.message.scroll.move();
}
},
move: function() {
height = $log.prop('scrollHeight') - $log.height();
$log
.scrollTop(height)
;
}
},
// sends chat message
send: function(message) {
if( !module.utils.emptyString(message) ) {
$.api({
url : settings.endpoint.message,
method : 'POST',
data : {
'message': {
content : message,
timestamp : new Date().getTime()
}
}
});
}
},
// receives chat response and processes
receive: function(response) {
message = response.data;
users = $module.data('users');
loggedInUser = $module.data('user');
if(users[ message.userID] !== undefined) {
// logged in user's messages already pushed instantly
if(loggedInUser === undefined || loggedInUser.id != message.userID) {
message.user = users[ message.userID ];
module.message.display(message);
}
}
},
// displays message in chat log
display: function(message) {
$log
.append( settings.templates.message(message) )
;
module.message.scroll.test();
$.proxy(settings.onMessage, $log.children().last() )();
}
},
expand: function() {
$module
.addClass(className.expand)
;
$.proxy(settings.onExpand, $module )();
module.refresh();
},
contract: function() {
$module
.removeClass(className.expand)
;
$.proxy(settings.onContract, $module )();
module.refresh();
},
event: {
input: {
keydown: function(event) {
if(event.which == 13) {
$messageButton
.addClass(className.down)
;
}
},
keyup: function(event) {
if(event.which == 13) {
$messageButton
.removeClass(className.down)
;
module.event.submit();
}
}
},
// handles message form submit
submit: function() {
var
message = $messageInput.val(),
loggedInUser = $module.data('user')
;
if(loggedInUser !== undefined && !module.utils.emptyString(message)) {
module.message.send(message);
// display immediately
module.message.display({
user: loggedInUser,
text: message
});
module.message.scroll.move();
$messageInput
.val('')
;
}
},
// handles button click on expand button
toggleExpand: function() {
if( !$module.hasClass(className.expand) ) {
$expandButton
.addClass(className.active)
;
module.expand();
}
else {
$expandButton
.removeClass(className.active)
;
module.contract();
}
},
// handles button click on user list button
toggleUserList: function() {
if( !$log.is(':animated') ) {
if( !$userListButton.hasClass(className.active) ) {
$userListButton
.addClass(className.active)
;
module.user.list.show();
}
else {
$userListButton
.removeClass('active')
;
module.user.list.hide();
}
}
}
},
utils: {
emptyString: function(string) {
if(typeof string == 'string') {
return (string.search(/\S/) == -1);
}
return false;
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
title += ' ' + '(' + $allDropdowns.size() + ')';
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( instance[value] !== undefined ) {
found = instance[value];
}
else {
module.error(error.method);
}
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
return found || false;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
invokedResponse = module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse)
? invokedResponse
: this
;
};
$.fn.chatroom.settings = {
name : 'Chat',
debug : false,
namespace : 'chat',
channel : 'present-chat',
onJoin : function(){},
onMessage : function(){},
onExpand : function(){},
onContract : function(){},
customEvents : {},
partingMessages : false,
userCount : true,
randomColor : true,
speed : 300,
easing : 'easeOutQuint',
// pixels from bottom of chat log that should trigger auto scroll to bottom
scrollArea : 9999,
endpoint : {
message : false,
authentication : false
},
error: {
method : 'The method you called is not defined',
endpoint : 'Please define a message and authentication endpoint.',
key : 'You must specify a pusher key and channel.',
pusher : 'You must include the Pusher library.'
},
className : {
expand : 'expand',
active : 'active',
hover : 'hover',
down : 'down',
loading : 'loading'
},
selector : {
userCount : '.actions .message',
userListButton : '.actions .list.button',
expandButton : '.actions .expand.button',
room : '.room',
userList : '.room .list',
log : '.room .log',
message : '.room .log .message',
author : '.room log .message .author',
messageInput : '.talk input',
messageButton : '.talk .send.button'
},
templates: {
userCount: function(number) {
return number + ' users in chat';
},
color: function(userID) {
var
colors = [
'#000000',
'#333333',
'#666666',
'#999999',
'#CC9999',
'#CC6666',
'#CC3333',
'#993333',
'#663333',
'#CC6633',
'#CC9966',
'#CC9933',
'#999966',
'#CCCC66',
'#99CC66',
'#669933',
'#669966',
'#33A3CC',
'#336633',
'#33CCCC',
'#339999',
'#336666',
'#336699',
'#6666CC',
'#9966CC',
'#333399',
'#663366',
'#996699',
'#993366',
'#CC6699'
]
;
return colors[ Math.floor( Math.random() * colors.length) ];
},
message: function(message) {
var
html = ''
;
if(message.user.isAdmin) {
message.user.color = '#55356A';
html += '<div class="admin message">';
html += '<span class="quirky ui flag team"></span>';
}
/*
else if(message.user.isPro) {
html += '<div class="indent message">';
html += '<span class="quirky ui flag pro"></span>';
}
*/
else {
html += '<div class="message">';
}
html += '<p>';
if(message.user.color !== undefined) {
html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: ';
}
else {
html += '<span class="author">' + message.user.name + '</span>: ';
}
html += ''
+ message.text
+ ' </p>'
+ '</div>'
;
return html;
},
joined: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has joined the chat.</div>'
: false
;
},
left: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has left the chat.</div>'
: false
;
},
userList: function(member) {
var
html = ''
;
if(member.isAdmin) {
member.color = '#55356A';
}
html += ''
+ '<div class="user" data-id="' + member.id + '">'
+ ' <div class="image">'
+ ' <img src="' + member.avatarURL + '">'
+ ' </div>'
;
if(member.color !== undefined) {
html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>';
}
else {
html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>';
}
html += '</div>';
return html;
}
}
};
})( jQuery, window , document );

2
build/minified/modules/dropdown.js

@ -23,7 +23,7 @@ $.fn.dropdown = function(parameters) {
error = settings.error, error = settings.error,
eventNamespace = '.' + namespace, eventNamespace = '.' + namespace,
dropdownNamespace = 'dropdown-' + namespace, dropdownNamespace = 'module-' + namespace,
dropdownSelector = $allDropdowns.selector || '', dropdownSelector = $allDropdowns.selector || '',
time = new Date().getTime(), time = new Date().getTime(),

358
build/minified/modules/rating.js

@ -0,0 +1,358 @@
/* ******************************
Star Review
Author: Jack Lukic
Notes: First Commit Sep 04, 2012
Simple rating module
****************************** */
;(function ($, window, document, undefined) {
$.fn.rating = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
settings = $.extend(true, {}, $.fn.rating.settings, parameters),
namespace = settings.namespace,
className = settings.className,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
invokedResponse
;
$allModules
.each(function() {
var
$module = $(this),
$icon = $module.find(selector.icon),
element = this,
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
module.verbose('Initializing rating module');
if(settings.interactive) {
$icon
.bind('mouseenter' + eventNamespace, module.event.mouseenter)
.bind('mouseleave' + eventNamespace, module.event.mouseleave)
.bind('click' + eventNamespace, module.event.click)
;
}
if(settings.initialRating) {
module.debug('Setting initial rating');
module.setRating(settings.initialRating);
}
if( $module.data(metadata.rating) ) {
module.debug('Rating found in metadata');
module.setRating( $module.data(metadata.rating) );
}
$module
.addClass(className.active)
;
module.instantiate();
},
instantiate: function() {
module.verbose('Instantiating module', settings);
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
$module
.removeData(moduleNamespace)
;
$icon
.off(eventNamespace)
;
},
setRating: function(rating) {
var
$activeIcon = $icon.eq(rating - 1)
;
module.verbose('Setting current rating to', rating);
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
$activeIcon
.nextAll()
.removeClass(className.active)
;
$activeIcon
.addClass(className.active)
.prevAll()
.addClass(className.active)
;
$.proxy(settings.onRate, element)();
},
event: {
mouseenter: function() {
var
$activeIcon = $(this)
;
$activeIcon
.nextAll()
.removeClass(className.hover)
;
$module
.addClass(className.hover)
;
$activeIcon
.addClass(className.hover)
.prevAll()
.addClass(className.hover)
;
},
mouseleave: function() {
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
},
click: function() {
var
$activeIcon = $(this)
;
module.setRating( $icon.index($activeIcon) + 1);
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.size() > 1) {
title += ' ' + '(' + $allModules.size() + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
instance = instance[camelCaseValue];
}
else if( instance[value] !== undefined ) {
found = instance[value];
return false;
}
else if( instance[camelCaseValue] !== undefined ) {
found = instance[camelCaseValue];
return false;
}
else {
module.error(error.method);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(invokedResponse)) {
invokedResponse.push(response);
}
else if(typeof invokedResponse == 'string') {
invokedResponse = [invokedResponse, response];
}
else if(response !== undefined) {
invokedResponse = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse !== undefined)
? invokedResponse
: this
;
};
$.fn.rating.settings = {
name : 'Rating',
namespace : 'rating',
verbose : true,
debug : true,
performance : true,
initialRating : 0,
interactive : true,
onRate : function(){},
error : {
method : 'The method you called is not defined'
},
metadata: {
rating: 'rating'
},
className : {
active : 'active',
hover : 'hover',
loading : 'loading'
},
selector : {
icon : '.icon'
}
};
})( jQuery, window , document );

766
build/packaged/modules/chatroom.js

@ -0,0 +1,766 @@
/* ******************************
Module - Chat Room
Author: Jack Lukic
Notes: First Commit Aug 8, 2012
Designed as a simple modular chat component
****************************** */
;(function ($, window, document, undefined) {
$.fn.chatroom = function(parameters) {
var
settings = $.extend(true, {}, $.fn.chatroom.settings, parameters),
className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
// hoist arguments
moduleArguments = arguments || false
;
$(this)
.each(function() {
var
$module = $(this),
$expandButton = $module.find(selector.expandButton),
$userListButton = $module.find(selector.userListButton),
$userList = $module.find(selector.userList),
$room = $module.find(selector.room),
$userCount = $module.find(selector.userCount),
$log = $module.find(selector.log),
$message = $module.find(selector.message),
$messageInput = $module.find(selector.messageInput),
$messageButton = $module.find(selector.messageButton),
instance = $module.data('module'),
html = '',
users = {},
channel,
loggedInUser,
message,
count,
height,
pusher,
module
;
module = {
width: {
log : $log.width(),
userList : $userList.outerWidth()
},
initialize: function() {
// check error conditions
if(Pusher === undefined) {
module.error(error.pusher);
}
if(settings.key === undefined || settings.channelName === undefined) {
module.error(error.key);
return false;
}
else if( !(settings.endpoint.message || settings.endpoint.authentication) ) {
module.error(error.endpoint);
return false;
}
// define pusher
pusher = new Pusher(settings.key);
Pusher.channel_auth_endpoint = settings.endpoint.authentication;
channel = pusher.subscribe(settings.channelName);
channel.bind('pusher:subscription_succeeded', module.user.list.create);
channel.bind('pusher:subscription_error', module.error);
channel.bind('pusher:member_added', module.user.joined);
channel.bind('pusher:member_removed', module.user.left);
channel.bind('update_messages', module.message.receive);
$.each(settings.customEvents, function(label, value) {
channel.bind(label, value);
});
// bind module events
$userListButton
.on('click.' + namespace, module.event.toggleUserList)
;
$expandButton
.on('click.' + namespace, module.event.toggleExpand)
;
$messageInput
.on('keydown.' + namespace, module.event.input.keydown)
.on('keyup.' + namespace, module.event.input.keyup)
;
$messageButton
.on('mouseenter.' + namespace, module.event.hover)
.on('mouseleave.' + namespace, module.event.hover)
.on('click.' + namespace, module.event.submit)
;
// scroll to bottom of chat log
$log
.animate({
scrollTop: $log.prop('scrollHeight')
}, 400)
;
$module
.data('module', module)
.addClass(className.loading)
;
},
// refresh module
refresh: function() {
// reset width calculations
$userListButton
.removeClass(className.active)
;
module.width = {
log : $log.width(),
userList : $userList.outerWidth()
};
if( $userListButton.hasClass(className.active) ) {
module.user.list.hide();
}
$module.data('module', module);
},
user: {
updateCount: function() {
if(settings.userCount) {
users = $module.data('users');
count = 0;
$.each(users, function() {
count++;
});
$userCount
.html( settings.templates.userCount(count) )
;
}
},
// add user to user list
joined: function(member) {
users = $module.data('users');
if(member.id != 'anonymous' && users[ member.id ] === undefined ) {
users[ member.id ] = member.info;
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
html = settings.templates.userList(member.info);
if(member.info.isAdmin) {
$(html)
.prependTo($userList)
;
}
else {
$(html)
.appendTo($userList)
;
}
if(settings.partingMessages) {
$log
.append( settings.templates.joined(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
// remove user from user list
left: function(member) {
users = $module.data('users');
if(member !== undefined && member.id !== 'anonymous') {
delete users[ member.id ];
$module
.data('users', users)
;
$userList
.find('[data-id='+ member.id + ']')
.remove()
;
if(settings.partingMessages) {
$log
.append( settings.templates.left(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
list: {
// receives list of members and generates user list
create: function(members) {
users = {};
members.each(function(member) {
if(member.id !== 'anonymous' && member.id !== 'undefined') {
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
// sort list with admin first
html = (member.info.isAdmin)
? settings.templates.userList(member.info) + html
: html + settings.templates.userList(member.info)
;
users[ member.id ] = member.info;
}
});
$module
.data('users', users)
.data('user', users[members.me.id] )
.removeClass(className.loading)
;
$userList
.html(html)
;
module.user.updateCount();
$.proxy(settings.onJoin, $userList.children())();
},
// shows user list
show: function() {
$log
.animate({
width: (module.width.log - module.width.userList)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
},
// hides user list
hide: function() {
$log
.stop()
.animate({
width: (module.width.log)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
}
}
},
message: {
// handles scrolling of chat log
scroll: {
test: function() {
height = $log.prop('scrollHeight') - $log.height();
if( Math.abs($log.scrollTop() - height) < settings.scrollArea) {
module.message.scroll.move();
}
},
move: function() {
height = $log.prop('scrollHeight') - $log.height();
$log
.scrollTop(height)
;
}
},
// sends chat message
send: function(message) {
if( !module.utils.emptyString(message) ) {
$.api({
url : settings.endpoint.message,
method : 'POST',
data : {
'message': {
content : message,
timestamp : new Date().getTime()
}
}
});
}
},
// receives chat response and processes
receive: function(response) {
message = response.data;
users = $module.data('users');
loggedInUser = $module.data('user');
if(users[ message.userID] !== undefined) {
// logged in user's messages already pushed instantly
if(loggedInUser === undefined || loggedInUser.id != message.userID) {
message.user = users[ message.userID ];
module.message.display(message);
}
}
},
// displays message in chat log
display: function(message) {
$log
.append( settings.templates.message(message) )
;
module.message.scroll.test();
$.proxy(settings.onMessage, $log.children().last() )();
}
},
expand: function() {
$module
.addClass(className.expand)
;
$.proxy(settings.onExpand, $module )();
module.refresh();
},
contract: function() {
$module
.removeClass(className.expand)
;
$.proxy(settings.onContract, $module )();
module.refresh();
},
event: {
input: {
keydown: function(event) {
if(event.which == 13) {
$messageButton
.addClass(className.down)
;
}
},
keyup: function(event) {
if(event.which == 13) {
$messageButton
.removeClass(className.down)
;
module.event.submit();
}
}
},
// handles message form submit
submit: function() {
var
message = $messageInput.val(),
loggedInUser = $module.data('user')
;
if(loggedInUser !== undefined && !module.utils.emptyString(message)) {
module.message.send(message);
// display immediately
module.message.display({
user: loggedInUser,
text: message
});
module.message.scroll.move();
$messageInput
.val('')
;
}
},
// handles button click on expand button
toggleExpand: function() {
if( !$module.hasClass(className.expand) ) {
$expandButton
.addClass(className.active)
;
module.expand();
}
else {
$expandButton
.removeClass(className.active)
;
module.contract();
}
},
// handles button click on user list button
toggleUserList: function() {
if( !$log.is(':animated') ) {
if( !$userListButton.hasClass(className.active) ) {
$userListButton
.addClass(className.active)
;
module.user.list.show();
}
else {
$userListButton
.removeClass('active')
;
module.user.list.hide();
}
}
}
},
utils: {
emptyString: function(string) {
if(typeof string == 'string') {
return (string.search(/\S/) == -1);
}
return false;
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
title += ' ' + '(' + $allDropdowns.size() + ')';
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( instance[value] !== undefined ) {
found = instance[value];
}
else {
module.error(error.method);
}
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
return found || false;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
invokedResponse = module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse)
? invokedResponse
: this
;
};
$.fn.chatroom.settings = {
name : 'Chat',
debug : false,
namespace : 'chat',
channel : 'present-chat',
onJoin : function(){},
onMessage : function(){},
onExpand : function(){},
onContract : function(){},
customEvents : {},
partingMessages : false,
userCount : true,
randomColor : true,
speed : 300,
easing : 'easeOutQuint',
// pixels from bottom of chat log that should trigger auto scroll to bottom
scrollArea : 9999,
endpoint : {
message : false,
authentication : false
},
error: {
method : 'The method you called is not defined',
endpoint : 'Please define a message and authentication endpoint.',
key : 'You must specify a pusher key and channel.',
pusher : 'You must include the Pusher library.'
},
className : {
expand : 'expand',
active : 'active',
hover : 'hover',
down : 'down',
loading : 'loading'
},
selector : {
userCount : '.actions .message',
userListButton : '.actions .list.button',
expandButton : '.actions .expand.button',
room : '.room',
userList : '.room .list',
log : '.room .log',
message : '.room .log .message',
author : '.room log .message .author',
messageInput : '.talk input',
messageButton : '.talk .send.button'
},
templates: {
userCount: function(number) {
return number + ' users in chat';
},
color: function(userID) {
var
colors = [
'#000000',
'#333333',
'#666666',
'#999999',
'#CC9999',
'#CC6666',
'#CC3333',
'#993333',
'#663333',
'#CC6633',
'#CC9966',
'#CC9933',
'#999966',
'#CCCC66',
'#99CC66',
'#669933',
'#669966',
'#33A3CC',
'#336633',
'#33CCCC',
'#339999',
'#336666',
'#336699',
'#6666CC',
'#9966CC',
'#333399',
'#663366',
'#996699',
'#993366',
'#CC6699'
]
;
return colors[ Math.floor( Math.random() * colors.length) ];
},
message: function(message) {
var
html = ''
;
if(message.user.isAdmin) {
message.user.color = '#55356A';
html += '<div class="admin message">';
html += '<span class="quirky ui flag team"></span>';
}
/*
else if(message.user.isPro) {
html += '<div class="indent message">';
html += '<span class="quirky ui flag pro"></span>';
}
*/
else {
html += '<div class="message">';
}
html += '<p>';
if(message.user.color !== undefined) {
html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: ';
}
else {
html += '<span class="author">' + message.user.name + '</span>: ';
}
html += ''
+ message.text
+ ' </p>'
+ '</div>'
;
return html;
},
joined: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has joined the chat.</div>'
: false
;
},
left: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has left the chat.</div>'
: false
;
},
userList: function(member) {
var
html = ''
;
if(member.isAdmin) {
member.color = '#55356A';
}
html += ''
+ '<div class="user" data-id="' + member.id + '">'
+ ' <div class="image">'
+ ' <img src="' + member.avatarURL + '">'
+ ' </div>'
;
if(member.color !== undefined) {
html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>';
}
else {
html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>';
}
html += '</div>';
return html;
}
}
};
})( jQuery, window , document );

2
build/packaged/modules/dropdown.js

@ -23,7 +23,7 @@ $.fn.dropdown = function(parameters) {
error = settings.error, error = settings.error,
eventNamespace = '.' + namespace, eventNamespace = '.' + namespace,
dropdownNamespace = 'dropdown-' + namespace, dropdownNamespace = 'module-' + namespace,
dropdownSelector = $allDropdowns.selector || '', dropdownSelector = $allDropdowns.selector || '',
time = new Date().getTime(), time = new Date().getTime(),

358
build/packaged/modules/rating.js

@ -0,0 +1,358 @@
/* ******************************
Star Review
Author: Jack Lukic
Notes: First Commit Sep 04, 2012
Simple rating module
****************************** */
;(function ($, window, document, undefined) {
$.fn.rating = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
settings = $.extend(true, {}, $.fn.rating.settings, parameters),
namespace = settings.namespace,
className = settings.className,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
invokedResponse
;
$allModules
.each(function() {
var
$module = $(this),
$icon = $module.find(selector.icon),
element = this,
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
module.verbose('Initializing rating module');
if(settings.interactive) {
$icon
.bind('mouseenter' + eventNamespace, module.event.mouseenter)
.bind('mouseleave' + eventNamespace, module.event.mouseleave)
.bind('click' + eventNamespace, module.event.click)
;
}
if(settings.initialRating) {
module.debug('Setting initial rating');
module.setRating(settings.initialRating);
}
if( $module.data(metadata.rating) ) {
module.debug('Rating found in metadata');
module.setRating( $module.data(metadata.rating) );
}
$module
.addClass(className.active)
;
module.instantiate();
},
instantiate: function() {
module.verbose('Instantiating module', settings);
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
$module
.removeData(moduleNamespace)
;
$icon
.off(eventNamespace)
;
},
setRating: function(rating) {
var
$activeIcon = $icon.eq(rating - 1)
;
module.verbose('Setting current rating to', rating);
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
$activeIcon
.nextAll()
.removeClass(className.active)
;
$activeIcon
.addClass(className.active)
.prevAll()
.addClass(className.active)
;
$.proxy(settings.onRate, element)();
},
event: {
mouseenter: function() {
var
$activeIcon = $(this)
;
$activeIcon
.nextAll()
.removeClass(className.hover)
;
$module
.addClass(className.hover)
;
$activeIcon
.addClass(className.hover)
.prevAll()
.addClass(className.hover)
;
},
mouseleave: function() {
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
},
click: function() {
var
$activeIcon = $(this)
;
module.setRating( $icon.index($activeIcon) + 1);
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.size() > 1) {
title += ' ' + '(' + $allModules.size() + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
instance = instance[camelCaseValue];
}
else if( instance[value] !== undefined ) {
found = instance[value];
return false;
}
else if( instance[camelCaseValue] !== undefined ) {
found = instance[camelCaseValue];
return false;
}
else {
module.error(error.method);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(invokedResponse)) {
invokedResponse.push(response);
}
else if(typeof invokedResponse == 'string') {
invokedResponse = [invokedResponse, response];
}
else if(response !== undefined) {
invokedResponse = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse !== undefined)
? invokedResponse
: this
;
};
$.fn.rating.settings = {
name : 'Rating',
namespace : 'rating',
verbose : true,
debug : true,
performance : true,
initialRating : 0,
interactive : true,
onRate : function(){},
error : {
method : 'The method you called is not defined'
},
metadata: {
rating: 'rating'
},
className : {
active : 'active',
hover : 'hover',
loading : 'loading'
},
selector : {
icon : '.icon'
}
};
})( jQuery, window , document );

2
build/uncompressed/elements/segment.css

@ -292,7 +292,7 @@
} }
.ui.inverted.segment, .ui.inverted.segment,
.ui.primary.inverted.segment { .ui.primary.inverted.segment {
background-color: #555555; background-color: #222222;
color: #FFFFFF; color: #FFFFFF;
} }
/*------------------- /*-------------------

242
build/uncompressed/modules/chatroom.css

@ -0,0 +1,242 @@
/*******************************
Chat Room
*******************************/
.ui.chatroom {
background-color: #F8F8F8;
width: 330px;
height: 370px;
padding: 0px;
}
.ui.chatroom .room {
position: relative;
background-color: #FFFFFF;
overflow: hidden;
height: 286px;
border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none;
border-bottom: none;
}
.ui.chatroom .room .loader {
display: none;
margin: -25px 0px 0px -25px;
}
/* Chat Room Actions */
.ui.chatroom .actions {
overflow: hidden;
background-color: #EEEEEE;
padding: 4px;
border: 1px solid rgba(0, 0, 0, 0.1);
-moz-border-radius: 5px 5px 0px 0px;
-webkit-border-radius: 5px 5px 0px 0px;
border-radius: 5px 5px 0px 0px;
}
.ui.chatroom .actions .button {
float: right;
margin-left: 3px;
}
/* Online User Count */
.ui.chatroom .actions .message {
float: left;
margin-left: 6px;
font-size: 11px;
color: #AAAAAA;
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.8);
line-height: 28px;
}
.ui.chatroom .actions .message .loader {
display: inline-block;
margin-right: 8px;
}
/* Chat Room Text Log */
.ui.chatroom .log {
float: left;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
.ui.chatroom .log .message {
padding: 3px 0px;
border-top: 1px dotted #DADADA;
}
.ui.chatroom .log .message:first-child {
border-top: none;
}
/* status event */
.ui.chatroom .status {
padding: 5px 0px;
color: #AAAAAA;
font-size: 12px;
font-style: italic;
line-height: 1.33;
border-top: 1px dotted #DADADA;
}
.ui.chatroom .log .status:first-child {
border-top: none;
}
.ui.chatroom .log .flag {
float: left;
}
.ui.chatroom .log p {
margin-left: 0px;
}
.ui.chatroom .log .author {
font-weight: bold;
-webkit-transition: color 0.3s ease-out;
-moz-transition: color 0.3s ease-out;
-o-transition: color 0.3s ease-out;
-ms-transition: color 0.3s ease-out;
transition: color 0.3s ease-out;
}
.ui.chatroom .log a.author:hover {
opacity: 0.8;
}
.ui.chatroom .log .message.admin p {
font-weight: bold;
margin: 1px 0px 0px 23px;
}
.ui.chatroom .log .divider {
margin: -1px 0px;
font-size: 11px;
padding: 10px 0px;
border-top: 1px solid #F8F8F8;
border-bottom: 1px solid #F8F8F8;
}
.ui.chatroom .log .divider .rule {
top: 50%;
width: 15%;
}
.ui.chatroom .log .divider .label {
color: #777777;
margin: 0px;
}
/* Chat Room User List */
.ui.chatroom .room .list {
position: relative;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
float: left;
background-color: #EEEEEE;
border-left: 1px solid #DDDDDD;
}
.ui.chatroom .room .list .user {
display: table;
padding: 3px 7px;
border-bottom: 1px solid #DDDDDD;
}
.ui.chatroom .room .list .user:hover {
background-color: #F8F8F8;
}
.ui.chatroom .room .list .image {
display: table-cell;
vertical-align: middle;
width: 20px;
}
.ui.chatroom .room .list .image img {
width: 20px;
height: 20px;
vertical-align: middle;
}
.ui.chatroom .room .list p {
display: table-cell;
vertical-align: middle;
padding-left: 7px;
padding-right: 14px;
font-size: 11px;
line-height: 1.2;
font-weight: bold;
}
.ui.chatroom .room .list a:hover {
opacity: 0.8;
}
/* User List Loading */
.ui.chatroom.loading .loader {
display: block;
}
/* Chat Room Talk Input */
.ui.chatroom .talk {
border: 1px solid rgba(0, 0, 0, 0.1);
padding: 5px 0px 0px;
background-color: #EEEEEE;
-webkit-border-radius: 0px 0px 5px 5px;
-moz-border-radius: 0px 0px 5px 5px;
border-radius: 0px 0px 5px 5px;
}
.ui.chatroom .talk .avatar,
.ui.chatroom .talk input,
.ui.chatroom .talk .button {
float: left;
}
.ui.chatroom .talk .avatar img {
display: block;
width: 30px;
height: 30px;
margin-right: 4px;
border-radius: 500rem;
}
.ui.chatroom .talk input {
border: 1px solid #CCCCCC;
margin: 0px;
width: 196px;
height: 14px;
padding: 8px 5px;
font-size: 12px;
color: #555555;
}
.ui.chatroom .talk input.focus {
border: 1px solid #AAAAAA;
}
.ui.chatroom .send {
width: 80px;
height: 32px;
margin-left: -1px;
padding: 4px 12px;
font-size: 12px;
line-height: 23px;
-webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
-moz-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
border-radius: 0 5px 5px 0;
}
.ui.chatroom .talk .log-in.button {
display: block;
float: none;
margin-top: -6px;
height: 22px;
border-radius: 0px 0px 4px 4px;
}
.ui.chatroom .talk .log-in.button i {
vertical-align: text-top;
}
/* Quirky Flags */
.ui.chatroom .log .team.flag {
width: 18px;
}
/* Chat room Loaded */
.ui.chatroom.loading .loader {
display: block;
}
/* Standard Size */
.ui.chatroom {
width: 330px;
height: 370px;
}
.ui.chatroom .room .container {
width: 3000px;
}
.ui.chatroom .log {
width: 314px;
height: 278px;
padding: 4px 7px;
}
.ui.chatroom .room .list {
width: 124px;
height: 278px;
padding: 4px 0px;
}
.ui.chatroom .room .list .user {
width: 110px;
}
.ui.chatroom .talk {
height: 40px;
}

766
build/uncompressed/modules/chatroom.js

@ -0,0 +1,766 @@
/* ******************************
Module - Chat Room
Author: Jack Lukic
Notes: First Commit Aug 8, 2012
Designed as a simple modular chat component
****************************** */
;(function ($, window, document, undefined) {
$.fn.chatroom = function(parameters) {
var
settings = $.extend(true, {}, $.fn.chatroom.settings, parameters),
className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
// hoist arguments
moduleArguments = arguments || false
;
$(this)
.each(function() {
var
$module = $(this),
$expandButton = $module.find(selector.expandButton),
$userListButton = $module.find(selector.userListButton),
$userList = $module.find(selector.userList),
$room = $module.find(selector.room),
$userCount = $module.find(selector.userCount),
$log = $module.find(selector.log),
$message = $module.find(selector.message),
$messageInput = $module.find(selector.messageInput),
$messageButton = $module.find(selector.messageButton),
instance = $module.data('module'),
html = '',
users = {},
channel,
loggedInUser,
message,
count,
height,
pusher,
module
;
module = {
width: {
log : $log.width(),
userList : $userList.outerWidth()
},
initialize: function() {
// check error conditions
if(Pusher === undefined) {
module.error(error.pusher);
}
if(settings.key === undefined || settings.channelName === undefined) {
module.error(error.key);
return false;
}
else if( !(settings.endpoint.message || settings.endpoint.authentication) ) {
module.error(error.endpoint);
return false;
}
// define pusher
pusher = new Pusher(settings.key);
Pusher.channel_auth_endpoint = settings.endpoint.authentication;
channel = pusher.subscribe(settings.channelName);
channel.bind('pusher:subscription_succeeded', module.user.list.create);
channel.bind('pusher:subscription_error', module.error);
channel.bind('pusher:member_added', module.user.joined);
channel.bind('pusher:member_removed', module.user.left);
channel.bind('update_messages', module.message.receive);
$.each(settings.customEvents, function(label, value) {
channel.bind(label, value);
});
// bind module events
$userListButton
.on('click.' + namespace, module.event.toggleUserList)
;
$expandButton
.on('click.' + namespace, module.event.toggleExpand)
;
$messageInput
.on('keydown.' + namespace, module.event.input.keydown)
.on('keyup.' + namespace, module.event.input.keyup)
;
$messageButton
.on('mouseenter.' + namespace, module.event.hover)
.on('mouseleave.' + namespace, module.event.hover)
.on('click.' + namespace, module.event.submit)
;
// scroll to bottom of chat log
$log
.animate({
scrollTop: $log.prop('scrollHeight')
}, 400)
;
$module
.data('module', module)
.addClass(className.loading)
;
},
// refresh module
refresh: function() {
// reset width calculations
$userListButton
.removeClass(className.active)
;
module.width = {
log : $log.width(),
userList : $userList.outerWidth()
};
if( $userListButton.hasClass(className.active) ) {
module.user.list.hide();
}
$module.data('module', module);
},
user: {
updateCount: function() {
if(settings.userCount) {
users = $module.data('users');
count = 0;
$.each(users, function() {
count++;
});
$userCount
.html( settings.templates.userCount(count) )
;
}
},
// add user to user list
joined: function(member) {
users = $module.data('users');
if(member.id != 'anonymous' && users[ member.id ] === undefined ) {
users[ member.id ] = member.info;
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
html = settings.templates.userList(member.info);
if(member.info.isAdmin) {
$(html)
.prependTo($userList)
;
}
else {
$(html)
.appendTo($userList)
;
}
if(settings.partingMessages) {
$log
.append( settings.templates.joined(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
// remove user from user list
left: function(member) {
users = $module.data('users');
if(member !== undefined && member.id !== 'anonymous') {
delete users[ member.id ];
$module
.data('users', users)
;
$userList
.find('[data-id='+ member.id + ']')
.remove()
;
if(settings.partingMessages) {
$log
.append( settings.templates.left(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
list: {
// receives list of members and generates user list
create: function(members) {
users = {};
members.each(function(member) {
if(member.id !== 'anonymous' && member.id !== 'undefined') {
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
// sort list with admin first
html = (member.info.isAdmin)
? settings.templates.userList(member.info) + html
: html + settings.templates.userList(member.info)
;
users[ member.id ] = member.info;
}
});
$module
.data('users', users)
.data('user', users[members.me.id] )
.removeClass(className.loading)
;
$userList
.html(html)
;
module.user.updateCount();
$.proxy(settings.onJoin, $userList.children())();
},
// shows user list
show: function() {
$log
.animate({
width: (module.width.log - module.width.userList)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
},
// hides user list
hide: function() {
$log
.stop()
.animate({
width: (module.width.log)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
}
}
},
message: {
// handles scrolling of chat log
scroll: {
test: function() {
height = $log.prop('scrollHeight') - $log.height();
if( Math.abs($log.scrollTop() - height) < settings.scrollArea) {
module.message.scroll.move();
}
},
move: function() {
height = $log.prop('scrollHeight') - $log.height();
$log
.scrollTop(height)
;
}
},
// sends chat message
send: function(message) {
if( !module.utils.emptyString(message) ) {
$.api({
url : settings.endpoint.message,
method : 'POST',
data : {
'message': {
content : message,
timestamp : new Date().getTime()
}
}
});
}
},
// receives chat response and processes
receive: function(response) {
message = response.data;
users = $module.data('users');
loggedInUser = $module.data('user');
if(users[ message.userID] !== undefined) {
// logged in user's messages already pushed instantly
if(loggedInUser === undefined || loggedInUser.id != message.userID) {
message.user = users[ message.userID ];
module.message.display(message);
}
}
},
// displays message in chat log
display: function(message) {
$log
.append( settings.templates.message(message) )
;
module.message.scroll.test();
$.proxy(settings.onMessage, $log.children().last() )();
}
},
expand: function() {
$module
.addClass(className.expand)
;
$.proxy(settings.onExpand, $module )();
module.refresh();
},
contract: function() {
$module
.removeClass(className.expand)
;
$.proxy(settings.onContract, $module )();
module.refresh();
},
event: {
input: {
keydown: function(event) {
if(event.which == 13) {
$messageButton
.addClass(className.down)
;
}
},
keyup: function(event) {
if(event.which == 13) {
$messageButton
.removeClass(className.down)
;
module.event.submit();
}
}
},
// handles message form submit
submit: function() {
var
message = $messageInput.val(),
loggedInUser = $module.data('user')
;
if(loggedInUser !== undefined && !module.utils.emptyString(message)) {
module.message.send(message);
// display immediately
module.message.display({
user: loggedInUser,
text: message
});
module.message.scroll.move();
$messageInput
.val('')
;
}
},
// handles button click on expand button
toggleExpand: function() {
if( !$module.hasClass(className.expand) ) {
$expandButton
.addClass(className.active)
;
module.expand();
}
else {
$expandButton
.removeClass(className.active)
;
module.contract();
}
},
// handles button click on user list button
toggleUserList: function() {
if( !$log.is(':animated') ) {
if( !$userListButton.hasClass(className.active) ) {
$userListButton
.addClass(className.active)
;
module.user.list.show();
}
else {
$userListButton
.removeClass('active')
;
module.user.list.hide();
}
}
}
},
utils: {
emptyString: function(string) {
if(typeof string == 'string') {
return (string.search(/\S/) == -1);
}
return false;
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
title += ' ' + '(' + $allDropdowns.size() + ')';
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( instance[value] !== undefined ) {
found = instance[value];
}
else {
module.error(error.method);
}
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
return found || false;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
invokedResponse = module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse)
? invokedResponse
: this
;
};
$.fn.chatroom.settings = {
name : 'Chat',
debug : false,
namespace : 'chat',
channel : 'present-chat',
onJoin : function(){},
onMessage : function(){},
onExpand : function(){},
onContract : function(){},
customEvents : {},
partingMessages : false,
userCount : true,
randomColor : true,
speed : 300,
easing : 'easeOutQuint',
// pixels from bottom of chat log that should trigger auto scroll to bottom
scrollArea : 9999,
endpoint : {
message : false,
authentication : false
},
error: {
method : 'The method you called is not defined',
endpoint : 'Please define a message and authentication endpoint.',
key : 'You must specify a pusher key and channel.',
pusher : 'You must include the Pusher library.'
},
className : {
expand : 'expand',
active : 'active',
hover : 'hover',
down : 'down',
loading : 'loading'
},
selector : {
userCount : '.actions .message',
userListButton : '.actions .list.button',
expandButton : '.actions .expand.button',
room : '.room',
userList : '.room .list',
log : '.room .log',
message : '.room .log .message',
author : '.room log .message .author',
messageInput : '.talk input',
messageButton : '.talk .send.button'
},
templates: {
userCount: function(number) {
return number + ' users in chat';
},
color: function(userID) {
var
colors = [
'#000000',
'#333333',
'#666666',
'#999999',
'#CC9999',
'#CC6666',
'#CC3333',
'#993333',
'#663333',
'#CC6633',
'#CC9966',
'#CC9933',
'#999966',
'#CCCC66',
'#99CC66',
'#669933',
'#669966',
'#33A3CC',
'#336633',
'#33CCCC',
'#339999',
'#336666',
'#336699',
'#6666CC',
'#9966CC',
'#333399',
'#663366',
'#996699',
'#993366',
'#CC6699'
]
;
return colors[ Math.floor( Math.random() * colors.length) ];
},
message: function(message) {
var
html = ''
;
if(message.user.isAdmin) {
message.user.color = '#55356A';
html += '<div class="admin message">';
html += '<span class="quirky ui flag team"></span>';
}
/*
else if(message.user.isPro) {
html += '<div class="indent message">';
html += '<span class="quirky ui flag pro"></span>';
}
*/
else {
html += '<div class="message">';
}
html += '<p>';
if(message.user.color !== undefined) {
html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: ';
}
else {
html += '<span class="author">' + message.user.name + '</span>: ';
}
html += ''
+ message.text
+ ' </p>'
+ '</div>'
;
return html;
},
joined: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has joined the chat.</div>'
: false
;
},
left: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has left the chat.</div>'
: false
;
},
userList: function(member) {
var
html = ''
;
if(member.isAdmin) {
member.color = '#55356A';
}
html += ''
+ '<div class="user" data-id="' + member.id + '">'
+ ' <div class="image">'
+ ' <img src="' + member.avatarURL + '">'
+ ' </div>'
;
if(member.color !== undefined) {
html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>';
}
else {
html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>';
}
html += '</div>';
return html;
}
}
};
})( jQuery, window , document );

2
build/uncompressed/modules/dropdown.js

@ -23,7 +23,7 @@ $.fn.dropdown = function(parameters) {
error = settings.error, error = settings.error,
eventNamespace = '.' + namespace, eventNamespace = '.' + namespace,
dropdownNamespace = 'dropdown-' + namespace, dropdownNamespace = 'module-' + namespace,
dropdownSelector = $allDropdowns.selector || '', dropdownSelector = $allDropdowns.selector || '',
time = new Date().getTime(), time = new Date().getTime(),

120
build/uncompressed/modules/rating.css

@ -0,0 +1,120 @@
/*******************************
Star Rating
*******************************/
.ui.rating {
display: inline-block;
vertical-align: middle;
margin: 0em 0.5em;
}
.ui.rating:first-child {
margin-left: 0em;
}
.ui.rating:last-child {
margin-right: 0em;
}
.ui.rating:after {
display: block;
content: '';
visibility: hidden;
clear: both;
height: 0;
}
/* Icon */
.ui.rating .icon {
cursor: default;
float: left;
margin: 0em;
width: 1em;
height: auto;
padding: 0em;
font-weight: normal;
font-style: normal;
}
.ui.rating .icon:after {
content: "\2605";
color: rgba(0, 0, 0, 0.15);
-webkit-transition: color 0.3s ease,
opacity 0.3s ease
;
-moz-transition: color 0.3s ease,
opacity 0.3s ease
;
-ms-transition: color 0.3s ease,
opacity 0.3s ease
;
-o-transition: color 0.3s ease,
opacity 0.3s ease
;
transition: color 0.3s ease,
opacity 0.3s ease
;
}
/*******************************
Types
*******************************/
/*-------------------
Star
--------------------*/
.ui.star.rating .icon:after {
content: '\e800';
font-family: 'Icons';
}
.ui.star.rating .active.icon:after {
content: '\e801';
font-family: 'Icons';
}
/*-------------------
Heart
--------------------*/
.ui.heart.rating .icon:after {
content: '\2661';
font-family: 'Icons';
}
.ui.heart.rating .active.icon:after {
content: '\2665';
font-family: 'Icons';
color: #EF404A;
}
.ui.heart.rating .hover.icon:after,
.ui.heart.rating .active.hover.icon:after {
color: #FF2733;
}
/*******************************
States
*******************************/
/*-------------------
Active
--------------------*/
/* active rating */
.ui.active.rating .icon {
cursor: pointer;
}
/* active icons */
.ui.rating .active.icon:after {
color: #FFCB08;
}
/*-------------------
Hover
--------------------*/
/* rating */
.ui.rating.hover .active.icon:after {
opacity: 0.5;
}
/* icon */
.ui.rating .icon.hover:after,
.ui.rating .icon.hover.active:after {
opacity: 1;
color: #FFB70A;
}
/*******************************
Variations
*******************************/
.ui.small.rating {
font-size: 1rem;
}
.ui.rating {
font-size: 1.5rem;
}
.ui.large.rating {
font-size: 2rem;
}

358
build/uncompressed/modules/rating.js

@ -0,0 +1,358 @@
/* ******************************
Star Review
Author: Jack Lukic
Notes: First Commit Sep 04, 2012
Simple rating module
****************************** */
;(function ($, window, document, undefined) {
$.fn.rating = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
settings = $.extend(true, {}, $.fn.rating.settings, parameters),
namespace = settings.namespace,
className = settings.className,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
invokedResponse
;
$allModules
.each(function() {
var
$module = $(this),
$icon = $module.find(selector.icon),
element = this,
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
module.verbose('Initializing rating module');
if(settings.interactive) {
$icon
.bind('mouseenter' + eventNamespace, module.event.mouseenter)
.bind('mouseleave' + eventNamespace, module.event.mouseleave)
.bind('click' + eventNamespace, module.event.click)
;
}
if(settings.initialRating) {
module.debug('Setting initial rating');
module.setRating(settings.initialRating);
}
if( $module.data(metadata.rating) ) {
module.debug('Rating found in metadata');
module.setRating( $module.data(metadata.rating) );
}
$module
.addClass(className.active)
;
module.instantiate();
},
instantiate: function() {
module.verbose('Instantiating module', settings);
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
$module
.removeData(moduleNamespace)
;
$icon
.off(eventNamespace)
;
},
setRating: function(rating) {
var
$activeIcon = $icon.eq(rating - 1)
;
module.verbose('Setting current rating to', rating);
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
$activeIcon
.nextAll()
.removeClass(className.active)
;
$activeIcon
.addClass(className.active)
.prevAll()
.addClass(className.active)
;
$.proxy(settings.onRate, element)();
},
event: {
mouseenter: function() {
var
$activeIcon = $(this)
;
$activeIcon
.nextAll()
.removeClass(className.hover)
;
$module
.addClass(className.hover)
;
$activeIcon
.addClass(className.hover)
.prevAll()
.addClass(className.hover)
;
},
mouseleave: function() {
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
},
click: function() {
var
$activeIcon = $(this)
;
module.setRating( $icon.index($activeIcon) + 1);
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.size() > 1) {
title += ' ' + '(' + $allModules.size() + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
instance = instance[camelCaseValue];
}
else if( instance[value] !== undefined ) {
found = instance[value];
return false;
}
else if( instance[camelCaseValue] !== undefined ) {
found = instance[camelCaseValue];
return false;
}
else {
module.error(error.method);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(invokedResponse)) {
invokedResponse.push(response);
}
else if(typeof invokedResponse == 'string') {
invokedResponse = [invokedResponse, response];
}
else if(response !== undefined) {
invokedResponse = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse !== undefined)
? invokedResponse
: this
;
};
$.fn.rating.settings = {
name : 'Rating',
namespace : 'rating',
verbose : true,
debug : true,
performance : true,
initialRating : 0,
interactive : true,
onRate : function(){},
error : {
method : 'The method you called is not defined'
},
metadata: {
rating: 'rating'
},
className : {
active : 'active',
hover : 'hover',
loading : 'loading'
},
selector : {
icon : '.icon'
}
};
})( jQuery, window , document );

2
node/src/documents/modules/chat.html

@ -14,7 +14,7 @@ type : 'UI Module'
<div class="segment"> <div class="segment">
<div class="container"> <div class="container">
<h1 class="ui dividing header">Chatroom <span class="ui red label">Incomplete</span></h1> <h1 class="ui dividing header">Chatroom <span class="ui red label">Incomplete</span></h1>
<p>A chatroom allows users to communicate to each other.</p> <p>A chatroom allows users to communicate with each other in real time.</p>
<div class="ui teal basic labeled icon overview toggle button"> <div class="ui teal basic labeled icon overview toggle button">
Definition Definition
<i class="book icon"></i> <i class="book icon"></i>

2
node/src/files/components/semantic/elements/segment.css

@ -292,7 +292,7 @@
} }
.ui.inverted.segment, .ui.inverted.segment,
.ui.primary.inverted.segment { .ui.primary.inverted.segment {
background-color: #555555; background-color: #222222;
color: #FFFFFF; color: #FFFFFF;
} }
/*------------------- /*-------------------

25
node/src/files/components/semantic/modules/chatroom.css

@ -9,9 +9,10 @@
} }
.ui.chatroom .room { .ui.chatroom .room {
position: relative; position: relative;
background-color: #FFFFFF;
overflow: hidden; overflow: hidden;
height: 286px; height: 286px;
border: 1px solid #999999; border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none; border-top: none;
border-bottom: none; border-bottom: none;
} }
@ -154,18 +155,9 @@
} }
/* Chat Room Talk Input */ /* Chat Room Talk Input */
.ui.chatroom .talk { .ui.chatroom .talk {
border: 1px solid #999999; border: 1px solid rgba(0, 0, 0, 0.1);
border-top: 1px solid rgba(0, 0, 0, 0.1);
padding: 5px 0px 0px; padding: 5px 0px 0px;
background-color: #CCCCCC; background-color: #EEEEEE;
background: #ffffff -webkit-linear-gradient(top, #eeeeee 0%, #aaaaaa 100%) repeat;
background: #ffffff -moz-linear-gradient(top, #eeeeee 0%, #aaaaaa 100%) repeat;
background: #ffffff -o-linear-gradient(top, #eeeeee 0%, #aaaaaa 100%) repeat;
background: #ffffff -ms-linear-gradient(top, #eeeeee 0%, #aaaaaa 100%) repeat;
background: #ffffff linear-gradient(top, #eeeeee 0%, #aaaaaa 100%) repeat;
-webkit-box-shadow: 0px 1px 0px #FFFFFF inset;
-moz-box-shadow: 0px 1px 0px #FFFFFF inset;
box-shadow: 0px 1px 0px #FFFFFF inset;
-webkit-border-radius: 0px 0px 5px 5px; -webkit-border-radius: 0px 0px 5px 5px;
-moz-border-radius: 0px 0px 5px 5px; -moz-border-radius: 0px 0px 5px 5px;
border-radius: 0px 0px 5px 5px; border-radius: 0px 0px 5px 5px;
@ -175,19 +167,12 @@
.ui.chatroom .talk .button { .ui.chatroom .talk .button {
float: left; float: left;
} }
.ui.chatroom .talk .avatar {
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-left: 1px solid rgba(0, 0, 0, 0.1);
width: 30px;
height: 30px;
margin: 0px 0px 0px 5px;
background-color: #DADADA;
}
.ui.chatroom .talk .avatar img { .ui.chatroom .talk .avatar img {
display: block; display: block;
width: 30px; width: 30px;
height: 30px; height: 30px;
margin-right: 4px; margin-right: 4px;
border-radius: 500rem;
} }
.ui.chatroom .talk input { .ui.chatroom .talk input {
border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;

166
node/src/files/components/semantic/modules/chatroom.js

@ -432,56 +432,160 @@
}, },
// standard methods
debug: function(message) {
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) { if(settings.debug) {
console.info(settings.moduleName + ': ' + message); if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
} }
}, },
error: function(errorMessage) { verbose: function() {
console.warn(settings.moduleName + ': ' + errorMessage); if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
}, },
invoke: function(methodName, context, methodArguments) { error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var var
method currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
; ;
methodArguments = methodArguments || Array.prototype.slice.call( arguments, 2 ); time = false;
if(typeof methodName == 'string' && instance !== undefined) { clearTimeout(module.performance.timer);
methodName = methodName.split('.'); $.each(performance, function(index, data) {
$.each(methodName, function(index, name) { totalTime += data['Execution Time'];
if( $.isPlainObject( instance[name] ) ) { });
instance = instance[name]; title += ' ' + totalTime + 'ms';
return true; if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
} }
else if( $.isFunction( instance[name] ) ) { title += ' ' + '(' + $allDropdowns.size() + ')';
method = instance[name]; if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
return true; console.groupCollapsed(title);
if(console.table) {
console.table(performance);
} }
module.error(error.method); else {
return false; $.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
}); });
} }
return ( $.isFunction( method ) ) console.groupEnd();
? method.apply(context, methodArguments) }
: false performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found
; ;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( instance[value] !== undefined ) {
found = instance[value];
}
else {
module.error(error.method);
}
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
return found || false;
} }
}; };
if(instance !== undefined && moduleArguments) { if(methodInvoked) {
// simpler than invoke realizing to invoke itself (and losing scope due prototype.call() if(instance === undefined) {
if(moduleArguments[0] == 'invoke') { module.initialize();
moduleArguments = Array.prototype.slice.call( moduleArguments, 1 ); }
invokedResponse = module.invoke(query);
} }
return module.invoke(moduleArguments[0], this, Array.prototype.slice.call( moduleArguments, 1 ) ); else {
if(instance !== undefined) {
module.destroy();
} }
// initializing
module.initialize(); module.initialize();
}
}) })
; ;
return this; return (invokedResponse)
? invokedResponse
: this
;
}; };
$.fn.chatroom.settings = { $.fn.chatroom.settings = {
@ -514,7 +618,7 @@
authentication : false authentication : false
}, },
errors: { error: {
method : 'The method you called is not defined', method : 'The method you called is not defined',
endpoint : 'Please define a message and authentication endpoint.', endpoint : 'Please define a message and authentication endpoint.',
key : 'You must specify a pusher key and channel.', key : 'You must specify a pusher key and channel.',

2
node/src/files/components/semantic/modules/dropdown.js

@ -23,7 +23,7 @@ $.fn.dropdown = function(parameters) {
error = settings.error, error = settings.error,
eventNamespace = '.' + namespace, eventNamespace = '.' + namespace,
dropdownNamespace = 'dropdown-' + namespace, dropdownNamespace = 'module-' + namespace,
dropdownSelector = $allDropdowns.selector || '', dropdownSelector = $allDropdowns.selector || '',
time = new Date().getTime(), time = new Date().getTime(),

1
node/src/files/javascript/semantic.js

@ -594,7 +594,6 @@ semantic.ready = function() {
$menuPopup $menuPopup
.popup({ .popup({
transition : 'fade up',
position : 'bottom center', position : 'bottom center',
className: { className: {
popup: 'ui popup' popup: 'ui popup'

84
node/src/files/stylesheets/semantic.css

@ -224,6 +224,7 @@ a:hover {
} }
#example .main.menu { #example .main.menu {
top: 0px;
min-width: 370px; min-width: 370px;
z-index: 900; z-index: 900;
@ -280,12 +281,85 @@ a:hover {
} }
#example .masthead { #example .masthead {
text-align: center; text-align: center;
background: #00B5AD url(/images/tile-bg.png) repeat-x fixed 50% 0%; background: #00B5AD url(/images/tile-bg.png) repeat fixed 0% 0%;
padding: 75px 0px 50px; margin-top: 40px;
padding: 50px 0px;
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
margin-bottom: 0px; margin-bottom: 0px;
border-bottom: none; border-bottom: none;
-webkit-animation-name: masthead;
-moz-animation-name: masthead;
-o-animation-name: masthead;
animation-name: masthead;
-webkit-animation-duration: 30s;
-moz-animation-duration: 30s;
-ms-animation-duration: 30s;
-o-animation-duration: 30s;
animation-duration: 30s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
} }
@-moz-keyframes masthead {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% -100%;
}
}
@-webkit-keyframes "masthead" {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% -100%;
}
}
@-ms-keyframes "masthead" {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% -100%;
}
}
@-o-keyframes "masthead" {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% -100%;
}
}
@keyframes "masthead" {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0% -100%;
}
}
#example .masthead .labeled.button { #example .masthead .labeled.button {
position: relative; position: relative;
left: 0px; left: 0px;
@ -297,7 +371,7 @@ a:hover {
font-size: 5em; font-size: 5em;
color: #FFFFFF; color: #FFFFFF;
line-height: 1.2; line-height: 1.2;
margin: 0em; margin: -20px 0px 0px;
padding-bottom: 0px; padding-bottom: 0px;
} }
#example .masthead strike { #example .masthead strike {
@ -395,13 +469,15 @@ a:hover {
#example .page .of { #example .page .of {
font-family: 'Neutraface'; font-family: 'Neutraface';
} }
#example .launch.button { #example .launch.button {
position: fixed; position: fixed;
top: 63px; top: 63px;
z-index: 500; z-index: 500;
width: 70px; width: 70px;
} }
#example.index .attached.launch.button {
top: 96px;
}
#example .launch.button .text { #example .launch.button .text {
display: inline-block; display: inline-block;
display: none; display: none;

2
src/elements/segment.less

@ -380,7 +380,7 @@
} }
.ui.inverted.segment, .ui.inverted.segment,
.ui.primary.inverted.segment { .ui.primary.inverted.segment {
background-color: #555555; background-color: #222222;
color: #FFFFFF; color: #FFFFFF;
} }

766
src/modules/chatroom.js

@ -0,0 +1,766 @@
/* ******************************
Module - Chat Room
Author: Jack Lukic
Notes: First Commit Aug 8, 2012
Designed as a simple modular chat component
****************************** */
;(function ($, window, document, undefined) {
$.fn.chatroom = function(parameters) {
var
settings = $.extend(true, {}, $.fn.chatroom.settings, parameters),
className = settings.className,
namespace = settings.namespace,
selector = settings.selector,
error = settings.error,
// hoist arguments
moduleArguments = arguments || false
;
$(this)
.each(function() {
var
$module = $(this),
$expandButton = $module.find(selector.expandButton),
$userListButton = $module.find(selector.userListButton),
$userList = $module.find(selector.userList),
$room = $module.find(selector.room),
$userCount = $module.find(selector.userCount),
$log = $module.find(selector.log),
$message = $module.find(selector.message),
$messageInput = $module.find(selector.messageInput),
$messageButton = $module.find(selector.messageButton),
instance = $module.data('module'),
html = '',
users = {},
channel,
loggedInUser,
message,
count,
height,
pusher,
module
;
module = {
width: {
log : $log.width(),
userList : $userList.outerWidth()
},
initialize: function() {
// check error conditions
if(Pusher === undefined) {
module.error(error.pusher);
}
if(settings.key === undefined || settings.channelName === undefined) {
module.error(error.key);
return false;
}
else if( !(settings.endpoint.message || settings.endpoint.authentication) ) {
module.error(error.endpoint);
return false;
}
// define pusher
pusher = new Pusher(settings.key);
Pusher.channel_auth_endpoint = settings.endpoint.authentication;
channel = pusher.subscribe(settings.channelName);
channel.bind('pusher:subscription_succeeded', module.user.list.create);
channel.bind('pusher:subscription_error', module.error);
channel.bind('pusher:member_added', module.user.joined);
channel.bind('pusher:member_removed', module.user.left);
channel.bind('update_messages', module.message.receive);
$.each(settings.customEvents, function(label, value) {
channel.bind(label, value);
});
// bind module events
$userListButton
.on('click.' + namespace, module.event.toggleUserList)
;
$expandButton
.on('click.' + namespace, module.event.toggleExpand)
;
$messageInput
.on('keydown.' + namespace, module.event.input.keydown)
.on('keyup.' + namespace, module.event.input.keyup)
;
$messageButton
.on('mouseenter.' + namespace, module.event.hover)
.on('mouseleave.' + namespace, module.event.hover)
.on('click.' + namespace, module.event.submit)
;
// scroll to bottom of chat log
$log
.animate({
scrollTop: $log.prop('scrollHeight')
}, 400)
;
$module
.data('module', module)
.addClass(className.loading)
;
},
// refresh module
refresh: function() {
// reset width calculations
$userListButton
.removeClass(className.active)
;
module.width = {
log : $log.width(),
userList : $userList.outerWidth()
};
if( $userListButton.hasClass(className.active) ) {
module.user.list.hide();
}
$module.data('module', module);
},
user: {
updateCount: function() {
if(settings.userCount) {
users = $module.data('users');
count = 0;
$.each(users, function() {
count++;
});
$userCount
.html( settings.templates.userCount(count) )
;
}
},
// add user to user list
joined: function(member) {
users = $module.data('users');
if(member.id != 'anonymous' && users[ member.id ] === undefined ) {
users[ member.id ] = member.info;
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
html = settings.templates.userList(member.info);
if(member.info.isAdmin) {
$(html)
.prependTo($userList)
;
}
else {
$(html)
.appendTo($userList)
;
}
if(settings.partingMessages) {
$log
.append( settings.templates.joined(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
// remove user from user list
left: function(member) {
users = $module.data('users');
if(member !== undefined && member.id !== 'anonymous') {
delete users[ member.id ];
$module
.data('users', users)
;
$userList
.find('[data-id='+ member.id + ']')
.remove()
;
if(settings.partingMessages) {
$log
.append( settings.templates.left(member.info) )
;
module.message.scroll.test();
}
module.user.updateCount();
}
},
list: {
// receives list of members and generates user list
create: function(members) {
users = {};
members.each(function(member) {
if(member.id !== 'anonymous' && member.id !== 'undefined') {
if(settings.randomColor && member.info.color === undefined) {
member.info.color = settings.templates.color(member.id);
}
// sort list with admin first
html = (member.info.isAdmin)
? settings.templates.userList(member.info) + html
: html + settings.templates.userList(member.info)
;
users[ member.id ] = member.info;
}
});
$module
.data('users', users)
.data('user', users[members.me.id] )
.removeClass(className.loading)
;
$userList
.html(html)
;
module.user.updateCount();
$.proxy(settings.onJoin, $userList.children())();
},
// shows user list
show: function() {
$log
.animate({
width: (module.width.log - module.width.userList)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
},
// hides user list
hide: function() {
$log
.stop()
.animate({
width: (module.width.log)
}, {
duration : settings.speed,
easing : settings.easing,
complete : module.message.scroll.move
})
;
}
}
},
message: {
// handles scrolling of chat log
scroll: {
test: function() {
height = $log.prop('scrollHeight') - $log.height();
if( Math.abs($log.scrollTop() - height) < settings.scrollArea) {
module.message.scroll.move();
}
},
move: function() {
height = $log.prop('scrollHeight') - $log.height();
$log
.scrollTop(height)
;
}
},
// sends chat message
send: function(message) {
if( !module.utils.emptyString(message) ) {
$.api({
url : settings.endpoint.message,
method : 'POST',
data : {
'message': {
content : message,
timestamp : new Date().getTime()
}
}
});
}
},
// receives chat response and processes
receive: function(response) {
message = response.data;
users = $module.data('users');
loggedInUser = $module.data('user');
if(users[ message.userID] !== undefined) {
// logged in user's messages already pushed instantly
if(loggedInUser === undefined || loggedInUser.id != message.userID) {
message.user = users[ message.userID ];
module.message.display(message);
}
}
},
// displays message in chat log
display: function(message) {
$log
.append( settings.templates.message(message) )
;
module.message.scroll.test();
$.proxy(settings.onMessage, $log.children().last() )();
}
},
expand: function() {
$module
.addClass(className.expand)
;
$.proxy(settings.onExpand, $module )();
module.refresh();
},
contract: function() {
$module
.removeClass(className.expand)
;
$.proxy(settings.onContract, $module )();
module.refresh();
},
event: {
input: {
keydown: function(event) {
if(event.which == 13) {
$messageButton
.addClass(className.down)
;
}
},
keyup: function(event) {
if(event.which == 13) {
$messageButton
.removeClass(className.down)
;
module.event.submit();
}
}
},
// handles message form submit
submit: function() {
var
message = $messageInput.val(),
loggedInUser = $module.data('user')
;
if(loggedInUser !== undefined && !module.utils.emptyString(message)) {
module.message.send(message);
// display immediately
module.message.display({
user: loggedInUser,
text: message
});
module.message.scroll.move();
$messageInput
.val('')
;
}
},
// handles button click on expand button
toggleExpand: function() {
if( !$module.hasClass(className.expand) ) {
$expandButton
.addClass(className.active)
;
module.expand();
}
else {
$expandButton
.removeClass(className.active)
;
module.contract();
}
},
// handles button click on user list button
toggleUserList: function() {
if( !$log.is(':animated') ) {
if( !$userListButton.hasClass(className.active) ) {
$userListButton
.addClass(className.active)
;
module.user.list.show();
}
else {
$userListButton
.removeClass('active')
;
module.user.list.hide();
}
}
}
},
utils: {
emptyString: function(string) {
if(typeof string == 'string') {
return (string.search(/\S/) == -1);
}
return false;
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
title += ' ' + '(' + $allDropdowns.size() + ')';
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( instance[value] !== undefined ) {
found = instance[value];
}
else {
module.error(error.method);
}
});
}
if ( $.isFunction( found ) ) {
return found.apply(context, passedArguments);
}
return found || false;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
invokedResponse = module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse)
? invokedResponse
: this
;
};
$.fn.chatroom.settings = {
name : 'Chat',
debug : false,
namespace : 'chat',
channel : 'present-chat',
onJoin : function(){},
onMessage : function(){},
onExpand : function(){},
onContract : function(){},
customEvents : {},
partingMessages : false,
userCount : true,
randomColor : true,
speed : 300,
easing : 'easeOutQuint',
// pixels from bottom of chat log that should trigger auto scroll to bottom
scrollArea : 9999,
endpoint : {
message : false,
authentication : false
},
error: {
method : 'The method you called is not defined',
endpoint : 'Please define a message and authentication endpoint.',
key : 'You must specify a pusher key and channel.',
pusher : 'You must include the Pusher library.'
},
className : {
expand : 'expand',
active : 'active',
hover : 'hover',
down : 'down',
loading : 'loading'
},
selector : {
userCount : '.actions .message',
userListButton : '.actions .list.button',
expandButton : '.actions .expand.button',
room : '.room',
userList : '.room .list',
log : '.room .log',
message : '.room .log .message',
author : '.room log .message .author',
messageInput : '.talk input',
messageButton : '.talk .send.button'
},
templates: {
userCount: function(number) {
return number + ' users in chat';
},
color: function(userID) {
var
colors = [
'#000000',
'#333333',
'#666666',
'#999999',
'#CC9999',
'#CC6666',
'#CC3333',
'#993333',
'#663333',
'#CC6633',
'#CC9966',
'#CC9933',
'#999966',
'#CCCC66',
'#99CC66',
'#669933',
'#669966',
'#33A3CC',
'#336633',
'#33CCCC',
'#339999',
'#336666',
'#336699',
'#6666CC',
'#9966CC',
'#333399',
'#663366',
'#996699',
'#993366',
'#CC6699'
]
;
return colors[ Math.floor( Math.random() * colors.length) ];
},
message: function(message) {
var
html = ''
;
if(message.user.isAdmin) {
message.user.color = '#55356A';
html += '<div class="admin message">';
html += '<span class="quirky ui flag team"></span>';
}
/*
else if(message.user.isPro) {
html += '<div class="indent message">';
html += '<span class="quirky ui flag pro"></span>';
}
*/
else {
html += '<div class="message">';
}
html += '<p>';
if(message.user.color !== undefined) {
html += '<span class="author" style="color: ' + message.user.color + ';">' + message.user.name + '</span>: ';
}
else {
html += '<span class="author">' + message.user.name + '</span>: ';
}
html += ''
+ message.text
+ ' </p>'
+ '</div>'
;
return html;
},
joined: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has joined the chat.</div>'
: false
;
},
left: function(member) {
return (typeof member.name !== undefined)
? '<div class="status">' + member.name + ' has left the chat.</div>'
: false
;
},
userList: function(member) {
var
html = ''
;
if(member.isAdmin) {
member.color = '#55356A';
}
html += ''
+ '<div class="user" data-id="' + member.id + '">'
+ ' <div class="image">'
+ ' <img src="' + member.avatarURL + '">'
+ ' </div>'
;
if(member.color !== undefined) {
html += ' <p><a href="/users/' + member.id + '" target="_blank" style="color: ' + member.color + ';">' + member.name + '</a></p>';
}
else {
html += ' <p><a href="/users/' + member.id + '" target="_blank">' + member.name + '</a></p>';
}
html += '</div>';
return html;
}
}
};
})( jQuery, window , document );

271
src/modules/chatroom.less

@ -0,0 +1,271 @@
/*******************************
Chat Room
*******************************/
.ui.chatroom {
background-color: #F8F8F8;
width: 330px;
height: 370px;
padding: 0px;
}
.ui.chatroom .room {
position: relative;
background-color: #FFFFFF;
overflow: hidden;
height: 286px;
border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none;
border-bottom: none;
}
.ui.chatroom .room .loader {
display: none;
margin: -25px 0px 0px -25px;
}
/* Chat Room Actions */
.ui.chatroom .actions {
overflow: hidden;
background-color: #EEEEEE;
padding: 4px;
border: 1px solid rgba(0, 0, 0, 0.1);
-moz-border-radius: 5px 5px 0px 0px;
-webkit-border-radius: 5px 5px 0px 0px;
border-radius: 5px 5px 0px 0px;
}
.ui.chatroom .actions .button {
float: right;
margin-left: 3px;
}
/* Online User Count */
.ui.chatroom .actions .message {
float: left;
margin-left: 6px;
font-size: 11px;
color: #AAAAAA;
text-shadow: 0px -1px 0px rgba(255, 255, 255, 0.8);
line-height: 28px;
}
.ui.chatroom .actions .message .loader {
display: inline-block;
margin-right: 8px;
}
/* Chat Room Text Log */
.ui.chatroom .log {
float: left;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
.ui.chatroom .log .message {
padding: 3px 0px;
border-top: 1px dotted #DADADA;
}
.ui.chatroom .log .message:first-child {
border-top: none;
}
/* status event */
.ui.chatroom .status {
padding: 5px 0px;
color: #AAAAAA;
font-size: 12px;
font-style: italic;
line-height: 1.33;
border-top: 1px dotted #DADADA;
}
.ui.chatroom .log .status:first-child {
border-top: none;
}
.ui.chatroom .log .flag {
float: left;
}
.ui.chatroom .log p {
margin-left: 0px;
}
.ui.chatroom .log .author {
font-weight: bold;
-webkit-transition: color 0.3s ease-out;
-moz-transition: color 0.3s ease-out;
-o-transition: color 0.3s ease-out;
-ms-transition: color 0.3s ease-out;
transition: color 0.3s ease-out;
}
.ui.chatroom .log a.author:hover {
opacity: 0.8;
}
.ui.chatroom .log .message.admin p {
font-weight: bold;
margin: 1px 0px 0px 23px;
}
.ui.chatroom .log .divider {
margin: -1px 0px;
font-size: 11px;
padding: 10px 0px;
border-top: 1px solid #F8F8F8;
border-bottom: 1px solid #F8F8F8;
}
.ui.chatroom .log .divider .rule {
top: 50%;
width: 15%;
}
.ui.chatroom .log .divider .label {
color: #777777;
margin: 0px;
}
/* Chat Room User List */
.ui.chatroom .room .list {
position: relative;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
float: left;
background-color: #EEEEEE;
border-left: 1px solid #DDDDDD;
}
.ui.chatroom .room .list .user {
display: table;
padding: 3px 7px;
border-bottom: 1px solid #DDDDDD;
}
.ui.chatroom .room .list .user:hover {
background-color: #F8F8F8;
}
.ui.chatroom .room .list .image {
display: table-cell;
vertical-align: middle;
width: 20px;
}
.ui.chatroom .room .list .image img {
width: 20px;
height: 20px;
vertical-align: middle;
}
.ui.chatroom .room .list p {
display: table-cell;
vertical-align: middle;
padding-left: 7px;
padding-right: 14px;
font-size: 11px;
line-height: 1.2;
font-weight: bold;
}
.ui.chatroom .room .list a:hover {
opacity: 0.8;
}
/* User List Loading */
.ui.chatroom.loading .loader {
display: block;
}
/* Chat Room Talk Input */
.ui.chatroom .talk {
border: 1px solid rgba(0, 0, 0, 0.1);
padding: 5px 0px 0px;
background-color: #EEEEEE;
-webkit-border-radius: 0px 0px 5px 5px;
-moz-border-radius: 0px 0px 5px 5px;
border-radius: 0px 0px 5px 5px;
}
.ui.chatroom .talk .avatar,
.ui.chatroom .talk input,
.ui.chatroom .talk .button {
float: left;
}
.ui.chatroom .talk .avatar img {
display: block;
width: 30px;
height: 30px;
margin-right: 4px;
border-radius: 500rem;
}
.ui.chatroom .talk input {
border: 1px solid #CCCCCC;
margin: 0px;
width: 196px;
height: 14px;
padding: 8px 5px;
font-size: 12px;
color: #555555;
}
.ui.chatroom .talk input.focus {
border: 1px solid #AAAAAA;
}
.ui.chatroom .send {
width: 80px;
height: 32px;
margin-left: -1px;
padding: 4px 12px;
font-size: 12px;
line-height: 23px;
-webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
-moz-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) inset;
border-radius: 0 5px 5px 0;
}
.ui.chatroom .talk .log-in.button {
display: block;
float: none;
margin-top: -6px;
height: 22px;
border-radius: 0px 0px 4px 4px;
}
.ui.chatroom .talk .log-in.button i {
vertical-align: text-top;
}
/* Quirky Flags */
.ui.chatroom .log .team.flag {
width: 18px;
}
/* Chat room Loaded */
.ui.chatroom.loading .loader {
display: block;
}
/* Standard Size */
.ui.chatroom {
width: 330px;
height: 370px;
}
.ui.chatroom .room .container {
width: 3000px;
}
.ui.chatroom .log {
width: 314px;
height: 278px;
padding: 4px 7px;
}
.ui.chatroom .room .list {
width: 124px;
height: 278px;
padding: 4px 0px;
}
.ui.chatroom .room .list .user {
width: 110px;
}
.ui.chatroom .talk {
height: 40px;
}

2
src/modules/dropdown.js

@ -23,7 +23,7 @@ $.fn.dropdown = function(parameters) {
error = settings.error, error = settings.error,
eventNamespace = '.' + namespace, eventNamespace = '.' + namespace,
dropdownNamespace = 'dropdown-' + namespace, dropdownNamespace = 'module-' + namespace,
dropdownSelector = $allDropdowns.selector || '', dropdownSelector = $allDropdowns.selector || '',
time = new Date().getTime(), time = new Date().getTime(),

358
src/modules/rating.js

@ -0,0 +1,358 @@
/* ******************************
Star Review
Author: Jack Lukic
Notes: First Commit Sep 04, 2012
Simple rating module
****************************** */
;(function ($, window, document, undefined) {
$.fn.rating = function(parameters) {
var
$allModules = $(this),
moduleSelector = $allModules.selector || '',
settings = $.extend(true, {}, $.fn.rating.settings, parameters),
namespace = settings.namespace,
className = settings.className,
metadata = settings.metadata,
selector = settings.selector,
error = settings.error,
eventNamespace = '.' + namespace,
moduleNamespace = 'module-' + namespace,
time = new Date().getTime(),
performance = [],
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
invokedResponse
;
$allModules
.each(function() {
var
$module = $(this),
$icon = $module.find(selector.icon),
element = this,
instance = $module.data(moduleNamespace),
module
;
module = {
initialize: function() {
module.verbose('Initializing rating module');
if(settings.interactive) {
$icon
.bind('mouseenter' + eventNamespace, module.event.mouseenter)
.bind('mouseleave' + eventNamespace, module.event.mouseleave)
.bind('click' + eventNamespace, module.event.click)
;
}
if(settings.initialRating) {
module.debug('Setting initial rating');
module.setRating(settings.initialRating);
}
if( $module.data(metadata.rating) ) {
module.debug('Rating found in metadata');
module.setRating( $module.data(metadata.rating) );
}
$module
.addClass(className.active)
;
module.instantiate();
},
instantiate: function() {
module.verbose('Instantiating module', settings);
$module
.data(moduleNamespace, module)
;
},
destroy: function() {
$module
.removeData(moduleNamespace)
;
$icon
.off(eventNamespace)
;
},
setRating: function(rating) {
var
$activeIcon = $icon.eq(rating - 1)
;
module.verbose('Setting current rating to', rating);
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
$activeIcon
.nextAll()
.removeClass(className.active)
;
$activeIcon
.addClass(className.active)
.prevAll()
.addClass(className.active)
;
$.proxy(settings.onRate, element)();
},
event: {
mouseenter: function() {
var
$activeIcon = $(this)
;
$activeIcon
.nextAll()
.removeClass(className.hover)
;
$module
.addClass(className.hover)
;
$activeIcon
.addClass(className.hover)
.prevAll()
.addClass(className.hover)
;
},
mouseleave: function() {
$module
.removeClass(className.hover)
;
$icon
.removeClass(className.hover)
;
},
click: function() {
var
$activeIcon = $(this)
;
module.setRating( $icon.index($activeIcon) + 1);
}
},
setting: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, settings, name);
}
else {
settings[name] = value;
}
}
else {
return settings[name];
}
},
internal: function(name, value) {
if(value !== undefined) {
if( $.isPlainObject(name) ) {
$.extend(true, module, name);
}
else {
module[name] = value;
}
}
else {
return module[name];
}
},
debug: function() {
if(settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.debug.apply(console, arguments);
}
}
},
verbose: function() {
if(settings.verbose && settings.debug) {
if(settings.performance) {
module.performance.log(arguments);
}
else {
module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
module.verbose.apply(console, arguments);
}
}
},
error: function() {
module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
module.error.apply(console, arguments);
},
performance: {
log: function(message) {
var
currentTime,
executionTime,
previousTime
;
if(settings.performance) {
currentTime = new Date().getTime();
previousTime = time || currentTime;
executionTime = currentTime - previousTime;
time = currentTime;
performance.push({
'Element' : element,
'Name' : message[0],
'Arguments' : [].slice.call(message, 1) || '',
'Execution Time' : executionTime
});
}
clearTimeout(module.performance.timer);
module.performance.timer = setTimeout(module.performance.display, 100);
},
display: function() {
var
title = settings.name + ':',
totalTime = 0
;
time = false;
clearTimeout(module.performance.timer);
$.each(performance, function(index, data) {
totalTime += data['Execution Time'];
});
title += ' ' + totalTime + 'ms';
if(moduleSelector) {
title += ' \'' + moduleSelector + '\'';
}
if($allModules.size() > 1) {
title += ' ' + '(' + $allModules.size() + ')';
}
if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
console.groupCollapsed(title);
if(console.table) {
console.table(performance);
}
else {
$.each(performance, function(index, data) {
console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
});
}
console.groupEnd();
}
performance = [];
}
},
invoke: function(query, passedArguments, context) {
var
maxDepth,
found,
response
;
passedArguments = passedArguments || queryArguments;
context = element || context;
if(typeof query == 'string' && instance !== undefined) {
query = query.split(/[\. ]/);
maxDepth = query.length - 1;
$.each(query, function(depth, value) {
var camelCaseValue = (depth != maxDepth)
? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
: query
;
if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
instance = instance[value];
}
else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
instance = instance[camelCaseValue];
}
else if( instance[value] !== undefined ) {
found = instance[value];
return false;
}
else if( instance[camelCaseValue] !== undefined ) {
found = instance[camelCaseValue];
return false;
}
else {
module.error(error.method);
return false;
}
});
}
if ( $.isFunction( found ) ) {
response = found.apply(context, passedArguments);
}
else if(found !== undefined) {
response = found;
}
if($.isArray(invokedResponse)) {
invokedResponse.push(response);
}
else if(typeof invokedResponse == 'string') {
invokedResponse = [invokedResponse, response];
}
else if(response !== undefined) {
invokedResponse = response;
}
return found;
}
};
if(methodInvoked) {
if(instance === undefined) {
module.initialize();
}
module.invoke(query);
}
else {
if(instance !== undefined) {
module.destroy();
}
module.initialize();
}
})
;
return (invokedResponse !== undefined)
? invokedResponse
: this
;
};
$.fn.rating.settings = {
name : 'Rating',
namespace : 'rating',
verbose : true,
debug : true,
performance : true,
initialRating : 0,
interactive : true,
onRate : function(){},
error : {
method : 'The method you called is not defined'
},
metadata: {
rating: 'rating'
},
className : {
active : 'active',
hover : 'hover',
loading : 'loading'
},
selector : {
icon : '.icon'
}
};
})( jQuery, window , document );

151
src/modules/rating.less

@ -0,0 +1,151 @@
/*******************************
Star Rating
*******************************/
.ui.rating {
display: inline-block;
vertical-align: middle;
margin: 0em 0.5em;
}
.ui.rating:first-child {
margin-left: 0em;
}
.ui.rating:last-child {
margin-right: 0em;
}
.ui.rating:after {
display: block;
content: '';
visibility: hidden;
clear: both;
height: 0;
}
/* Icon */
.ui.rating .icon {
cursor: default;
float: left;
margin: 0em;
width: 1em;
height: auto;
padding: 0em;
font-weight: normal;
font-style: normal;
}
.ui.rating .icon:after {
content: "\2605";
color: rgba(0, 0, 0, 0.15);
-webkit-transition:
color 0.3s ease,
opacity 0.3s ease
;
-moz-transition:
color 0.3s ease,
opacity 0.3s ease
;
-ms-transition:
color 0.3s ease,
opacity 0.3s ease
;
-o-transition:
color 0.3s ease,
opacity 0.3s ease
;
transition:
color 0.3s ease,
opacity 0.3s ease
;
}
/*******************************
Types
*******************************/
/*-------------------
Star
--------------------*/
.ui.star.rating .icon:after {
content: '\e800';
font-family: 'Icons';
}
.ui.star.rating .active.icon:after {
content: '\e801';
font-family: 'Icons';
}
/*-------------------
Heart
--------------------*/
.ui.heart.rating .icon:after {
content: '\2661';
font-family: 'Icons';
}
.ui.heart.rating .active.icon:after {
content: '\2665';
font-family: 'Icons';
color: #EF404A;
}
.ui.heart.rating .hover.icon:after,
.ui.heart.rating .active.hover.icon:after {
color: #FF2733;
}
/*******************************
States
*******************************/
/*-------------------
Active
--------------------*/
/* active rating */
.ui.active.rating .icon {
cursor: pointer;
}
/* active icons */
.ui.rating .active.icon:after {
color: #FFCB08;
}
/*-------------------
Hover
--------------------*/
/* rating */
.ui.rating.hover .active.icon:after {
opacity: 0.5;
}
/* icon */
.ui.rating .icon.hover:after,
.ui.rating .icon.hover.active:after {
opacity: 1;
color: #FFB70A;
}
/*******************************
Variations
*******************************/
.ui.small.rating {
font-size: 1rem;
}
.ui.rating {
font-size: 1.5rem;
}
.ui.large.rating {
font-size: 2rem;
}
Loading…
Cancel
Save