Merge branch 'develop' of git://github.com/Pita/etherpad-lite into body-block
Resolved conflicts: src/templates/pad.html
This commit is contained in:
commit
cf54c23228
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ var ejs = require("ejs");
|
|||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
|
||||
var resolve = require("resolve");
|
||||
|
||||
exports.info = {
|
||||
buf_stack: [],
|
||||
|
@ -91,13 +92,28 @@ exports.inherit = function (name, args) {
|
|||
exports.info.file_stack[exports.info.file_stack.length-1].inherit.push({name:name, args:args});
|
||||
}
|
||||
|
||||
exports.require = function (name, args) {
|
||||
exports.require = function (name, args, mod) {
|
||||
if (args == undefined) args = {};
|
||||
|
||||
if ((name.indexOf("./") == 0 || name.indexOf("../") == 0) && exports.info.file_stack.length) {
|
||||
name = path.join(path.dirname(exports.info.file_stack[exports.info.file_stack.length-1].path), name);
|
||||
|
||||
var basedir = __dirname;
|
||||
var paths = [];
|
||||
|
||||
if (exports.info.file_stack.length) {
|
||||
basedir = path.dirname(exports.info.file_stack[exports.info.file_stack.length-1].path);
|
||||
}
|
||||
var ejspath = require.resolve(name)
|
||||
if (mod) {
|
||||
basedir = path.dirname(mod.filename);
|
||||
paths = mod.paths;
|
||||
}
|
||||
|
||||
var ejspath = resolve.sync(
|
||||
name,
|
||||
{
|
||||
paths : paths,
|
||||
basedir : basedir,
|
||||
extensions : [ '.html', '.ejs' ],
|
||||
}
|
||||
)
|
||||
|
||||
args.e = exports;
|
||||
args.require = require;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -13,10 +13,12 @@
|
|||
"yajsml" : "1.1.2",
|
||||
"request" : "2.9.100",
|
||||
"require-kernel" : "1.0.5",
|
||||
"resolve" : "0.2.1",
|
||||
"socket.io" : "0.8.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",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
color: #333;
|
||||
font: 14px helvetica, sans-serif;
|
||||
background: #ddd;
|
||||
|
@ -42,34 +41,33 @@ form {
|
|||
width: 300px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
button, input {
|
||||
input {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
}
|
||||
input[type="button"] {
|
||||
height: 30px;
|
||||
padding: 4px 6px;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
input[value="Uninstall"], input[value="Install"] {
|
||||
input[type="button"].do-install, input[type="button"].do-uninstall {
|
||||
float: right;
|
||||
width: 100px;
|
||||
}
|
||||
input[type="button"]#do-search {
|
||||
display: block;
|
||||
}
|
||||
input[type="text"] {
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
padding: 10px;
|
||||
*padding: 0; /* IE7 hack */
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: 1px solid #ddd;
|
||||
margin: 0 0 5px 1px;
|
||||
margin: 0 0 5px 0;
|
||||
max-width: 500px;
|
||||
}
|
||||
button{
|
||||
display:block;
|
||||
}
|
||||
table {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
|
@ -95,13 +93,13 @@ td, th {
|
|||
height: 500px;
|
||||
margin-left: -350px;
|
||||
margin-top: -250px;
|
||||
border: 3px solid #999999;
|
||||
background: #eeeeee;
|
||||
border: 3px solid #999;
|
||||
background: #eee;
|
||||
}
|
||||
.dialog .title {
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
border-bottom: 3px solid #999999;
|
||||
border-bottom: 3px solid #999;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
|
@ -109,10 +107,11 @@ td, th {
|
|||
}
|
||||
.dialog .title .close {
|
||||
float: right;
|
||||
padding: 1px 10px;
|
||||
}
|
||||
.dialog .history {
|
||||
background: #222222;
|
||||
color: #eeeeee;
|
||||
background: #222;
|
||||
color: #eee;
|
||||
position: absolute;
|
||||
top: 41px;
|
||||
bottom: 10px;
|
||||
|
|
|
@ -1402,7 +1402,7 @@ input[type=checkbox] {
|
|||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
#settingsmenu,
|
||||
#settings,
|
||||
#importexport,
|
||||
#embed {
|
||||
position: absolute;
|
||||
|
@ -1546,7 +1546,7 @@ input[type=checkbox] {
|
|||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
#settingsmenu,
|
||||
#settings,
|
||||
#importexport,
|
||||
#embed {
|
||||
left: 0;
|
||||
|
|
|
@ -167,7 +167,13 @@ require.setGlobalKeyPath("require");\n\
|
|||
buffer.push(Ace2Editor.EMBEDED[KERNEL_SOURCE]);
|
||||
buffer.push(KERNEL_BOOT);
|
||||
buffer.push('<\/script>');
|
||||
}
|
||||
} else {
|
||||
file = KERNEL_SOURCE;
|
||||
buffer.push('<script type="application/javascript" src="' + KERNEL_SOURCE + '"><\/script>');
|
||||
buffer.push('<script type="text/javascript">');
|
||||
buffer.push(KERNEL_BOOT);
|
||||
buffer.push('<\/script>');
|
||||
}
|
||||
}
|
||||
function pushScriptsTo(buffer) {
|
||||
/* Folling is for packaging regular expression. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
$(document).ready(function () {
|
||||
|
||||
var socket,
|
||||
loc = document.location,
|
||||
port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port,
|
||||
url = loc.protocol + "//" + loc.hostname + ":" + port + "/",
|
||||
pathComponents = location.pathname.split('/'),
|
||||
// Strip admin/plugins
|
||||
baseURL = pathComponents.slice(0,pathComponents.length-2).join('/') + '/',
|
||||
resource = baseURL.substring(1) + "socket.io";
|
||||
|
||||
//connect
|
||||
socket = io.connect(url, {resource : resource}).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 = "<span class='status'>" + data.message.toString() + "</span>";
|
||||
}
|
||||
if (data.error) {
|
||||
message = "<span class='error'>" + data.error.toString() + "<span>";
|
||||
}
|
||||
$("#progress.dialog .message").html(message);
|
||||
$("#progress.dialog .history").append("<div>" + message + "</div>");
|
||||
|
||||
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();
|
||||
|
||||
});
|
|
@ -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(' ');
|
||||
$('<span /> ')
|
||||
$('<span> </span>')
|
||||
.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. <a href=\"/ep/about/faq#disabledslider\">Why not?</a>");
|
||||
$("#error").show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clientVars.supportsSlider)
|
||||
{
|
||||
setSliderLength(clientVars.totalRevs);
|
||||
setSliderPosition(clientVars.revNum);
|
||||
}
|
||||
}
|
||||
addSavedRevision(revision.revNum, revision);
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -229,6 +229,10 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
|||
result.node.innerHTML = curHTML;
|
||||
}
|
||||
if (lineClass !== null) result.node.className = lineClass;
|
||||
|
||||
hooks.callAll("acePostWriteDomLineHTML", {
|
||||
node: result.node
|
||||
});
|
||||
}
|
||||
result.prepareForAdd = writeHTML;
|
||||
result.finishUpdate = writeHTML;
|
||||
|
|
|
@ -203,7 +203,7 @@ function handshake()
|
|||
//create the url
|
||||
var url = loc.protocol + "//" + loc.hostname + ":" + port + "/";
|
||||
//find out in which subfolder we are
|
||||
var resource = loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "socket.io";
|
||||
var resource = exports.baseURL.substring(1) + "socket.io";
|
||||
//connect
|
||||
socket = pad.socket = io.connect(url, {
|
||||
resource: resource,
|
||||
|
@ -1029,7 +1029,7 @@ var settings = {
|
|||
};
|
||||
|
||||
pad.settings = settings;
|
||||
|
||||
exports.baseURL = '';
|
||||
exports.settings = settings;
|
||||
exports.createCookie = createCookie;
|
||||
exports.readCookie = readCookie;
|
||||
|
|
|
@ -119,7 +119,7 @@ var padeditbar = (function()
|
|||
}
|
||||
else if (cmd == 'settings')
|
||||
{
|
||||
self.toogleDropDown("settingsmenu");
|
||||
self.toogleDropDown("settings");
|
||||
}
|
||||
else if (cmd == 'embed')
|
||||
{
|
||||
|
@ -177,12 +177,11 @@ var padeditbar = (function()
|
|||
},
|
||||
toogleDropDown: function(moduleName)
|
||||
{
|
||||
var modules = ["settingsmenu", "importexport", "embed", "users"];
|
||||
var modules = ["settings", "importexport", "embed", "users"];
|
||||
|
||||
//hide all modules
|
||||
// hide all modules and remove highlighting of all buttons
|
||||
if(moduleName == "none")
|
||||
{
|
||||
$("#editbar ul#menu_right > li").removeClass("selected");
|
||||
for(var i=0;i<modules.length;i++)
|
||||
{
|
||||
//skip the userlist
|
||||
|
@ -193,29 +192,27 @@ var padeditbar = (function()
|
|||
|
||||
if(module.css('display') != "none")
|
||||
{
|
||||
$("#" + modules[i] + "link").removeClass("selected");
|
||||
module.slideUp("fast");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var nth_child = indexOf(modules, moduleName) + 1;
|
||||
if (nth_child > 0 && nth_child <= (modules.length-1)) {
|
||||
$("#editbar ul#menu_right li:not(:nth-child(" + nth_child + "))").removeClass("selected");
|
||||
$("#editbar ul#menu_right li:nth-child(" + nth_child + ")").toggleClass("selected");
|
||||
}
|
||||
if(modules[modules.length-1] === moduleName) $("#editbar ul#menu_right li").removeClass("selected");
|
||||
//hide all modules that are not selected and show the selected one
|
||||
// hide all modules that are not selected and remove highlighting
|
||||
// respectively add highlighting to the corresponding button
|
||||
for(var i=0;i<modules.length;i++)
|
||||
{
|
||||
var module = $("#" + modules[i]);
|
||||
|
||||
if(module.css('display') != "none")
|
||||
{
|
||||
$("#" + modules[i] + "link").removeClass("selected");
|
||||
module.slideUp("fast");
|
||||
}
|
||||
else if(modules[i]==moduleName)
|
||||
{
|
||||
$("#" + modules[i] + "link").addClass("selected");
|
||||
module.slideDown("fast");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -748,13 +748,14 @@ function closeColorPicker(accept)
|
|||
var newColor = $("#mycolorpickerpreview").css("background-color");
|
||||
var parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"]
|
||||
delete (parts[0]);
|
||||
for (var i = 1; i <= 3; ++i) {
|
||||
parts[i] = parseInt(parts[i]).toString(16);
|
||||
if (parts[i].length == 1) parts[i] = '0' + parts[i];
|
||||
if (parts) {
|
||||
delete (parts[0]);
|
||||
for (var i = 1; i <= 3; ++i) {
|
||||
parts[i] = parseInt(parts[i]).toString(16);
|
||||
if (parts[i].length == 1) parts[i] = '0' + parts[i];
|
||||
}
|
||||
var newColor = "#" +parts.join(''); // "0070ff"
|
||||
}
|
||||
var newColor = "#" +parts.join(''); // "0070ff"
|
||||
|
||||
myUserInfo.colorId = newColor;
|
||||
pad.notifyChangeColor(newColor);
|
||||
paduserlist.renderMyUserInfo();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
|
|
@ -24,6 +24,7 @@ exports.loaded = false;
|
|||
exports.plugins = {};
|
||||
exports.parts = [];
|
||||
exports.hooks = {};
|
||||
exports.baseURL = '';
|
||||
|
||||
exports.ensure = function (cb) {
|
||||
if (!exports.loaded)
|
||||
|
@ -61,7 +62,7 @@ exports.loadFn = function (path, hookName) {
|
|||
return fn;
|
||||
};
|
||||
|
||||
exports.extractHooks = function (parts, hook_set_name) {
|
||||
exports.extractHooks = function (parts, hook_set_name, plugins) {
|
||||
var hooks = {};
|
||||
_.each(parts,function (part) {
|
||||
_.chain(part[hook_set_name] || {})
|
||||
|
@ -69,14 +70,27 @@ exports.extractHooks = function (parts, hook_set_name) {
|
|||
.each(function (hook_name) {
|
||||
if (hooks[hook_name] === undefined) hooks[hook_name] = [];
|
||||
|
||||
|
||||
var hook_fn_name = part[hook_set_name][hook_name];
|
||||
var hook_fn = exports.loadFn(hook_fn_name, hook_name);
|
||||
|
||||
/* On the server side, you can't just
|
||||
* require("pluginname/whatever") if the plugin is installed as
|
||||
* a dependency of another plugin! Bah, pesky little details of
|
||||
* npm... */
|
||||
if (!exports.isClient) {
|
||||
hook_fn_name = path.normalize(path.join(path.dirname(exports.plugins[part.plugin].package.path), hook_fn_name));
|
||||
}
|
||||
|
||||
try {
|
||||
var hook_fn = exports.loadFn(hook_fn_name, hook_name);
|
||||
if (!hook_fn) {
|
||||
throw "Not a function";
|
||||
}
|
||||
} catch (exc) {
|
||||
console.error("Failed to load '" + hook_fn_name + "' for '" + part.full_name + "/" + hook_set_name + "/" + hook_name + "': " + exc.toString())
|
||||
}
|
||||
if (hook_fn) {
|
||||
hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part});
|
||||
} else {
|
||||
console.error("Unable to load hook function for " + part.full_name + " for hook " + hook_name + ": " + part.hooks[hook_name]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return hooks;
|
||||
|
@ -90,7 +104,7 @@ if (exports.isClient) {
|
|||
// which appears to fix the issue.
|
||||
var callback = function () {setTimeout(cb, 0);};
|
||||
|
||||
jQuery.getJSON('/pluginfw/plugin-definitions.json', function(data) {
|
||||
jQuery.getJSON(exports.baseURL + 'pluginfw/plugin-definitions.json', function(data) {
|
||||
exports.plugins = data.plugins;
|
||||
exports.parts = data.parts;
|
||||
exports.hooks = exports.extractHooks(exports.parts, "client_hooks");
|
||||
|
@ -139,7 +153,7 @@ exports.update = function (cb) {
|
|||
if (err) cb(err);
|
||||
exports.plugins = plugins;
|
||||
exports.parts = exports.sortParts(parts);
|
||||
exports.hooks = exports.extractHooks(exports.parts, "hooks");
|
||||
exports.hooks = exports.extractHooks(exports.parts, "hooks");
|
||||
exports.loaded = true;
|
||||
exports.callInit(cb);
|
||||
}
|
||||
|
|
|
@ -60,8 +60,8 @@ function init() {
|
|||
//create the url
|
||||
var url = loc.protocol + "//" + loc.hostname + ":" + port + "/";
|
||||
//find out in which subfolder we are
|
||||
var resource = loc.pathname.substr(1,loc.pathname.indexOf("/p/")) + "socket.io";
|
||||
|
||||
var resource = exports.baseURL.substring(1) + 'socket.io';
|
||||
|
||||
//build up the socket io connection
|
||||
socket = io.connect(url, {resource: resource});
|
||||
|
||||
|
@ -153,4 +153,5 @@ function handleClientVars(message)
|
|||
}
|
||||
}
|
||||
|
||||
exports.baseURL = '';
|
||||
exports.init = init;
|
||||
|
|
|
@ -1,106 +1,15 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Plugin manager</title>
|
||||
<link href="../../static/css/admin.css" rel="stylesheet" type="text/css" />
|
||||
<script src="../../static/js/jquery.js"></script>
|
||||
<script src="../../socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
var socket = io.connect().of("/pluginfw/installer");
|
||||
|
||||
var doUpdate = false;
|
||||
|
||||
function updateHandlers() {
|
||||
$("#progress.dialog .close").unbind('click').click(function () {
|
||||
$("#progress.dialog").hide();
|
||||
});
|
||||
|
||||
$("#do-search").unbind('click').click(function () {
|
||||
if ($("#search-query")[0].value != "")
|
||||
socket.emit("search", $("#search-query")[0].value);
|
||||
});
|
||||
|
||||
$(".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());
|
||||
});
|
||||
}
|
||||
|
||||
updateHandlers();
|
||||
|
||||
socket.on('progress', function (data) {
|
||||
$("#progress.dialog .close").hide();
|
||||
$("#progress.dialog").show();
|
||||
var message = "Unknown status";
|
||||
if (data.message) {
|
||||
message = "<span class='status'>" + data.message.toString() + "</span>";
|
||||
}
|
||||
if (data.error) {
|
||||
message = "<span class='error'>" + data.error.toString() + "<span>";
|
||||
}
|
||||
$("#progress.dialog .message").html(message);
|
||||
$("#progress.dialog .history").append("<div>" + message + "</div>");
|
||||
|
||||
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) {
|
||||
$("#search-results *").remove();
|
||||
for (plugin_name in data.results) {
|
||||
var plugin = data.results[plugin_name];
|
||||
var row = $("#search-result-template").clone();
|
||||
|
||||
for (attr in plugin) {
|
||||
row.find("." + attr).html(plugin[attr]);
|
||||
}
|
||||
$("#search-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");
|
||||
|
||||
});
|
||||
</script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||
<link rel="stylesheet" href="../static/css/admin.css">
|
||||
<script src="../static/js/jquery.js"></script>
|
||||
<script src="../socket.io/socket.io.js"></script>
|
||||
<script src="../static/js/admin/plugins.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
|
||||
<h1>Etherpad Lite</h1>
|
||||
|
||||
<div class="seperator"></div>
|
||||
|
||||
<% if (errors.length) { %>
|
||||
<div class="errors">
|
||||
<% errors.forEach(function (item) { %>
|
||||
|
@ -110,6 +19,8 @@
|
|||
<% } %>
|
||||
|
||||
|
||||
<h1>Etherpad Lite</h1>
|
||||
<div class="seperator"></div>
|
||||
<h2>Installed plugins</h2>
|
||||
<table>
|
||||
<thead>
|
||||
|
@ -131,32 +42,38 @@
|
|||
<tbody id="installed-plugins">
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="seperator"></div>
|
||||
<h2>Search for plugins to install</h2>
|
||||
<form>
|
||||
<input type="text" name="search" placeholder="Search term" id="search-query">
|
||||
<input type="button" value="Search" id="do-search">
|
||||
</form>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="template">
|
||||
<tr id="search-result-template">
|
||||
<td class="name"></td>
|
||||
<td class="description"></td>
|
||||
<td class="actions">
|
||||
<input type="button" value="Install" class="do-install">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody id="search-results">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="paged listing search-results">
|
||||
<div class="seperator"></div>
|
||||
<h2>Search for plugins to install</h2>
|
||||
<form>
|
||||
<input type="text" name="search" placeholder="Search term" id="search-query">
|
||||
<input type="button" value="Search" id="do-search">
|
||||
</form>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="template">
|
||||
<tr>
|
||||
<td class="name"></td>
|
||||
<td class="description"></td>
|
||||
<td class="actions">
|
||||
<input type="button" value="Install" class="do-install">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody class="results">
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="button" value="<<" class="do-prev-page">
|
||||
<span class="offset"></span>..<span class="limit"></span> of <span class="total"></span>.
|
||||
<input type="button" value=">>" class="do-next-page">
|
||||
</div>
|
||||
|
||||
<div id="progress" class="dialog">
|
||||
<h1 class="title">
|
||||
|
@ -167,4 +84,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||
|
||||
<% e.begin_block("styles"); %>
|
||||
<link href="../static/css/pad.css" rel="stylesheet">
|
||||
<link href="../static/custom/pad.css" rel="stylesheet">
|
||||
<style title="dynamicsyntax"></style>
|
||||
<link href="../static/css/pad.css" rel="stylesheet">
|
||||
<link href="../static/custom/pad.css" rel="stylesheet">
|
||||
<style title="dynamicsyntax"></style>
|
||||
<% e.end_block(); %>
|
||||
|
||||
<!-- head and body had been removed intentionally -->
|
||||
|
@ -21,70 +21,68 @@
|
|||
<% e.begin_block("body"); %>
|
||||
<div id="editbar" class="toolbar">
|
||||
<ul class="menu_left">
|
||||
<% e.begin_block("editbarMenuLeft"); %>
|
||||
<li id="bold" onClick="window.pad&&pad.editbarClick('bold');return false">
|
||||
<a class="buttonicon buttonicon-bold" title="Bold (ctrl-B)"></a>
|
||||
</li>
|
||||
<li id="italic" onClick="window.pad&&pad.editbarClick('italic'); return false;">
|
||||
<a class="buttonicon buttonicon-italic" title="Italics (ctrl-I)"></a>
|
||||
</li>
|
||||
<li id="underline" onClick="window.pad&&pad.editbarClick('underline');return false;" >
|
||||
<a class="buttonicon buttonicon-underline" title="Underline (ctrl-U)"></a>
|
||||
</li>
|
||||
<li id="strikethrough" onClick="window.pad&&pad.editbarClick('strikethrough');return false;">
|
||||
<a class="buttonicon buttonicon-strikethrough" title="Strikethrough"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="oderedlist" onClick="window.pad&&pad.editbarClick('insertorderedlist');return false;">
|
||||
<a class="buttonicon buttonicon-insertorderedlist" title="Toggle Ordered List"></a>
|
||||
</li>
|
||||
<li id="unoderedlist" onClick="window.pad&&pad.editbarClick('insertunorderedlist');return false;">
|
||||
<a class="buttonicon buttonicon-insertunorderedlist" title="Toggle Bullet List"></a>
|
||||
</li>
|
||||
<li id="indent" onClick="window.pad&&pad.editbarClick('indent');return false;">
|
||||
<a class="buttonicon buttonicon-indent" title="Indent"></a>
|
||||
</li>
|
||||
<li id="outdent" onClick="window.pad&&pad.editbarClick('outdent');return false;">
|
||||
<a class="buttonicon buttonicon-outdent" title="Unindent"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="undo" onClick="window.pad&&pad.editbarClick('undo');return false;">
|
||||
<a class="buttonicon buttonicon-undo" title="Undo (ctrl-Z)"></a>
|
||||
</li>
|
||||
<li id="redo" onClick="window.pad&&pad.editbarClick('redo');return false;">
|
||||
<a class="buttonicon buttonicon-redo" title="Redo (ctrl-Y)"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="clearAuthorship" onClick="window.pad&&pad.editbarClick('clearauthorship');return false;">
|
||||
<a class="buttonicon buttonicon-clearauthorship" title="Clear Authorship Colors"></a>
|
||||
</li>
|
||||
<% e.end_block(); %>
|
||||
</ul>
|
||||
<% e.begin_block("editbarMenuLeft"); %>
|
||||
<li id="bold" onClick="window.pad&&pad.editbarClick('bold');return false">
|
||||
<a class="buttonicon buttonicon-bold" title="Bold (ctrl-B)"></a>
|
||||
</li>
|
||||
<li id="italic" onClick="window.pad&&pad.editbarClick('italic'); return false;">
|
||||
<a class="buttonicon buttonicon-italic" title="Italics (ctrl-I)"></a>
|
||||
</li>
|
||||
<li id="underline" onClick="window.pad&&pad.editbarClick('underline');return false;" >
|
||||
<a class="buttonicon buttonicon-underline" title="Underline (ctrl-U)"></a>
|
||||
</li>
|
||||
<li id="strikethrough" onClick="window.pad&&pad.editbarClick('strikethrough');return false;">
|
||||
<a class="buttonicon buttonicon-strikethrough" title="Strikethrough"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="oderedlist" onClick="window.pad&&pad.editbarClick('insertorderedlist');return false;">
|
||||
<a class="buttonicon buttonicon-insertorderedlist" title="Toggle Ordered List"></a>
|
||||
</li>
|
||||
<li id="unoderedlist" onClick="window.pad&&pad.editbarClick('insertunorderedlist');return false;">
|
||||
<a class="buttonicon buttonicon-insertunorderedlist" title="Toggle Bullet List"></a>
|
||||
</li>
|
||||
<li id="indent" onClick="window.pad&&pad.editbarClick('indent');return false;">
|
||||
<a class="buttonicon buttonicon-indent" title="Indent"></a>
|
||||
</li>
|
||||
<li id="outdent" onClick="window.pad&&pad.editbarClick('outdent');return false;">
|
||||
<a class="buttonicon buttonicon-outdent" title="Unindent"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="undo" onClick="window.pad&&pad.editbarClick('undo');return false;">
|
||||
<a class="buttonicon buttonicon-undo" title="Undo (ctrl-Z)"></a>
|
||||
</li>
|
||||
<li id="redo" onClick="window.pad&&pad.editbarClick('redo');return false;">
|
||||
<a class="buttonicon buttonicon-redo" title="Redo (ctrl-Y)"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="clearAuthorship" onClick="window.pad&&pad.editbarClick('clearauthorship');return false;">
|
||||
<a class="buttonicon buttonicon-clearauthorship" title="Clear Authorship Colors"></a>
|
||||
</li>
|
||||
<% e.end_block(); %>
|
||||
</ul>
|
||||
<ul class="menu_right">
|
||||
<% e.begin_block("editbarMenuRight"); %>
|
||||
<li onClick="window.pad&&pad.editbarClick('savedRevision');return false;">
|
||||
<a id="settingslink" title="Mark this revision as a saved revision">
|
||||
<div class="buttonicon buttonicon-savedRevision"></div>
|
||||
</a>
|
||||
</li>
|
||||
<li id="settingslink" onClick="window.pad&&pad.editbarClick('settings');return false;">
|
||||
<a class="buttonicon buttonicon-settings" id="settingslink" title="Settings of this pad"></a>
|
||||
</li>
|
||||
<li id="importexportlink" onClick="window.pad&&pad.editbarClick('import_export');return false;">
|
||||
<a class="buttonicon buttonicon-import_export" id="exportlink" title="Import/Export from/to different document formats"></a>
|
||||
</li>
|
||||
<li id="embedlink" onClick="window.pad&&pad.editbarClick('embed');return false;" >
|
||||
<a class="buttonicon buttonicon-embed" id="embedlink" title="Share and Embed this pad"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="timesliderlink" onClick="document.location = document.location.pathname+ '/timeslider'">
|
||||
<a class="buttonicon buttonicon-history" title="Show the history of this pad"></a>
|
||||
</li>
|
||||
<li id="usericon" onClick="window.pad&&pad.editbarClick('showusers');return false;" title="Show connected users">
|
||||
<span class="buttonicon buttonicon-showusers" id="usericonback"></span>
|
||||
<span id="online_count">1</span>
|
||||
</li>
|
||||
<% e.end_block(); %>
|
||||
<% e.begin_block("editbarMenuRight"); %>
|
||||
<li id="settingslink" onClick="window.pad&&pad.editbarClick('settings');return false;">
|
||||
<a class="buttonicon buttonicon-settings" title="Settings of this pad"></a>
|
||||
</li>
|
||||
<li id="importexportlink" onClick="window.pad&&pad.editbarClick('import_export');return false;">
|
||||
<a class="buttonicon buttonicon-import_export" title="Import/Export from/to different document formats"></a>
|
||||
</li>
|
||||
<li id="embedlink" onClick="window.pad&&pad.editbarClick('embed');return false;">
|
||||
<a class="buttonicon buttonicon-embed" title="Share and Embed this pad"></a>
|
||||
</li>
|
||||
<li id="revisionlink" onClick="window.pad&&pad.editbarClick('savedRevision');return false;">
|
||||
<a class="buttonicon buttonicon-savedRevision" title="Mark this revision as a saved revision"></a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="timesliderlink" onClick="document.location = document.location.pathname+ '/timeslider'">
|
||||
<a class="buttonicon buttonicon-history" title="Show the history of this pad"></a>
|
||||
</li>
|
||||
<li id="usericon" onClick="window.pad&&pad.editbarClick('showusers');return false;" title="Show connected users">
|
||||
<span class="buttonicon buttonicon-showusers" id="usericonback"></span>
|
||||
<span id="online_count">1</span>
|
||||
</li>
|
||||
<% e.end_block(); %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -96,17 +94,17 @@
|
|||
<button id="mycolorpickersave">Save</button>
|
||||
<button id="mycolorpickercancel">Cancel</button>
|
||||
<span id="mycolorpickerpreview" class="myswatchboxhoverable"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="myswatchbox"><div id="myswatch"></div></div>
|
||||
<div id="myusernameform"><input type="text" id="myusernameedit" disabled="disabled"></div>
|
||||
<div id="mystatusform"><input type="text" id="mystatusedit" disabled="disabled"></div>
|
||||
<div id="mystatusform"><input type="text" id="mystatusedit" disabled="disabled"></div>
|
||||
</div>
|
||||
<div id="otherusers">
|
||||
<div id="guestprompts"></div>
|
||||
<table id="otheruserstable" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr><td></td></tr>
|
||||
</table>
|
||||
<div id="nootherusers"></div>
|
||||
<div id="nootherusers"></div>
|
||||
</div>
|
||||
<div id="userlistbuttonarea"></div>
|
||||
</div>
|
||||
|
@ -116,7 +114,7 @@
|
|||
<div id="editorloadingbox">Loading...</div>
|
||||
</div>
|
||||
|
||||
<div id="settingsmenu" class="popup">
|
||||
<div id="settings" class="popup">
|
||||
<h1>Pad settings</h1>
|
||||
<div class="column">
|
||||
<% e.begin_block("mySettings"); %>
|
||||
|
@ -156,20 +154,20 @@
|
|||
<% e.begin_block("importColumn"); %>
|
||||
<h2>Import from text file, HTML, PDF, Word, ODT or RTF</h2><br>
|
||||
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
|
||||
<div class="importformdiv" id="importformfilediv">
|
||||
<input type="file" name="file" size="15" id="importfileinput">
|
||||
<div class="importmessage" id="importmessagefail"></div>
|
||||
</div>
|
||||
<div class="importformdiv" id="importformfilediv">
|
||||
<input type="file" name="file" size="15" id="importfileinput">
|
||||
<div class="importmessage" id="importmessagefail"></div>
|
||||
</div>
|
||||
<div id="import"></div>
|
||||
<div class="importmessage" id="importmessagesuccess">Successful!</div>
|
||||
<div class="importformdiv" id="importformsubmitdiv">
|
||||
<input type="hidden" name="padId" value="blpmaXT35R">
|
||||
<span class="nowrap">
|
||||
<input type="submit" name="submit" value="Import Now" disabled="disabled" id="importsubmitinput">
|
||||
<img alt="" id="importstatusball" src="../static/img/loading.gif" align="top">
|
||||
<img alt="" id="importarrow" src="../static/img/leftarrow.png" align="top">
|
||||
</span>
|
||||
</div>
|
||||
<div class="importmessage" id="importmessagesuccess">Successful!</div>
|
||||
<div class="importformdiv" id="importformsubmitdiv">
|
||||
<input type="hidden" name="padId" value="blpmaXT35R">
|
||||
<span class="nowrap">
|
||||
<input type="submit" name="submit" value="Import Now" disabled="disabled" id="importsubmitinput">
|
||||
<img alt="" id="importstatusball" src="../static/img/loading.gif" align="top">
|
||||
<img alt="" id="importarrow" src="../static/img/leftarrow.png" align="top">
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<% e.end_block(); %>
|
||||
</div>
|
||||
|
@ -234,80 +232,90 @@
|
|||
<div id="modaloverlay">
|
||||
<div id="modaloverlay-inner"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="mainmodals">
|
||||
<% e.begin_block("modals"); %>
|
||||
<div id="connectionbox" class="modaldialog">
|
||||
<div id="connectionboxinner" class="modaldialog-inner">
|
||||
<div class="connecting">Connecting...</div>
|
||||
<div class="reconnecting">Reestablishing connection...</div>
|
||||
<div class="disconnected">
|
||||
<h2 class="h2_disconnect">Disconnected.</h2>
|
||||
<h2 class="h2_userdup">Opened in another window.</h2>
|
||||
<h2 class="h2_unauth">No Authorization.</h2>
|
||||
<div id="disconnected_looping">
|
||||
<p><b>We're having trouble talking to the EtherPad lite synchronization server.</b> You may be connecting through an incompatible firewall or proxy server.</p>
|
||||
</div>
|
||||
<div id="disconnected_initsocketfail">
|
||||
<p><b>We were unable to connect to the EtherPad lite synchronization server.</b> This may be due to an incompatibility with your web browser or internet connection.</p>
|
||||
</div>
|
||||
<div id="disconnected_userdup">
|
||||
<p><b>You seem to have opened this pad in another browser window.</b> If you'd like to use this window instead, you can reconnect.</p>
|
||||
</div>
|
||||
<div id="disconnected_unknown">
|
||||
<p><b>Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity.</p>
|
||||
</div>
|
||||
<div id="disconnected_slowcommit">
|
||||
<p><b>Server not responding.</b> This may be due to network connectivity issues or high load on the server.</p>
|
||||
</div>
|
||||
<div id="disconnected_unauth">
|
||||
<p>Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.</p>
|
||||
</div>
|
||||
<div id="disconnected_deleted">
|
||||
<p>This pad was deleted.</p>
|
||||
</div>
|
||||
<div id="reconnect_advise">
|
||||
<p>If this continues to happen, please let us know</p>
|
||||
</div>
|
||||
<div id="reconnect_form">
|
||||
<button id="forcereconnect">Reconnect Now</button>
|
||||
</div>
|
||||
<div id="connectionbox" class="modaldialog">
|
||||
<div id="connectionboxinner" class="modaldialog-inner">
|
||||
<div class="connecting">Connecting...</div>
|
||||
<div class="reconnecting">Reestablishing connection...</div>
|
||||
<div class="disconnected">
|
||||
<h2 class="h2_disconnect">Disconnected.</h2>
|
||||
<h2 class="h2_userdup">Opened in another window.</h2>
|
||||
<h2 class="h2_unauth">No Authorization.</h2>
|
||||
<div id="disconnected_looping">
|
||||
<p><b>We're having trouble talking to the EtherPad lite synchronization server.</b> You may be connecting through an incompatible firewall or proxy server.</p>
|
||||
</div>
|
||||
<div id="disconnected_initsocketfail">
|
||||
<p><b>We were unable to connect to the EtherPad lite synchronization server.</b> This may be due to an incompatibility with your web browser or internet connection.</p>
|
||||
</div>
|
||||
<div id="disconnected_userdup">
|
||||
<p><b>You seem to have opened this pad in another browser window.</b> If you'd like to use this window instead, you can reconnect.</p>
|
||||
</div>
|
||||
<div id="disconnected_unknown">
|
||||
<p><b>Lost connection with the EtherPad lite synchronization server.</b> This may be due to a loss of network connectivity.</p>
|
||||
</div>
|
||||
<div id="disconnected_slowcommit">
|
||||
<p><b>Server not responding.</b> This may be due to network connectivity issues or high load on the server.</p>
|
||||
</div>
|
||||
<div id="disconnected_unauth">
|
||||
<p>Your browser's credentials or permissions have changed while viewing this pad. Try reconnecting.</p>
|
||||
</div>
|
||||
<div id="disconnected_deleted">
|
||||
<p>This pad was deleted.</p>
|
||||
</div>
|
||||
<div id="reconnect_advise">
|
||||
<p>If this continues to happen, please let us know</p>
|
||||
</div>
|
||||
<div id="reconnect_form">
|
||||
<button id="forcereconnect">Reconnect Now</button>
|
||||
</div>
|
||||
</div>
|
||||
<form id="reconnectform" method="post" action="/ep/pad/reconnect" accept-charset="UTF-8" style="display: none;">
|
||||
<input type="hidden" class="padId" name="padId">
|
||||
<input type="hidden" class="diagnosticInfo" name="diagnosticInfo">
|
||||
<input type="hidden" class="missedChanges" name="missedChanges">
|
||||
</form>
|
||||
</div>
|
||||
<form id="reconnectform" method="post" action="/ep/pad/reconnect" accept-charset="UTF-8" style="display: none;">
|
||||
<input type="hidden" class="padId" name="padId">
|
||||
<input type="hidden" class="diagnosticInfo" name="diagnosticInfo">
|
||||
<input type="hidden" class="missedChanges" name="missedChanges">
|
||||
</form>
|
||||
</div>
|
||||
<% e.end_block(); %>
|
||||
</div>
|
||||
<% e.end_block(); %>
|
||||
|
||||
<% e.begin_block("scripts"); %>
|
||||
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
|
||||
<script type="text/javascript" src="../static/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="../javascripts/lib/ep_etherpad-lite/static/js/pad.js?callback=require.define"></script>
|
||||
<script type="text/javascript">
|
||||
document.domain = document.domain;
|
||||
var clientVars = {};
|
||||
(function () {
|
||||
require.setRootURI("../javascripts/src");
|
||||
require.setLibraryURI("../javascripts/lib");
|
||||
require.setGlobalKeyPath("require");
|
||||
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
|
||||
<script type="text/javascript" src="../static/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="../javascripts/lib/ep_etherpad-lite/static/js/pad.js?callback=require.define"></script>
|
||||
<script type="text/javascript">
|
||||
document.domain = document.domain;
|
||||
var clientVars = {};
|
||||
(function () {
|
||||
|
||||
|
||||
var pathComponents = location.pathname.split('/');
|
||||
|
||||
// Strip 'p' and the padname from the pathname and set as baseURL
|
||||
var baseURL = pathComponents.slice(0,pathComponents.length-2).join('/') + '/';
|
||||
|
||||
require.setRootURI(baseURL + "javascripts/src");
|
||||
require.setLibraryURI(baseURL + "javascripts/lib");
|
||||
require.setGlobalKeyPath("require");
|
||||
|
||||
var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins');
|
||||
plugins.update(function () {
|
||||
require('ep_etherpad-lite/static/js/pad').init();
|
||||
});
|
||||
var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins');
|
||||
plugins.baseURL = baseURL;
|
||||
plugins.update(function () {
|
||||
var pad = require('ep_etherpad-lite/static/js/pad');
|
||||
pad.baseURL = baseURL;
|
||||
pad.init();
|
||||
});
|
||||
|
||||
/* TODO: These globals shouldn't exist. */
|
||||
pad = require('ep_etherpad-lite/static/js/pad').pad;
|
||||
chat = require('ep_etherpad-lite/static/js/chat').chat;
|
||||
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
|
||||
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
|
||||
}());
|
||||
</script>
|
||||
/* TODO: These globals shouldn't exist. */
|
||||
pad = require('ep_etherpad-lite/static/js/pad').pad;
|
||||
chat = require('ep_etherpad-lite/static/js/chat').chat;
|
||||
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
|
||||
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
|
||||
}());
|
||||
</script>
|
||||
<% e.end_block(); %>
|
||||
</html>
|
||||
|
|
|
@ -123,22 +123,35 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="../../../static/js/require-kernel.js"></script>
|
||||
<script type="text/javascript" src="../../../static/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../../../socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="../../../javascripts/lib/ep_etherpad-lite/static/js/timeslider.js?callback=require.define"></script>
|
||||
<script type="text/javascript" src="../../../static/custom/timeslider.js"></script>
|
||||
<script type="text/javascript" src="../../static/js/require-kernel.js"></script>
|
||||
<script type="text/javascript" src="../../static/js/jquery.js"></script>
|
||||
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
|
||||
<script type="text/javascript" src="../../javascripts/lib/ep_etherpad-lite/static/js/timeslider.js?callback=require.define"></script>
|
||||
<script type="text/javascript" src="../../static/custom/timeslider.js"></script>
|
||||
|
||||
<script type="text/javascript" >
|
||||
document.domain = document.domain;
|
||||
var clientVars = {};
|
||||
|
||||
(function () {
|
||||
require.setRootURI("../../../javascripts/src");
|
||||
require.setLibraryURI("../../../javascripts/lib");
|
||||
|
||||
var pathComponents = location.pathname.split('/');
|
||||
|
||||
// Strip 'p', the padname and 'timeslider' from the pathname and set as baseURL
|
||||
var baseURL = pathComponents.slice(0,pathComponents.length-3).join('/') + '/';
|
||||
|
||||
|
||||
require.setRootURI(baseURL + "javascripts/src");
|
||||
require.setLibraryURI(baseURL + "javascripts/lib");
|
||||
require.setGlobalKeyPath("require");
|
||||
|
||||
var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins');
|
||||
plugins.baseURL = baseURL;
|
||||
|
||||
plugins.update(function () {
|
||||
require('ep_etherpad-lite/static/js/timeslider').init();
|
||||
var timeslider = require('ep_etherpad-lite/static/js/timeslider')
|
||||
timeslider.baseURL = baseURL;
|
||||
timeslider.init();
|
||||
|
||||
/* TODO: These globals shouldn't exist. */
|
||||
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
|
||||
|
|
Loading…
Reference in New Issue