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,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) 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