mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
Merge branch 'master' of github.com:Pita/etherpad-lite into HEAD
This commit is contained in:
commit
7a10e1783a
11 changed files with 209 additions and 92 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
node_modules
|
||||
settings.json
|
||||
settings.json
|
||||
static/js/jquery.min.js
|
27
README.md
27
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**<br>
|
||||
Visit <http://pitapoison.de:9001> 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
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td><td> </td><td><b>Etherpad</b></td><td> </td><td><b>Etherpad Lite</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Size of the folder (without git history)</td><td> </td><td>30 MB</td><td> </td><td>1.5 MB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Languages used server side</td><td> </td><td>Javascript (Rhino), Java, Scala</td><td> </td><td>Javascript (node.js)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Lines of server side Javascript code</td><td> </td><td>101410</td><td> </td><td>5330</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">RAM Usage immediately after start</td><td> </td><td>257 MB</td><td> </td><td>16 MB</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
# Installation
|
||||
1. Download latest node.js version from <http://nodejs.org/> and build it with this instructions <https://github.com/joyent/node/wiki/Installation>. <br>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.
|
||||
|
|
15
bin/run.sh
15
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
var clientVars = {}; // ]]>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
|
||||
|
||||
<!--<script type="text/javascript" src="/static/js/plugins.js"></script>
|
||||
|
@ -100,7 +99,10 @@ var clientVars = {}; // ]]>
|
|||
</li>
|
||||
|
||||
<li>
|
||||
<a href="javascript:document.location = document.location+ '/timeslider'" title="Show the history of this pad">
|
||||
<a id="timesliderlink" title="Show the history of this pad">
|
||||
<script>
|
||||
$("#timesliderlink").attr("href", document.location+ '/timeslider');
|
||||
</script>
|
||||
<img src="/static/img/editbar_timeslider.gif" />
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<link href="/static/css/pad_lite.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/static/css/broadcast.css" rel="stylesheet" type="text/css" />
|
||||
<style type="text/css" title="dynamicsyntax"></style>
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
var clientVars = {};
|
||||
|
@ -274,7 +274,10 @@
|
|||
|
||||
<div id="editbarright" class="editbarright">
|
||||
<!-- termporary place holder-->
|
||||
<a id = "returnbutton" href="javascript:document.location=document.location.href.substring(0,document.location.href.lastIndexOf('/timeslider'))">Return to pad</a>
|
||||
<a id = "returnbutton">Return to pad</a>
|
||||
<script>
|
||||
$("#returnbutton").attr("href", document.location.href.substring(0,document.location.href.lastIndexOf('/timeslider')));
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="editbarinner" class="editbarinner">
|
||||
|
|
Loading…
Reference in a new issue