diff --git a/app.js b/app.js index fbf00c5..4f51635 100644 --- a/app.js +++ b/app.js @@ -14,13 +14,15 @@ var express = require('express') , sanitizer = require('sanitizer') , sassMiddleware = require('node-sass-middleware') , config = require('config') - , validate = require('./util/validate')(rooms, { maxUserNameLength: config.get('app.max_username_length') }) , arrayUtil = require('./util/arrayUtil')(console); // Globals var app = express(); var rooms = {}; +// Set up validator +var validate = require('./util/validate')(rooms, { maxUserNameLength: config.get('app.max_username_length') }); + // Constants var IS_PROD_ENV = 'production' == app.get('env'); var MAX_ROOM_NAME_LENGTH = config.get('app.max_room_name_length'); @@ -120,26 +122,26 @@ io.of('/chat').on('connection', function (socket) { socket.on('adduser', function(username, room){ username = sanitizer.escape(username).trim(); room = sanitizer.escape(room); - + validate.room(room, function (err, isRoomValid) { if (err) { socket.emit(err.name, err.arg); socket.disconnect(); } - + if (isRoomValid) { socket.join(room); socket.room = room; - + validate.username(username, room, function (err, isUsernameValid) { if (err) { socket.emit(err.name, err.arg); } - + if (isUsernameValid) { rooms[room].usernames.push(username); socket.username = username; - + socket.emit('updatechatserver', 'you have connected to room ' + socket.room); socket.emit('addusersuccess', room); socket.broadcast.to(socket.room).emit('updatechatserver', username + ' has connected'); @@ -150,11 +152,12 @@ io.of('/chat').on('connection', function (socket) { }); }); - socket.on('changelang', function (lang) { - lang = sanitizer.escape(lang); + socket.on('changelang', function (value, caption) { + value = sanitizer.escape(value); + caption = sanitizer.escape(caption); // TODO: Do some validation on the lang here - io.of('/chat').in(socket.room).emit('updatelang', lang, socket.username); + io.of('/chat').in(socket.room).emit('updatelang', value, caption, socket.username); }); socket.on('userleft', function () { diff --git a/public/javascripts/main.js b/public/javascripts/main.js index c10f15c..827014a 100644 --- a/public/javascripts/main.js +++ b/public/javascripts/main.js @@ -22,15 +22,78 @@ $(function() { editor.setTheme("ace/theme/monokai"); session.setMode("ace/mode/javascript"); + var modeList = ace.require("ace/ext/modelist"); + var themeList = ace.require("ace/ext/themelist"); + // Chosen // ========================================================= + // Fill mode select with available modes + var modes = document.createDocumentFragment(); + for(var i = 0; i < modeList.modes.length; i++) { + var mode = modeList.modes[i]; + + var opt = document.createElement("option"); + opt.setAttribute("value", mode.mode); + opt.innerText = mode.caption; + modes.appendChild(opt); + } + + // Populate select + $selectMode.html(modes); + + // Default to JavaScript + $selectMode.val(modeList.modesByName.javascript.mode); + + // Set up chosen $selectMode.chosen({ width: "180px", - search_contains: true + search_contains: true, + placeholder_text_single: "Choose a language", + inherit_select_classes: true + }) + .on('change', function () { + editor.getSession().setMode(this.value); + socket.emit('changelang', this.value, this.options[this.selectedIndex].text); + editor.focus(); + }); + + // Fill theme select with available themes + var darkThemes = document.createElement("optgroup"); + darkThemes.setAttribute("label", "Dark"); + var lightThemes = document.createElement("optgroup"); + lightThemes.setAttribute("label", "Light"); + + for(var i = 0; i < themeList.themes.length; i++) { + var theme = themeList.themes[i]; + + var opt = document.createElement("option"); + opt.setAttribute("value", theme.theme); + opt.innerHTML = theme.caption; + + if (theme.isDark) { + darkThemes.appendChild(opt); + } else { + lightThemes.appendChild(opt); + } + } + + // Populate select + $selectTheme.html(darkThemes); + $selectTheme.append(lightThemes); + + // Default to monokai + $selectTheme.val(themeList.themesByName.monokai.theme); + + // Set up chosen + $selectTheme.chosen({ + width: "180px", + search_contains: true, + placeholder_text_single: "Choose a theme", + inherit_select_classes: true }) .on('change', function () { - editor.getSession().setMode("ace/mode/" + this.value); - socket.emit('changelang', this.value); + editor.setTheme(this.value); + editor.focus(); }); // Socket.IO @@ -99,11 +162,11 @@ $(function() { }); // [SOCKET] UPDATE LANG - socket.on("updatelang", function(lang, username) { - console.log("SOCKET: updatelang detected. Language changed to " + lang + " by " + username); + socket.on("updatelang", function(value, caption, username) { + console.log("SOCKET: updatelang detected. Language changed to " + caption + " by " + username); // TODO: Should probably do some validation on this - $("select#mode").val(lang).trigger("chosen:updated"); - write_server_chat_message(username + " changed the language to " + lang); + $selectMode.val(value).trigger("chosen:updated"); + write_server_chat_message(username + " changed the language to " + caption); }); // [SOCKET] ADD USER SUCCESS @@ -196,7 +259,7 @@ $(function() { // Build message container var msgElem = document.createElement('div'); msgElem.classList.add('message'); - + if (fServer) { msgElem.classList.add('server'); } @@ -212,7 +275,7 @@ $(function() { msgElem.appendChild(unameElem); msgElem.appendChild(msgBody); $messages.append(msgElem); - + // Scroll to the bottom of the messages container $messages[0].scrollTop = $messages[0].scrollHeight; } diff --git a/views/includes/controls.jade b/views/includes/controls.jade index 6e5bd79..8845b04 100644 --- a/views/includes/controls.jade +++ b/views/includes/controls.jade @@ -1,129 +1,2 @@ select#mode.chosen-select(size='1') - option(value='abap') ABAP - option(value='ada') ADA - option(value='actionscript') ActionScript - option(value='asciidoc') AsciiDoc - option(value='assembly_x86') Assembly_x86 - option(value='autohotkey') AutoHotKey - option(value='batchfile') BatchFile - option(value='c9search') C9Search - option(value='c_cpp') C/C++ - option(value='clojure') Clojure - option(value='cobol') Cobol - option(value='coffee') CoffeeScript - option(value='coldfusion') ColdFusion - option(value='csharp') C# - option(value='css') CSS - option(value='curly') Curly - option(value='d') D - option(value='dart') Dart - option(value='diff') Diff - option(value='dot') Dot - option(value='erlang') Erlang - option(value='ejs') EJS - option(value='forth') Forth - option(value='ftl') FreeMarker - option(value='glsl') Glsl - option(value='golang') Go - option(value='groovy') Groovy - option(value='haml') HAML - option(value='haskell') Haskell - option(value='haxe') haXe - option(value='html') HTML - option(value='html_ruby') HTML (Ruby) - option(value='ini') Ini - option(value='jade') Jade - option(value='java') Java - option(value='javascript', selected='selected') JavaScript - option(value='json') JSON - option(value='jsoniq') JSONiq - option(value='jsp') JSP - option(value='jsx') JSX - option(value='julia') Julia - option(value='latex') LaTeX - option(value='less') LESS - option(value='liquid') Liquid - option(value='lisp') Lisp - option(value='livescript') LiveScript - option(value='logiql') LogiQL - option(value='lsl') LSL - option(value='lua') Lua - option(value='luapage') LuaPage - option(value='lucene') Lucene - option(value='makefile') Makefile - option(value='matlab') MATLAB - option(value='markdown') Markdown - option(value='mysql') MySQL - option(value='mushcode') MUSHCode - option(value='objectivec') Objective-C - option(value='ocaml') OCaml - option(value='pascal') Pascal - option(value='perl') Perl - option(value='pgsql') pgSQL - option(value='php') PHP - option(value='powershell') Powershell - option(value='prolog') Prolog - option(value='properties') Properties - option(value='python') Python - option(value='r') R - option(value='rdoc') RDoc - option(value='rhtml') RHTML - option(value='ruby') Ruby - option(value='rust') Rust - option(value='sass') SASS - option(value='scad') SCAD - option(value='scala') Scala - option(value='scheme') Scheme - option(value='scss') SCSS - option(value='sh') SH - option(value='snippets') snippets - option(value='sql') SQL - option(value='stylus') Stylus - option(value='svg') SVG - option(value='tcl') Tcl - option(value='tex') Tex - option(value='text') Text - option(value='textile') Textile - option(value='toml') Toml - option(value='twig') Twig - option(value='typescript') Typescript - option(value='vbscript') VBScript - option(value='velocity') Velocity - option(value='xml') XML - option(value='xquery') XQuery - option(value='yaml') YAML - -//- select#theme.chosen-select(size='1') -//- optgroup(label='Bright') -//- option(value='ace/theme/chrome') Chrome -//- option(value='ace/theme/clouds') Clouds -//- option(value='ace/theme/crimson_editor') Crimson Editor -//- option(value='ace/theme/dawn') Dawn -//- option(value='ace/theme/dreamweaver') Dreamweaver -//- option(value='ace/theme/eclipse') Eclipse -//- option(value='ace/theme/github') GitHub -//- option(value='ace/theme/solarized_light') Solarized Light -//- option(value='ace/theme/textmate') TextMate -//- option(value='ace/theme/tomorrow') Tomorrow -//- option(value='ace/theme/xcode') XCode -//- optgroup(label='Dark') -//- option(value='ace/theme/ambiance') Ambiance -//- option(value='ace/theme/chaos') Chaos -//- option(value='ace/theme/clouds_midnight') Clouds Midnight -//- option(value='ace/theme/cobalt') Cobalt -//- option(value='ace/theme/idle_fingers') idleFingers -//- option(value='ace/theme/kr_theme') krTheme -//- option(value='ace/theme/merbivore') Merbivore -//- option(value='ace/theme/merbivore_soft') Merbivore Soft -//- option(value='ace/theme/mono_industrial') Mono Industrial -//- option(value='ace/theme/monokai', selected='selected') Monokai -//- option(value='ace/theme/pastel_on_dark') Pastel on dark -//- option(value='ace/theme/solarized_dark') Solarized Dark -//- option(value='ace/theme/terminal') Terminal -//- option(value='ace/theme/tomorrow_night') Tomorrow Night -//- option(value='ace/theme/tomorrow_night_blue') Tomorrow Night Blue -//- option(value='ace/theme/tomorrow_night_bright') Tomorrow Night Bright -//- option(value='ace/theme/tomorrow_night_eighties') Tomorrow Night 80s -//- option(value='ace/theme/twilight') Twilight -//- option(value='ace/theme/vibrant_ink') Vibrant Ink - +select#theme.chosen-select(size='1') diff --git a/views/layout.jade b/views/layout.jade index 88f2acc..ecb9fd4 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -18,6 +18,8 @@ html include includes/header block content script(src="/bower_components/ace-builds/src-min/ace.js") + script(src="/bower_components/ace-builds/src-min/ext-modelist.js") + script(src="/bower_components/ace-builds/src-min/ext-themelist.js") script(src="/bower_components/socket.io-client/dist/socket.io.js") script(src="/vendor/share.js/bcsocket.js") script(src="/vendor/share.js/share.js")