diff --git a/.gitignore b/.gitignore index ea051b290..df6d75bec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -settings.json \ No newline at end of file +settings.json +static/js/jquery.min.js \ No newline at end of file diff --git a/README.md b/README.md index a3faefa41..52660d971 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,30 @@ Etherpad lite is a really-real time collaborative editor spawned from the Hell f We're reusing the well tested Etherpad easysync library to make it really realtime. Etherpad Lite is based on node.js what makes it much leigther and more stable than the original Etherpad. Our hope is that this will encourage more users to install a realtime collaborative editor. A smaller and well -documented codebase makes it easier for developers to improve the code +documented codebase makes it easier for developers to improve the code. Etherpad Lite is optimized +to be easy embeddable **Online demo**
Visit to test it live -# Why use Etherpad Lite? -* Tiny server hardware footprint -* Pure Javascript client and server side -* Simplfied interface -* Easy to embed -* Well documented +# Etherpad vs Etherpad Lite + + + + + + + + + + + + + + + + +
  Etherpad Etherpad Lite
Size of the folder (without git history) 30 MB 1.5 MB
Languages used server side Javascript (Rhino), Java, Scala Javascript (node.js)
Lines of server side Javascript code 101410 5330
RAM Usage immediately after start 257 MB 16 MB
# Installation 1. Download latest node.js version from and build it with this instructions .
THE NODE.JS VERSION OF YOUR LINUX REPOSITORY MAY BE TOO OLD. PLEASE COMPILE FROM THE SOURCE TO GET SURE YOU HAVE THE LATEST VERSION. diff --git a/bin/run.sh b/bin/run.sh index 3940e87c4..f1a1af995 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -37,6 +37,21 @@ fi echo "Ensure that all dependencies are up to date..." npm install +echo "Ensure jQuery is downloaded and up to date..." +DOWNLOAD_JQUERY="true" +NEEDED_VERSION="1.6.1" +if [ -f "static/js/jquery.min.js" ]; then + VERSION=$(cat static/js/jquery.min.js | head -n 2 | tail -n 1 | grep -o "v[0-9]*\.[0-9]*\.[0-9]*"); + + if [[ ${VERSION:1} = $NEEDED_VERSION ]]; then + DOWNLOAD_JQUERY="false" + fi +fi + +if [[ $DOWNLOAD_JQUERY = "true" ]]; then + wget -O static/js/jquery.min.js http://code.jquery.com/jquery-$NEEDED_VERSION.min.js +fi + #Remove all minified data to force node creating it new echo "Clear minfified cache..." rm var/minified* 2> /dev/null diff --git a/node/PadMessageHandler.js b/node/PadMessageHandler.js index c728a9e0a..786bfd37a 100644 --- a/node/PadMessageHandler.js +++ b/node/PadMessageHandler.js @@ -145,7 +145,7 @@ exports.handleMessage = function(client, message) } if(!message.type) { - throw "Message have no type attribute!"; + throw "Message has no type attribute!"; } //Check what type of message we get and delegate to the other methodes @@ -163,6 +163,12 @@ exports.handleMessage = function(client, message) { handleUserInfoUpdate(client, message); } + else if(message.type == "COLLABROOM" && + message.data.type == "CLIENT_MESSAGE" && + message.data.payload.type == "suggestUserName") + { + handleSuggestUserName(client, message); + } //if the message type is unkown, throw an exception else { @@ -170,6 +176,36 @@ exports.handleMessage = function(client, message) } } +/** + * Handles a handleSuggestUserName, that means a user have suggest a userName for a other user + * @param client the client that send this message + * @param message the message from the client + */ +function handleSuggestUserName(client, message) +{ + //check if all ok + if(message.data.payload.newName == null) + { + throw "suggestUserName Message has no newName!"; + } + if(message.data.payload.unnamedId == null) + { + throw "suggestUserName Message has no unnamedId!"; + } + + var padId = session2pad[client.sessionId]; + + //search the author and send him this message + for(var i in pad2sessions[padId]) + { + if(sessioninfos[pad2sessions[padId][i]].author == message.data.payload.unnamedId) + { + socketio.clients[pad2sessions[padId][i]].send(message); + break; + } + } +} + /** * Handles a USERINFO_UPDATE, that means that a user have changed his color or name. Anyway, we get both informations * @param client the client that send this message @@ -180,7 +216,7 @@ function handleUserInfoUpdate(client, message) //check if all ok if(message.data.userInfo.colorId == null) { - throw "USERINFO_UPDATE Message have no colorId!"; + throw "USERINFO_UPDATE Message has no colorId!"; } //Find out the author name of this session @@ -202,7 +238,7 @@ function handleUserInfoUpdate(client, message) message.data.type = "USER_NEWINFO"; //Send the other clients on the pad the update message - for(i in pad2sessions[padId]) + for(var i in pad2sessions[padId]) { if(pad2sessions[padId][i] != client.id) { @@ -228,15 +264,15 @@ function handleUserChanges(client, message) //check if all ok if(message.data.baseRev == null) { - throw "USER_CHANGES Message have no baseRev!"; + throw "USER_CHANGES Message has no baseRev!"; } if(message.data.apool == null) { - throw "USER_CHANGES Message have no apool!"; + throw "USER_CHANGES Message has no apool!"; } if(message.data.changeset == null) { - throw "USER_CHANGES Message have no changeset!"; + throw "USER_CHANGES Message has no changeset!"; } //get all Vars we need @@ -451,25 +487,26 @@ function handleClientReady(client, message) //check if all ok if(!message.token) { - throw "CLIENT_READY Message have no token!"; + throw "CLIENT_READY Message has no token!"; } if(!message.padId) { - throw "CLIENT_READY Message have no padId!"; + throw "CLIENT_READY Message has no padId!"; } if(!message.protocolVersion) { - throw "CLIENT_READY Message have no protocolVersion!"; + throw "CLIENT_READY Message has no protocolVersion!"; } if(message.protocolVersion != 2) { - throw "CLIENT_READY Message have a unkown protocolVersion '" + message.protocolVersion + "'!"; + throw "CLIENT_READY Message has a unkown protocolVersion '" + message.protocolVersion + "'!"; } var author; var authorName; var authorColorId; var pad; + var historicalAuthorData = {}; async.series([ //get all authordata of this new user @@ -511,6 +548,20 @@ function handleClientReady(client, message) }); }, function(callback) + { + var authors = pad.getAllAuthors(); + + //get all author data out of the database + async.forEach(authors, function(authorId, callback) + { + authorManager.getAuthor(authorId, function(err, author) + { + historicalAuthorData[authorId] = author; + callback(err); + }); + }, callback); + }, + function(callback) { //Check if this author is already on the pad, if yes, kick the other sessions! if(pad2sessions[message.padId]) @@ -556,7 +607,7 @@ function handleClientReady(client, message) "clientIp": (client.request && client.request.connection) ? client.request.connection.remoteAddress : "127.0.0.1", //"clientAgent": "Anonymous Agent", "padId": message.padId, - "historicalAuthorData": {}, + "historicalAuthorData": historicalAuthorData, "apool": apool, "rev": pad.getHeadRevisionNumber(), "globalPadId": message.padId @@ -570,7 +621,7 @@ function handleClientReady(client, message) "opts": {}, "chatHistory": { "start": 0, - "historicalAuthorData": {}, + "historicalAuthorData": historicalAuthorData, "end": 0, "lines": [] }, @@ -592,16 +643,6 @@ function handleClientReady(client, message) clientVars.userName = authorName; } - //Add all authors that worked on this pad, to the historicalAuthorData on clientVars - var allAuthors = pad.getAllAuthors(); - for(i in allAuthors) - { - clientVars.collab_client_vars.historicalAuthorData[allAuthors[i]] = {}; - if(authorName != null) - clientVars.collab_client_vars.historicalAuthorData[allAuthors[i]].name = authorName; - clientVars.collab_client_vars.historicalAuthorData[allAuthors[i]].colorId = authorColorId; - } - //Send the clientVars to the Client client.json.send(clientVars); diff --git a/node/SocketIORouter.js b/node/SocketIORouter.js index 5dd0c8f7f..81f8e683d 100644 --- a/node/SocketIORouter.js +++ b/node/SocketIORouter.js @@ -58,6 +58,12 @@ exports.setSocketIO = function(_socket) client.on('message', function(message) { + if(message.protocolVersion && message.protocolVersion != 2) + { + console.error("Protocolversion header is not correct:" + JSON.stringify(message)); + return; + } + //route this message to the correct component, if possible if(message.component && components[message.component]) { @@ -71,7 +77,7 @@ exports.setSocketIO = function(_socket) } else { - throw "Can't route the message:" + JSON.stringify(message); + console.error("Can't route the message:" + JSON.stringify(message)); } }); diff --git a/node/minify.js b/node/minify.js index 7245b214f..aee3d3c05 100644 --- a/node/minify.js +++ b/node/minify.js @@ -39,7 +39,7 @@ exports.padJS = function(req, res) { res.header("Content-Type","text/javascript"); - var jsFiles = ["plugins.js", "undo-xpopup.js", "json2.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js"]; + var jsFiles = ["jquery.min.js", "plugins.js", "undo-xpopup.js", "json2.js", "pad_utils.js", "pad_cookie.js", "pad_editor.js", "pad_editbar.js", "pad_docbar.js", "pad_modals.js", "ace.js", "collab_client.js", "pad_userlist.js", "pad_impexp.js", "pad_savedrevs.js", "pad_connectionstatus.js", "pad2.js"]; //minifying is enabled if(settings.minify) @@ -182,9 +182,9 @@ exports.padJS = function(req, res) { //put all javascript files in an array var values = []; - for(var i in fileValues) + for(var i in jsFiles) { - values.push(fileValues[i]); + values.push(fileValues[jsFiles[i]]); } //minify all javascript files to one diff --git a/node/server.js b/node/server.js index 712638d13..822230c55 100644 --- a/node/server.js +++ b/node/server.js @@ -23,6 +23,7 @@ require('joose'); var socketio = require('socket.io'); +var fs = require('fs'); var settings = require('./settings'); var socketIORouter = require("./SocketIORouter"); var db = require('./db'); @@ -31,9 +32,24 @@ var express = require('express'); var path = require('path'); var minify = require('./minify'); -var serverName = "Etherpad-Lite ( http://j.mp/ep-lite )"; +//try to get the git version +var version = ""; +try +{ + var ref = fs.readFileSync("../.git/HEAD", "utf-8"); + var refPath = "../.git/" + ref.substring(5, ref.indexOf("\n")); + version = fs.readFileSync(refPath, "utf-8"); + version = version.substring(0, 8); +} +catch(e) +{ + console.error("Can't get git version for server header\n" + e.message) +} + +var serverName = "Etherpad-Lite " + version + " (http://j.mp/ep-lite)"; + //cache a week -exports.maxAge = 1000*60*60*24*1; +exports.maxAge = 1000*60*60*6; async.waterfall([ //initalize the database @@ -77,16 +93,30 @@ async.waterfall([ }); //serve pad.html under /p - app.get('/p/:pad', function(req, res) + app.get('/p/:pad', function(req, res, next) { + //ensure the padname is valid and the url doesn't end with a / + if(!isValidPadname(req.params.pad) || /\/$/.test(req.url)) + { + next(); + return; + } + res.header("Server", serverName); var filePath = path.normalize(__dirname + "/../static/pad.html"); res.sendfile(filePath, { maxAge: exports.maxAge }); }); //serve timeslider.html under /p/$padname/timeslider - app.get('/p/:pad/timeslider', function(req, res) + app.get('/p/:pad/timeslider', function(req, res, next) { + //ensure the padname is valid and the url doesn't end with a / + if(!isValidPadname(req.params.pad) || /\/$/.test(req.url)) + { + next(); + return; + } + res.header("Server", serverName); var filePath = path.normalize(__dirname + "/../static/timeslider.html"); res.sendfile(filePath, { maxAge: exports.maxAge }); @@ -134,3 +164,12 @@ async.waterfall([ callback(null); } ]); + +function isValidPadname(padname) +{ + //ensure there is no dollar sign in the pad name + if(padname.indexOf("$")!=-1) + return false; + + return true; +} diff --git a/static/css/broadcast.css b/static/css/broadcast.css index 982d2e47c..3f47b77bb 100644 --- a/static/css/broadcast.css +++ b/static/css/broadcast.css @@ -171,7 +171,7 @@ div #timeslider div#steppers div#rightstep { -#rightbars { +/*#rightbars { margin-left: 730px; margin-top: 5px; margin-bottom: 5px; @@ -220,10 +220,10 @@ div #timeslider div#steppers div#rightstep { color: rgb(50, 132, 213); text-decoration: none; } +*/ - -#legend { +/*#legend { width: 143px; background-color: white; border: 1px solid rgb(194, 194, 194); @@ -249,7 +249,7 @@ div #timeslider div#steppers div#rightstep { margin-top:3px; margin-right: 14px; border: rgb(149, 149, 149) 1px solid; -} +}*/ .topbarcenter{ display:none; diff --git a/static/css/pad_lite.css b/static/css/pad_lite.css index 80a9d41e7..7a33cc3bd 100644 --- a/static/css/pad_lite.css +++ b/static/css/pad_lite.css @@ -22,7 +22,7 @@ body, textarea { font-family: Helvetica, Arial, sans-serif; } border-radius: 6px; } -#sharebutton { +/*#sharebutton { background: url(static/img/inviteshare2.gif) no-repeat 0 -31px; position: relative; display: block; @@ -31,7 +31,7 @@ body, textarea { font-family: Helvetica, Arial, sans-serif; } height: 0; overflow: hidden; width: 96px; left:50%; margin-left: -48px; -} +}*/ a img @@ -193,20 +193,17 @@ a#backtoprosite { padding-left: 20px; left: 6px; background: url(static/img/protop.gif) no-repeat -5px -6px; } #accountnav { right: 30px; color: #fff; } -#topbarcenter { margin-left: 150px; margin-right: 150px; text-align:center;} +/*#topbarcenter { margin-left: 150px; margin-right: 150px; text-align:center;} a#topbaretherpad { margin-left: auto; margin-right: auto; display: block; width: 103px; position: relative; top: 3px; height: 0; padding-top: 20px; -/* background: url(static/img/padtop5.gif) no-repeat -397px -3px; overflow: hidden; */ -} - - -#topbarBrand {font-size:2.1em; color: white; font-weight: bold; text-decoration: none; text-align: center;} +}*/ +/*#topbarBrand {font-size:2.1em; color: white; font-weight: bold; text-decoration: none; text-align: center;} #EtherpadLink {font-size: 1.2em; color: white;float:left;margin-left:-140px;margin-top:4px; text-decoration: none; } #Licensing {font-size: 1.2em; color: white;float:left;margin-top:4px;margin-left:-75px; text-decoration: none; } -#fullscreen {font-size: 1.2em; color: white;float:right;margin-top:4px;margin-right:-120px; text-decoration: none; } +#fullscreen {font-size: 1.2em; color: white;float:right;margin-top:4px;margin-right:-120px; text-decoration: none; }*/ .propad a#topbaretherpad { background: url(static/img/protop.gif) no-repeat -397px -3px; } @@ -361,7 +358,7 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; } white-space: nowrap; } -.editbarbutton +/*.editbarbutton { border-top: 1px solid #8b9eba; border-bottom: 1px solid #8b9eba; @@ -386,21 +383,21 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; } position: relative; top: 1px; left: 1px; -} +}*/ -.editbargroupsfirst +/*.editbargroupsfirst { border-left-width: 0px !important; -} +}*/ -#editbar #syncstatussyncing { position: absolute; height: 26px; width: 26px; +/*#editbar #syncstatussyncing { position: absolute; height: 26px; width: 26px; background: url(static/img/syncing2.gif) no-repeat center center; right: 38px; top: 5px; display: none; } #editbar #syncstatusdone { position: absolute; height: 26px; width: 26px; background: url(static/img/syncdone.gif) no-repeat center center; - right: 38px; top: 5px; display: none; } + right: 38px; top: 5px; display: none; }*/ -#padsidebar { +/*#padsidebar { bottom: 0px; position: absolute; right: 0; @@ -409,7 +406,7 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; } overflow: hidden; z-index: 11; } -.hidesidebar #padsidebar { width: 0; overflow: hidden; } +.hidesidebar #padsidebar { width: 0; overflow: hidden; }*/ #myswatchbox { position: absolute; left: 5px; top: 5px; width: 22px; height: 22px; /*border-top: 1px solid #c3cfe0; border-left: 1px solid #c3cfe0; @@ -504,12 +501,12 @@ table#otheruserstable { display: none; } top: 5px; width: 95px; } .guestpolicystuff { display: none; }*/ -.guestprompt { border: 1px solid #ccc; font-size: 1.2em; +/*.guestprompt { border: 1px solid #ccc; font-size: 1.2em; padding: 5px; color: #222; background: #ffc; } .guestprompt .choices { float: right; } -.guestprompt a { margin: 0 0.5em; } +.guestprompt a { margin: 0 0.5em; }*/ -#chattop { background: #ecf2fa; padding: 5px; font-size: 1.2em; border-bottom: 1px solid #ddd; } +/*#chattop { background: #ecf2fa; padding: 5px; font-size: 1.2em; border-bottom: 1px solid #ddd; } #chattop a { color: #36b; } #chatlines .chatline { color: #444; padding-left: 5px; padding-top: 2px; padding-bottom: 2px; background: #ddd; overflow: hidden; } @@ -527,13 +524,13 @@ table#otheruserstable { display: none; } #padchat a#chatloadmore { display: none; font-size: 1.2em; padding: 2px 5px; font-style: italic; } #padchat #chatloadingmore { display: none; font-size: 1.2em; padding: 2px 5px; font-style: italic; color: #999; } -#padchat a#chatloadmore:focus { outline: 0; } +#padchat a#chatloadmore:focus { outline: 0; }*/ -#djs { font-family: monospace; font-size: 10pt; +/*#djs { font-family: monospace; font-size: 10pt; height: 200px; overflow: auto; border: 1px solid #ccc; background: #fee; margin: 0; padding: 6px; } -#djs p { margin: 0; padding: 0; display: block; } +#djs p { margin: 0; padding: 0; display: block; }*/ .modaldialog.cboxreconnecting .modaldialog-inner, .modaldialog.cboxconnecting .modaldialog-inner { @@ -635,14 +632,14 @@ table#otheruserstable { display: none; } /* We don't ever actually hide the wrapper, even when the panel is cloased, so that its contents can always be manipulated accurately. */ -.dbpanel-wrapper { position: absolute; - overflow: hidden; /* animated: */ height: 0; top: 25px; /* /animated */ +/*.dbpanel-wrapper { position: absolute; + overflow: hidden; height: 0; top: 25px; z-index: 51; zoom: 1; } .dbpanel-panel { position: absolute; bottom: 0; width: 100%; } .dbpanel-middle { margin-left: 7px; margin-right: 7px; position: relative; height: 100%; overflow: hidden; zoom: 1; } -.dbpanel-inner { background: #f7f7f7 /* covered up by images */; +.dbpanel-inner { background: #f7f7f7 ; width: 100%; height: 100%; position: absolute; overflow: hidden; top: -10px; } .dbpanel-top { position: absolute; top: 0; width: 100%; @@ -655,10 +652,10 @@ table#otheruserstable { display: none; } background-position: left top; } -* html .dbpanel-top, * html .dbpanel-bottom { /* for IE 6+ */ +* html .dbpanel-top, * html .dbpanel-bottom { background-color: transparent; background-image: url(static/img/apr09/blank.gif); - /* scale the image instead of repeating, but it amounts to the same */ + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="static/img/docpanelmiddle2.png", sizingMethod="scale"); } @@ -681,12 +678,12 @@ table#otheruserstable { display: none; } * html .dbpanel-leftedge, * html .dbpanel-rightedge, * html .dbpanel-botleftcorner, * html .dbpanel-botrightcorner { background-color: transparent; background-image: url(static/img/apr09/blank.gif); - /* crop the image */ + filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="static/img/docpaneledge2.png", sizingMethod="crop"); } * html .dbpanel-leftedge, * html .dbpanel-botleftcorner { left: -7px; width: 14px; } - -#impexp-importlabel { position: absolute; top: 5px; left: 10px; width: 300px; } +*/ +/*#impexp-importlabel { position: absolute; top: 5px; left: 10px; width: 300px; } #importform { position: absolute; top: 24px; left: 5px; width: 300px; height: 60px; } #importformsubmitdiv, #importformfilediv { padding: 5px 5px; } @@ -703,7 +700,7 @@ table#otheruserstable { display: none; } #importexport #importmessagesuccess { margin: 0 20px; } #importexport a.disabledexport { color: #333; text-decoration: none; - opacity: 0.5; filter: alpha(opacity = 50) /*IE*/; + opacity: 0.5; filter: alpha(opacity = 50) ; } #importexport #importfileinput { padding: 2px 0; } #importexport #importsubmitinput { padding: 2px; } @@ -712,7 +709,7 @@ table#otheruserstable { display: none; } background: #ddd; } #impexp-close { display: block; position: absolute; right: 2px; bottom: 15px; width: auto; height: auto; font-size: 85%; color: #444; - z-index: 61 /* > clickcatcher */} + z-index: 61} #impexp-disabled-clickcatcher { display: none; position: absolute; width: 100%; height: 100%; @@ -721,7 +718,7 @@ table#otheruserstable { display: none; } #impexp-exportlabel { position: absolute; top: 5px; left: 350px; width: 300px; } -#exportlinks .exportlink { + #exportlinks .exportlink { display: block; position: absolute; height: 22px; width: auto; background-repeat: no-repeat; background-image: url(static/img/fileicons.gif); @@ -759,7 +756,7 @@ table#otheruserstable { display: none; } width: auto; height: 100%; overflow: hidden; position: relative; } #savedrevs-scrollinner { position: absolute; width: 1px; height: 100%; - overflow: visible; right: 0/*...initially*/; top: 0; } + overflow: visible; right: 0; top: 0; } #savedrevisions .srouterbox { width: 120px; height: 100%; position: absolute; top: 0; } @@ -767,10 +764,10 @@ table#otheruserstable { display: none; } height: 59px; width: auto; border-left: 1px solid #ddd; padding: 0 8px 0 8px; } #savedrevisions a.srname { display: block; white-space: nowrap; - text-overflow: ellipsis /*no FF support*/; overflow: hidden; + text-overflow: ellipsis ; overflow: hidden; text-decoration: none; color: #444; cursor: text; padding: 1px; height: 14px; position: relative; left: -1px; - width: 100px /*specify for proper overflow in IE*/; + width: 100px ; } #savedrevisions a.srname:hover { text-decoration: none; color: #444; border: 1px solid #ccc; padding: 0; } @@ -782,7 +779,7 @@ table#otheruserstable { display: none; } #savedrevisions .srtime { color: #666; font-size: 90%; white-space: nowrap; margin-top: 3px; } #savedrevisions .srauthor { color: #666; font-size: 90%; - white-space: nowrap; overflow: hidden; text-overflow: ellipsis /*no FF*/; + white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } #savedrevisions .srtwirly { position: absolute; display: block; bottom: 0; right: 10px; display: none; } @@ -797,7 +794,7 @@ table#otheruserstable { display: none; } #savedrevs-savenow:active { background-position: 0 -24px; } #savedrevs-close { display: block; position: absolute; right: 7px; bottom: 8px; width: auto; height: auto; font-size: 85%; color: #444; } -form#reconnectform { display: none; } +form#reconnectform { display: none; }*/ #padoptions { position: absolute; top: 0; left: 0; font-size: 1.2em; color: #444; height: 100%; width: 100%; line-height: 15px; } @@ -817,7 +814,7 @@ form#reconnectform { display: none; } #options-close { display: block; position: absolute; right: 7px; bottom: 8px; width: auto; height: auto; font-size: 85%; color: #444; } -#padsecurity { position: absolute; top: 0; left: 0; font-size: 1.1em; +/*#padsecurity { position: absolute; top: 0; left: 0; font-size: 1.1em; color: #444; height: 100%; width: 100%; line-height: 15px; } #security-close { display: block; position: absolute; right: 7px; bottom: 8px; width: auto; height: auto; font-size: 85%; color: #444; } @@ -856,7 +853,7 @@ form#reconnectform { display: none; } #access-public, #access-public-label { top: 60px; } #security-access label { color: #999; } #security-access label strong { font-weight: normal; padding-right: 10px; - color: #444; } + color: #444; }*/ #mainmodals { z-index: 600; /* higher than the modals themselves so that modals are on top in IE */ } @@ -865,10 +862,10 @@ form#reconnectform { display: none; } #mainmodals .editempty { color: #aaa; } -#feedbackbox { +/*#feedbackbox { position: absolute; display: none; width: 400px; height: 270px; - left: 100px/*set in code*/; bottom: 50px; + left: 100px ; bottom: 50px; z-index: 501; zoom: 1; } #feedbackbox-tl, #feedbackbox-tr, #feedbackbox-bl, #feedbackbox-br, @@ -914,7 +911,7 @@ form#reconnectform { display: none; } #feedbackbox li a:hover { background: #ffe; } #feedbackbox a, #feedbackbox li a:visited { color: #47b; } #feedbackbox tt { font-size: 110%; } - +*/ .expand-collapse { height: 22px; background-image: url(static/img/sharedistri.gif); @@ -1142,7 +1139,7 @@ ul#colorpickerswatches li:hover cursor: pointer; } -.user{ +/*.user{ border: 1px solid #BBBBBB; padding-left:2px; padding-right:2px; @@ -1182,4 +1179,4 @@ color:#000; padding-left:4px; padding-right:4px; padding-top:2px; -} +}*/ diff --git a/static/pad.html b/static/pad.html index 6da27fae8..5b263648d 100644 --- a/static/pad.html +++ b/static/pad.html @@ -19,7 +19,6 @@ var clientVars = {}; // ]]> - - Return to pad + Return to pad +