Merge with upstream develop.

This commit is contained in:
Mikk Andresen 2018-04-02 13:47:16 +03:00
commit 6f2466bebc
141 changed files with 4084 additions and 778 deletions

View file

@ -592,6 +592,11 @@ Pad.prototype.copy = function copy(destinationID, force, callback) {
setTimeout(function(){
padManager.getPad(destinationID, null, callback) // this runs too early.
},10);
},
// let the plugins know the pad was copied
function(callback) {
hooks.callAll('padCopy', { 'originalPad': _this, 'destinationID': destinationID });
callback();
}
// series
], function(err)

View file

@ -31,7 +31,7 @@ var authLogger = log4js.getLogger("auth");
/**
* This function controlls the access to a pad, it checks if the user can access a pad.
* @param padID the pad the user wants to access
* @param sesssionID the session the user has (set via api)
* @param sessionCookie the session the user has (set via api)
* @param token the token of the author (randomly generated at client side, used for public pads)
* @param password the password the user has given to access this pad, can be null
* @param callback will be called with (err, {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx})

View file

@ -56,10 +56,14 @@ exports.doImport = function(req, res, padId)
, pad
, text
, importHandledByPlugin
, directDatabaseAccess;
, directDatabaseAccess
, useAbiword;
var randNum = Math.floor(Math.random()*0xFFFFFFFF);
// setting flag for whether to use abiword or not
useAbiword = (abiword != null);
async.series([
//save the uploaded file to /tmp
function(callback) {
@ -147,9 +151,9 @@ exports.doImport = function(req, res, padId)
var fileEnding = path.extname(srcFile).toLowerCase();
var fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm");
var fileIsTXT = (fileEnding === ".txt");
if (fileIsTXT) abiword = false; // Don't use abiword for text files
if (fileIsTXT) useAbiword = false; // Don't use abiword for text files
// See https://github.com/ether/etherpad-lite/issues/2572
if (abiword && !fileIsHTML) {
if (useAbiword && !fileIsHTML) {
abiword.convertFile(srcFile, destFile, "htm", function(err) {
//catch convert errors
if(err) {
@ -169,7 +173,7 @@ exports.doImport = function(req, res, padId)
},
function(callback) {
if (!abiword && !directDatabaseAccess){
if (!useAbiword && !directDatabaseAccess){
// Read the file with no encoding for raw buffer access.
fs.readFile(destFile, function(err, buf) {
if (err) throw err;
@ -228,7 +232,7 @@ exports.doImport = function(req, res, padId)
function(callback) {
if(!directDatabaseAccess){
var fileEnding = path.extname(srcFile).toLowerCase();
if (importHandledByPlugin || abiword || fileEnding == ".htm" || fileEnding == ".html") {
if (importHandledByPlugin || useAbiword || fileEnding == ".htm" || fileEnding == ".html") {
importHtml.setPadHTML(pad, text, function(e){
if(e) apiLogger.warn("Error importing, possibly caused by malformed HTML");
});

View file

@ -936,7 +936,7 @@ function handleSwitchToPad(client, message)
var currentSession = sessioninfos[client.id];
var padId = currentSession.padId;
var roomClients = _getRoomClients(padId);
async.forEach(roomClients, function(client, callback) {
var sinfo = sessioninfos[client.id];
if(sinfo && sinfo.author == currentSession.author) {
@ -1115,7 +1115,7 @@ function handleClientReady(client, message)
//Check if this author is already on the pad, if yes, kick the other sessions!
var roomClients = _getRoomClients(pad.id);
async.forEach(roomClients, function(client, callback) {
var sinfo = sessioninfos[client.id];
if(sinfo && sinfo.author == author) {
@ -1176,6 +1176,7 @@ function handleClientReady(client, message)
"accountPrivs": {
"maxRevisions": 100
},
"automaticReconnectionTimeout": settings.automaticReconnectionTimeout,
"initialRevisionList": [],
"initialOptions": {
"guestPolicy": "deny"
@ -1196,6 +1197,7 @@ function handleClientReady(client, message)
"userColor": authorColorId,
"padId": message.padId,
"padOptions": settings.padOptions,
"padShortcutEnabled": settings.padShortcutEnabled,
"initialTitle": "Pad: " + message.padId,
"opts": {},
// tell the client the number of the latest chat-message, which will be
@ -1214,6 +1216,15 @@ function handleClientReady(client, message)
"parts": plugins.parts,
},
"indentationOnNewLine": settings.indentationOnNewLine,
"scrollWhenFocusLineIsOutOfViewport": {
"percentage" : {
"editionAboveViewport": settings.scrollWhenFocusLineIsOutOfViewport.percentage.editionAboveViewport,
"editionBelowViewport": settings.scrollWhenFocusLineIsOutOfViewport.percentage.editionBelowViewport,
},
"duration": settings.scrollWhenFocusLineIsOutOfViewport.duration,
"scrollWhenCaretIsInTheLastLineOfViewport": settings.scrollWhenFocusLineIsOutOfViewport.scrollWhenCaretIsInTheLastLineOfViewport,
"percentageToScrollWhenUserPressesArrowUp": settings.scrollWhenFocusLineIsOutOfViewport.percentageToScrollWhenUserPressesArrowUp,
},
"initialChangesets": [] // FIXME: REMOVE THIS SHIT
}
@ -1676,13 +1687,13 @@ function composePadChangesets(padId, startNum, endNum, callback)
function _getRoomClients(padID) {
var roomClients = []; var room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room.sockets) {
roomClients.push(socketio.sockets.sockets[id]);
}
}
return roomClients;
}

View file

@ -3,6 +3,7 @@ var apiLogger = log4js.getLogger("API");
var clientLogger = log4js.getLogger("client");
var formidable = require('formidable');
var apiHandler = require('../../handler/APIHandler');
var isVarName = require('is-var-name');
//This is for making an api call, collecting all post information and passing it to the apiHandler
var apiCaller = function(req, res, fields) {
@ -18,7 +19,7 @@ var apiCaller = function(req, res, fields) {
apiLogger.info("RESPONSE, " + req.params.func + ", " + response);
//is this a jsonp call, if yes, add the function call
if(req.query.jsonp)
if(req.query.jsonp && isVarName(response))
response = req.query.jsonp + "(" + response + ")";
res._____send(response);

View file

@ -49,5 +49,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
//sigint is so far not working on windows
//https://github.com/joyent/node/issues/1553
process.on('SIGINT', exports.gracefulShutdown);
// when running as PID1 (e.g. in docker container)
// allow graceful shutdown on SIGTERM c.f. #3265
process.on('SIGTERM', exports.gracefulShutdown);
}
}

View file

@ -116,7 +116,7 @@ exports.expressConfigure = function (hook_name, args, cb) {
if (!exports.sessionStore) {
exports.sessionStore = new ueberStore();
exports.secret = settings.sessionKey; // Isn't this being reset each time the server spawns?
exports.secret = settings.sessionKey;
}
args.app.sessionStore = exports.sessionStore;

View file

@ -34,5 +34,10 @@ for ( var i = 0; i < argv.length; i++ ) {
exports.argv.settings = arg;
}
// Override location of credentials.json file
if ( prevArg == '--credentials' ) {
exports.argv.credentials = arg;
}
prevArg = arg;
}

View file

@ -23,9 +23,9 @@ var ERR = require("async-stacktrace");
var settings = require('./Settings');
var async = require('async');
var fs = require('fs');
var StringDecoder = require('string_decoder').StringDecoder;
var CleanCSS = require('clean-css');
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
var uglifyJS = require("uglify-js");
var path = require('path');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var RequireKernel = require('etherpad-require-kernel');
@ -400,10 +400,10 @@ function getFile(filename, callback) {
function compressJS(content)
{
var ast = jsp.parse(content); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
return pro.gen_code(ast); // compressed code here
var decoder = new StringDecoder('utf8');
var code = decoder.write(content); // convert from buffer to string
var codeMinified = uglifyJS.minify(code, {fromString: true}).code;
return codeMinified;
}
function compressCSS(filename, content, callback)

View file

@ -100,7 +100,35 @@ exports.padOptions = {
"alwaysShowChat": false,
"chatAndUsers": false,
"lang": "en-gb"
}
},
/**
* Whether certain shortcut keys are enabled for a user in the pad
*/
exports.padShortcutEnabled = {
"altF9" : true,
"altC" : true,
"delete" : true,
"cmdShift2" : true,
"return" : true,
"esc" : true,
"cmdS" : true,
"tab" : true,
"cmdZ" : true,
"cmdY" : true,
"cmdB" : true,
"cmdI" : true,
"cmdU" : true,
"cmd5" : true,
"cmdShiftL" : true,
"cmdShiftN" : true,
"cmdShift1" : true,
"cmdShiftC" : true,
"cmdH" : true,
"ctrlHome" : true,
"pageUp" : true,
"pageDown" : true,
},
/**
* The toolbar buttons and order.
@ -177,6 +205,11 @@ exports.loglevel = "INFO";
*/
exports.disableIPlogging = false;
/**
* Number of seconds to automatically reconnect pad
*/
exports.automaticReconnectionTimeout = 0;
/**
* Disable Load Testing
*/
@ -214,6 +247,33 @@ exports.users = {};
*/
exports.showSettingsInAdminPage = true;
/*
* By default, when caret is moved out of viewport, it scrolls the minimum height needed to make this
* line visible.
*/
exports.scrollWhenFocusLineIsOutOfViewport = {
/*
* Percentage of viewport height to be additionally scrolled.
*/
"percentage": {
"editionAboveViewport": 0,
"editionBelowViewport": 0
},
/*
* Time (in milliseconds) used to animate the scroll transition. Set to 0 to disable animation
*/
"duration": 0,
/*
* Flag to control if it should scroll when user places the caret in the last line of the viewport
*/
/*
* Percentage of viewport height to be additionally scrolled when user presses arrow up
* in the line of the top of the viewport.
*/
"percentageToScrollWhenUserPressesArrowUp": 0,
"scrollWhenCaretIsInTheLastLineOfViewport": false
};
//checks if abiword is avaiable
exports.abiwordAvailable = function()
{