Permalink
Please sign in to comment.
Showing
with
477 additions
and 2,844 deletions.
- +81 −1 app.js
- +1 −0 config/passport.js
- +0 −2 controllers/curriculum.js
- +2 −1 models/User.js
- +1 −0 package.json
- +0 −944 public/css/firechat-default.css
- +123 −0 public/css/styles.less
- +0 −1,869 public/js/firechat-default.js
- +257 −26 public/js/main.js
- +11 −1 views/curriculum/curriculum.jade
- +1 −0 views/layout.jade
82
app.js
1
config/passport.js
2
controllers/curriculum.js
3
models/User.js
1
package.json
944
public/css/firechat-default.css
| @@ -1,944 +0,0 @@ | ||
| -@charset "UTF-8"; | ||
| -/* Boilerplate: Reset | ||
| -============================================================ */ | ||
| -#firechat div, | ||
| -#firechat span, | ||
| -#firechat applet, | ||
| -#firechat object, | ||
| -#firechat iframe, | ||
| -#firechat h1, | ||
| -#firechat h2, | ||
| -#firechat h3, | ||
| -#firechat h4, | ||
| -#firechat h5, | ||
| -#firechat h6, | ||
| -#firechat p, | ||
| -#firechat blockquote, | ||
| -#firechat pre, | ||
| -#firechat a, | ||
| -#firechat abbr, | ||
| -#firechat acronym, | ||
| -#firechat address, | ||
| -#firechat big, | ||
| -#firechat cite, | ||
| -#firechat code, | ||
| -#firechat del, | ||
| -#firechat dfn, | ||
| -#firechat em, | ||
| -#firechat img, | ||
| -#firechat ins, | ||
| -#firechat kbd, | ||
| -#firechat q, | ||
| -#firechat s, | ||
| -#firechat samp, | ||
| -#firechat small, | ||
| -#firechat strike, | ||
| -#firechat strong, | ||
| -#firechat sub, | ||
| -#firechat sup, | ||
| -#firechat tt, | ||
| -#firechat var, | ||
| -#firechat b, | ||
| -#firechat u, | ||
| -#firechat i, | ||
| -#firechat center, | ||
| -#firechat dl, | ||
| -#firechat dt, | ||
| -#firechat dd, | ||
| -#firechat ol, | ||
| -#firechat ul, | ||
| -#firechat li, | ||
| -#firechat fieldset, | ||
| -#firechat form, | ||
| -#firechat label, | ||
| -#firechat legend, | ||
| -#firechat table, | ||
| -#firechat caption, | ||
| -#firechat tbody, | ||
| -#firechat tfoot, | ||
| -#firechat thead, | ||
| -#firechat tr, | ||
| -#firechat th, | ||
| -#firechat td, | ||
| -#firechat article, | ||
| -#firechat aside, | ||
| -#firechat canvas, | ||
| -#firechat details, | ||
| -#firechat embed, | ||
| -#firechat figure, | ||
| -#firechat figcaption, | ||
| -#firechat footer, | ||
| -#firechat header, | ||
| -#firechat hgroup, | ||
| -#firechat menu, | ||
| -#firechat nav, | ||
| -#firechat output, | ||
| -#firechat ruby, | ||
| -#firechat section, | ||
| -#firechat summary, | ||
| -#firechat time, | ||
| -#firechat mark, | ||
| -#firechat audio, | ||
| -#firechat video { | ||
| - border: 0; | ||
| - font-size: 12px; | ||
| - font-family: arial, helvetica, sans-serif; | ||
| - vertical-align: baseline; | ||
| - margin: 0; | ||
| - padding: 0; | ||
| -} | ||
| -#firechat article, | ||
| -#firechat aside, | ||
| -#firechat details, | ||
| -#firechat figcaption, | ||
| -#firechat figure, | ||
| -#firechat footer, | ||
| -#firechat header, | ||
| -#firechat hgroup, | ||
| -#firechat menu, | ||
| -#firechat nav, | ||
| -#firechat section { | ||
| - display: block; | ||
| -} | ||
| -#firechat body { | ||
| - line-height: 1; | ||
| -} | ||
| -#firechat ol, | ||
| -#firechat ul { | ||
| - list-style: none; | ||
| -} | ||
| -#firechat blockquote, | ||
| -#firechat q { | ||
| - quotes: none; | ||
| -} | ||
| -#firechat blockquote:before, | ||
| -#firechat blockquote:after, | ||
| -#firechat q:before, | ||
| -#firechat q:after { | ||
| - content: none; | ||
| -} | ||
| -#firechat table { | ||
| - border-collapse: collapse; | ||
| - border-spacing: 0; | ||
| -} | ||
| -/* Boilerplate: Mixins | ||
| -============================================================ */ | ||
| -.clearfix { | ||
| - *zoom: 1; | ||
| -} | ||
| -.clearfix:before, | ||
| -.clearfix:after { | ||
| - display: table; | ||
| - content: ""; | ||
| - line-height: 0; | ||
| -} | ||
| -.clearfix:after { | ||
| - clear: both; | ||
| -} | ||
| -/* Boilerplate: Responsive Layout | ||
| -============================================================ */ | ||
| -#firechat { | ||
| - color: #333; | ||
| - text-align: left; | ||
| -} | ||
| -#firechat .center { | ||
| - float: none !important; | ||
| - margin-left: auto !important; | ||
| - margin-right: auto !important; | ||
| -} | ||
| -#firechat .left { | ||
| - float: left !important; | ||
| -} | ||
| -#firechat .right { | ||
| - float: right !important; | ||
| -} | ||
| -#firechat .alignleft { | ||
| - text-align: left !important; | ||
| -} | ||
| -#firechat .alignright { | ||
| - text-align: right !important; | ||
| -} | ||
| -#firechat .aligncenter { | ||
| - text-align: center !important; | ||
| -} | ||
| -#firechat .hidden { | ||
| - display: none !important; | ||
| -} | ||
| -#firechat .row { | ||
| - clear: both; | ||
| -} | ||
| -#firechat .fifth, | ||
| -#firechat .fivesixth, | ||
| -#firechat .fourfifth, | ||
| -#firechat .half, | ||
| -#firechat .ninetenth, | ||
| -#firechat .quarter, | ||
| -#firechat .sevententh, | ||
| -#firechat .sixth, | ||
| -#firechat .tenth, | ||
| -#firechat .third, | ||
| -#firechat .threefifth, | ||
| -#firechat .threequarter, | ||
| -#firechat .threetenth, | ||
| -#firechat .twofifth, | ||
| -#firechat .twothird, | ||
| -#firechat .full { | ||
| - margin-left: 2.127659574468085%; | ||
| - float: left; | ||
| - min-height: 1px; | ||
| -} | ||
| -#firechat .fifth:first-child, | ||
| -#firechat .fivesixth:first-child, | ||
| -#firechat .fourfifth:first-child, | ||
| -#firechat .half:first-child, | ||
| -#firechat .ninetenth:first-child, | ||
| -#firechat .quarter:first-child, | ||
| -#firechat .sevententh:first-child, | ||
| -#firechat .sixth:first-child, | ||
| -#firechat .tenth:first-child, | ||
| -#firechat .third:first-child, | ||
| -#firechat .threefifth:first-child, | ||
| -#firechat .threequarter:first-child, | ||
| -#firechat .threetenth:first-child, | ||
| -#firechat .twofifth:first-child, | ||
| -#firechat .twothird:first-child, | ||
| -#firechat .full:first-child { | ||
| - margin-left: 0; | ||
| -} | ||
| -#firechat .tenth { | ||
| - width: 8.08510638297872%; | ||
| -} | ||
| -#firechat .sixth { | ||
| - width: 14.893617021276595%; | ||
| -} | ||
| -#firechat .fifth { | ||
| - width: 18.297872340425535%; | ||
| -} | ||
| -#firechat .quarter { | ||
| - width: 23.404255319148938%; | ||
| -} | ||
| -#firechat .threetenth { | ||
| - width: 26.3829787235%; | ||
| -} | ||
| -#firechat .third { | ||
| - width: 31.914893617021278%; | ||
| -} | ||
| -#firechat .twofifth { | ||
| - width: 38.72340425531915%; | ||
| -} | ||
| -#firechat .half { | ||
| - width: 48.93617021276596%; | ||
| -} | ||
| -#firechat .sevententh { | ||
| - width: 58.7234042555%; | ||
| -} | ||
| -#firechat .threefifth { | ||
| - width: 59.14893617021278%; | ||
| -} | ||
| -#firechat .twothird { | ||
| - width: 65.95744680851064%; | ||
| -} | ||
| -#firechat .threequarter { | ||
| - width: 74.46808510638297%; | ||
| -} | ||
| -#firechat .ninetenth { | ||
| - width: 74.8936170215%; | ||
| -} | ||
| -#firechat .fourfifth { | ||
| - width: 79.57446808510639%; | ||
| -} | ||
| -#firechat .fivesixth { | ||
| - width: 82.9787234042553%; | ||
| -} | ||
| -#firechat .full { | ||
| - width: 100%; | ||
| -} | ||
| -#firechat .clipped { | ||
| - overflow: hidden; | ||
| -} | ||
| -#firechat strong { | ||
| - font-weight: bold; | ||
| -} | ||
| -#firechat em { | ||
| - font-style: italic; | ||
| -} | ||
| -#firechat label { | ||
| - display: block; | ||
| -} | ||
| -#firechat a { | ||
| - color: #005580; | ||
| -} | ||
| -#firechat a:visited, | ||
| -#firechat a:hover, | ||
| -#firechat a:active { | ||
| - color: #005580; | ||
| -} | ||
| -#firechat p { | ||
| - margin: 10px 0; | ||
| -} | ||
| -#firechat h1, | ||
| -#firechat h2, | ||
| -#firechat h3, | ||
| -#firechat h4, | ||
| -#firechat h5, | ||
| -#firechat h6 { | ||
| - margin: 10px 0; | ||
| - font-family: inherit; | ||
| - font-weight: bold; | ||
| - line-height: 20px; | ||
| - color: inherit; | ||
| -} | ||
| -#firechat h1, | ||
| -#firechat h2, | ||
| -#firechat h3 { | ||
| - line-height: 40px; | ||
| -} | ||
| -#firechat h1 { | ||
| - font-size: 38.5px; | ||
| -} | ||
| -#firechat h2 { | ||
| - font-size: 31.5px; | ||
| -} | ||
| -#firechat h3 { | ||
| - font-size: 24.5px; | ||
| -} | ||
| -#firechat h4 { | ||
| - font-size: 17.5px; | ||
| -} | ||
| -#firechat h5 { | ||
| - font-size: 14px; | ||
| -} | ||
| -#firechat h6 { | ||
| - font-size: 11.9px; | ||
| -} | ||
| -#firechat small { | ||
| - font-size: 90%; | ||
| -} | ||
| -/* Component: Tabs | ||
| -============================================================ */ | ||
| -#firechat .nav { | ||
| - list-style: none; | ||
| -} | ||
| -#firechat .nav > li > a { | ||
| - display: block; | ||
| - background-color: #eeeeee; | ||
| - text-decoration: none; | ||
| - overflow: hidden; | ||
| - white-space: nowrap; | ||
| -} | ||
| -#firechat .nav > li > a:hover, | ||
| -#firechat .nav > li > a:focus { | ||
| - background-color: #ffffff; | ||
| -} | ||
| -#firechat .nav-tabs { | ||
| - border-bottom: 1px solid #ddd; | ||
| - clear: both; | ||
| -} | ||
| -#firechat .nav-tabs > li { | ||
| - float: left; | ||
| - margin-bottom: -1px; | ||
| - max-width: 45%; | ||
| -} | ||
| -#firechat .nav-tabs > li > a { | ||
| - -webkit-border-top-right-radius: 4px; | ||
| - -webkit-border-bottom-right-radius: 0; | ||
| - -webkit-border-bottom-left-radius: 0; | ||
| - -webkit-border-top-left-radius: 4px; | ||
| - -moz-border-radius-topright: 4px; | ||
| - -moz-border-radius-bottomright: 0; | ||
| - -moz-border-radius-bottomleft: 0; | ||
| - -moz-border-radius-topleft: 4px; | ||
| - border-top-right-radius: 4px; | ||
| - border-bottom-right-radius: 0; | ||
| - border-bottom-left-radius: 0; | ||
| - border-top-left-radius: 4px; | ||
| - padding: 4px 8px; | ||
| - margin-right: 2px; | ||
| - line-height: 20px; | ||
| - border: 1px solid transparent; | ||
| - border-color: #cccccc; | ||
| -} | ||
| -#firechat .nav-tabs > .active > a, | ||
| -#firechat .nav-tabs > .active > a:hover, | ||
| -#firechat .nav-tabs > .active > a:focus { | ||
| - border-bottom-color: transparent; | ||
| - background-color: #ffffff; | ||
| - cursor: default; | ||
| -} | ||
| -#firechat .tab-content { | ||
| - overflow: auto; | ||
| -} | ||
| -#firechat .tab-content > .tab-pane { | ||
| - display: none; | ||
| -} | ||
| -#firechat .tab-content > .active { | ||
| - display: block; | ||
| - background-color: #ffffff; | ||
| -} | ||
| -/* Component: dropdowns | ||
| -============================================================ */ | ||
| -#firechat .caret { | ||
| - display: inline-block; | ||
| - width: 0; | ||
| - height: 0; | ||
| - vertical-align: top; | ||
| - border-top: 4px solid #000000; | ||
| - border-right: 4px solid transparent; | ||
| - border-left: 4px solid transparent; | ||
| - content: ""; | ||
| - margin-top: 8px; | ||
| - margin-left: 2px; | ||
| -} | ||
| -#firechat .firechat-dropdown { | ||
| - position: relative; | ||
| -} | ||
| -#firechat .firechat-dropdown-toggle { | ||
| - -webkit-touch-callout: none; | ||
| - -webkit-user-select: none; | ||
| - -khtml-user-select: none; | ||
| - -moz-user-select: none; | ||
| - -ms-user-select: none; | ||
| - user-select: none; | ||
| - text-decoration: none; | ||
| -} | ||
| -#firechat .firechat-dropdown-toggle:focus, | ||
| -#firechat .firechat-dropdown-toggle:active { | ||
| - outline: none; | ||
| - text-decoration: none; | ||
| -} | ||
| -#firechat .firechat-dropdown-toggle.btn { | ||
| - padding: 4px 0 0; | ||
| - height: 22px; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu { | ||
| - *zoom: 1; | ||
| - -webkit-border-top-right-radius: 0; | ||
| - -webkit-border-bottom-right-radius: 4px; | ||
| - -webkit-border-bottom-left-radius: 4px; | ||
| - -webkit-border-top-left-radius: 0; | ||
| - -moz-border-radius-topright: 0; | ||
| - -moz-border-radius-bottomright: 4px; | ||
| - -moz-border-radius-bottomleft: 4px; | ||
| - -moz-border-radius-topleft: 0; | ||
| - border-top-right-radius: 0; | ||
| - border-bottom-right-radius: 4px; | ||
| - border-bottom-left-radius: 4px; | ||
| - border-top-left-radius: 0; | ||
| - z-index: 1000; | ||
| - display: none; | ||
| - float: left; | ||
| - position: absolute; | ||
| - top: 100%; | ||
| - left: 0; | ||
| - width: 100%; | ||
| - background-color: #ffffff; | ||
| - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | ||
| - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | ||
| - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); | ||
| - -webkit-background-clip: padding-box; | ||
| - -moz-background-clip: padding; | ||
| - background-clip: padding-box; | ||
| - border: 1px solid #ccc; | ||
| - min-width: 98%; | ||
| - padding: 0; | ||
| - margin: -1px 0 0; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu:before, | ||
| -#firechat .firechat-dropdown-menu:after { | ||
| - display: table; | ||
| - content: ""; | ||
| - line-height: 0; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu:after { | ||
| - clear: both; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu ul { | ||
| - background-color: #ffffff; | ||
| - list-style: none; | ||
| - overflow-y: scroll; | ||
| - max-height: 300px; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu ul > li > a { | ||
| - display: block; | ||
| - padding: 1px 1px 1px 3px; | ||
| - clear: both; | ||
| - font-weight: normal; | ||
| - line-height: 20px; | ||
| - color: #333333; | ||
| - white-space: nowrap; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu ul > li > a.highlight { | ||
| - background-color: #d9edf7; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu ul > li > a:hover, | ||
| -#firechat .firechat-dropdown-menu ul > li > a:focus, | ||
| -#firechat .firechat-dropdown-menu ul > .active > a, | ||
| -#firechat .firechat-dropdown-menu ul > .active > a:hover, | ||
| -#firechat .firechat-dropdown-menu ul > .active > a:focus { | ||
| - text-decoration: none; | ||
| - color: #000000; | ||
| - background-color: #d9edf7; | ||
| - outline: 0; | ||
| -} | ||
| -#firechat .firechat-dropdown-menu ul > .disabled > a, | ||
| -#firechat .firechat-dropdown-menu ul > .disabled > a:hover, | ||
| -#firechat .firechat-dropdown-menu ul > .disabled > a:focus { | ||
| - color: #999999; | ||
| - text-decoration: none; | ||
| - background-color: transparent; | ||
| - background-image: none; | ||
| - cursor: default; | ||
| -} | ||
| -#firechat .firechat-dropdown-header { | ||
| - position: relative; | ||
| - width: 100%; | ||
| - padding: 10px 0; | ||
| - background-color: #eeeeee; | ||
| - border-bottom: 1px solid #cccccc; | ||
| -} | ||
| -#firechat .firechat-dropdown-footer { | ||
| - position: relative; | ||
| - width: 100%; | ||
| - padding: 10px 0px; | ||
| - background-color: #eeeeee; | ||
| - border-top: 1px solid #cccccc; | ||
| - -webkit-box-sizing: border-box; | ||
| - -moz-box-sizing: border-box; | ||
| - box-sizing: border-box; | ||
| -} | ||
| -#firechat .open { | ||
| - *z-index: 1000; | ||
| -} | ||
| -#firechat .open > .firechat-dropdown-menu { | ||
| - display: block; | ||
| - border: 1px solid #cccccc; | ||
| - -webkit-border-top-right-radius: 0; | ||
| - -webkit-border-bottom-right-radius: 4px; | ||
| - -webkit-border-bottom-left-radius: 4px; | ||
| - -webkit-border-top-left-radius: 0; | ||
| - -moz-border-radius-topright: 0; | ||
| - -moz-border-radius-bottomright: 4px; | ||
| - -moz-border-radius-bottomleft: 4px; | ||
| - -moz-border-radius-topleft: 0; | ||
| - border-top-right-radius: 0; | ||
| - border-bottom-right-radius: 4px; | ||
| - border-bottom-left-radius: 4px; | ||
| - border-top-left-radius: 0; | ||
| -} | ||
| -#firechat .open > .firechat-dropdown-toggle { | ||
| - outline: none; | ||
| - text-decoration: none; | ||
| - -webkit-border-top-right-radius: 4px; | ||
| - -webkit-border-bottom-right-radius: 0; | ||
| - -webkit-border-bottom-left-radius: 0; | ||
| - -webkit-border-top-left-radius: 4px; | ||
| - -moz-border-radius-topright: 4px; | ||
| - -moz-border-radius-bottomright: 0; | ||
| - -moz-border-radius-bottomleft: 0; | ||
| - -moz-border-radius-topleft: 4px; | ||
| - border-top-right-radius: 4px; | ||
| - border-bottom-right-radius: 0; | ||
| - border-bottom-left-radius: 0; | ||
| - border-top-left-radius: 4px; | ||
| -} | ||
| -/* Component: Prompts | ||
| -============================================================ */ | ||
| -#firechat .prompt-wrapper { | ||
| - position: absolute; | ||
| - z-index: 1000; | ||
| -} | ||
| -#firechat .prompt { | ||
| - position: absolute; | ||
| - z-index: 1001; | ||
| - background-color: #ffffff; | ||
| - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45); | ||
| - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45); | ||
| - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.45); | ||
| -} | ||
| -#firechat .prompt-header { | ||
| - padding: 4px 8px; | ||
| - font-weight: bold; | ||
| - background-color: #eeeeee; | ||
| - border: 1px solid #cccccc; | ||
| - -webkit-border-top-right-radius: 4px; | ||
| - -webkit-border-bottom-right-radius: 0; | ||
| - -webkit-border-bottom-left-radius: 0; | ||
| - -webkit-border-top-left-radius: 4px; | ||
| - -moz-border-radius-topright: 4px; | ||
| - -moz-border-radius-bottomright: 0; | ||
| - -moz-border-radius-bottomleft: 0; | ||
| - -moz-border-radius-topleft: 4px; | ||
| - border-top-right-radius: 4px; | ||
| - border-bottom-right-radius: 0; | ||
| - border-bottom-left-radius: 0; | ||
| - border-top-left-radius: 4px; | ||
| -} | ||
| -#firechat .prompt-header a.close { | ||
| - opacity: 0.6; | ||
| - font-size: 13px; | ||
| - margin-top: 2px; | ||
| -} | ||
| -#firechat .prompt-header a.close:hover { | ||
| - opacity: 0.9; | ||
| -} | ||
| -#firechat .prompt-body { | ||
| - background-color: #ffffff; | ||
| - padding: 4px 8px; | ||
| - border-left: 1px solid #cccccc; | ||
| - border-right: 1px solid #cccccc; | ||
| -} | ||
| -#firechat .prompt-footer { | ||
| - padding: 4px 8px; | ||
| - background-color: #eeeeee; | ||
| - border: 1px solid #cccccc; | ||
| - -webkit-border-top-right-radius: 0; | ||
| - -webkit-border-bottom-right-radius: 4px; | ||
| - -webkit-border-bottom-left-radius: 4px; | ||
| - -webkit-border-top-left-radius: 0; | ||
| - -moz-border-radius-topright: 0; | ||
| - -moz-border-radius-bottomright: 4px; | ||
| - -moz-border-radius-bottomleft: 4px; | ||
| - -moz-border-radius-topleft: 0; | ||
| - border-top-right-radius: 0; | ||
| - border-bottom-right-radius: 4px; | ||
| - border-bottom-left-radius: 4px; | ||
| - border-top-left-radius: 0; | ||
| -} | ||
| -#firechat .prompt-background { | ||
| - background-color: #333333; | ||
| - border: 1px solid #333333; | ||
| - opacity: 0.8; | ||
| - z-index: 1000; | ||
| - height: 100%; | ||
| - width: 100%; | ||
| -} | ||
| -/* Component: Buttons | ||
| -============================================================ */ | ||
| -#firechat .btn { | ||
| - -webkit-touch-callout: none; | ||
| - -webkit-user-select: none; | ||
| - -khtml-user-select: none; | ||
| - -moz-user-select: none; | ||
| - -ms-user-select: none; | ||
| - user-select: none; | ||
| - -webkit-border-radius: 4px; | ||
| - -moz-border-radius: 4px; | ||
| - border-radius: 4px; | ||
| - height: 24px; | ||
| - display: inline-block; | ||
| - *display: inline; | ||
| - *zoom: 1; | ||
| - padding: 2px 5px; | ||
| - margin-bottom: 0; | ||
| - text-align: center; | ||
| - vertical-align: middle; | ||
| - cursor: pointer; | ||
| - color: #333333; | ||
| - font-size: 12px; | ||
| - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); | ||
| - background-color: #f5f5f5; | ||
| - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); | ||
| - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); | ||
| - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); | ||
| - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); | ||
| - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); | ||
| - background-repeat: repeat-x; | ||
| - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); | ||
| - border-color: #e6e6e6 #e6e6e6 #bfbfbf; | ||
| - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | ||
| - *background-color: #e6e6e6; | ||
| - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); | ||
| - border: 1px solid #cccccc; | ||
| - *border: 0; | ||
| - border-bottom-color: #b3b3b3; | ||
| - *margin-left: .3em; | ||
| - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| -} | ||
| -#firechat .btn:hover, | ||
| -#firechat .btn:focus, | ||
| -#firechat .btn:active, | ||
| -#firechat .btn.active, | ||
| -#firechat .btn.disabled, | ||
| -#firechat .btn[disabled] { | ||
| - color: #333333; | ||
| - background-color: #e6e6e6; | ||
| - *background-color: #d9d9d9; | ||
| - outline: 0; | ||
| -} | ||
| -#firechat .btn:active, | ||
| -#firechat .btn.active { | ||
| - background-color: #cccccc; | ||
| -} | ||
| -#firechat .btn:first-child { | ||
| - *margin-left: 0; | ||
| -} | ||
| -#firechat .btn:hover, | ||
| -#firechat .btn:focus { | ||
| - color: #333333; | ||
| - text-decoration: none; | ||
| - background-position: 0 -15px; | ||
| - -webkit-transition: background-position 0.1s linear; | ||
| - -moz-transition: background-position 0.1s linear; | ||
| - -o-transition: background-position 0.1s linear; | ||
| - transition: background-position 0.1s linear; | ||
| -} | ||
| -#firechat .btn.active, | ||
| -#firechat .btn:active { | ||
| - background-image: none; | ||
| - outline: 0; | ||
| - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); | ||
| -} | ||
| -#firechat .btn.disabled, | ||
| -#firechat .btn[disabled] { | ||
| - cursor: default; | ||
| - background-image: none; | ||
| - opacity: 0.65; | ||
| - filter: alpha(opacity=65); | ||
| -} | ||
| -#firechat .btn.disabled:active, | ||
| -#firechat .btn[disabled]:active { | ||
| - -webkit-box-shadow: inherit; | ||
| - -moz-box-shadow: inherit; | ||
| - box-shadow: inherit; | ||
| - background-color: #e6e6e6; | ||
| -} | ||
| -/* Component: Context Menu | ||
| -============================================================ */ | ||
| -#firechat .contextmenu { | ||
| - position: fixed; | ||
| - z-index: 1001; | ||
| - min-width: 150px; | ||
| - border: 1px solid #cccccc; | ||
| - -webkit-border-radius: 4px; | ||
| - -moz-border-radius: 4px; | ||
| - border-radius: 4px; | ||
| -} | ||
| -#firechat .contextmenu ul { | ||
| - background-color: #ffffff; | ||
| - list-style: none; | ||
| -} | ||
| -#firechat .contextmenu ul > li > a { | ||
| - display: block; | ||
| - padding: 3px 10px; | ||
| - clear: both; | ||
| - font-weight: normal; | ||
| - line-height: 20px; | ||
| - color: #333333; | ||
| - white-space: nowrap; | ||
| -} | ||
| -#firechat .contextmenu ul > li > a.highlight { | ||
| - background-color: #d9edf7; | ||
| -} | ||
| -#firechat .contextmenu ul > li > a:hover, | ||
| -#firechat .contextmenu ul > li > a:focus { | ||
| - text-decoration: none; | ||
| - color: #ffffff; | ||
| - background-color: #0081c2; | ||
| - outline: 0; | ||
| -} | ||
| -/* Custom Styles | ||
| -============================================================ */ | ||
| -#firechat { | ||
| - padding: 0; | ||
| - font-family: sans-serif; | ||
| - font-size: 12px; | ||
| - line-height: 18px; | ||
| -} | ||
| -#firechat input, | ||
| -#firechat textarea { | ||
| - width: 100%; | ||
| - font-family: sans-serif; | ||
| - font-size: 12px; | ||
| - line-height: 18px; | ||
| - padding: 2px 5px; | ||
| - border: 1px solid #cccccc; | ||
| - -webkit-border-radius: 1px; | ||
| - -moz-border-radius: 1px; | ||
| - border-radius: 1px; | ||
| - -webkit-box-sizing: border-box; | ||
| - -moz-box-sizing: border-box; | ||
| - box-sizing: border-box; | ||
| -} | ||
| -#firechat input:-moz-placeholder, | ||
| -#firechat textarea:-moz-placeholder { | ||
| - color: #aaaaaa; | ||
| -} | ||
| -#firechat input:-ms-input-placeholder, | ||
| -#firechat textarea:-ms-input-placeholder { | ||
| - color: #aaaaaa; | ||
| -} | ||
| -#firechat input::-webkit-input-placeholder, | ||
| -#firechat textarea::-webkit-input-placeholder { | ||
| - color: #aaaaaa; | ||
| -} | ||
| -#firechat input[disabled], | ||
| -#firechat textarea[disabled] { | ||
| - background-color: #eeeeee; | ||
| -} | ||
| -#firechat input { | ||
| - height: 24px; | ||
| -} | ||
| -#firechat textarea { | ||
| - resize: none; | ||
| - height: 40px; | ||
| -} | ||
| -#firechat .search-wrapper { | ||
| - -webkit-border-radius: 15px; | ||
| - -moz-border-radius: 15px; | ||
| - border-radius: 15px; | ||
| - border: 1px solid #cccccc; | ||
| - margin: 0 5px; | ||
| - padding: 2px 5px; | ||
| - background: #ffffff; | ||
| -} | ||
| -#firechat .search-wrapper > input[type=text] { | ||
| - padding-left: 0px; | ||
| - border: none; | ||
| -} | ||
| -#firechat .search-wrapper > input[type=text]:focus, | ||
| -#firechat .search-wrapper > input[type=text]:active { | ||
| - outline: 0; | ||
| -} | ||
| -#firechat .chat { | ||
| - overflow: auto; | ||
| - -ms-overflow-x: hidden; | ||
| - overflow-x: hidden; | ||
| - height: 290px; | ||
| - position: relative; | ||
| - margin-bottom: 5px; | ||
| - border: 1px solid #cccccc; | ||
| - border-top: none; | ||
| - overflow-y: scroll; | ||
| -} | ||
| -#firechat .chat textarea { | ||
| - overflow: auto; | ||
| - vertical-align: top; | ||
| -} | ||
| -#firechat .message { | ||
| - color: #333; | ||
| - padding: 3px 5px; | ||
| - border-bottom: 1px solid #ccc; | ||
| -} | ||
| -#firechat .message.highlighted { | ||
| - background-color: #d9edf7; | ||
| -} | ||
| -#firechat .message .name { | ||
| - font-weight: bold; | ||
| - overflow-x: hidden; | ||
| -} | ||
| -#firechat .message.message-self { | ||
| - color: #2675ab; | ||
| -} | ||
| -#firechat .message:nth-child(odd) { | ||
| - background-color: #f9f9f9; | ||
| -} | ||
| -#firechat .message:nth-child(odd).highlighted { | ||
| - background-color: #d9edf7; | ||
| -} | ||
| -#firechat .message:nth-child(odd).message-local { | ||
| - background-color: #effafc; | ||
| -} | ||
| -#firechat .message-content { | ||
| - word-wrap: break-word; | ||
| - padding-right: 45px; | ||
| -} | ||
| -#firechat .message-content.red { | ||
| - color: red; | ||
| -} | ||
| -#firechat .message.message-notification .message-content { | ||
| - font-style: italic; | ||
| -} | ||
| -#firechat ul::-webkit-scrollbar { | ||
| - -webkit-appearance: none; | ||
| - width: 7px; | ||
| -} | ||
| -#firechat ul::-webkit-scrollbar-thumb { | ||
| - border-radius: 4px; | ||
| - -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); | ||
| -} | ||
| -#firechat #firechat-header { | ||
| - padding: 6px 0 0 0; | ||
| - height: 40px; | ||
| -} | ||
| -#firechat #firechat-tabs { | ||
| - height: 435px; | ||
| -} | ||
| -#firechat #firechat-tab-list { | ||
| - background-color: #ffffff; | ||
| -} | ||
| -#firechat #firechat-tab-content { | ||
| - width: 100%; | ||
| - background-color: #ffffff; | ||
| -} | ||
| -#firechat .tab-pane-menu { | ||
| - border: 1px solid #ccc; | ||
| - border-top: none; | ||
| - vertical-align: middle; | ||
| - padding-bottom: 5px; | ||
| -} | ||
| -#firechat .tab-pane-menu .firechat-dropdown { | ||
| - margin: 5px 0 0 5px; | ||
| -} | ||
| -#firechat .tab-pane-menu > .icon { | ||
| - margin: 5px 2px 0; | ||
| -} | ||
| -#firechat .icon { | ||
| - display: inline-block; | ||
| - *margin-right: .3em; | ||
| - line-height: 20px; | ||
| - vertical-align: middle; | ||
| - background-repeat: no-repeat; | ||
| - padding: 0; | ||
| - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL8AAAANEAYAAACoeGM7AAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAM80lEQVR42t2cZ4xWRRfHZ3dhwbK7CJZYYiOxV+wlUQzCKmBBsWPvYjQiaiyxYUwULLErltgrNpRF4q5iV0BRLFE0diUi7LIq6Pqw74f//rzO4Zm9d+5z9c37ni//3OfemXtm5sypc58q55xzrrpauHSpcOONheedJ9x9d2Hv3sLvvxfefbfw5puFf/5Zvr+8VFUl7Ozs/rkNNxTef79w222F77wjPOoo4ccfF/O+UDvGzTVEf8wH1zU1wlJJePTRwv33Fx57rPDnn/1+wbzzG+IXvrhmPUPzY/kJEc/HzqslK1fLLy8cMUK4667CFVYQ/vqr8PXXhU884f8eL6eXXKJ2wqSd3tDY2KOHc84NGqSRnnCC7tbVCdvbhRMnasWnTdt5Z+eca2pK6797Yh6ef1641lrCPfYQfv21UNwl62qv115b2Nws/PZb4d57C3/7LftalaOQ/C63nPCII4Tsg6228scHffqp8LHHhPfe6/8eu49feEH44YfCq64S/v67cMGC7tuvu65w6FDhllsKkS/0zoQJaZzMmSO+JaEzZmgkY8b88Ydzzs2b19HhnHNffSWJ6tVLM1cq/fKLrjXiUaPUrn9/XZ9yip6rqVmyxDnnnnrKvPbAA4V6TTJxP/zgT4zdyC+9JOzXz++PgceSVSS1tUJtE+c22si/f+21Pj9Wwd54o//8ZpsJd9xR2KtX9+8vmkLzcsABPt9z5wr32af88xiOf4oaGoSHH17M+/LKg203aJDwiy+EVh5DyHzuuWcxfDn31lvOOffMM7Nn6z1SsZ2dn30m/OQT4eefC7/8UvjBB0LaVzav7D873vfeE6LQISvv3Of50P6OJetgWFp5ZeFzz5V/b1bEEd1333x80g+O4mWXCXEQMDB33CG8/XYhBhuDmMZnOn30kZ5/+23nnGtpefNN55wbP96Xl/nzhYsWCdvauEbeQP1Of6US/XRZfDz8Bx8U9uwpPPFE4eOPC/EMVl9dOG6ccORI4Q03CA87LHbA5RcCwgO47TbhokXCYcOERCKQ7GJiMLiPokeQ2QCjRwtvukkY6zHg0V10kXDAAH++EIz77hM++aRwxRWFq64q3H57v9/+/YVPPy2cOFF47rnCNE8kll/Gi4eIAWU9v/vOnz8MA4qjb18hG51+2JiLF+ebX/hA4U+b5t+/7jrhAw8IkQ88WvnPiZzi4Q0eXL6/dEJhawaGDydmk4uEQmhu1kj79tVImb8RI8TZwIG0p78ddnAubOhDhIcPIXd4nnh4OHYYzPXXF7K/ed5GBLb/NLKRFOtMfyCZAiIKns8aSVp9xP4i8nv//Ti+icjgl0iDeUsjpKDSyJYeqqs1A+3taDBpkn79Qi5YW9vf5wXq0YP+1L5U6loAUjpW4WPhQhN00EFC2SXnDj1UiAF44w2hTWnEEqkcCIWJYkShQNbDIIJZZx2h9Xhs/7EpFDwCNs6UKf584tGQsiFCGTJEuMEG/jxBzBe/H3+8cJddhBiAZ58thl/eM2uW8MgjhWyAyy8XojhRUGuuKayvF7Jhf/pJ+O67wltvFU6dGscv78fTgg45RPjII+XbYZA23bT8/Vtu8ecBDy9MpHS0EROFr1B76lQp7r32su20EwYMkGSOG4dq4I0a4fDh9G9TQN0TKR0iB8aD3G+9tRDHDoPPenKf53GYiABiPWm7f046SUgKDs8aQwxlVfiQTVXh0BChxir+kDol5WPv24im+Ahcb6iu9jVnR4euGX9oXsLj7GKYHP68eUI8ANsRA7WKE8sNkUopdvgJsW0QUBbc3oewl6GQs9LUDgr85JOF5OZHjRKyESZNEp55ppBIC7IbxgoSkQzt2OgXX1wMv9RCFBAuG4HgSREKU0vB42Jjo6gxtPvtJ8TzTM91+kQOf731hHj4KHybA0bRK8B1bpNNhAqkE8OH40CKLZ3I4a+0kq6l8JuapPAbGx991Lm/r5s8+aFDlWOdOVMuS0ODNm5bm1RWSwsSrJY2FZVGRFYYYgwt+wO5EpeJ4eaa+zxPexQ+/Wcl+iFCxeBvs43QRujW048lu09Y16KI/m3Ewu8h/VS55w/5b7AGMrbW5lyXImQh8EhtqGBDGOu525QDnm5RhOcBzZ8vfO01IYIaev/Mmf5zpALsfSiv5bYLfeqpQhSUrYHY92GYbD+shx0XKSOKlrFk1xHFTQRon7M1FNtepaOErwsvFBIqkzKKlQ8MDoTnCpFKwyCi2FZbTYhDgydO6gfaaaesnFC0xQcUUQwlBi6VpPCHDJGKmDyZGWMldY2nPmmSP5NEdlkJRYSCZr7FRbiIzTX3eZ72tiiclZjf444rzyd6hkid9+fNCNhxvfJKvn5C/YVy9nZVYw89ZCdfI6TVEuCLCI4Zhp+Ojq6FIAdLFR0PjpQOFpyFsQMidw5ZxRo7ATaEI6fMgFD8FJsxXCgee00qSiWPJNfKaYLp08u/P1YQ4ZfxWgWDAcOjZmMR8G+3nZBTPbwffhYuFJ5zjhCPKi9ZBUzkh8dpBTkk2KSKLr1UiAIJEYYhK2GQIOto4OGj8NdYQ4hck8tnvkmtQSGDHKK6On8nUNtIPHwUvp05SeSwYTI1s2YpJhk5kliO/uP4Qe6IxMnhk9JhXqyCtQ4Oz9Oe/nwzl05EtJbI5fMeTs8QscIP+zwtEuA+csz+fvjhOH5tf6SSoZCjEipeKw5MVj12PemZ9tXVvunt2dOuHE+K06oqvbG2lp2ikS1ZIknv3burO45lXn+9kKItOfzQwhO6jR0r5PiXPaUQmzNHkMllIyhMMBudmgKnjqxnwnSssooQhWpTLOR6UVwc/4ul1lYhx7rwRBF4PBEEwxLFavhkeTmmN2aMEAG3ghdrqHx149z555efx9DGY37vvFNoPcxQe1v0SyObe8cRIYf/4otCPHwUPsVge4yXWgTEumWl9nZtsPp6irbk8OVyTJ5sYyRJdGOjkitJjUP3FyzwNzIOV1ZivdinFG3J4dt5twqW9eJ5nUFKDIB1xNIIh8p6oijUa64RcnyT2SLSJHWXdtqKcdD/BRcIifBiCf44TIGe2WILYaiGhWHFoaFGxnxtvnlWDvwZY/yLF6toy+8LF2rGamrESXK8WRIwe7YcjKYmzdD06Xpi7lzFWqR4/1pYeywMT5ncL4rpiiuE9tgnIRyeozP9ZyVSBNZyskHxpFFUCGroOCf36Zf28MtzRCqxOXPaM24iJxsJQQgOCgyiqM4GJvduKZRbjOWXXH+fPkKKiUQmOnyYRBrwZeeXCIxxQ/mPSfpEkZn3KZO+7PHiH38U2mKurQHY478ooHSSaZswgWOZum5uFra2iqPOTs0g93EE4NzWAKZM4RioIoDx4/PNE4YQxWNTs6HUgL1Pe3sMNCuF9qOVG2penIPHYOHokcJ8+WVhS4sQR4NaJP3F7luI9tSALBFxovhBW6uonFSORm7mzMEAzJjhnHMNDdLI9fXgq68651xdnZLYffpY+cpIhLzkUNNySd98I7QKFPs0cGC+4dv3sCAYIE4bhXJboWvwrruExxwjJPWStyjD8/b0AyEiCt4Wh6xBpCi+225CG5kUdWogxC/HMyldshGJ7IhcWIfTTxciLxhWqKgcJxuPc/h2nTAAaYrq4IP9dni01jCEiVM3nIdWdaizUxuTDdvaSgQQ6kfPNTVhKPgOgP7j5id0Dh9DbR05Unlch54PfQeQRuyrUM7ZOoxkCq6+WkikhiOBIQ/JEx7sGWfE8QlZOYKyOi7sS+uQgdn3ra/4LT/ZSS1razEEfBgoOf0rdRUaIB4rXyCedpqQFAu5KzxdPyBJPPRlj7d1Tw89JLznHiGeb+hDFVIWIQPll9SS3ynKUUwj5RWbI6Q/inWVEgJsUxRFKdKi+T3rLKEtshf9IZytPdgIgNM75PA5dWQ9fBAFE0+cu+dDGQyAHwGMHi0P/sordT12LB4+Ct//0Cbvh1zWINr9gAePIYe4thGCbU//sYRHn/fDLBwyawhDOfe8ESbvCx3/zHuKJp5Cil8cVlVlxcjXhv5yICvh4aPwreDlJY5nUay1Cj2rINn2lD4qPX6KwcPzRQHhKeP5WeQ+ng2nSyhCcv4fKip1EuIXRQlfXIMUn7nPl9SkhKhFFM2v7QcDEIoAQoiHbxV+5V/uEgGQAuJLXRQ7X/KS0sHD///8cpcIl/P69MN3GDh2RBzUvvjLFVI2NuK1einty+CsZDMY/z0qyuOvkGwIY8+zMuE2ZYGHj8JHUWQlm/sm1ENRZ81dWrShLEVAy1/20F9EEZrTQnk9HJCNYL+YLMrD+F/jF7IbnBQQNQDOi/MFJ9fk8O26xisMQmb7OykaagD+p/RLl3JNDj+U0gn13z0xLhQ0BtEqfLtP7TXP057+YvcDCpvDInwvYInUcnIqqjLKK2/IydlnF8NHfvq3FP9/ANgTCJ9z9ZF7AAAAAElFTkSuQmCC) no-repeat top left; | ||
| - opacity: 0.3; | ||
| - font-size: 22px; | ||
| - font-family: Arial; | ||
| - font-weight: bold; | ||
| - overflow: hidden; | ||
| -} | ||
| -#firechat .icon.plus { | ||
| - margin-top: 0; | ||
| - vertical-align: top; | ||
| - background: transparent; | ||
| -} | ||
| -#firechat .icon.search { | ||
| - background-position: 0 0; | ||
| - width: 13px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon.close { | ||
| - background-position: -120px 0; | ||
| - width: 13px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon.user-chat { | ||
| - background-position: -138px 0; | ||
| - width: 17px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon.user-group { | ||
| - background-position: -18px 0; | ||
| - width: 17px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon.user-mute { | ||
| - background-position: -84px 0; | ||
| - width: 13px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon.user-mute.red { | ||
| - background-position: -102px 0; | ||
| - width: 13px; | ||
| - height: 13px; | ||
| -} | ||
| -#firechat .icon:hover, | ||
| -#firechat .btn:hover > .icon { | ||
| - opacity: 0.6; | ||
| -} | ||
| -#firechat a > .icon { | ||
| - margin: 3px 1px; | ||
| -} |
123
public/css/styles.less
1,869
public/js/firechat-default.js
0 additions,
1,869 deletions
not shown because the diff is too large. Please use a local Git client to view these changes.
283
public/js/main.js
| @@ -1,38 +1,269 @@ | ||
| $(document).ready(function() { | ||
| - function init() { | ||
| - var firepadRef = getExampleRef(); | ||
| - var ref = new Firebase('scorching-heat-2873.firebaseIO.com'); | ||
| - var codeMirror = CodeMirror(document.getElementById('firepad-container'), { | ||
| - lineNumbers: true, | ||
| - mode: 'javascript' | ||
| - }); | ||
| - var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror, { | ||
| - defaultText: '// JavaScript Editing with Firepad!\\nfunction go() {\n var message = "Hello, world.";\n console.log(message);\n}' | ||
| + var FADE_TIME = 150; // ms | ||
| + var TYPING_TIMER_LENGTH = 400; // ms | ||
| + var COLORS = [ | ||
| + '#e21400', '#91580f', '#f8a700', '#f78b00', | ||
| + '#58dc00', '#287b00', '#a8f07a', '#4ae8c4', | ||
| + '#3b88eb', '#3824aa', '#a700ff', '#d300e7' | ||
| + ]; | ||
| + | ||
| + // Initialize varibles | ||
| + var $window = $(window); | ||
| + var $usernameInput = $('.usernameInput'); // Input for username | ||
| + var $messages = $('.messages'); // Messages area | ||
| + var $inputMessage = $('.inputMessage'); // Input message input box | ||
| + | ||
| + var $loginPage = $('.login.page'); // The login page | ||
| + var $chatPage = $('.chat.page'); // The chatroom page | ||
| + | ||
| + // Prompt for setting a username | ||
| + var username; | ||
| + var connected = false; | ||
| + var typing = false; | ||
| + var lastTypingTime; | ||
| + var $currentInput = $usernameInput.focus(); | ||
| + | ||
| + var socket = io("http://localhost:2999"); | ||
| + | ||
| + | ||
| + function addParticipantsMessage (data) { | ||
| + var message = ''; | ||
| + if (data.numUsers === 1) { | ||
| + message += "there's 1 participant"; | ||
| + } else { | ||
| + message += "there are " + data.numUsers + " participants"; | ||
| + } | ||
| + log(message); | ||
| + } | ||
| + | ||
| + // Sets the client's username | ||
| + function setUsername () { | ||
| + username = cleanInput($usernameInput.val().trim()); | ||
| + | ||
| + // If the username is valid | ||
| + if (username) { | ||
| + $loginPage.fadeOut(); | ||
| + $chatPage.show(); | ||
| + $loginPage.off('click'); | ||
| + $currentInput = $inputMessage.focus(); | ||
| + | ||
| + // Tell the server your username | ||
| + socket.emit('add user', username); | ||
| + } | ||
| + } | ||
| + | ||
| + // Sends a chat message | ||
| + function sendMessage () { | ||
| + var message = $inputMessage.val(); | ||
| + // Prevent markup from being injected into the message | ||
| + message = cleanInput(message); | ||
| + // if there is a non-empty message and a socket connection | ||
| + if (message && connected) { | ||
| + $inputMessage.val(''); | ||
| + addChatMessage({ | ||
| + username: username, | ||
| + message: message | ||
| + }); | ||
| + // tell server to execute 'new message' and send along one parameter | ||
| + socket.emit('new message', message); | ||
| + } | ||
| + } | ||
| + | ||
| + // Log a message | ||
| + function log (message, options) { | ||
| + var $el = $('<li>').addClass('log').text(message); | ||
| + addMessageElement($el, options); | ||
| + } | ||
| + | ||
| + // Adds the visual chat message to the message list | ||
| + function addChatMessage (data, options) { | ||
| + // Don't fade the message in if there is an 'X was typing' | ||
| + var $typingMessages = getTypingMessages(data); | ||
| + options = options || {}; | ||
| + if ($typingMessages.length !== 0) { | ||
| + options.fade = false; | ||
| + $typingMessages.remove(); | ||
| + } | ||
| + | ||
| + var $usernameDiv = $('<span class="username"/>') | ||
| + .text(data.username) | ||
| + .css('color', getUsernameColor(data.username)); | ||
| + var $messageBodyDiv = $('<span class="messageBody">') | ||
| + .text(data.message); | ||
| + | ||
| + var typingClass = data.typing ? 'typing' : ''; | ||
| + var $messageDiv = $('<li class="message"/>') | ||
| + .data('username', data.username) | ||
| + .addClass(typingClass) | ||
| + .append($usernameDiv, $messageBodyDiv); | ||
| + | ||
| + addMessageElement($messageDiv, options); | ||
| + } | ||
| + | ||
| + // Adds the visual chat typing message | ||
| + function addChatTyping (data) { | ||
| + data.typing = true; | ||
| + data.message = 'is typing'; | ||
| + addChatMessage(data); | ||
| + } | ||
| + | ||
| + // Removes the visual chat typing message | ||
| + function removeChatTyping (data) { | ||
| + getTypingMessages(data).fadeOut(function () { | ||
| + $(this).remove(); | ||
| }); | ||
| } | ||
| - function getExampleRef() { | ||
| - var ref = new Firebase('https://firepad.firebaseio-demo.com'); | ||
| - var hash = window.location.hash.replace(/#/g, ''); | ||
| - if (hash) { | ||
| - ref = ref.child(hash); | ||
| + | ||
| + // Adds a message element to the messages and scrolls to the bottom | ||
| + // el - The element to add as a message | ||
| + // options.fade - If the element should fade-in (default = true) | ||
| + // options.prepend - If the element should prepend | ||
| + // all other messages (default = false) | ||
| + function addMessageElement (el, options) { | ||
| + var $el = $(el); | ||
| + | ||
| + // Setup default options | ||
| + if (!options) { | ||
| + options = {}; | ||
| + } | ||
| + if (typeof options.fade === 'undefined') { | ||
| + options.fade = true; | ||
| + } | ||
| + if (typeof options.prepend === 'undefined') { | ||
| + options.prepend = false; | ||
| + } | ||
| + | ||
| + // Apply options | ||
| + if (options.fade) { | ||
| + $el.hide().fadeIn(FADE_TIME); | ||
| + } | ||
| + if (options.prepend) { | ||
| + $messages.prepend($el); | ||
| } else { | ||
| - ref = ref.push(); // generate unique location. | ||
| - window.location = window.location + '#' + ref.name(); // add it as a hash to the URL. | ||
| + $messages.append($el); | ||
| } | ||
| - if (typeof console !== 'undefined') | ||
| - console.log('Firebase data: ', ref.toString()); | ||
| - return ref; | ||
| + $messages[0].scrollTop = $messages[0].scrollHeight; | ||
| } | ||
| - init(); | ||
| - var chatRef = new Firebase('https://scorching-heat-2873.firebaseio.com/chat'); | ||
| - var auth = new FirebaseSimpleLogin(chatRef, function(err, user) { | ||
| - console.log("HEY!") | ||
| - if (user) { | ||
| - var chat = new FirechatUI(chatRef, document.getElementById('firechat-wrapper')); | ||
| - chat.setUser(user.uid, user.displayName); | ||
| + | ||
| + // Prevents input from having injected markup | ||
| + function cleanInput (input) { | ||
| + return $('<div/>').text(input).text(); | ||
| + } | ||
| + | ||
| + // Updates the typing event | ||
| + function updateTyping () { | ||
| + if (connected) { | ||
| + if (!typing) { | ||
| + typing = true; | ||
| + socket.emit('typing'); | ||
| + } | ||
| + lastTypingTime = (new Date()).getTime(); | ||
| + | ||
| + setTimeout(function () { | ||
| + var typingTimer = (new Date()).getTime(); | ||
| + var timeDiff = typingTimer - lastTypingTime; | ||
| + if (timeDiff >= TYPING_TIMER_LENGTH && typing) { | ||
| + socket.emit('stop typing'); | ||
| + typing = false; | ||
| + } | ||
| + }, TYPING_TIMER_LENGTH); | ||
| + } | ||
| + } | ||
| + | ||
| + // Gets the 'X is typing' messages of a user | ||
| + function getTypingMessages (data) { | ||
| + return $('.typing.message').filter(function (i) { | ||
| + return $(this).data('username') === data.username; | ||
| + }); | ||
| + } | ||
| + | ||
| + // Gets the color of a username through our hash function | ||
| + function getUsernameColor (username) { | ||
| + // Compute hash code | ||
| + var hash = 7; | ||
| + for (var i = 0; i < username.length; i++) { | ||
| + hash = username.charCodeAt(i) + (hash << 5) - hash; | ||
| + } | ||
| + // Calculate color | ||
| + var index = Math.abs(hash % COLORS.length); | ||
| + return COLORS[index]; | ||
| + } | ||
| + | ||
| + // Keyboard events | ||
| + | ||
| + $window.keydown(function (event) { | ||
| + // Auto-focus the current input when a key is typed | ||
| + if (!(event.ctrlKey || event.metaKey || event.altKey)) { | ||
| + $currentInput.focus(); | ||
| } | ||
| + // When the client hits ENTER on their keyboard | ||
| + if (event.which === 13) { | ||
| + if (username) { | ||
| + sendMessage(); | ||
| + socket.emit('stop typing'); | ||
| + typing = false; | ||
| + } else { | ||
| + setUsername(); | ||
| + } | ||
| + } | ||
| + }); | ||
| + | ||
| + $inputMessage.on('input', function() { | ||
| + updateTyping(); | ||
| }); | ||
| + // Click events | ||
| + | ||
| + // Focus input when clicking anywhere on login page | ||
| + $loginPage.click(function () { | ||
| + $currentInput.focus(); | ||
| + }); | ||
| + | ||
| + // Focus input when clicking on the message input's border | ||
| + $inputMessage.click(function () { | ||
| + $inputMessage.focus(); | ||
| + }); | ||
| + | ||
| + // Socket events | ||
| + | ||
| + // Whenever the server emits 'login', log the login message | ||
| + socket.on('login', function (data) { | ||
| + connected = true; | ||
| + // Display the welcome message | ||
| + var message = "Welcome to Socket.IO Chat – "; | ||
| + log(message, { | ||
| + prepend: true | ||
| + }); | ||
| + addParticipantsMessage(data); | ||
| + }); | ||
| + | ||
| + // Whenever the server emits 'new message', update the chat body | ||
| + socket.on('new message', function (data) { | ||
| + addChatMessage(data); | ||
| + }); | ||
| + | ||
| + // Whenever the server emits 'user joined', log it in the chat body | ||
| + socket.on('user joined', function (data) { | ||
| + log(data.username + ' joined'); | ||
| + addParticipantsMessage(data); | ||
| + }); | ||
| + | ||
| + // Whenever the server emits 'user left', log it in the chat body | ||
| + socket.on('user left', function (data) { | ||
| + log(data.username + ' left'); | ||
| + addParticipantsMessage(data); | ||
| + removeChatTyping(data); | ||
| + }); | ||
| + | ||
| + // Whenever the server emits 'typing', show the typing message | ||
| + socket.on('typing', function (data) { | ||
| + addChatTyping(data); | ||
| + }); | ||
| + | ||
| + // Whenever the server emits 'stop typing', kill the typing message | ||
| + socket.on('stop typing', function (data) { | ||
| + removeChatTyping(data); | ||
| + }); | ||
| }); | ||
12
views/curriculum/curriculum.jade
1
views/layout.jade
0 comments on commit
254740c