2013-09-17 13:04:40 -04:00
( function ( module ) {
2013-10-28 23:33:37 +02:00
'use strict' ;
2013-08-28 02:32:38 +08:00
2013-05-23 13:21:38 -04:00
var utils , fs ;
2013-10-28 23:55:45 +02:00
if ( 'undefined' === typeof window ) {
2013-05-23 13:21:38 -04:00
fs = require ( 'fs' ) ;
2013-10-28 23:55:45 +02:00
}
2013-05-23 13:21:38 -04:00
module . exports = utils = {
generateUUID : function ( ) {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( /[xy]/g , function ( c ) {
2013-09-17 13:04:40 -04:00
var r = Math . random ( ) * 16 | 0 ,
2013-10-28 02:10:44 +02:00
v = c === 'x' ? r : ( r & 0x3 | 0x8 ) ;
2013-05-23 13:21:38 -04:00
return v . toString ( 16 ) ;
} ) ;
} ,
//Adapted from http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
walk : function ( dir , done ) {
2013-09-06 22:22:42 -04:00
var results = [ ] ,
2013-09-07 11:51:37 -04:00
path = require ( 'path' ) ,
main _dir = path . join ( _ _dirname , '..' , 'templates' ) ;
2013-05-23 13:21:38 -04:00
fs . readdir ( dir , function ( err , list ) {
2013-10-28 23:33:37 +02:00
if ( err ) {
return done ( err ) ;
}
2013-06-20 16:48:17 -04:00
var pending = list . length ;
2013-10-28 23:33:37 +02:00
if ( ! pending ) {
return done ( null , results ) ;
}
2013-06-20 16:48:17 -04:00
list . forEach ( function ( file ) {
2013-05-23 13:21:38 -04:00
file = dir + '/' + file ;
fs . stat ( file , function ( err , stat ) {
if ( stat && stat . isDirectory ( ) ) {
utils . walk ( file , function ( err , res ) {
results = results . concat ( res ) ;
2013-10-28 23:33:37 +02:00
if ( ! -- pending ) {
done ( null , results ) ;
}
2013-05-23 13:21:38 -04:00
} ) ;
} else {
2013-09-07 11:51:37 -04:00
results . push ( file . replace ( main _dir + '/' , '' ) . replace ( '.tpl' , '' ) ) ;
2013-10-28 23:33:37 +02:00
if ( ! -- pending ) {
done ( null , results ) ;
}
2013-06-20 16:48:17 -04:00
}
2013-05-23 13:21:38 -04:00
} ) ;
} ) ;
} ) ;
} ,
2013-08-28 02:32:38 +08:00
2013-05-23 14:32:25 -04:00
relativeTime : function ( timestamp , min ) {
2013-09-17 13:04:40 -04:00
var now = + new Date ( ) ,
2013-05-23 13:21:38 -04:00
difference = now - Math . floor ( parseFloat ( timestamp ) ) ;
difference = Math . floor ( difference / 1000 ) ;
2013-08-28 02:32:38 +08:00
2013-10-28 23:33:37 +02:00
if ( difference < 60 ) {
return difference + ( min ? 's' : ' second' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
}
2013-08-28 02:32:38 +08:00
2013-05-23 13:21:38 -04:00
difference = Math . floor ( difference / 60 ) ;
2013-10-28 23:33:37 +02:00
if ( difference < 60 ) {
return difference + ( min ? 'm' : ' minute' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
}
2013-05-23 13:21:38 -04:00
difference = Math . floor ( difference / 60 ) ;
2013-10-28 23:33:37 +02:00
if ( difference < 24 ) {
return difference + ( min ? 'h' : ' hour' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
}
2013-05-23 13:21:38 -04:00
difference = Math . floor ( difference / 24 ) ;
2013-10-28 23:33:37 +02:00
if ( difference < 30 ) {
return difference + ( min ? 'd' : ' day' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
}
2013-05-23 13:21:38 -04:00
difference = Math . floor ( difference / 30 ) ;
2013-10-28 23:33:37 +02:00
if ( difference < 12 ) {
return difference + ( min ? 'mon' : ' month' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
}
2013-05-23 13:21:38 -04:00
difference = Math . floor ( difference / 12 ) ;
2013-05-23 14:32:25 -04:00
return difference + ( min ? 'y' : ' year' ) + ( difference !== 1 && ! min ? 's' : '' ) ;
2013-05-23 13:21:38 -04:00
} ,
2013-08-28 02:32:38 +08:00
2013-05-23 13:21:38 -04:00
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
slugify : function ( str ) {
str = str . replace ( /^\s+|\s+$/g , '' ) ; // trim
str = str . toLowerCase ( ) ;
// remove accents, swap ñ for n, etc
2013-06-24 14:33:53 -04:00
var from = "àáäâèéëêìíïîıòóöôùúüûñçşğ·/_,:;" ;
2013-09-17 13:04:40 -04:00
var to = "aaaaeeeeiiiiioooouuuuncsg------" ;
for ( var i = 0 , l = from . length ; i < l ; i ++ ) {
2013-05-23 13:21:38 -04:00
str = str . replace ( new RegExp ( from . charAt ( i ) , 'g' ) , to . charAt ( i ) ) ;
}
str = str . replace ( /[^a-z0-9 -]/g , '' ) // remove invalid chars
2013-09-17 13:04:40 -04:00
. replace ( /\s+/g , '-' ) // collapse whitespace and replace by -
. replace ( /-+/g , '-' ) ; // collapse dashes
2013-05-23 13:21:38 -04:00
return str ;
} ,
2013-06-25 15:50:14 -04:00
// from http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
isEmailValid : function ( email ) {
2013-07-16 15:22:59 -04:00
// var re = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
2013-07-31 12:48:30 -04:00
var valid = email . indexOf ( '@' ) !== - 1 ? true : false ;
2013-07-17 16:13:53 -04:00
return valid ;
2013-06-25 15:50:14 -04:00
} ,
isUserNameValid : function ( name ) {
2013-10-19 13:11:28 -04:00
return ( name && name !== "" && ( /^['"\s\-.*0-9\u00BF-\u1FFF\u2C00-\uD7FF\w]+$/ . test ( name ) ) ) ;
2013-06-25 15:50:14 -04:00
} ,
2013-08-28 02:32:38 +08:00
2013-06-25 15:50:14 -04:00
isPasswordValid : function ( password ) {
2013-08-28 13:47:52 -04:00
return password && password . indexOf ( ' ' ) === - 1 ;
2013-06-25 15:50:14 -04:00
} ,
2013-05-23 14:32:25 -04:00
// Blatently stolen from: http://phpjs.org/functions/strip_tags/
2013-05-23 13:21:38 -04:00
'strip_tags' : function ( input , allowed ) {
allowed = ( ( ( allowed || "" ) + "" ) . toLowerCase ( ) . match ( /<[a-z][a-z0-9]*>/g ) || [ ] ) . join ( '' ) ; // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
2013-09-17 13:04:40 -04:00
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi ,
2013-05-23 13:21:38 -04:00
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi ;
2013-09-17 13:04:40 -04:00
return input . replace ( commentsAndPhpTags , '' ) . replace ( tags , function ( $0 , $1 ) {
2013-05-23 13:21:38 -04:00
return allowed . indexOf ( '<' + $1 . toLowerCase ( ) + '>' ) > - 1 ? $0 : '' ;
} ) ;
2013-07-23 17:21:44 -04:00
} ,
buildMetaTags : function ( tagsArr ) {
2013-09-17 13:04:40 -04:00
var tags = '' ,
2013-07-23 17:21:44 -04:00
tag ;
2013-09-17 13:04:40 -04:00
for ( var x = 0 , numTags = tagsArr . length ; x < numTags ; x ++ ) {
2013-10-28 23:33:37 +02:00
if ( tags . length > 0 ) {
tags += "\n\t" ;
}
2013-07-23 17:21:44 -04:00
tag = '<meta' ;
2013-10-28 23:33:37 +02:00
var y ;
2013-09-17 13:04:40 -04:00
for ( y in tagsArr [ x ] ) {
2013-07-23 17:21:44 -04:00
tag += ' ' + y + '="' + tagsArr [ x ] [ y ] + '"' ;
2013-10-22 12:23:07 -04:00
}
tag += ' />' ;
tags += tag ;
}
return tags ;
} ,
buildLinkTags : function ( tagsArr ) {
var tags = '' ,
tag ;
for ( var x = 0 , numTags = tagsArr . length ; x < numTags ; x ++ ) {
if ( tags . length > 0 ) tags += "\n\t" ;
tag = '<link' ;
2013-10-28 23:33:37 +02:00
var y ;
2013-10-22 12:23:07 -04:00
for ( y in tagsArr [ x ] ) {
tag += ' ' + y + '="' + tagsArr [ x ] [ y ] + '"' ;
2013-07-23 17:21:44 -04:00
}
tag += ' />' ;
tags += tag ;
}
return tags ;
2013-08-11 16:41:49 -04:00
} ,
2013-08-21 23:34:35 +08:00
refreshTitle : function ( url ) {
if ( ! url ) {
2013-09-17 13:04:40 -04:00
var a = document . createElement ( 'a' ) ;
2013-08-21 23:34:35 +08:00
a . href = document . location ;
url = a . pathname . slice ( 1 ) ;
}
2013-08-28 02:32:38 +08:00
var notificationIcon ;
2013-08-11 16:41:49 -04:00
2013-08-21 23:34:35 +08:00
socket . emit ( 'api:meta.buildTitle' , url , function ( title , numNotifications ) {
2013-09-17 13:04:40 -04:00
document . title = ( numNotifications > 0 ? '(' + numNotifications + ') ' : '' ) + title ;
2013-08-28 02:32:38 +08:00
notificationIcon = notificationIcon || document . querySelector ( '.notifications a i' ) ;
2013-10-28 23:33:37 +02:00
if ( numNotifications > 0 && notificationIcon ) {
2013-11-26 14:25:46 -05:00
notificationIcon . className = 'fa fa-circle active' ;
2013-10-28 23:33:37 +02:00
}
2013-08-11 16:41:49 -04:00
} ) ;
2013-08-22 00:08:11 +08:00
jQuery . getJSON ( RELATIVE _PATH + '/api/unread/total' , function ( data ) {
var badge = jQuery ( '#numUnreadBadge' ) ;
badge . html ( data . count > 20 ? '20+' : data . count ) ;
if ( data . count > 0 ) {
badge
. removeClass ( 'badge-inverse' )
2013-10-28 23:33:37 +02:00
. addClass ( 'badge-important' ) ;
2013-09-17 13:04:40 -04:00
} else {
2013-08-22 00:08:11 +08:00
badge
. removeClass ( 'badge-important' )
2013-10-28 23:33:37 +02:00
. addClass ( 'badge-inverse' ) ;
2013-08-22 00:08:11 +08:00
}
} ) ;
2013-08-22 09:50:29 -04:00
} ,
isRelativeUrl : function ( url ) {
2013-09-17 13:04:40 -04:00
var firstChar = url . slice ( 0 , 1 ) ;
2013-08-22 09:50:29 -04:00
return ( firstChar === '.' || firstChar === '/' ) ;
2013-10-16 13:25:17 -04:00
} ,
makeNumberHumanReadable : function ( num ) {
num = parseInt ( num , 10 ) ;
2013-10-28 23:33:37 +02:00
if ( num > 999999 ) {
2013-10-16 13:25:17 -04:00
return ( num / 1000000 ) . toFixed ( 1 ) + 'm' ;
2013-10-28 23:33:37 +02:00
}
else if ( num > 999 ) {
2013-10-16 13:25:17 -04:00
return ( num / 1000 ) . toFixed ( 1 ) + 'k' ;
2013-10-28 23:33:37 +02:00
}
2013-10-16 13:25:17 -04:00
return num ;
2013-05-23 13:21:38 -04:00
}
2013-10-28 23:33:37 +02:00
} ;
2013-05-23 13:21:38 -04:00
2013-06-25 15:50:14 -04:00
if ( ! String . prototype . trim ) {
2013-09-17 13:04:40 -04:00
String . prototype . trim = function ( ) {
return this . replace ( /^\s+|\s+$/g , '' ) ;
} ;
2013-06-25 15:50:14 -04:00
}
2013-05-23 13:21:38 -04:00
if ( 'undefined' !== typeof window ) {
window . utils = module . exports ;
}
2013-09-17 13:04:40 -04:00
} ) ( 'undefined' === typeof module ? {
module : {
exports : { }
}
2013-10-28 02:10:44 +02:00
} : module ) ;