diff --git a/settings.json.template b/settings.json.template
index 7aaa5d7ed..f89fcd8ed 100644
--- a/settings.json.template
+++ b/settings.json.template
@@ -40,22 +40,35 @@
"minify" : true,
/* How long may clients use served javascript code (in seconds)? Without versioning this
- is may cause problems during deployment. Set to 0 to disable caching */
- "maxAge" : 21600, // 6 hours
+ may cause problems during deployment. Set to 0 to disable caching */
+ "maxAge" : 21600, // 60 * 60 * 6 = 6 hours
/* This is the path to the Abiword executable. Setting it to null, disables abiword.
Abiword is needed to enable the import/export of pads*/
"abiword" : null,
-
- /* This setting is used if you need http basic auth */
- // "httpAuth" : "user:pass",
+
+ /* This setting is used if you require authentication of all users.
+ Note: /admin always requires authentication. */
+ "requireAuthentication": false,
- /* This setting is used for http basic auth for admin pages. If not set, the admin page won't be accessible from web*/
- // "adminHttpAuth" : "user:pass",
+ /* Require authorization by a module, or a user with is_admin set, see below. */
+ "requireAuthorization": false,
+
+ /* Users for basic authentication. is_admin = true gives access to /admin.
+ If you do not uncomment this, /admin will not be available! */
+ /*
+ "users": {
+ "admin": {
+ "password": "changeme1",
+ "is_admin": true
+ },
+ "user": {
+ "password": "changeme1",
+ "is_admin": false
+ }
+ },
+ */
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
- "loglevel": "INFO",
-
- /* cache 6 hours = 1000*60*60*6 */
- "maxAge": 21600000
+ "loglevel": "INFO"
}
diff --git a/src/node/handler/TimesliderMessageHandler.js b/src/node/handler/TimesliderMessageHandler.js
index a6cf8f4d8..5556efa1e 100644
--- a/src/node/handler/TimesliderMessageHandler.js
+++ b/src/node/handler/TimesliderMessageHandler.js
@@ -155,8 +155,6 @@ function createTimesliderClientVars (padId, callback)
var clientVars = {
viewId: padId,
colorPalette: ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ff8f8f", "#ffe38f", "#c7ff8f", "#8fffab", "#8fffff", "#8fabff", "#c78fff", "#ff8fe3", "#d97979", "#d9c179", "#a9d979", "#79d991", "#79d9d9", "#7991d9", "#a979d9", "#d979c1", "#d9a9a9", "#d9cda9", "#c1d9a9", "#a9d9b5", "#a9d9d9", "#a9b5d9", "#c1a9d9", "#d9a9cd"],
- sliderEnabled : true,
- supportsSlider: true,
savedRevisions: [],
padIdForUrl: padId,
fullWidth: false,
diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js
index fa7e70771..7b21206c9 100644
--- a/src/node/hooks/express/adminplugins.js
+++ b/src/node/hooks/express/adminplugins.js
@@ -21,13 +21,15 @@ exports.expressCreateServer = function (hook_name, args, cb) {
exports.socketio = function (hook_name, args, cb) {
var io = args.io.of("/pluginfw/installer");
io.on('connection', function (socket) {
+ if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
+
socket.on("load", function (query) {
socket.emit("installed-results", {results: plugins.plugins});
});
socket.on("search", function (query) {
socket.emit("progress", {progress:0, message:'Fetching results...'});
- installer.search(query, function (progress) {
+ installer.search(query, true, function (progress) {
if (progress.results)
socket.emit("search-result", progress);
socket.emit("progress", progress);
diff --git a/src/node/hooks/express/socketio.js b/src/node/hooks/express/socketio.js
index e040f7aca..6774b653a 100644
--- a/src/node/hooks/express/socketio.js
+++ b/src/node/hooks/express/socketio.js
@@ -7,11 +7,27 @@ var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var padMessageHandler = require("../../handler/PadMessageHandler");
var timesliderMessageHandler = require("../../handler/TimesliderMessageHandler");
-
+var connect = require('connect');
+
exports.expressCreateServer = function (hook_name, args, cb) {
//init socket.io and redirect all requests to the MessageHandler
var io = socketio.listen(args.app);
+ /* Require an express session cookie to be present, and load the
+ * session. See http://www.danielbaulig.de/socket-ioexpress for more
+ * info */
+ io.set('authorization', function (data, accept) {
+ if (!data.headers.cookie) return accept('No session cookie transmitted.', false);
+ data.cookie = connect.utils.parseCookie(data.headers.cookie);
+ data.sessionID = data.cookie.express_sid;
+ args.app.sessionStore.get(data.sessionID, function (err, session) {
+ if (err || !session) return accept('Bad session / session has expired', false);
+ data.session = new connect.middleware.session.Session(data, session);
+ accept(null, true);
+ });
+ });
+
+
//this is only a workaround to ensure it works with all browers behind a proxy
//we should remove this when the new socket.io version is more stable
io.set('transports', ['xhr-polling']);
diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js
index d0e287373..028d8ab1b 100644
--- a/src/node/hooks/express/webaccess.js
+++ b/src/node/hooks/express/webaccess.js
@@ -2,50 +2,108 @@ var express = require('express');
var log4js = require('log4js');
var httpLogger = log4js.getLogger("http");
var settings = require('../../utils/Settings');
+var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
+var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
//checks for basic http auth
exports.basicAuth = function (req, res, next) {
-
- // When handling HTTP-Auth, an undefined password will lead to no authorization at all
- var pass = settings.httpAuth || '';
-
- if (req.path.indexOf('/admin') == 0) {
- var pass = settings.adminHttpAuth;
-
- }
-
- // Just pass if password is an empty string
- if (pass === '') {
- return next();
- }
-
-
- // If a password has been set and auth headers are present...
- if (pass && req.headers.authorization && req.headers.authorization.search('Basic ') === 0) {
- // ...check login and password
- if (new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString() === pass) {
- return next();
+ var hookResultMangle = function (cb) {
+ return function (err, data) {
+ return cb(!err && data.length && data[0]);
}
}
- // Otherwise return Auth required Headers, delayed for 1 second, if auth failed.
- res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
- if (req.headers.authorization) {
- setTimeout(function () {
- res.send('Authentication required', 401);
- }, 1000);
- } else {
- res.send('Authentication required', 401);
+ var authorize = function (cb) {
+ // Do not require auth for static paths...this could be a bit brittle
+ if (req.path.match(/^\/(static|javascripts|pluginfw)/)) return cb(true);
+
+ if (req.path.indexOf('/admin') != 0) {
+ if (!settings.requireAuthentication) return cb(true);
+ if (!settings.requireAuthorization && req.session && req.session.user) return cb(true);
+ }
+
+ if (req.session && req.session.user && req.session.user.is_admin) return cb(true);
+
+ hooks.aCallFirst("authorize", {req: req, res:res, next:next, resource: req.path}, hookResultMangle(cb));
}
+
+ var authenticate = function (cb) {
+ // If auth headers are present use them to authenticate...
+ if (req.headers.authorization && req.headers.authorization.search('Basic ') === 0) {
+ var userpass = new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString().split(":")
+ var username = userpass[0];
+ var password = userpass[1];
+
+ if (settings.users[username] != undefined && settings.users[username].password == password) {
+ settings.users[username].username = username;
+ req.session.user = settings.users[username];
+ return cb(true);
+ }
+ return hooks.aCallFirst("authenticate", {req: req, res:res, next:next, username: username, password: password}, hookResultMangle(cb));
+ }
+ hooks.aCallFirst("authenticate", {req: req, res:res, next:next}, hookResultMangle(cb));
+ }
+
+
+ /* Authentication OR authorization failed. */
+ var failure = function () {
+ return hooks.aCallFirst("authFailure", {req: req, res:res, next:next}, hookResultMangle(function (ok) {
+ if (ok) return;
+ /* No plugin handler for invalid auth. Return Auth required
+ * Headers, delayed for 1 second, if authentication failed
+ * before. */
+ res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
+ if (req.headers.authorization) {
+ setTimeout(function () {
+ res.send('Authentication required', 401);
+ }, 1000);
+ } else {
+ res.send('Authentication required', 401);
+ }
+ }));
+ }
+
+
+ /* This is the actual authentication/authorization hoop. It is done in four steps:
+
+ 1) Try to just access the thing
+ 2) If not allowed using whatever creds are in the current session already, try to authenticate
+ 3) If authentication using already supplied credentials succeeds, try to access the thing again
+ 4) If all els fails, give the user a 401 to request new credentials
+
+ Note that the process could stop already in step 3 with a redirect to login page.
+
+ */
+
+ authorize(function (ok) {
+ if (ok) return next();
+ authenticate(function (ok) {
+ if (!ok) return failure();
+ authorize(function (ok) {
+ if (ok) return next();
+ failure();
+ });
+ });
+ });
}
exports.expressConfigure = function (hook_name, args, cb) {
- args.app.use(exports.basicAuth);
-
// If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
// Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR"))
args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'}));
args.app.use(express.cookieParser());
+
+ /* Do not let express create the session, so that we can retain a
+ * reference to it for socket.io to use. Also, set the key (cookie
+ * name) to a javascript identifier compatible string. Makes code
+ * handling it cleaner :) */
+
+ args.app.sessionStore = new express.session.MemoryStore();
+ args.app.use(express.session({store: args.app.sessionStore,
+ key: 'express_sid',
+ secret: apikey = randomString(32)}));
+
+ args.app.use(exports.basicAuth);
}
diff --git a/src/node/server.js b/src/node/server.js
index 6b443edb7..9d2c52e44 100644
--- a/src/node/server.js
+++ b/src/node/server.js
@@ -30,6 +30,7 @@ var path = require('path');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var npm = require("npm/lib/npm.js");
+var _ = require("underscore");
//try to get the git version
var version = "";
@@ -88,11 +89,11 @@ async.waterfall([
//let the server listen
app.listen(settings.port, settings.ip);
console.log("Server is listening at " + settings.ip + ":" + settings.port);
- if(settings.adminHttpAuth){
+ if(!_.isEmpty(settings.users)){
console.log("Plugin admin page listening at " + settings.ip + ":" + settings.port + "/admin/plugins");
}
else{
- console.log("Admin username and password not set in settings.json. To access admin please uncomment and edit adminHttpAuth in settings.json");
+ console.log("Admin username and password not set in settings.json. To access admin please uncomment and edit 'users' in settings.json");
}
callback(null);
}
diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js
index 12fcc55c5..cb6a64033 100644
--- a/src/node/utils/Settings.js
+++ b/src/node/utils/Settings.js
@@ -80,15 +80,12 @@ exports.abiword = null;
*/
exports.loglevel = "INFO";
-/**
- * Http basic auth, with "user:password" format
- */
-exports.httpAuth = null;
-
-/**
- * Http basic auth, with "user:password" format
- */
-exports.adminHttpAuth = null;
+/* This setting is used if you need authentication and/or
+ * authorization. Note: /admin always requires authentication, and
+ * either authorization by a module, or a user with is_admin set */
+exports.requireAuthentication = false;
+exports.requireAuthorization = false;
+exports.users = {};
//checks if abiword is avaiable
exports.abiwordAvailable = function()
diff --git a/src/package.json b/src/package.json
index 83441da08..eda385b22 100644
--- a/src/package.json
+++ b/src/package.json
@@ -17,6 +17,7 @@
"ueberDB" : "0.1.7",
"async" : "0.1.18",
"express" : "2.5.8",
+ "connect" : "1.8.7",
"clean-css" : "0.3.2",
"uglify-js" : "1.2.5",
"formidable" : "1.0.9",
diff --git a/src/static/css/admin.css b/src/static/css/admin.css
index 209465317..67706fa2f 100644
--- a/src/static/css/admin.css
+++ b/src/static/css/admin.css
@@ -136,4 +136,3 @@ td, th {
padding: 2px;
overflow: auto;
}
-
diff --git a/src/static/css/pad.css b/src/static/css/pad.css
index 21f365e24..2ce8dbb66 100644
--- a/src/static/css/pad.css
+++ b/src/static/css/pad.css
@@ -1,13 +1,27 @@
-*,html,body,p{ margin: 0; padding: 0; }
-.clear { clear: both; }
-html { font-size: 62.5%; width: 100%; }
-body, textarea { font-family: Helvetica, Arial, sans-serif; }
-iframe {position:absolute;}
-
-#users
-{
+*,
+html,
+body,
+p {
+ margin: 0;
+ padding: 0;
+}
+.clear {
+ clear: both
+}
+html {
+ font-size: 62.5%;
+ width: 100%;
+}
+body,
+textarea {
+ font-family: Helvetica, Arial, sans-serif
+}
+iframe {
+ position: absolute
+}
+#users {
position: absolute;
- z-index:500;
+ z-index: 500;
background-color: #000;
background-color: rgba(0,0,0,0.7);
width: 160px;
@@ -15,29 +29,32 @@ iframe {position:absolute;}
top: 40px;
color: #fff;
padding: 5px;
- border-radius: 6px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
}
-
-a img
-{
- border: 0;
+#otherusers {
+ max-height: 400px;
+ overflow: auto;
+}
+a img {
+ border: 0
}
-
/* menu */
-.toolbar ul
-{
+.toolbar ul {
position: relative;
list-style: none;
padding-right: 3px;
padding-left: 1px;
z-index: 2;
overflow: hidden;
-
}
-
-.toolbar
-{
+.toolbar {
background: #f7f7f7;
+ background: -webkit-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -moz-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -o-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -ms-linear-gradient(#f7f7f7, #f1f1f1 80%);
background: linear-gradient(#f7f7f7, #f1f1f1 80%);
border-bottom: 1px solid #ccc;
overflow: hidden;
@@ -46,12 +63,16 @@ a img
white-space: nowrap;
height: 32px;
}
-
-.toolbar ul li
-{
+.toolbar ul li {
background: #fff;
+ background: -webkit-linear-gradient(#fff, #f0f0f0);
+ background: -moz-linear-gradient(#fff, #f0f0f0);
+ background: -o-linear-gradient(#fff, #f0f0f0);
+ background: -ms-linear-gradient(#fff, #f0f0f0);
background: linear-gradient(#fff, #f0f0f0);
border: 1px solid #ccc;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
border-radius: 4px;
cursor: pointer;
float: left;
@@ -61,150 +82,195 @@ a img
padding: 4px 5px;
width: 18px;
}
-
-.toolbar ul li a
-{
+.toolbar ul li a {
text-decoration: none;
color: #ccc;
position: absolute;
}
-
-.toolbar ul li a span
-{
+.toolbar ul li a span {
position: relative;
- top:-2px
+ top: -2px;
}
-
.toolbar ul li:hover {
background: #fff;
+ background: -webkit-linear-gradient(#f4f4f4, #e4e4e4);
+ background: -moz-linear-gradient(#f4f4f4, #e4e4e4);
+ background: -o-linear-gradient(#f4f4f4, #e4e4e4);
+ background: -ms-linear-gradient(#f4f4f4, #e4e4e4);
background: linear-gradient(#f4f4f4, #e4e4e4);
}
-
.toolbar ul li:active {
background: #eee;
+ background: -webkit-linear-gradient(#ddd, #fff);
+ background: -moz-linear-gradient(#ddd, #fff);
+ background: -o-linear-gradient(#ddd, #fff);
+ background: -ms-linear-gradient(#ddd, #fff);
background: linear-gradient(#ddd, #fff);
+ -webkit-box-shadow: 0 0 8px rgba(0,0,0,.1) inset;
+ -moz-box-shadow: 0 0 8px rgba(0,0,0,.1) inset;
box-shadow: 0 0 8px rgba(0,0,0,.1) inset;
}
-
-.toolbar ul li.separator
-{
+.toolbar ul li.separator {
border: inherit;
background: inherit;
- visibility:hidden;
+ visibility: hidden;
width: 0px;
}
-.toolbar ul li a
-{
- display: block;
+.toolbar ul li a {
+ display: block
}
-.toolbar ul li a img
-{
- padding: 1px;
+.toolbar ul li a img {
+ padding: 1px
}
-
-
-.toolbar ul
-{
- float: left;
+.toolbar ul {
+ float: left
}
-.toolbar ul.menu_right
-{
- float: right;
+.toolbar ul.menu_right {
+ float: right
}
-
-#users
-{
- display: none;
+#users {
+ display: none
}
-
-#editorcontainer
-{
+#editorcontainer {
position: absolute;
-
width: 100%;
-
top: 36px;
- left: 0px;
+ left: 0px;
bottom: 0px;
-
z-index: 1;
}
-
#editorcontainer iframe {
height: 100%;
- width: 100%;
- padding: 0;
- margin: 0;
+ width: 100%;
+ padding: 0;
+ margin: 0;
}
-
-#editorloadingbox { padding-top: 100px; padding-bottom: 100px; font-size: 2.5em; color: #aaa;
- text-align: center; position: absolute; width: 100%; height: 30px; z-index: 100; }
-
-#editorcontainerbox{
- position:absolute;
- bottom:0;
- top:0;
- width:100%;
+#editorloadingbox {
+ padding-top: 100px;
+ padding-bottom: 100px;
+ font-size: 2.5em;
+ color: #aaa;
+ text-align: center;
+ position: absolute;
+ width: 100%;
+ height: 30px;
+ z-index: 100;
+}
+#editorcontainerbox {
+ position: absolute;
+ bottom: 0;
+ top: 0;
+ width: 100%;
}
-
-
#padpage {
- position: absolute;
- top: 0px;
- bottom: 0px;
- width: 100%;
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ width: 100%;
}
-
.maximized #padpage {
- left: 8px;
- right: 8px;
- width: auto;
- margin-left: 0;
+ left: 8px;
+ right: 8px;
+ width: auto;
+ margin-left: 0;
}
-
-body.fullwidth #padpage { width: auto; margin-left: 6px; margin-right: 6px; }
-body.squish1width #padpage { width: 800px; }
-body.squish2width #padpage { width: 700px; }
-
-a#backtoprosite, #accountnav {
- display: block; position: absolute; height: 15px; line-height: 15px;
- width: auto; top: 5px; font-size: 1.2em; display:none;
+body.fullwidth #padpage {
+ width: auto;
+ margin-left: 6px;
+ margin-right: 6px;
+}
+body.squish1width #padpage {
+ width: 800px
+}
+body.squish2width #padpage {
+ width: 700px
+}
+a#backtoprosite,
+#accountnav {
+ display: block;
+ position: absolute;
+ height: 15px;
+ line-height: 15px;
+ width: auto;
+ top: 5px;
+ font-size: 1.2em;
+ display: none;
+}
+a#backtoprosite,
+#accountnav a {
+ color: #cde7ff;
+ text-decoration: underline;
+}
+a#backtoprosite {
+ padding-left: 20px;
+ left: 6px;
+ background: url(static/img/protop.gif) no-repeat -5px -6px;
+}
+#accountnav {
+ right: 30px;
+ color: #fff;
+}
+#specialkeyarea {
+ top: 5px;
+ left: 250px;
+ color: yellow;
+ font-weight: bold;
+ font-size: 1.5em;
+ position: absolute;
}
-a#backtoprosite, #accountnav a { color: #cde7ff; text-decoration: underline; }
-
-a#backtoprosite { padding-left: 20px; left: 6px;
- background: url(static/img/protop.gif) no-repeat -5px -6px; }
-#accountnav { right: 30px; color: #fff; }
-
-
-#specialkeyarea { top: 5px; left: 250px; color: yellow; font-weight: bold;
- font-size: 1.5em; position: absolute; }
-
#alertbar {
margin-top: 6px;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+ filter: alpha(opacity=0);
opacity: 0;
display: none;
- position:absolute;
- left:0;
- right:0;
- z-index:53;
+ position: absolute;
+ left: 0;
+ right: 0;
+ z-index: 53;
}
-
-#servermsg { position: relative; zoom: 1; border: 1px solid #992;
- background: #ffc; padding: 0.8em; font-size: 1.2em; }
-#servermsg h3 { font-weight: bold; margin-right: 10px;
- margin-bottom: 1em; float: left; width: auto; }
-#servermsg #servermsgdate { font-style: italic; font-weight: normal; color: #666; }
-a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; }
-
-#shuttingdown { position: relative; zoom: 1; border: 1px solid #992;
- background: #ffc; padding: 0.6em; font-size: 1.2em; margin-top: 6px; }
-
-#docbar { margin-top: 6px; height: 25px; position: relative; zoom: 1;
- background: #fbfbfb url(static/img/padtopback2.gif) repeat-x 0 -31px; }
-
-.docbarbutton
-{
+#servermsg {
+ position: relative;
+ zoom: 1;
+ border: 1px solid #992;
+ background: #ffc;
+ padding: 0.8em;
+ font-size: 1.2em;
+}
+#servermsg h3 {
+ font-weight: bold;
+ margin-right: 10px;
+ margin-bottom: 1em;
+ float: left;
+ width: auto;
+}
+#servermsg #servermsgdate {
+ font-style: italic;
+ font-weight: normal;
+ color: #666;
+}
+a#hidetopmsg {
+ position: absolute;
+ right: 5px;
+ bottom: 5px;
+}
+#shuttingdown {
+ position: relative;
+ zoom: 1;
+ border: 1px solid #992;
+ background: #ffc;
+ padding: 0.6em;
+ font-size: 1.2em;
+ margin-top: 6px;
+}
+#docbar {
+ margin-top: 6px;
+ height: 25px;
+ position: relative;
+ zoom: 1;
+ background: #fbfbfb url(static/img/padtopback2.gif) repeat-x 0 -31px;
+}
+.docbarbutton {
padding-top: 2px;
padding-bottom: 2px;
padding-left: 4px;
@@ -212,9 +278,7 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; }
border-left: 1px solid #CCC;
white-space: nowrap;
}
-
-.docbarbutton img
-{
+.docbarbutton img {
border: 0px;
width: 13px;
margin-right: 2px;
@@ -222,17 +286,14 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; }
margin-top: 3px;
margin-bottom: 2px;
}
-
.menu,
.menu ul {
font-size: 10pt;
list-style-type: none;
}
-
.menu ul {
- padding-left: 20px;
+ padding-left: 20px
}
-
.menu a {
font-size: 10px;
line-height: 18px;
@@ -240,49 +301,99 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; }
color: #444;
font-weight: bold;
}
-
-.docbarbutton.highlight
-{
+.docbarbutton.highlight {
background-color: #fef2bd;
border: 1px solid #CCC;
border-right: 0px;
}
-
-#docbarleft { position: absolute; left: 0; top: 0; height: 100%;
+#docbarleft {
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
overflow: hidden;
- background: url(static/img/padtop5.gif) no-repeat left -31px; width: 7px; }
-
-
-
-#docbarpadtitle { position: absolute; height: auto; left: 9px;
- width: 280px; font-size: 1.6em; color: #444; font-weight: normal;
- line-height: 22px; margin-left: 2px; height: 22px; top: 2px;
- overflow: hidden; text-overflow: ellipsis /*not supported in FF*/;
- white-space:nowrap; }
-.docbar-public #docbarpadtitle { padding-left: 22px;
- background: url(static/img/public.gif) no-repeat left center; }
-
-#docbarrenamelink { position: absolute; top: 6px;
- font-size: 1.1em; display: none; }
-#docbarrenamelink a { color: #999; }
-#docbarrenamelink a:hover { color: #48d; }
-#padtitlebuttons { position: absolute; width: 74px; zoom: 1;
- height: 17px; top: 4px; left: 170px; display: none;
- background: url(static/img/ok_or_cancel.gif) 0px 0px; }
-#padtitlesave { position: absolute; display: block;
- height: 0; padding-top: 17px; overflow: hidden;
- width: 23px; left: 0; top: 0; }
-#padtitlecancel { position: absolute; display: block;
- height: 0; padding-top: 17px; overflow: hidden;
- width: 35px; right: 0; top: 0; }
-#padtitleedit { position: absolute; top: 2px; left: 5px;
- height: 15px; padding: 2px; font-size: 1.4em;
- background: white; border-left: 1px solid #c3c3c3;
- border-top: 1px solid #c3c3c3;
- border-right: 1px solid #e6e6e6; border-bottom: 1px solid #e6e6e6;
- width: 150px; display: none;
+ background: url(static/img/padtop5.gif) no-repeat left -31px;
+ width: 7px;
+}
+#docbarpadtitle {
+ position: absolute;
+ height: auto;
+ left: 9px;
+ width: 280px;
+ font-size: 1.6em;
+ color: #444;
+ font-weight: normal;
+ line-height: 22px;
+ margin-left: 2px;
+ height: 22px;
+ top: 2px;
+ overflow: hidden; /*not supported in FF*/
+ -o-text-overflow: ellipsis;
+ -ms-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.docbar-public #docbarpadtitle {
+ padding-left: 22px;
+ background: url(static/img/public.gif) no-repeat left center;
+}
+#docbarrenamelink {
+ position: absolute;
+ top: 6px;
+ font-size: 1.1em;
+ display: none;
+}
+#docbarrenamelink a {
+ color: #999
+}
+#docbarrenamelink a:hover {
+ color: #48d
+}
+#padtitlebuttons {
+ position: absolute;
+ width: 74px;
+ zoom: 1;
+ height: 17px;
+ top: 4px;
+ left: 170px;
+ display: none;
+ background: url(static/img/ok_or_cancel.gif) 0px 0px;
+}
+#padtitlesave {
+ position: absolute;
+ display: block;
+ height: 0;
+ padding-top: 17px;
+ overflow: hidden;
+ width: 23px;
+ left: 0;
+ top: 0;
+}
+#padtitlecancel {
+ position: absolute;
+ display: block;
+ height: 0;
+ padding-top: 17px;
+ overflow: hidden;
+ width: 35px;
+ right: 0;
+ top: 0;
+}
+#padtitleedit {
+ position: absolute;
+ top: 2px;
+ left: 5px;
+ height: 15px;
+ padding: 2px;
+ font-size: 1.4em;
+ background: white;
+ border-left: 1px solid #c3c3c3;
+ border-top: 1px solid #c3c3c3;
+ border-right: 1px solid #e6e6e6;
+ border-bottom: 1px solid #e6e6e6;
+ width: 150px;
+ display: none;
}
-
#padmain {
margin-top: 0px;
position: absolute;
@@ -292,212 +403,324 @@ a#hidetopmsg { position: absolute; right: 5px; bottom: 5px; }
bottom: 0px;
zoom: 1;
}
-
#padeditor {
- bottom:0px;
- left:0;
- position:absolute;
- right:0px;
- top:0;
+ bottom: 0px;
+ left: 0;
+ position: absolute;
+ right: 0px;
+ top: 0;
zoom: 1;
}
-.hidesidebar #padeditor { right: 0; }
-
+.hidesidebar #padeditor {
+ right: 0
+}
#vdraggie {
-/* background: url(static/img/vdraggie.gif) no-repeat top center;*/
- width:16px;
- height:16px;
- background-image:url('../../static/img/etherpad_lite_icons.png');
+ /* background: url(static/img/vdraggie.gif) no-repeat top center;;*/
+ width: 16px;
+ height: 16px;
+ background-image: url('../../static/img/etherpad_lite_icons.png');
background-repeat: no-repeat;
background-position: 0px -300px;
-
cursor: W-resize;
- bottom:0;
- position:absolute;
- right:268px;
- top:0;
- width:56px;
+ bottom: 0;
+ position: absolute;
+ right: 268px;
+ top: 0;
+ width: 56px;
z-index: 10;
}
-
-.toolbarsavetable
-{
- position:absolute;
+.toolbarsavetable {
+ position: absolute;
top: 6px;
right: 8px;
height: 24px;
}
-
-.toolbarsavetable td, .toolbartable td
-{
- white-space: nowrap;
+.toolbarsavetable td,
+.toolbartable td {
+ white-space: nowrap
}
-
-#myswatchbox {
- position: absolute;
- left: 5px;
- top: 5px;
+#myswatchbox {
+ position: absolute;
+ left: 5px;
+ top: 5px;
width: 24px;
height: 24px;
border: 1px solid #000;
- background: transparent;
- cursor: pointer;
+ background: transparent;
+ cursor: pointer;
+}
+#myswatch {
+ width: 100%;
+ height: 100%;
+ background: transparent; /*...initially*/
}
-
-#myswatch { width: 100%; height: 100%; background: transparent;/*...initially*/ }
-
#mycolorpicker {
- width: 232px; height: 265px;
+ width: 232px;
+ height: 265px;
position: absolute;
- left: -250px; top: 0px; z-index: 101;
+ left: -250px;
+ top: 0px;
+ z-index: 101;
display: none;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
border-radius: 5px;
- background: rgba(0, 0, 0, 0.7);
- padding-left:10px;
- padding-top:10px;
+ background: rgba(0, 0, 0, 0.7);
+ padding-left: 10px;
+ padding-top: 10px;
}
/*
#mycolorpicker ul li
-{
- float: left;
+ {
+
+float: left;
+
}
-#mycolorpicker .picked { border: 1px solid #000 !important; }
-#mycolorpicker .picked .pickerswatch { border: 1px solid #fff; }
-*/
-#mycolorpickersave {
- left: 10px;
+#mycolorpicker .picked {
+ border: 1px solid #000 !important;
+ }
+
+
+#mycolorpicker .picked .pickerswatch {
+ border: 1px solid #fff;
+ }
+
+ */
+#mycolorpickersave {
+ left: 10px;
font-weight: bold;
}
-
-#mycolorpickercancel {
- left: 85px;
+#mycolorpickercancel {
+ left: 85px
}
-
-#mycolorpickersave, #mycolorpickercancel {
+#mycolorpickersave,
+#mycolorpickercancel {
background: #fff;
+ background: -webkit-linear-gradient(#fff, #ccc);
+ background: -moz-linear-gradient(#fff, #ccc);
+ background: -o-linear-gradient(#fff, #ccc);
+ background: -ms-linear-gradient(#fff, #ccc);
background: linear-gradient(#fff, #ccc);
border: 1px solid #ccc;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
border-radius: 4px;
- font-size:12px;
- cursor: pointer;
- color:#000;
- overflow: hidden;
- padding: 4px;
+ font-size: 12px;
+ cursor: pointer;
+ color: #000;
+ overflow: hidden;
+ padding: 4px;
top: 240px;
- text-align:center;
- position: absolute;
- width: 60px;
+ text-align: center;
+ position: absolute;
+ width: 60px;
}
-
-#mycolorpickerpreview {
- position: absolute;
- left: 207px;
- top: 240px;
- width:16px;
- height:16px;
- padding:4px;
- overflow: hidden;
- color: #fff;
- border-radius:5px;
+#mycolorpickerpreview {
+ position: absolute;
+ left: 207px;
+ top: 240px;
+ width: 16px;
+ height: 16px;
+ padding: 4px;
+ overflow: hidden;
+ color: #fff;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
}
-
-
-#myusernameform { margin-left: 35px; }
-#myusernameedit { font-size: 1.3em; color: #fff;
- padding: 3px; height: 18px; margin: 0; border: 0;
- width: 117px; background: transparent; }
-#myusernameform input.editable { border: 1px solid #444; }
-#myuser .myusernameedithoverable:hover { background: white; color: black}
-#mystatusform { margin-left: 35px; margin-top: 5px; }
-#mystatusedit { font-size: 1.2em; color: #777;
- font-style: italic; display: none;
- padding: 2px; height: 14px; margin: 0; border: 1px solid #bbb;
- width: 199px; background: transparent; }
-#myusernameform .editactive, #myusernameform .editempty {
- background: white; border-left: 1px solid #c3c3c3;
+#myusernameform {
+ margin-left: 35px
+}
+#myusernameedit {
+ font-size: 1.3em;
+ color: #fff;
+ padding: 3px;
+ height: 18px;
+ margin: 0;
+ border: 0;
+ width: 117px;
+ background: transparent;
+}
+#myusernameform input.editable {
+ border: 1px solid #444
+}
+#myuser .myusernameedithoverable:hover {
+ background: white;
+ color: black;
+}
+#mystatusform {
+ margin-left: 35px;
+ margin-top: 5px;
+}
+#mystatusedit {
+ font-size: 1.2em;
+ color: #777;
+ font-style: italic;
+ display: none;
+ padding: 2px;
+ height: 14px;
+ margin: 0;
+ border: 1px solid #bbb;
+ width: 199px;
+ background: transparent;
+}
+#myusernameform .editactive,
+#myusernameform .editempty {
+ background: white;
+ border-left: 1px solid #c3c3c3;
border-top: 1px solid #c3c3c3;
- border-right: 1px solid #e6e6e6; border-bottom: 1px solid #e6e6e6;
- color: #000
+ border-right: 1px solid #e6e6e6;
+ border-bottom: 1px solid #e6e6e6;
+ color: #000;
+}
+#myusernameform .editempty {
+ color: #333
+}
+table#otheruserstable {
+ display: none
+}
+#nootherusers {
+ padding: 10px;
+ font-size: 1.2em;
+ color: #eee;
+ font-weight: bold;
+}
+#nootherusers a {
+ color: #3C88FF
}
-#myusernameform .editempty { color: #333; }
-
-table#otheruserstable { display: none; }
-#nootherusers { padding: 10px; font-size: 1.2em; color: #eee; font-weight: bold;}
-#nootherusers a { color: #3C88FF; }
-
#otheruserstable td {
- border-top: 1px solid #555;
height: 26px;
vertical-align: middle;
padding: 0 2px;
color: #fff;
}
-
#otheruserstable .swatch {
- border: 1px solid #000; width: 13px; height: 13px; overflow: hidden;
+ border: 1px solid #000;
+ width: 13px;
+ height: 13px;
+ overflow: hidden;
margin: 0 4px;
}
-
-.usertdswatch { width: 1%; }
-.usertdname { font-size: 1.3em; color: #444; }
-.usertdstatus { font-size: 1.1em; font-style: italic; color: #999; }
-.usertdactivity { font-size: 1.1em; color: #777; }
-
-.usertdname input { border: 1px solid #bbb; width: 80px; padding: 2px; }
-.usertdname input.editactive, .usertdname input.editempty {
- background: white; border-left: 1px solid #c3c3c3;
- border-top: 1px solid #c3c3c3;
- border-right: 1px solid #e6e6e6; border-bottom: 1px solid #e6e6e6;
+.usertdswatch {
+ width: 1%
+}
+.usertdname {
+ font-size: 1.3em;
+ color: #444;
+}
+.usertdstatus {
+ font-size: 1.1em;
+ font-style: italic;
+ color: #999;
+}
+.usertdactivity {
+ font-size: 1.1em;
+ color: #777;
+}
+.usertdname input {
+ border: 1px solid #bbb;
+ width: 80px;
+ padding: 2px;
+}
+.usertdname input.editactive,
+.usertdname input.editempty {
+ background: white;
+ border-left: 1px solid #c3c3c3;
+ border-top: 1px solid #c3c3c3;
+ border-right: 1px solid #e6e6e6;
+ border-bottom: 1px solid #e6e6e6;
+}
+.usertdname input.editempty {
+ color: #888;
+ font-style: italic;
}
-.usertdname input.editempty { color: #888; font-style: italic;}
-
.modaldialog.cboxreconnecting .modaldialog-inner,
.modaldialog.cboxconnecting .modaldialog-inner {
background: url(../../static/img/connectingbar.gif) no-repeat center 60px;
height: 100px;
}
-.modaldialog.cboxreconnecting,
+.modaldialog.cboxreconnecting,
.modaldialog.cboxconnecting,
.modaldialog.cboxdisconnected {
- background: #8FCDE0;
+ background: #8FCDE0
+}
+.cboxdisconnected #connectionboxinner div {
+ display: none
+}
+.cboxdisconnected_userdup #connectionboxinner #disconnected_userdup {
+ display: block
+}
+.cboxdisconnected_deleted #connectionboxinner #disconnected_deleted {
+ display: block
+}
+.cboxdisconnected_initsocketfail #connectionboxinner #disconnected_initsocketfail {
+ display: block
+}
+.cboxdisconnected_looping #connectionboxinner #disconnected_looping {
+ display: block
+}
+.cboxdisconnected_slowcommit #connectionboxinner #disconnected_slowcommit {
+ display: block
+}
+.cboxdisconnected_unauth #connectionboxinner #disconnected_unauth {
+ display: block
+}
+.cboxdisconnected_unknown #connectionboxinner #disconnected_unknown {
+ display: block
}
-.cboxdisconnected #connectionboxinner div { display: none; }
-.cboxdisconnected_userdup #connectionboxinner #disconnected_userdup { display: block; }
-.cboxdisconnected_deleted #connectionboxinner #disconnected_deleted { display: block; }
-.cboxdisconnected_initsocketfail #connectionboxinner #disconnected_initsocketfail { display: block; }
-.cboxdisconnected_looping #connectionboxinner #disconnected_looping { display: block; }
-.cboxdisconnected_slowcommit #connectionboxinner #disconnected_slowcommit { display: block; }
-.cboxdisconnected_unauth #connectionboxinner #disconnected_unauth { display: block; }
-.cboxdisconnected_unknown #connectionboxinner #disconnected_unknown { display: block; }
.cboxdisconnected_initsocketfail #connectionboxinner #reconnect_advise,
.cboxdisconnected_looping #connectionboxinner #reconnect_advise,
.cboxdisconnected_slowcommit #connectionboxinner #reconnect_advise,
-.cboxdisconnected_unknown #connectionboxinner #reconnect_advise { display: block; }
-.cboxdisconnected div#reconnect_form { display: block; }
-.cboxdisconnected .disconnected h2 { display: none; }
-.cboxdisconnected .disconnected .h2_disconnect { display: block; }
-.cboxdisconnected_userdup .disconnected h2.h2_disconnect { display: none; }
-.cboxdisconnected_userdup .disconnected h2.h2_userdup { display: block; }
-.cboxdisconnected_unauth .disconnected h2.h2_disconnect { display: none; }
-.cboxdisconnected_unauth .disconnected h2.h2_unauth { display: block; }
-
+.cboxdisconnected_unknown #connectionboxinner #reconnect_advise {
+ display: block
+}
+.cboxdisconnected div#reconnect_form {
+ display: block
+}
+.cboxdisconnected .disconnected h2 {
+ display: none
+}
+.cboxdisconnected .disconnected .h2_disconnect {
+ display: block
+}
+.cboxdisconnected_userdup .disconnected h2.h2_disconnect {
+ display: none
+}
+.cboxdisconnected_userdup .disconnected h2.h2_userdup {
+ display: block
+}
+.cboxdisconnected_unauth .disconnected h2.h2_disconnect {
+ display: none
+}
+.cboxdisconnected_unauth .disconnected h2.h2_unauth {
+ display: block
+}
#connectionstatus {
- position: absolute; width: 37px; height: 41px; overflow: hidden;
+ position: absolute;
+ width: 37px;
+ height: 41px;
+ overflow: hidden;
right: 0;
z-index: 11;
}
#connectionboxinner .connecting {
margin-top: 20px;
- font-size: 2.0em; color: #555;
- text-align: center; display: none;
+ font-size: 2.0em;
+ color: #555;
+ text-align: center;
+ display: none;
+}
+.cboxconnecting #connectionboxinner .connecting {
+ display: block
}
-.cboxconnecting #connectionboxinner .connecting { display: block; }
-
#connectionboxinner .disconnected h2 {
- font-size: 1.8em; color: #333;
+ font-size: 1.8em;
+ color: #333;
text-align: left;
- margin-top: 10px; margin-left: 10px; margin-right: 10px;
+ margin-top: 10px;
+ margin-left: 10px;
+ margin-right: 10px;
margin-bottom: 10px;
}
#connectionboxinner .disconnected p {
@@ -506,54 +729,104 @@ table#otheruserstable { display: none; }
line-height: 1.1;
color: #333;
}
-#connectionboxinner .disconnected { display: none; }
-.cboxdisconnected #connectionboxinner .disconnected { display: block; }
-
+#connectionboxinner .disconnected {
+ display: none
+}
+.cboxdisconnected #connectionboxinner .disconnected {
+ display: block
+}
#connectionboxinner .reconnecting {
margin-top: 20px;
- font-size: 1.6em; color: #555;
- text-align: center; display: none;
+ font-size: 1.6em;
+ color: #555;
+ text-align: center;
+ display: none;
+}
+.cboxreconnecting #connectionboxinner .reconnecting {
+ display: block
}
-.cboxreconnecting #connectionboxinner .reconnecting { display: block; }
-
#reconnect_form button {
font-size: 12pt;
padding: 5px;
}
-
/* We give docbar a higher z-index than its descendant impexp-wrapper in
- order to allow the Import/Export panel to be on top of stuff lower
- down on the page in IE. Strange but it works! */
-#docbar { z-index: 52; }
-
-#impexp-wrapper { width: 650px; right: 10px; }
-#impexp-panel { height: 160px; }
-.docbarimpexp-closing #impexp-wrapper { z-index: 50; }
-
-#savedrevs-wrapper { width: 100%; left: 0; }
-#savedrevs-panel { height: 79px; }
-.docbarsavedrevs-closing #savedrevs-wrapper { z-index: 50; }
-#savedrevs-wrapper .dbpanel-rightedge { background-position: 0 -10px; }
-
-#options-wrapper { width: 340px; right: 200px; }
-#options-panel { height: 114px; }
-.docbaroptions-closing #options-wrapper { z-index: 50; }
-
-#security-wrapper { width: 320px; right: 300px; }
-#security-panel { height: 130px; }
-.docbarsecurity-closing #security-wrapper { z-index: 50; }
-
-#revision-notifier { position: absolute; right: 8px; top: 25px;
- width: auto; height: auto; font-size: 1.2em; background: #ffc;
- border: 1px solid #aaa; color: #444; padding: 3px 5px;
- display: none; z-index: 55; }
-#revision-notifier .label { color: #777; font-weight: bold; }
-
-#mainmodals { z-index: 600; /* higher than the modals themselves
- so that modals are on top in IE */ }
-.modalfield { font-size: 1.2em; padding: 1px; border: 1px solid #bbb;}
-#mainmodals .editempty { color: #aaa; }
-
+order to allow the Import/Export panel to be on top of stuff lower
+down on the page in IE. Strange but it works! */
+#docbar {
+ z-index: 52
+}
+#impexp-wrapper {
+ width: 650px;
+ right: 10px;
+}
+#impexp-panel {
+ height: 160px
+}
+.docbarimpexp-closing #impexp-wrapper {
+ z-index: 50
+}
+#savedrevs-wrapper {
+ width: 100%;
+ left: 0;
+}
+#savedrevs-panel {
+ height: 79px
+}
+.docbarsavedrevs-closing #savedrevs-wrapper {
+ z-index: 50
+}
+#savedrevs-wrapper .dbpanel-rightedge {
+ background-position: 0 -10px
+}
+#options-wrapper {
+ width: 340px;
+ right: 200px;
+}
+#options-panel {
+ height: 114px
+}
+.docbaroptions-closing #options-wrapper {
+ z-index: 50
+}
+#security-wrapper {
+ width: 320px;
+ right: 300px;
+}
+#security-panel {
+ height: 130px
+}
+.docbarsecurity-closing #security-wrapper {
+ z-index: 50
+}
+#revision-notifier {
+ position: absolute;
+ right: 8px;
+ top: 25px;
+ width: auto;
+ height: auto;
+ font-size: 1.2em;
+ background: #ffc;
+ border: 1px solid #aaa;
+ color: #444;
+ padding: 3px 5px;
+ display: none;
+ z-index: 55;
+}
+#revision-notifier .label {
+ color: #777;
+ font-weight: bold;
+}
+#mainmodals {
+ z-index: 600; /* higher than the modals themselves: */
+}
+.modalfield {
+ font-size: 1.2em;
+ padding: 1px;
+ border: 1px solid #bbb;
+}
+#mainmodals .editempty {
+ color: #aaa
+}
.expand-collapse {
height: 22px;
background-image: url(static/img/sharedistri.gif);
@@ -563,72 +836,75 @@ table#otheruserstable { display: none; }
text-decoration: none;
}
.expand-collapse.expanded {
- background-position: 0 -31px;
+ background-position: 0 -31px
}
-
-
.modaldialog {
position: absolute;
top: 100px;
- left:50%;
- margin-left:-243px;
+ left: 50%;
+ margin-left: -243px;
width: 485px;
display: none;
z-index: 501;
zoom: 1;
overflow: hidden;
background: white;
- border: 1px solid #999;
+ border: 1px solid #999;
+}
+.modaldialog .modaldialog-inner {
+ padding: 10pt
}
-.modaldialog .modaldialog-inner { padding: 10pt; }
.modaldialog .modaldialog-hide {
float: right;
background-repeat: no-repeat;
background-image: url(static/img/sharebox4.gif);
display: block;
- width: 22px; height: 22px;
+ width: 22px;
+ height: 22px;
background-position: -454px -6px;
- margin-right:-5px;
- margin-top:-5px;
+ margin-right: -5px;
+ margin-top: -5px;
}
-
.modaldialog label,
.modaldialog h1 {
- color:#222222;
- font-size:125%;
- font-weight:bold;
+ color: #222222;
+ font-size: 125%;
+ font-weight: bold;
}
-
.modaldialog th {
vertical-align: top;
text-align: left;
}
-
.sharebox-url {
- width: 440px; height: 18px;
+ width: 440px;
+ height: 18px;
text-align: left;
font-size: 1.3em;
line-height: 18px;
padding: 2px;
}
-
#sharebox-send {
float: right;
background-repeat: no-repeat;
background-image: url(static/img/sharebox4.gif);
display: block;
- width: 87px; height: 22px;
+ width: 87px;
+ height: 22px;
background-position: -383px -289px;
}
-
-
-#viewbarcontents { display: none; }
+#viewbarcontents {
+ display: none
+}
#viewzoomtitle {
- position: absolute; left: 10px; top: 4px; height: 20px; line-height: 20px;
+ position: absolute;
+ left: 10px;
+ top: 4px;
+ height: 20px;
+ line-height: 20px;
width: auto;
}
#viewzoommenu {
- width: 65px;
+ width: 65px
}
#bottomarea {
height: 28px;
@@ -641,123 +917,136 @@ table#otheruserstable { display: none; }
font-size: 1.2em;
color: #444;
}
-#widthprefcheck { position: absolute;
+#widthprefcheck {
+ position: absolute;
background-image: url(static/img/layoutbuttons.gif);
- background-repeat: no-repeat; cursor: pointer;
- width: 86px; height: 20px; top: 4px; right: 2px; }
-.widthprefunchecked { background-position: -1px -1px; }
-.widthprefchecked { background-position: -1px -23px; }
-#sidebarcheck { position: absolute;
+ background-repeat: no-repeat;
+ cursor: pointer;
+ width: 86px;
+ height: 20px;
+ top: 4px;
+ right: 2px;
+}
+.widthprefunchecked {
+ background-position: -1px -1px
+}
+.widthprefchecked {
+ background-position: -1px -23px
+}
+#sidebarcheck {
+ position: absolute;
background-image: url(static/img/layoutbuttons.gif);
- background-repeat: no-repeat; cursor: pointer;
- width: 86px; height: 20px; top: 4px; right: 90px; }
-.sidebarunchecked { background-position: -1px -45px; }
-.sidebarchecked { background-position: -1px -67px; }
-#feedbackbutton { display: block; position: absolute; width: 68px;
- height: 0; padding-top: 17px; overflow: hidden;
+ background-repeat: no-repeat;
+ cursor: pointer;
+ width: 86px;
+ height: 20px;
+ top: 4px;
+ right: 90px;
+}
+.sidebarunchecked {
+ background-position: -1px -45px
+}
+.sidebarchecked {
+ background-position: -1px -67px
+}
+#feedbackbutton {
+ display: block;
+ position: absolute;
+ width: 68px;
+ height: 0;
+ padding-top: 17px;
+ overflow: hidden;
background: url(static/img/bottomareagfx.gif);
- top: 5px; right: 220px;
+ top: 5px;
+ right: 220px;
}
-
#modaloverlay {
- z-index: 500; display: none;
+ z-index: 500;
+ display: none;
background-repeat: repeat-both;
- width: 100%; position: absolute;
- height: 100%; left: 0; top: 0;
+ width: 100%;
+ position: absolute;
+ height: 100%;
+ left: 0;
+ top: 0;
}
-
-* html #modaloverlay { /* for IE 6+ */
+* html #modaloverlay {
+ /* for IE 6+ */
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
+ filter: alpha(opacity=100);
opacity: 1; /* in case this is looked at */
background-image: none;
- background-repeat: no-repeat;
- /* scale the image */
+ background-repeat: no-repeat; /* scale the image */
}
-
a#topbarmaximize {
- float: right;
- width: 16px;
- height: 16px;
- margin-right:-143px;
- margin-top:4px;
- background: url(static/img/maximize_normal.png);
+ float: right;
+ width: 16px;
+ height: 16px;
+ margin-right: -143px;
+ margin-top: 4px;
+ background: url(static/img/maximize_normal.png);
}
-
.maximized a#topbarmaximize {
- background: url(static/img/maximize_maximized.png);
+ background: url(static/img/maximize_maximized.png)
}
-
.toolbarinner h1 {
- line-height: 29px;
- font-size: 16px;
- padding-left: 6pt;
- margin-top: 0;
- white-space: nowrap;
+ line-height: 29px;
+ font-size: 16px;
+ padding-left: 6pt;
+ margin-top: 0;
+ white-space: nowrap;
}
-
.toolbarinner h1 a {
- font-size: 12px;
+ font-size: 12px
}
-
.bigbutton {
- display: block;
- background-color: #a3bde0;
- color: #555555;
- border-style: solid;
- border-width: 2px;
- border-left-color: #d6e2f1;
- border-right-color: #86aee1;
- border-top-color: #d6e2f1;
- border-bottom-color: #86aee1;
- margin: 10pt;
- text-align: center;
- text-decoration: none;
- padding: 50pt;
- font-size: 20pt;
- border-radius: 3pt;
+ display: block;
+ background-color: #a3bde0;
+ color: #555555;
+ border-style: solid;
+ border-width: 2px;
+ border-left-color: #d6e2f1;
+ border-right-color: #86aee1;
+ border-top-color: #d6e2f1;
+ border-bottom-color: #86aee1;
+ margin: 10pt;
+ text-align: center;
+ text-decoration: none;
+ padding: 50pt;
+ font-size: 20pt;
+ -webkit-border-radius: 3pt;
+ -moz-border-radius: 3pt;
+ border-radius: 3pt;
}
-
.modaldialog .bigbutton {
- padding-left: 0;
- padding-right: 0;
- width: 100%;
+ padding-left: 0;
+ padding-right: 0;
+ width: 100%;
}
-
-}
-
-
-ul#colorpickerswatches
-{
+ul#colorpickerswatches {
padding-left: 3px;
padding-top: 5px;
}
-
-ul#colorpickerswatches li
-{
- border: 1px solid #ccc;
- width: 14px;
- height: 14px;
+ul#colorpickerswatches li {
+ border: 1px solid #ccc;
+ width: 14px;
+ height: 14px;
overflow: hidden;
margin: 3px 6px;
padding: 0px;
}
-
-ul#colorpickerswatches li:hover
-{
- border: 1px solid #000;
+ul#colorpickerswatches li:hover {
+ border: 1px solid #000;
cursor: pointer;
}
-
-
-
-#chatbox
-{
- position:absolute;
- bottom:0px;
+#chatbox {
+ position: absolute;
+ bottom: 0px;
right: 20px;
width: 180px;
height: 200px;
z-index: 400;
- background-color:#f7f7f7;
+ background-color: #f7f7f7;
border-left: 1px solid #999;
border-right: 1px solid #999;
border-top: 1px solid #999;
@@ -765,57 +1054,47 @@ ul#colorpickerswatches li:hover
padding-bottom: 10px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
- display:none;
+ display: none;
}
-
-#chattext
-{
+#chattext {
background-color: white;
border: 1px solid white;
- overflow-y:scroll;
+ -ms-overflow-y: scroll;
+ overflow-y: scroll;
font-size: 12px;
- position:absolute;
- right:0px;
- left:0px;
- top:25px;
- bottom:25px;
- z-index:1002;
+ position: absolute;
+ right: 0px;
+ left: 0px;
+ top: 25px;
+ bottom: 25px;
+ z-index: 1002;
}
-
-#chattext p
-{
+#chattext p {
padding: 3px;
+ -ms-overflow-x: hidden;
overflow-x: hidden;
}
-
-#chatinputbox
-{
+#chatinputbox {
padding: 3px 2px;
position: absolute;
- bottom:0px;
- right:0px;
- left:3px;
+ bottom: 0px;
+ right: 0px;
+ left: 3px;
}
-
-#chatlabel
-{
- font-size:13px;
- font-weight:bold;
- color:#555;
+#chatlabel {
+ font-size: 13px;
+ font-weight: bold;
+ color: #555;
text-decoration: none;
margin-right: 3px;
vertical-align: middle;
}
-
-#chatinput
-{
+#chatinput {
border: 1px solid #BBBBBB;
width: 100%;
- float:right;
+ float: right;
}
-
-#chaticon
-{
+#chaticon {
z-index: 400;
position: fixed;
bottom: 0px;
@@ -826,202 +1105,183 @@ ul#colorpickerswatches li:hover
border-top: 1px solid #999;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
- background-color:#fff;
+ background-color: #fff;
cursor: pointer;
}
-
-#chaticon a
-{
- text-decoration: none;
+#chaticon a {
+ text-decoration: none
}
-
-#chatcounter
-{
- color:#555;
- font-size:9px;
+#chatcounter {
+ color: #555;
+ font-size: 9px;
vertical-align: middle;
}
-
-#titlebar
-{
- line-height:16px;
- font-weight:bold;
- color:#555;
+#titlebar {
+ line-height: 16px;
+ font-weight: bold;
+ color: #555;
position: relative;
bottom: 2px;
-}
-
-#titlelabel
-{
- font-size:13px;
- margin:4px 0 0 4px;
- position:absolute;
-}
-
-#titlecross
-{
- font-size:25px;
- float:right;
+}
+#titlelabel {
+ font-size: 13px;
+ margin: 4px 0 0 4px;
+ position: absolute;
+}
+#titlecross {
+ font-size: 25px;
+ float: right;
text-align: right;
text-decoration: none;
cursor: pointer;
- color:#555;
+ color: #555;
}
-
-.time
-{
- float:right;
- color:#333;
- font-style:italic;
+.time {
+ float: right;
+ color: #333;
+ font-style: italic;
font-size: 10px;
margin-left: 3px;
margin-right: 3px;
- margin-top:2px;
-}
-
-.exporttype{
margin-top: 2px;
- background-repeat:no-repeat;
- padding-left:25px;
- background-image: url("../../static/img/etherpad_lite_icons.png");
- color:#fff;
- text-decoration:none;
}
-
-#importexportline{
+.exporttype {
+ margin-top: 2px;
+ background-repeat: no-repeat;
+ padding-left: 25px;
+ background-image: url("../../static/img/etherpad_lite_icons.png");
+ color: #fff;
+ text-decoration: none;
+}
+#importexportline {
border-left: 1px solid #fff;
height: 190px;
- position:absolute;
- width:0px;
- left:260px;
- opacity:.8;
+ position: absolute;
+ width: 0px;
+ left: 260px;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
+ filter: alpha(opacity=80);
+ opacity: .8;
}
-
-.impexpbutton{
+.impexpbutton {
+ background-image: -webkit-linear-gradient(center top , #EEEEEE, white 20%, white 20%);
+ background-image: -moz-linear-gradient(center top , #EEEEEE, white 20%, white 20%);
+ background-image: -o-linear-gradient(center top , #EEEEEE, white 20%, white 20%);
+ background-image: -ms-linear-gradient(center top , #EEEEEE, white 20%, white 20%);
background-image: linear-gradient(center top , #EEEEEE, white 20%, white 20%);
- padding:3px;
+ padding: 3px;
}
-
-#exporthtml{
- background-position: 0px -299px;
+#exporthtml {
+ background-position: 0px -299px
}
-
-#exportplain{
- background-position: 0px -395px;
+#exportplain {
+ background-position: 0px -395px
}
-
-#exportword{
- background-position: 0px -275px;
+#exportword {
+ background-position: 0px -275px
}
-
-#exportpdf{
- background-position: 0px -371px;
+#exportpdf {
+ background-position: 0px -371px
}
-
-#exportopen{
- background-position: 0px -347px;
+#exportopen {
+ background-position: 0px -347px
}
-
-#exportwordle{
- background-position: 0px -323px;
+#exportwordle {
+ background-position: 0px -323px
}
-
-#exportdokuwiki{
- background-position: 0px -459px;
+#exportdokuwiki {
+ background-position: 0px -459px
}
-
-#importstatusball{
- display:none;
+#importstatusball {
+ display: none
}
-
-#importarrow{
- display:none;
+#importarrow {
+ display: none
}
-
-#importmessagesuccess{
- display:none;
+#importmessagesuccess {
+ display: none
}
-
-#importsubmitinput{
- height:25px;
- width:85px;
- margin-top:12px;
+#importsubmitinput {
+ height: 25px;
+ width: 85px;
+ margin-top: 12px;
}
-
-#importstatusball{
- height:50px;
+#importstatusball {
+ height: 50px
}
-
-#chatthrob{
-display:none;
-position:absolute;
-bottom:40px;
-font-size:14px;
-width:150px;
-height:40px;
-right: 20px;
-z-index: 200;
-background-color: #000;
-color: white;
-background-color: rgb(0,0,0);
-background-color: rgba(0,0,0,0.7);
-padding: 10px;
-border-radius: 6px;
-opacity:.8;
+#chatthrob {
+ display: none;
+ position: absolute;
+ bottom: 40px;
+ font-size: 14px;
+ width: 150px;
+ height: 40px;
+ right: 20px;
+ z-index: 200;
+ background-color: #000;
+ color: white;
+ background-color: rgb(0,0,0);
+ background-color: rgba(0,0,0,0.7);
+ padding: 10px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
+ filter: alpha(opacity=80);
+ opacity: .8;
}
-
-.buttonicon{
-width:16px;
-height:16px;
-background-image:url('../../static/img/etherpad_lite_icons.png');
-background-repeat: no-repeat;
-margin-left: 1px;
-margin-top: 1px;
+.buttonicon {
+ width: 16px;
+ height: 16px;
+ background-image: url('../../static/img/etherpad_lite_icons.png');
+ background-repeat: no-repeat;
+ margin-left: 1px;
+ margin-top: 1px;
}
.buttonicon-bold {
- background-position: 0px -116px;
+ background-position: 0px -116px
}
.buttonicon-italic {
- background-position: 0px 0px;
+ background-position: 0px 0px
}
.buttonicon-underline {
- background-position: 0px -236px;
+ background-position: 0px -236px
}
.buttonicon-strikethrough {
- background-position: 0px -200px;
+ background-position: 0px -200px
}
.buttonicon-insertorderedlist {
background-position: 0px -477px
}
.buttonicon-insertunorderedlist {
- background-position: 0px -34px;
+ background-position: 0px -34px
}
.buttonicon-indent {
- background-position: 0px -52px;
+ background-position: 0px -52px
}
.buttonicon-outdent {
- background-position: 0px -134px;
+ background-position: 0px -134px
}
.buttonicon-undo {
- background-position: 0px -255px;
+ background-position: 0px -255px
}
.buttonicon-redo {
- background-position :0px -166px;
+ background-position: 0px -166px
}
.buttonicon-clearauthorship {
- background-position: 0px -86px;
+ background-position: 0px -86px
}
.buttonicon-settings {
- background-position: 0px -436px;
+ background-position: 0px -436px
}
.buttonicon-import_export {
- background-position: 0px -68px;
+ background-position: 0px -68px
}
.buttonicon-embed {
- background-position: 0px -18px;
+ background-position: 0px -18px
}
.buttonicon-history {
- background-position: 0px -218px;
+ background-position: 0px -218px
}
.buttonicon-chat {
background-position: 0px -102px;
@@ -1036,14 +1296,10 @@ margin-top: 1px;
.buttonicon-savedRevision {
background-position: 0px -493px
}
-
-#usericon
-{
-width:33px !important;
+#usericon {
+ width: 33px !important
}
-
-#focusprotector
-{
+#focusprotector {
z-index: 100;
position: absolute;
bottom: 0px;
@@ -1051,222 +1307,257 @@ width:33px !important;
left: 0px;
right: 0px;
background-color: white;
- opacity:0.01;
- display:none;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=1)";
+ filter: alpha(opacity=1);
+ opacity: 0.01;
+ display: none;
}
-
-#online_count{
+#online_count {
color: #888;
font-size: 11px;
line-height: 18px;
position: fixed;
}
-
#qr_center {
margin: 10px 10px auto 0;
text-align: center;
}
-
#embedreadonlyqr {
+ -webkit-box-shadow: 0 0 10px #000;
+ -moz-box-shadow: 0 0 10px #000;
box-shadow: 0 0 10px #000;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
border-radius: 3px;
+ -webkit-transition: all .2s ease-in-out;
+ -moz-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ -ms-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
-
#embedreadonlyqr:hover {
cursor: none;
+ -webkit-transform: scale(1.5);
+ -moz-transform: scale(1.5);
+ -o-transform: scale(1.5);
+ -ms-transform: scale(1.5);
transform: scale(1.5);
}
-
-.rtl{
- direction:RTL;
-}
-
-#chattext p {
- word-wrap: break-word;
+.rtl {
+ direction: RTL
+}
+#chattext p {
+ word-wrap: break-word
}
-
/* fix for misaligned checkboxes */
input[type=checkbox] {
- vertical-align: -1px;
+ vertical-align: -1px
}
-
.right {
- float:right;
+ float: right
}
-
.popup {
- font-size: 14px;
- width: 450px;
- z-index: 500;
- padding: 10px;
- border-radius: 6px;
- background: #222;
- background: rgba(0,0,0,.7);
- background: linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
- box-shadow: 0 0 8px #888;
- color: #fff;
+ font-size: 14px;
+ width: 450px;
+ z-index: 500;
+ padding: 10px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ background: #222;
+ background: rgba(0,0,0,.7);
+ background: -webkit-linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
+ background: -moz-linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
+ background: -o-linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
+ background: -ms-linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
+ background: linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.7) 35px, rgba(0,0,0,.6));
+ -webkit-box-shadow: 0 0 8px #888;
+ -moz-box-shadow: 0 0 8px #888;
+ box-shadow: 0 0 8px #888;
+ color: #fff;
}
-
.popup input[type=text] {
- width: 100%;
- padding: 5px;
- box-sizing: border-box;
- display:block;
- margin-top: 10px;
+ width: 100%;
+ padding: 5px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ display: block;
+ margin-top: 10px;
}
-
.popup a {
- text-decoration: none;
+ text-decoration: none
}
-
.popup h1 {
- font-size: 18px;
+ font-size: 18px
}
.popup h2 {
- font-size: 15px;
+ font-size: 15px
}
.popup p {
- margin: 5px 0;
+ margin: 5px 0
}
-
.column {
- float: left;
- width: 50%;
+ float: left;
+ width: 50%;
}
-
-#settingsmenu, #importexport, #embed {
- position: absolute;
- top: 55px;
- right: 20px;
- display: none;
+#settingsmenu,
+#importexport,
+#embed {
+ position: absolute;
+ top: 55px;
+ right: 20px;
+ display: none;
}
-
.note {
- color: #ddd;
- font-size: 11px;
- font-weight: bold;
+ color: #ddd;
+ font-size: 11px;
+ font-weight: bold;
}
-
.selected {
- background: #eee !important;
- background: linear-gradient(#EEE, #F0F0F0) !important;
+ background: #eee !important;
+ background: -webkit-linear-gradient(#EEE, #F0F0F0) !important;
+ background: -moz-linear-gradient(#EEE, #F0F0F0) !important;
+ background: -o-linear-gradient(#EEE, #F0F0F0) !important;
+ background: -ms-linear-gradient(#EEE, #F0F0F0) !important;
+ background: linear-gradient(#EEE, #F0F0F0) !important;
}
-
.stickyChat {
- background-color: #f1f1f1 !important;
- right: 0px !important;
- top: 36px;
- border-radius: 0px !important;
- height: auto !important;
- border: none !important;
- border-left: 1px solid #ccc !important;
- width: 185px !important;
+ background-color: #f1f1f1 !important;
+ right: 0px !important;
+ top: 36px;
+ -webkit-border-radius: 0px !important;
+ -moz-border-radius: 0px !important;
+ border-radius: 0px !important;
+ height: auto !important;
+ border: none !important;
+ border-left: 1px solid #ccc !important;
+ width: 185px !important;
}
-
-@media screen and (max-width: 960px) {
- .modaldialog {
- position: relative;
- margin: 0 auto;
- width: 80%;
- top: 40px;
- left: 0;
- }
+@media screen and (max-width: 960px) {
+ .modaldialog {
+ position: relative;
+ margin: 0 auto;
+ width: 80%;
+ top: 40px;
+ left: 0;
+ }
}
-
-@media screen and (max-width: 600px) {
- .toolbar ul li {
- padding: 4px 1px;
- }
-}
-
-@media only screen and (min-device-width: 320px) and (max-device-width: 720px) {
- .toolbar ul li {
- padding: 4px 3px;
- }
- #users {
- right: 0;
- top: 36px;
- bottom: 33px;
- border-radius: none;
- }
- #mycolorpicker {
- left: -72px; /* #mycolorpicker:width - #users:width */
- }
- #editorcontainer {
- margin-bottom: 33px;
- }
- .toolbar ul.menu_right {
- background: #f7f7f7;
- background: linear-gradient(#f7f7f7, #f1f1f1 80%);
- width: 100%;
- overflow: hidden;
- height: 32px;
- position: fixed;
- bottom: 0;
- border-top: 1px solid #ccc;
- }
- .toolbar ul.menu_right li:last-child {
- height: 24px;
- border-radius: 0;
- margin-top: 0;
- border: 0;
- float: right;
- }
- #chaticon {
- bottom: 3px;
- right: 55px;
- border-right: none;
- border-radius: 0;
- background: #f7f7f7;
- background: linear-gradient(#f7f7f7, #f1f1f1 80%);
- border: 0;
- }
- #chatbox {
- bottom: 32px;
- right: 0;
- border-top-right-radius: 0;
- border-right: none;
- }
- .toolbar ul li a span {
- top: -3px;
- }
- #usericonback {
- margin-top: 4px;
- }
- #qrcode {
- display: none;
- }
- .toolbar ul.menu_right li:not(:last-child) {
- display: block;
- }
- .toolbar ul.menu_right > li {
- background: none;
- border: none;
- margin-top: 4px;
- padding: 4px 8px;
- }
- .selected {
- background: none !important;
- }
- #timesliderlink {
- display: none !important;
- }
- .popup {
- border-radius: 0;
- box-sizing: border-box;
- width: 100%;
- }
- #settingsmenu, #importexport, #embed {
- left: 0;
- top: 0;
- bottom: 33px;
- right: 0;
- }
- .separator {
- display: none;
- }
- #online_count {
- line-height: 24px;
- }
+@media screen and (max-width: 600px) {
+ .toolbar ul li {
+ padding: 4px 1px
+ }
}
+@media only screen and (min-device-width: 320px) and (max-device-width: 720px) {
+ .toolbar ul li {
+ padding: 4px 3px
+ }
+ #users {
+ right: 0;
+ top: 36px;
+ bottom: 33px;
+ -webkit-border-radius: none;
+ -moz-border-radius: none;
+ border-radius: none;
+ }
+ #mycolorpicker {
+ left: -72px;
+ /* #mycolorpicker: width -#users: width */;
+ }
+ #editorcontainer {
+ margin-bottom: 33px
+ }
+ .toolbar ul.menu_right {
+ background: #f7f7f7;
+ background: -webkit-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -moz-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -o-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -ms-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: linear-gradient(#f7f7f7, #f1f1f1 80%);
+ width: 100%;
+ overflow: hidden;
+ height: 32px;
+ position: fixed;
+ bottom: 0;
+ border-top: 1px solid #ccc;
+ }
+ .toolbar ul.menu_right li:last-child {
+ height: 24px;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+ margin-top: 0;
+ border: 0;
+ float: right;
+ }
+ #chaticon {
+ bottom: 3px;
+ right: 55px;
+ border-right: none;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+ background: #f7f7f7;
+ background: -webkit-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -moz-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -o-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -ms-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: linear-gradient(#f7f7f7, #f1f1f1 80%);
+ border: 0;
+ }
+ #chatbox {
+ bottom: 32px;
+ right: 0;
+ border-top-right-radius: 0;
+ border-right: none;
+ }
+ .toolbar ul li a span {
+ top: -3px
+ }
+ #usericonback {
+ margin-top: 4px
+ }
+ #qrcode {
+ display: none
+ }
+ .toolbar ul.menu_right li:not(:last-child) {
+ display: block
+ }
+ .toolbar ul.menu_right > li {
+ background: none;
+ border: none;
+ margin-top: 4px;
+ padding: 4px 8px;
+ }
+ .selected {
+ background: none !important
+ }
+ #timesliderlink {
+ display: none !important
+ }
+ .popup {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -ms-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%;
+ }
+ #settingsmenu,
+ #importexport,
+ #embed {
+ left: 0;
+ top: 0;
+ bottom: 33px;
+ right: 0;
+ }
+ .separator {
+ display: none
+ }
+ #online_count {
+ line-height: 24px
+ }
+}
\ No newline at end of file
diff --git a/src/static/css/timeslider.css b/src/static/css/timeslider.css
index 03e970481..4c8913d38 100644
--- a/src/static/css/timeslider.css
+++ b/src/static/css/timeslider.css
@@ -1,160 +1,288 @@
#editorcontainerbox {
- overflow:auto; top:40px;
+ overflow: auto;
+ top: 40px;
position: static;
}
-
-#padcontent {font-size:12px; padding:10px;}
-
-#timeslider-wrapper {left:0; position:relative; right:0; top:0;}
-#timeslider-left {background-image:url(../../static/img/timeslider_left.png); height:63px; left:0; position:absolute; width:134px;}
-#timeslider-right {background-image:url(../../static/img/timeslider_right.png); height:63px; position:absolute; right:0; top:0; width:155px;}
-#timeslider {background-image:url(../../static/img/timeslider_background.png); height:63px; margin:0 9px;}
-#timeslider #timeslider-slider {height:61px; left:0; position:absolute; top:1px; width:100%;}
+#padcontent {
+ font-size: 12px;
+ padding: 10px;
+}
+#timeslider-wrapper {
+ left: 0;
+ position: relative;
+ right: 0;
+ top: 0;
+}
+#timeslider-left {
+ background-image: url(../../static/img/timeslider_left.png);
+ height: 63px;
+ left: 0;
+ position: absolute;
+ width: 134px;
+}
+#timeslider-right {
+ background-image: url(../../static/img/timeslider_right.png);
+ height: 63px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 155px;
+}
+#timeslider {
+ background-image: url(../../static/img/timeslider_background.png);
+ height: 63px;
+ margin: 0 9px;
+}
+#timeslider #timeslider-slider {
+ height: 61px;
+ left: 0;
+ position: absolute;
+ top: 1px;
+ width: 100%;
+}
#ui-slider-handle {
- -khtml-user-select:none;
- -moz-user-select:none;
- -ms-user-select:none;
- -webkit-user-select:none;
- background-image:url(../../static/img/crushed_current_location.png);
- cursor:pointer;
- height:61px;
- left:0;
- position:absolute;
- top:0;
- user-select:none;
- width:13px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ background-image: url(../../static/img/crushed_current_location.png);
+ cursor: pointer;
+ height: 61px;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 13px;
}
#ui-slider-bar {
- -khtml-user-select:none;
- -moz-user-select:none;
- -ms-user-select:none;
- -webkit-user-select:none;
- cursor:pointer;
- height:35px;
- margin-left:5px;
- margin-right:148px;
- position:relative;
- top:20px;
- user-select:none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ cursor: pointer;
+ height: 35px;
+ margin-left: 5px;
+ margin-right: 148px;
+ position: relative;
+ top: 20px;
+}
+#playpause_button,
+#playpause_button_icon {
+ height: 47px;
+ position: absolute;
+ width: 47px;
+}
+#playpause_button {
+ background-image: url(../../static/img/crushed_button_undepressed.png);
+ right: 77px;
+ top: 9px;
+}
+#playpause_button_icon {
+ background-image: url(../../static/img/play.png);
+ left: 0;
+ top: 0;
+}
+.pause#playpause_button_icon {
+ background-image: url(../../static/img/pause.png)
+}
+#leftstar,
+#rightstar,
+#leftstep,
+#rightstep {
+ background: url(../../static/img/stepper_buttons.png) 0 0 no-repeat;
+ height: 21px;
+ overflow: hidden;
+ position: absolute;
+}
+#leftstar {
+ background-position: 0 -44px;
+ right: 34px;
+ top: 8px;
+ width: 30px;
+}
+#rightstar {
+ background-position: -29px -44px;
+ right: 5px;
+ top: 8px;
+ width: 29px;
+}
+#leftstep {
+ background-position: 0 -22px;
+ right: 34px;
+ top: 20px;
+ width: 30px;
+}
+#rightstep {
+ background-position: -29px -22px;
+ right: 5px;
+ top: 20px;
+ width: 29px;
}
-
-#playpause_button, #playpause_button_icon {height:47px; position:absolute; width:47px;}
-#playpause_button {background-image:url(../../static/img/crushed_button_undepressed.png); right:77px; top:9px;}
-#playpause_button_icon {background-image:url(../../static/img/play.png); left:0; top:0;}
-.pause#playpause_button_icon {background-image:url(../../static/img/pause.png);}
-
-#leftstar, #rightstar, #leftstep, #rightstep
- {background:url(../../static/img/stepper_buttons.png) 0 0 no-repeat; height:21px; overflow:hidden; position:absolute;}
-#leftstar {background-position:0 -44px; right:34px; top:8px; width:30px;}
-#rightstar {background-position:-29px -44px; right:5px; top:8px; width:29px;}
-#leftstep {background-position:0 -22px; right:34px; top:20px; width:30px;}
-#rightstep {background-position:-29px -22px; right:5px; top:20px; width:29px;}
-
#timeslider .star {
- background-image:url(../../static/img/star.png);
- cursor:pointer;
- height:16px;
- position:absolute;
- top:40px;
- width:15px;
+ background-image: url(../../static/img/star.png);
+ cursor: pointer;
+ height: 16px;
+ position: absolute;
+ top: 40px;
+ width: 15px;
}
-
#timeslider #timer {
- color:#fff;
- font-family:Arial, sans-serif;
- font-size:11px;
- left:7px;
- position:absolute;
- text-align:center;
- top:9px;
- width:122px;
+ color: #fff;
+ font-family: Arial, sans-serif;
+ font-size: 11px;
+ left: 7px;
+ position: absolute;
+ text-align: center;
+ top: 9px;
+ width: 122px;
}
-
-
-.topbarcenter, #docbar {display:none;}
-#padmain {top:0px !important;}
-#editbarright {float:right;}
-#returnbutton {color:#222; font-size:16px; line-height:29px; margin-top:0; padding-right:6px;}
-#importexport .popup {width:185px;}
-#importexport{
- top:118px;
- width:185px;
+.topbarcenter,
+#docbar {
+ display: none
}
-
-
-.timeslider-bar
-{
+#padmain {
+ top: 0px !important
+}
+#editbarright {
+ float: right
+}
+#returnbutton {
+ color: #222;
+ font-size: 16px;
+ line-height: 29px;
+ margin-top: 0;
+ padding-right: 6px;
+}
+#importexport .popup {
+ width: 185px
+}
+#importexport {
+ top: 118px;
+ width: 185px;
+}
+.timeslider-bar {
background: #f7f7f7;
+ background: -webkit-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -moz-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -o-linear-gradient(#f7f7f7, #f1f1f1 80%);
+ background: -ms-linear-gradient(#f7f7f7, #f1f1f1 80%);
background: linear-gradient(#f7f7f7, #f1f1f1 80%);
- border-bottom: 1px solid #ccc;
overflow: hidden;
padding-top: 3px;
width: 100%;
}
-
-.timeslider-bar #editbar
-{
+.timeslider-bar #editbar {
border-bottom: none;
float: right;
width: 170px;
width: initial;
}
-
-.timeslider-bar h1
-{
- margin: 5px;
+.timeslider-bar h1 {
+ margin: 5px
}
-.timeslider-bar p
-{
- margin: 5px;
+.timeslider-bar p {
+ margin: 5px
}
#timeslider-top {
width: 100%;
position: fixed;
z-index: 1;
}
-
#authorsList .author {
padding-left: 0.4em;
padding-right: 0.4em;
}
-
#authorsList .author-anonymous {
padding-left: 0.6em;
padding-right: 0.6em;
}
-
#padeditor {
- position: static;
+ position: static
}
-
/* lists */
-.list-bullet2, .list-indent2, .list-number2 {margin-left:3em;}
-.list-bullet3, .list-indent3, .list-number3 {margin-left:4.5em;}
-.list-bullet4, .list-indent4, .list-number4 {margin-left:6em;}
-.list-bullet5, .list-indent5, .list-number5 {margin-left:7.5em;}
-.list-bullet6, .list-indent6, .list-number6 {margin-left:9em;}
-.list-bullet7, .list-indent7, .list-number7 {margin-left:10.5em;}
-.list-bullet8, .list-indent8, .list-number8 {margin-left:12em;}
-
+.list-bullet2,
+.list-indent2,
+.list-number2 {
+ margin-left: 3em
+}
+.list-bullet3,
+.list-indent3,
+.list-number3 {
+ margin-left: 4.5em
+}
+.list-bullet4,
+.list-indent4,
+.list-number4 {
+ margin-left: 6em
+}
+.list-bullet5,
+.list-indent5,
+.list-number5 {
+ margin-left: 7.5em
+}
+.list-bullet6,
+.list-indent6,
+.list-number6 {
+ margin-left: 9em
+}
+.list-bullet7,
+.list-indent7,
+.list-number7 {
+ margin-left: 10.5em
+}
+.list-bullet8,
+.list-indent8,
+.list-number8 {
+ margin-left: 12em
+}
/* unordered lists */
-UL {list-style-type:disc; margin-left:1.5em;}
-UL UL {margin-left:0 !important;}
-
-.list-bullet2, .list-bullet5, .list-bullet8 {list-style-type:circle;}
-.list-bullet3, .list-bullet6 {list-style-type:square;}
-
-.list-indent1, .list-indent2, .list-indent3, .list-indent5, .list-indent5, .list-indent6, .list-indent7, .list-indent8 {list-style-type:none;}
-
+UL {
+ list-style-type: disc;
+ margin-left: 1.5em;
+}
+UL UL {
+ margin-left: 0 !important
+}
+.list-bullet2,
+.list-bullet5,
+.list-bullet8 {
+ list-style-type: circle
+}
+.list-bullet3,
+.list-bullet6 {
+ list-style-type: square
+}
+.list-indent1,
+.list-indent2,
+.list-indent3,
+.list-indent5,
+.list-indent5,
+.list-indent6,
+.list-indent7,
+.list-indent8 {
+ list-style-type: none
+}
/* ordered lists */
-OL {list-style-type:decimal; margin-left:1.5em;}
-.list-number2, .list-number5, .list-number8 {list-style-type:lower-latin;}
-.list-number3, .list-number6 {list-style-type:lower-roman;}
-
-
-
-/* IE 6/7 fixes ################################################################ */
-* HTML #ui-slider-handle {background-image:url(../../static/img/current_location.gif);}
-* HTML #timeslider .star {background-image:url(../../static/img/star.gif);}
-* HTML #playpause_button_icon {background-image:url(../../static/img/play.gif);}
-* HTML .pause#playpause_button_icon {background-image:url(../../static/img/pause.gif);}
\ No newline at end of file
+OL {
+ list-style-type: decimal;
+ margin-left: 1.5em;
+}
+.list-number2,
+.list-number5,
+.list-number8 {
+ list-style-type: lower-latin
+}
+.list-number3,
+.list-number6 {
+ list-style-type: lower-roman
+}
+/* IE 6/7 fixes */
+* HTML #ui-slider-handle {
+ background-image: url(../../static/img/current_location.gif)
+}
+* HTML #timeslider .star {
+ background-image: url(../../static/img/star.gif)
+}
+* HTML #playpause_button_icon {
+ background-image: url(../../static/img/play.gif)
+}
+* HTML .pause#playpause_button_icon {
+ background-image: url(../../static/img/pause.gif)
+}
\ No newline at end of file
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index d2d145035..6e5f07bcb 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -4635,7 +4635,7 @@ function Ace2Inner(){
function setClassPresence(elem, className, present)
{
if (present) $(elem).addClass(className);
- else $(elem).removeClass(elem, className);
+ else $(elem).removeClass(className);
}
function setup()
@@ -5401,7 +5401,9 @@ function Ace2Inner(){
// Init documentAttributeManager
documentAttributeManager = new AttributeManager(rep, performDocumentApplyChangeset);
- editorInfo.ace_performDocumentApplyAttributesToRange = documentAttributeManager.setAttributesOnRange;
+ editorInfo.ace_performDocumentApplyAttributesToRange = function () {
+ return documentAttributeManager.setAttributesOnRange.apply(documentAttributeManager, arguments);
+ };
$(document).ready(function(){
doc = document; // defined as a var in scope outside
diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js
new file mode 100644
index 000000000..6ae085c2a
--- /dev/null
+++ b/src/static/js/admin/plugins.js
@@ -0,0 +1,132 @@
+$(document).ready(function () {
+ var socket = io.connect().of("/pluginfw/installer");
+
+ $('.search-results').data('query', {
+ pattern: '',
+ offset: 0,
+ limit: 4,
+ });
+
+ var doUpdate = false;
+
+ var search = function () {
+ socket.emit("search", $('.search-results').data('query'));
+ }
+
+ function updateHandlers() {
+ $("#progress.dialog .close").unbind('click').click(function () {
+ $("#progress.dialog").hide();
+ });
+
+ $("#do-search").unbind('click').click(function () {
+ var query = $('.search-results').data('query');
+ query.pattern = $("#search-query")[0].value;
+ query.offset = 0;
+ search();
+ });
+
+ $(".do-install").unbind('click').click(function (e) {
+ var row = $(e.target).closest("tr");
+ doUpdate = true;
+ socket.emit("install", row.find(".name").html());
+ });
+
+ $(".do-uninstall").unbind('click').click(function (e) {
+ var row = $(e.target).closest("tr");
+ doUpdate = true;
+ socket.emit("uninstall", row.find(".name").html());
+ });
+
+ $(".do-prev-page").unbind('click').click(function (e) {
+ var query = $('.search-results').data('query');
+ query.offset -= query.limit;
+ if (query.offset < 0) {
+ query.offset = 0;
+ }
+ search();
+ });
+ $(".do-next-page").unbind('click').click(function (e) {
+ var query = $('.search-results').data('query');
+ var total = $('.search-results').data('total');
+ if (query.offset + query.limit < total) {
+ query.offset += query.limit;
+ }
+ search();
+ });
+ }
+
+ updateHandlers();
+
+ socket.on('progress', function (data) {
+ if (data.progress > 0 && $('#progress.dialog').data('progress') > data.progress) return;
+
+ $("#progress.dialog .close").hide();
+ $("#progress.dialog").show();
+
+ $('#progress.dialog').data('progress', data.progress);
+
+ var message = "Unknown status";
+ if (data.message) {
+ message = "" + data.message.toString() + "";
+ }
+ if (data.error) {
+ message = "" + data.error.toString() + "";
+ }
+ $("#progress.dialog .message").html(message);
+ $("#progress.dialog .history").append("" + message + "
");
+
+ if (data.progress >= 1) {
+ if (data.error) {
+ $("#progress.dialog .close").show();
+ } else {
+ if (doUpdate) {
+ doUpdate = false;
+ socket.emit("load");
+ }
+ $("#progress.dialog").hide();
+ }
+ }
+ });
+
+ socket.on('search-result', function (data) {
+ var widget=$(".search-results");
+
+ widget.data('query', data.query);
+ widget.data('total', data.total);
+
+ widget.find('.offset').html(data.query.offset);
+ widget.find('.limit').html(data.query.offset + data.query.limit);
+ widget.find('.total').html(data.total);
+
+ widget.find(".results *").remove();
+ for (plugin_name in data.results) {
+ var plugin = data.results[plugin_name];
+ var row = widget.find(".template tr").clone();
+
+ for (attr in plugin) {
+ row.find("." + attr).html(plugin[attr]);
+ }
+ widget.find(".results").append(row);
+ }
+
+ updateHandlers();
+ });
+
+ socket.on('installed-results', function (data) {
+ $("#installed-plugins *").remove();
+ for (plugin_name in data.results) {
+ var plugin = data.results[plugin_name];
+ var row = $("#installed-plugin-template").clone();
+
+ for (attr in plugin.package) {
+ row.find("." + attr).html(plugin.package[attr]);
+ }
+ $("#installed-plugins").append(row);
+ }
+ updateHandlers();
+ });
+
+ socket.emit("load");
+ search();
+
+});
diff --git a/src/static/js/broadcast_slider.js b/src/static/js/broadcast_slider.js
index a2a157733..87007263f 100644
--- a/src/static/js/broadcast_slider.js
+++ b/src/static/js/broadcast_slider.js
@@ -162,11 +162,8 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
function showReconnectUI()
{
- if (!clientVars.sliderEnabled || !clientVars.supportsSlider)
- {
- $("#padmain, #rightbars").css('top', "130px");
- $("#timeslider").show();
- }
+ $("#padmain, #rightbars").css('top', "130px");
+ $("#timeslider").show();
$('#error').show();
}
@@ -216,7 +213,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
authorsList.append(' (');
_.each(colorsAnonymous, function(color, i){
if( i > 0 ) authorsList.append(' ');
- $(' ')
+ $(' ')
.css('background-color', color)
.addClass('author author-anonymous')
.appendTo(authorsList);
@@ -287,55 +284,52 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
disableSelection($("#playpause_button")[0]);
disableSelection($("#timeslider")[0]);
-
- if (clientVars.sliderEnabled && clientVars.supportsSlider)
+
+ $(document).keyup(function(e)
{
- $(document).keyup(function(e)
- {
- var code = -1;
- if (!e) var e = window.event;
- if (e.keyCode) code = e.keyCode;
- else if (e.which) code = e.which;
+ var code = -1;
+ if (!e) var e = window.event;
+ if (e.keyCode) code = e.keyCode;
+ else if (e.which) code = e.which;
- if (code == 37)
- { // left
- if (!e.shiftKey)
- {
- setSliderPosition(getSliderPosition() - 1);
- }
- else
- {
- var nextStar = 0; // default to first revision in document
- for (var i = 0; i < savedRevisions.length; i++)
- {
- var pos = parseInt(savedRevisions[i].attr('pos'));
- if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
- }
- setSliderPosition(nextStar);
- }
- }
- else if (code == 39)
+ if (code == 37)
+ { // left
+ if (!e.shiftKey)
{
- if (!e.shiftKey)
- {
- setSliderPosition(getSliderPosition() + 1);
- }
- else
- {
- var nextStar = sliderLength; // default to last revision in document
- for (var i = 0; i < savedRevisions.length; i++)
- {
- var pos = parseInt(savedRevisions[i].attr('pos'));
- if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
- }
- setSliderPosition(nextStar);
- }
+ setSliderPosition(getSliderPosition() - 1);
}
- else if (code == 32) playpause();
-
- });
- }
+ else
+ {
+ var nextStar = 0; // default to first revision in document
+ for (var i = 0; i < savedRevisions.length; i++)
+ {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if (pos < getSliderPosition() && nextStar < pos) nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ }
+ else if (code == 39)
+ {
+ if (!e.shiftKey)
+ {
+ setSliderPosition(getSliderPosition() + 1);
+ }
+ else
+ {
+ var nextStar = sliderLength; // default to last revision in document
+ for (var i = 0; i < savedRevisions.length; i++)
+ {
+ var pos = parseInt(savedRevisions[i].attr('pos'));
+ if (pos > getSliderPosition() && nextStar > pos) nextStar = pos;
+ }
+ setSliderPosition(nextStar);
+ }
+ }
+ else if (code == 32) playpause();
+ });
+
$(window).resize(function()
{
updateSliderElements();
@@ -485,37 +479,16 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
$("#revision").css('right', "20px");
$("#revision").css('top', "20px");
}
-
-
- if (clientVars.sliderEnabled)
+
+ $("#timeslider").show();
+ setSliderLength(clientVars.totalRevs);
+ setSliderPosition(clientVars.revNum);
+
+ _.each(clientVars.savedRevisions, function(revision)
{
- if (clientVars.supportsSlider)
- {
- $("#timeslider").show();
- setSliderLength(clientVars.totalRevs);
- setSliderPosition(clientVars.revNum);
- _.each(clientVars.savedRevisions, function(revision)
- {
- addSavedRevision(revision.revNum, revision);
- })
- }
- else
- {
- // slider is not supported
- $("#padmain, #rightbars").css('top', "130px");
- $("#timeslider").show();
- $("#error").html("The timeslider feature is not supported on this pad. Why not?");
- $("#error").show();
- }
- }
- else
- {
- if (clientVars.supportsSlider)
- {
- setSliderLength(clientVars.totalRevs);
- setSliderPosition(clientVars.revNum);
- }
- }
+ addSavedRevision(revision.revNum, revision);
+ })
+
}
});
})();
diff --git a/src/static/js/pad_userlist.js b/src/static/js/pad_userlist.js
index 5a3f9b355..f7ee81434 100644
--- a/src/static/js/pad_userlist.js
+++ b/src/static/js/pad_userlist.js
@@ -120,7 +120,7 @@ var paduserlist = (function()
nameHtml = '';
}
- return ['
| ', '', nameHtml, ' | ', '', padutils.escapeHtml(data.status), ' | ', '', padutils.escapeHtml(data.activity), ' | '].join('');
+ return [' | ', '', nameHtml, ' | ', '', padutils.escapeHtml(data.activity), ' | '].join('');
}
function getRowHtml(id, innerHtml)
diff --git a/src/static/js/pluginfw/hooks.js b/src/static/js/pluginfw/hooks.js
index c4cd5aebf..49e46c608 100644
--- a/src/static/js/pluginfw/hooks.js
+++ b/src/static/js/pluginfw/hooks.js
@@ -4,27 +4,63 @@ var _;
/* FIXME: Ugly hack, in the future, use same code for server & client */
if (plugins.isClient) {
var async = require("ep_etherpad-lite/static/js/pluginfw/async");
- _ = require("ep_etherpad-lite/static/js/underscore");
+ var _ = require("ep_etherpad-lite/static/js/underscore");
} else {
var async = require("async");
- _ = require("underscore");
+ var _ = require("underscore");
}
exports.bubbleExceptions = true
var hookCallWrapper = function (hook, hook_name, args, cb) {
if (cb === undefined) cb = function (x) { return x; };
+
+ // Normalize output to list for both sync and async cases
+ var normalize = function(x) {
+ if (x == undefined) return [];
+ return x;
+ }
+ var normalizedhook = function () {
+ return normalize(hook.hook_fn(hook_name, args, function (x) {
+ return cb(normalize(x));
+ }));
+ }
+
if (exports.bubbleExceptions) {
- return hook.hook_fn(hook_name, args, cb);
+ return normalizedhook();
} else {
try {
- return hook.hook_fn(hook_name, args, cb);
+ return normalizedhook();
} catch (ex) {
console.error([hook_name, hook.part.full_name, ex.stack || ex]);
}
}
}
+exports.syncMapFirst = function (lst, fn) {
+ var i;
+ var result;
+ for (i = 0; i < lst.length; i++) {
+ result = fn(lst[i])
+ if (result.length) return result;
+ }
+ return undefined;
+}
+
+exports.mapFirst = function (lst, fn, cb) {
+ var i = 0;
+
+ next = function () {
+ if (i >= lst.length) return cb(undefined);
+ fn(lst[i++], function (err, result) {
+ if (err) return cb(err);
+ if (result.length) return cb(null, result);
+ next();
+ });
+ }
+ next();
+}
+
/* Don't use Array.concat as it flatterns arrays within the array */
exports.flatten = function (lst) {
@@ -44,9 +80,9 @@ exports.flatten = function (lst) {
exports.callAll = function (hook_name, args) {
if (!args) args = {};
if (plugins.hooks[hook_name] === undefined) return [];
- return exports.flatten(_.map(plugins.hooks[hook_name], function (hook) {
+ return _.flatten(_.map(plugins.hooks[hook_name], function (hook) {
return hookCallWrapper(hook, hook_name, args);
- }));
+ }), true);
}
exports.aCallAll = function (hook_name, args, cb) {
@@ -59,7 +95,7 @@ exports.aCallAll = function (hook_name, args, cb) {
hookCallWrapper(hook, hook_name, args, function (res) { cb(null, res); });
},
function (err, res) {
- cb(null, exports.flatten(res));
+ cb(null, _.flatten(res, true));
}
);
}
@@ -67,14 +103,22 @@ exports.aCallAll = function (hook_name, args, cb) {
exports.callFirst = function (hook_name, args) {
if (!args) args = {};
if (plugins.hooks[hook_name][0] === undefined) return [];
- return exports.flatten(hookCallWrapper(plugins.hooks[hook_name][0], hook_name, args));
+ return exports.syncMapFirst(plugins.hooks[hook_name], function (hook) {
+ return hookCallWrapper(hook, hook_name, args);
+ });
}
exports.aCallFirst = function (hook_name, args, cb) {
if (!args) args = {};
if (!cb) cb = function () {};
- if (plugins.hooks[hook_name][0] === undefined) return cb(null, []);
- hookCallWrapper(plugins.hooks[hook_name][0], hook_name, args, function (res) { cb(null, exports.flatten(res)); });
+ if (plugins.hooks[hook_name] === undefined) return cb(null, []);
+ exports.mapFirst(
+ plugins.hooks[hook_name],
+ function (hook, cb) {
+ hookCallWrapper(hook, hook_name, args, function (res) { cb(null, res); });
+ },
+ cb
+ );
}
exports.callAllStr = function(hook_name, args, sep, pre, post) {
diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js
index 127a95aa7..1bb8db9e0 100644
--- a/src/static/js/pluginfw/installer.js
+++ b/src/static/js/pluginfw/installer.js
@@ -55,19 +55,41 @@ exports.install = function(plugin_name, cb) {
);
};
-exports.search = function(pattern, cb) {
+exports.searchCache = null;
+
+exports.search = function(query, cache, cb) {
withNpm(
function (cb) {
- registry.get(
- "/-/all", null, 600, false, true,
+ var getData = function (cb) {
+ if (cache && exports.searchCache) {
+ cb(null, exports.searchCache);
+ } else {
+ registry.get(
+ "/-/all", null, 600, false, true,
+ function (er, data) {
+ if (er) return cb(er);
+ exports.searchCache = data;
+ cb(er, data);
+ }
+ );
+ }
+ }
+ getData(
function (er, data) {
if (er) return cb(er);
var res = {};
+ var i = 0;
for (key in data) {
- if (key.indexOf(plugins.prefix) == 0 && key.indexOf(pattern) != -1)
- res[key] = data[key];
+ if ( key.indexOf(plugins.prefix) == 0
+ && key.indexOf(query.pattern) != -1) {
+ i++;
+ if (i > query.offset
+ && i <= query.offset + query.limit) {
+ res[key] = data[key];
+ }
+ }
}
- cb(null, {results:res});
+ cb(null, {results:res, query: query, total:i});
}
);
},
diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js
index 5f44bb6f2..e6cb51905 100644
--- a/src/static/js/pluginfw/plugins.js
+++ b/src/static/js/pluginfw/plugins.js
@@ -85,15 +85,20 @@ exports.extractHooks = function (parts, hook_set_name) {
if (exports.isClient) {
exports.update = function (cb) {
+ // It appears that this response (see #620) may interrupt the current thread
+ // of execution on Firefox. This schedules the response in the run-loop,
+ // which appears to fix the issue.
+ var callback = function () {setTimeout(cb, 0);};
+
jQuery.getJSON('/pluginfw/plugin-definitions.json', function(data) {
exports.plugins = data.plugins;
exports.parts = data.parts;
exports.hooks = exports.extractHooks(exports.parts, "client_hooks");
exports.loaded = true;
- cb();
+ callback();
}).error(function(xhr, s, err){
console.error("Failed to load plugin-definitions: " + err);
- cb();
+ callback();
});
};
} else {
diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html
index 6f38d0480..c1cc645a0 100644
--- a/src/templates/admin/plugins.html
+++ b/src/templates/admin/plugins.html
@@ -4,95 +4,7 @@
-
+
@@ -128,31 +40,37 @@
-
Search for plugins to install
-
-
+
+
Search for plugins to install
+
+
+
+
..
of
.
+
+
+
diff --git a/src/templates/pad.html b/src/templates/pad.html
index 533bb2ba7..91583b360 100644
--- a/src/templates/pad.html
+++ b/src/templates/pad.html
@@ -276,21 +276,14 @@
- <% if (settings.minify) { %>
-
- <% } %>
+