mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
lint: pad prefix files (#4577)
* lint: pad_connectionstatus * lint: pad_utils * lint: pad_userlist.js -- still WIP * shift underscore not to be in require but to be used from window * lint: pad_modals * pad_impexp.js * lint: more errors done * lint: auto reconn * lint: pad_editor * lint: finish auto reconn * lint: imp exp rework * lint: import * lint: pad.js nearly done but pizza here... * lint: clientVars global query * put clientVars in window * Revert incorrect lint fixes * Properly fix guard-for-in lint errors * Properly fix no-unused-vars error regarding `gritter` * Refine lint fixes Co-authored-by: Richard Hansen <rhansen@rhansen.org>
This commit is contained in:
parent
34ee77993f
commit
0362d3b05d
11 changed files with 512 additions and 459 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -20,8 +22,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global $, window */
|
|
||||||
|
|
||||||
let socket;
|
let socket;
|
||||||
|
|
||||||
// These jQuery things should create local references, but for now `require()`
|
// These jQuery things should create local references, but for now `require()`
|
||||||
|
@ -43,24 +43,13 @@ const padsavedrevs = require('./pad_savedrevs');
|
||||||
const paduserlist = require('./pad_userlist').paduserlist;
|
const paduserlist = require('./pad_userlist').paduserlist;
|
||||||
const padutils = require('./pad_utils').padutils;
|
const padutils = require('./pad_utils').padutils;
|
||||||
const colorutils = require('./colorutils').colorutils;
|
const colorutils = require('./colorutils').colorutils;
|
||||||
var randomString = require('./pad_utils').randomString;
|
const randomString = require('./pad_utils').randomString;
|
||||||
const gritter = require('./gritter').gritter;
|
require('./gritter'); // Mutates the jQuery object to make $.gritter available.
|
||||||
|
|
||||||
const hooks = require('./pluginfw/hooks');
|
const hooks = require('./pluginfw/hooks');
|
||||||
|
|
||||||
let receivedClientVars = false;
|
let receivedClientVars = false;
|
||||||
|
|
||||||
function randomString() {
|
|
||||||
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
||||||
const string_length = 20;
|
|
||||||
let randomstring = '';
|
|
||||||
for (let i = 0; i < string_length; i++) {
|
|
||||||
const rnum = Math.floor(Math.random() * chars.length);
|
|
||||||
randomstring += chars.substring(rnum, rnum + 1);
|
|
||||||
}
|
|
||||||
return `t.${randomstring}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This array represents all GET-parameters which can be used to change a setting.
|
// This array represents all GET-parameters which can be used to change a setting.
|
||||||
// name: the parameter-name, eg `?noColors=true` => `noColors`
|
// name: the parameter-name, eg `?noColors=true` => `noColors`
|
||||||
// checkVal: the callback is only executed when
|
// checkVal: the callback is only executed when
|
||||||
|
@ -68,26 +57,101 @@ function randomString() {
|
||||||
// * the parameter was supplied and checkVal is null
|
// * the parameter was supplied and checkVal is null
|
||||||
// callback: the function to call when all above succeeds, `val` is the value supplied by the user
|
// callback: the function to call when all above succeeds, `val` is the value supplied by the user
|
||||||
const getParameters = [
|
const getParameters = [
|
||||||
{name: 'noColors', checkVal: 'true', callback(val) { settings.noColors = true; $('#clearAuthorship').hide(); }},
|
{
|
||||||
{name: 'showControls', checkVal: 'true', callback(val) { $('#editbar').css('display', 'flex'); }},
|
name: 'noColors',
|
||||||
{name: 'showChat', checkVal: null, callback(val) { if (val === 'false') { settings.hideChat = true; chat.hide(); $('#chaticon').hide(); } }},
|
checkVal: 'true',
|
||||||
{name: 'showLineNumbers', checkVal: 'false', callback(val) { settings.LineNumbersDisabled = true; }},
|
callback: (val) => {
|
||||||
{name: 'useMonospaceFont', checkVal: 'true', callback(val) { settings.useMonospaceFontGlobal = true; }},
|
settings.noColors = true;
|
||||||
// If the username is set as a parameter we should set a global value that we can call once we have initiated the pad.
|
$('#clearAuthorship').hide();
|
||||||
{name: 'userName', checkVal: null, callback(val) { settings.globalUserName = decodeURIComponent(val); clientVars.userName = decodeURIComponent(val); }},
|
},
|
||||||
// If the userColor is set as a parameter, set a global value to use once we have initiated the pad.
|
},
|
||||||
{name: 'userColor', checkVal: null, callback(val) { settings.globalUserColor = decodeURIComponent(val); clientVars.userColor = decodeURIComponent(val); }},
|
{
|
||||||
{name: 'rtl', checkVal: 'true', callback(val) { settings.rtlIsTrue = true; }},
|
name: 'showControls',
|
||||||
{name: 'alwaysShowChat', checkVal: 'true', callback(val) { if (!settings.hideChat) chat.stickToScreen(); }},
|
checkVal: 'true',
|
||||||
{name: 'chatAndUsers', checkVal: 'true', callback(val) { chat.chatAndUsers(); }},
|
callback: (val) => {
|
||||||
{name: 'lang', checkVal: null, callback(val) { window.html10n.localize([val, 'en']); Cookies.set('language', val); }},
|
$('#editbar').css('display', 'flex');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'showChat',
|
||||||
|
checkVal: null,
|
||||||
|
callback: (val) => {
|
||||||
|
if (val === 'false') {
|
||||||
|
settings.hideChat = true;
|
||||||
|
chat.hide();
|
||||||
|
$('#chaticon').hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'showLineNumbers',
|
||||||
|
checkVal: 'false',
|
||||||
|
callback: (val) => {
|
||||||
|
settings.LineNumbersDisabled = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'useMonospaceFont',
|
||||||
|
checkVal: 'true',
|
||||||
|
callback: (val) => {
|
||||||
|
settings.useMonospaceFontGlobal = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// If the username is set as a parameter we should set a global value that we can call once we
|
||||||
|
// have initiated the pad.
|
||||||
|
{
|
||||||
|
name: 'userName',
|
||||||
|
checkVal: null,
|
||||||
|
callback: (val) => {
|
||||||
|
settings.globalUserName = decodeURIComponent(val);
|
||||||
|
clientVars.userName = decodeURIComponent(val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// If the userColor is set as a parameter, set a global value to use once we have initiated the
|
||||||
|
// pad.
|
||||||
|
{
|
||||||
|
name: 'userColor',
|
||||||
|
checkVal: null,
|
||||||
|
callback: (val) => {
|
||||||
|
settings.globalUserColor = decodeURIComponent(val);
|
||||||
|
clientVars.userColor = decodeURIComponent(val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rtl',
|
||||||
|
checkVal: 'true',
|
||||||
|
callback: (val) => {
|
||||||
|
settings.rtlIsTrue = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'alwaysShowChat',
|
||||||
|
checkVal: 'true',
|
||||||
|
callback: (val) => {
|
||||||
|
if (!settings.hideChat) chat.stickToScreen();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'chatAndUsers',
|
||||||
|
checkVal: 'true',
|
||||||
|
callback: (val) => {
|
||||||
|
chat.chatAndUsers();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'lang',
|
||||||
|
checkVal: null,
|
||||||
|
callback: (val) => {
|
||||||
|
window.html10n.localize([val, 'en']);
|
||||||
|
Cookies.set('language', val);
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function getParams() {
|
const getParams = () => {
|
||||||
// Tries server enforced options first..
|
// Tries server enforced options first..
|
||||||
for (var i = 0; i < getParameters.length; i++) {
|
for (const setting of getParameters) {
|
||||||
var setting = getParameters[i];
|
const value = clientVars.padOptions[setting.name];
|
||||||
var value = clientVars.padOptions[setting.name];
|
|
||||||
if (value.toString() === setting.checkVal) {
|
if (value.toString() === setting.checkVal) {
|
||||||
setting.callback(value);
|
setting.callback(value);
|
||||||
}
|
}
|
||||||
|
@ -96,19 +160,18 @@ function getParams() {
|
||||||
// Then URL applied stuff
|
// Then URL applied stuff
|
||||||
const params = getUrlVars();
|
const params = getUrlVars();
|
||||||
|
|
||||||
for (var i = 0; i < getParameters.length; i++) {
|
for (const setting of getParameters) {
|
||||||
var setting = getParameters[i];
|
const value = params[setting.name];
|
||||||
var value = params[setting.name];
|
|
||||||
|
|
||||||
if (value && (value == setting.checkVal || setting.checkVal == null)) {
|
if (value && (value === setting.checkVal || setting.checkVal == null)) {
|
||||||
setting.callback(value);
|
setting.callback(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function getUrlVars() {
|
const getUrlVars = () => {
|
||||||
const vars = []; let
|
const vars = [];
|
||||||
hash;
|
let hash;
|
||||||
const hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
const hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||||
for (let i = 0; i < hashes.length; i++) {
|
for (let i = 0; i < hashes.length; i++) {
|
||||||
hash = hashes[i].split('=');
|
hash = hashes[i].split('=');
|
||||||
|
@ -116,12 +179,13 @@ function getUrlVars() {
|
||||||
vars[hash[0]] = hash[1];
|
vars[hash[0]] = hash[1];
|
||||||
}
|
}
|
||||||
return vars;
|
return vars;
|
||||||
}
|
};
|
||||||
|
|
||||||
function sendClientReady(isReconnect, messageType) {
|
const sendClientReady = (isReconnect, messageType) => {
|
||||||
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
|
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
|
||||||
let padId = document.location.pathname.substring(document.location.pathname.lastIndexOf('/') + 1);
|
let padId = document.location.pathname.substring(document.location.pathname.lastIndexOf('/') + 1);
|
||||||
padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces
|
// unescape neccesary due to Safari and Opera interpretation of spaces
|
||||||
|
padId = decodeURIComponent(padId);
|
||||||
|
|
||||||
if (!isReconnect) {
|
if (!isReconnect) {
|
||||||
const titleArray = document.title.split('|');
|
const titleArray = document.title.split('|');
|
||||||
|
@ -151,12 +215,12 @@ function sendClientReady(isReconnect, messageType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.json.send(msg);
|
socket.json.send(msg);
|
||||||
}
|
};
|
||||||
|
|
||||||
function handshake() {
|
const handshake = () => {
|
||||||
const loc = document.location;
|
const loc = document.location;
|
||||||
// get the correct port
|
// get the correct port
|
||||||
const port = loc.port == '' ? (loc.protocol == 'https:' ? 443 : 80) : loc.port;
|
const port = loc.port === '' ? (loc.protocol === 'https:' ? 443 : 80) : loc.port;
|
||||||
// create the url
|
// create the url
|
||||||
const url = `${loc.protocol}//${loc.hostname}:${port}/`;
|
const url = `${loc.protocol}//${loc.hostname}:${port}/`;
|
||||||
// find out in which subfolder we are
|
// find out in which subfolder we are
|
||||||
|
@ -211,12 +275,10 @@ function handshake() {
|
||||||
throw new Error(`socket.io connection error: ${JSON.stringify(error)}`);
|
throw new Error(`socket.io connection error: ${JSON.stringify(error)}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
let initalized = false;
|
|
||||||
|
|
||||||
socket.on('message', (obj) => {
|
socket.on('message', (obj) => {
|
||||||
// the access was not granted, give the user a message
|
// the access was not granted, give the user a message
|
||||||
if (obj.accessStatus) {
|
if (obj.accessStatus) {
|
||||||
if (obj.accessStatus == 'deny') {
|
if (obj.accessStatus === 'deny') {
|
||||||
$('#loading').hide();
|
$('#loading').hide();
|
||||||
$('#permissionDenied').show();
|
$('#permissionDenied').show();
|
||||||
|
|
||||||
|
@ -226,18 +288,15 @@ function handshake() {
|
||||||
$('#editorloadingbox').show();
|
$('#editorloadingbox').show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (!receivedClientVars && obj.type === 'CLIENT_VARS') {
|
||||||
|
// if we haven't recieved the clientVars yet, then this message should it be
|
||||||
// if we haven't recieved the clientVars yet, then this message should it be
|
|
||||||
else if (!receivedClientVars && obj.type == 'CLIENT_VARS') {
|
|
||||||
receivedClientVars = true;
|
receivedClientVars = true;
|
||||||
|
|
||||||
// set some client vars
|
// set some client vars
|
||||||
clientVars = obj.data;
|
window.clientVars = obj.data;
|
||||||
|
|
||||||
// initalize the pad
|
// initalize the pad
|
||||||
pad._afterHandshake();
|
pad._afterHandshake();
|
||||||
initalized = true;
|
|
||||||
|
|
||||||
if (clientVars.readonly) {
|
if (clientVars.readonly) {
|
||||||
chat.hide();
|
chat.hide();
|
||||||
|
@ -255,63 +314,61 @@ function handshake() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the LineNumbersDisabled value is set to true then we need to hide the Line Numbers
|
// If the LineNumbersDisabled value is set to true then we need to hide the Line Numbers
|
||||||
if (settings.LineNumbersDisabled == true) {
|
if (settings.LineNumbersDisabled === true) {
|
||||||
pad.changeViewOption('showLineNumbers', false);
|
pad.changeViewOption('showLineNumbers', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the noColors value is set to true then we need to hide the background colors on the ace spans
|
// If the noColors value is set to true then we need to
|
||||||
if (settings.noColors == true) {
|
// hide the background colors on the ace spans
|
||||||
|
if (settings.noColors === true) {
|
||||||
pad.changeViewOption('noColors', true);
|
pad.changeViewOption('noColors', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.rtlIsTrue == true) {
|
if (settings.rtlIsTrue === true) {
|
||||||
pad.changeViewOption('rtlIsTrue', true);
|
pad.changeViewOption('rtlIsTrue', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the Monospacefont value is set to true then change it to monospace.
|
// If the Monospacefont value is set to true then change it to monospace.
|
||||||
if (settings.useMonospaceFontGlobal == true) {
|
if (settings.useMonospaceFontGlobal === true) {
|
||||||
pad.changeViewOption('padFontFamily', 'monospace');
|
pad.changeViewOption('padFontFamily', 'monospace');
|
||||||
}
|
}
|
||||||
// if the globalUserName value is set we need to tell the server and the client about the new authorname
|
// if the globalUserName value is set we need to tell the server and
|
||||||
|
// the client about the new authorname
|
||||||
if (settings.globalUserName !== false) {
|
if (settings.globalUserName !== false) {
|
||||||
pad.notifyChangeName(settings.globalUserName); // Notifies the server
|
pad.notifyChangeName(settings.globalUserName); // Notifies the server
|
||||||
pad.myUserInfo.name = settings.globalUserName;
|
pad.myUserInfo.name = settings.globalUserName;
|
||||||
$('#myusernameedit').val(settings.globalUserName); // Updates the current users UI
|
$('#myusernameedit').val(settings.globalUserName); // Updates the current users UI
|
||||||
}
|
}
|
||||||
if (settings.globalUserColor !== false && colorutils.isCssHex(settings.globalUserColor)) {
|
if (settings.globalUserColor !== false && colorutils.isCssHex(settings.globalUserColor)) {
|
||||||
// Add a 'globalUserColor' property to myUserInfo, so collabClient knows we have a query parameter.
|
// Add a 'globalUserColor' property to myUserInfo,
|
||||||
|
// so collabClient knows we have a query parameter.
|
||||||
pad.myUserInfo.globalUserColor = settings.globalUserColor;
|
pad.myUserInfo.globalUserColor = settings.globalUserColor;
|
||||||
pad.notifyChangeColor(settings.globalUserColor); // Updates pad.myUserInfo.colorId
|
pad.notifyChangeColor(settings.globalUserColor); // Updates pad.myUserInfo.colorId
|
||||||
paduserlist.setMyUserInfo(pad.myUserInfo);
|
paduserlist.setMyUserInfo(pad.myUserInfo);
|
||||||
}
|
}
|
||||||
}
|
} else if (obj.disconnect) {
|
||||||
// This handles every Message after the clientVars
|
padconnectionstatus.disconnected(obj.disconnect);
|
||||||
else {
|
socket.disconnect();
|
||||||
// this message advices the client to disconnect
|
|
||||||
if (obj.disconnect) {
|
|
||||||
padconnectionstatus.disconnected(obj.disconnect);
|
|
||||||
socket.disconnect();
|
|
||||||
|
|
||||||
// block user from making any change to the pad
|
// block user from making any change to the pad
|
||||||
padeditor.disable();
|
padeditor.disable();
|
||||||
padeditbar.disable();
|
padeditbar.disable();
|
||||||
padimpexp.disable();
|
padimpexp.disable();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
pad.collabClient.handleMessageFromServer(obj);
|
pad.collabClient.handleMessageFromServer(obj);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Bind the colorpicker
|
// Bind the colorpicker
|
||||||
const fb = $('#colorpicker').farbtastic({callback: '#mycolorpickerpreview', width: 220});
|
$('#colorpicker').farbtastic({callback: '#mycolorpickerpreview', width: 220});
|
||||||
// Bind the read only button
|
// Bind the read only button
|
||||||
$('#readonlyinput').on('click', () => {
|
$('#readonlyinput').on('click', () => {
|
||||||
padeditbar.setEmbedLinks();
|
padeditbar.setEmbedLinks();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var pad = {
|
const pad = {
|
||||||
// don't access these directly from outside this file, except
|
// don't access these directly from outside this file, except
|
||||||
// for debugging
|
// for debugging
|
||||||
collabClient: null,
|
collabClient: null,
|
||||||
|
@ -322,44 +379,28 @@ var pad = {
|
||||||
padOptions: {},
|
padOptions: {},
|
||||||
|
|
||||||
// these don't require init; clientVars should all go through here
|
// these don't require init; clientVars should all go through here
|
||||||
getPadId() {
|
getPadId: () => clientVars.padId,
|
||||||
return clientVars.padId;
|
getClientIp: () => clientVars.clientIp,
|
||||||
},
|
getColorPalette: () => clientVars.colorPalette,
|
||||||
getClientIp() {
|
getIsDebugEnabled: () => clientVars.debugEnabled,
|
||||||
return clientVars.clientIp;
|
getPrivilege: (name) => clientVars.accountPrivs[name],
|
||||||
},
|
getUserId: () => pad.myUserInfo.userId,
|
||||||
getColorPalette() {
|
getUserName: () => pad.myUserInfo.name,
|
||||||
return clientVars.colorPalette;
|
userList: () => paduserlist.users(),
|
||||||
},
|
switchToPad: (padId) => {
|
||||||
getIsDebugEnabled() {
|
let newHref = new RegExp(/.*\/p\/[^/]+/).exec(document.location.pathname) || clientVars.padId;
|
||||||
return clientVars.debugEnabled;
|
|
||||||
},
|
|
||||||
getPrivilege(name) {
|
|
||||||
return clientVars.accountPrivs[name];
|
|
||||||
},
|
|
||||||
getUserId() {
|
|
||||||
return pad.myUserInfo.userId;
|
|
||||||
},
|
|
||||||
getUserName() {
|
|
||||||
return pad.myUserInfo.name;
|
|
||||||
},
|
|
||||||
userList() {
|
|
||||||
return paduserlist.users();
|
|
||||||
},
|
|
||||||
switchToPad(padId) {
|
|
||||||
let newHref = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId;
|
|
||||||
newHref = newHref[0];
|
newHref = newHref[0];
|
||||||
|
|
||||||
const options = clientVars.padOptions;
|
const options = clientVars.padOptions;
|
||||||
if (typeof options !== 'undefined' && options != null) {
|
if (typeof options !== 'undefined' && options != null) {
|
||||||
var option_str = [];
|
const optionArr = [];
|
||||||
$.each(options, (k, v) => {
|
$.each(options, (k, v) => {
|
||||||
const str = `${k}=${v}`;
|
const str = `${k}=${v}`;
|
||||||
option_str.push(str);
|
optionArr.push(str);
|
||||||
});
|
});
|
||||||
var option_str = option_str.join('&');
|
const optionStr = optionArr.join('&');
|
||||||
|
|
||||||
newHref = `${newHref}?${option_str}`;
|
newHref = `${newHref}?${optionStr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy old pad from DOM
|
// destroy old pad from DOM
|
||||||
|
@ -373,21 +414,21 @@ var pad = {
|
||||||
window.history.pushState('', '', newHref);
|
window.history.pushState('', '', newHref);
|
||||||
receivedClientVars = false;
|
receivedClientVars = false;
|
||||||
sendClientReady(false, 'SWITCH_TO_PAD');
|
sendClientReady(false, 'SWITCH_TO_PAD');
|
||||||
} else // fallback
|
} else {
|
||||||
{
|
// fallback
|
||||||
window.location.href = newHref;
|
window.location.href = newHref;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendClientMessage(msg) {
|
sendClientMessage: (msg) => {
|
||||||
pad.collabClient.sendClientMessage(msg);
|
pad.collabClient.sendClientMessage(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
init() {
|
init: () => {
|
||||||
padutils.setupGlobalExceptionHandler();
|
padutils.setupGlobalExceptionHandler();
|
||||||
|
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
// start the custom js
|
// start the custom js
|
||||||
if (typeof customStart === 'function') customStart();
|
if (typeof customStart === 'function') customStart(); // eslint-disable-line no-undef
|
||||||
handshake();
|
handshake();
|
||||||
|
|
||||||
// To use etherpad you have to allow cookies.
|
// To use etherpad you have to allow cookies.
|
||||||
|
@ -406,7 +447,6 @@ var pad = {
|
||||||
pad.initTime = +(new Date());
|
pad.initTime = +(new Date());
|
||||||
pad.padOptions = clientVars.initialOptions;
|
pad.padOptions = clientVars.initialOptions;
|
||||||
|
|
||||||
// order of inits is important here:
|
|
||||||
pad.myUserInfo = {
|
pad.myUserInfo = {
|
||||||
userId: clientVars.userId,
|
userId: clientVars.userId,
|
||||||
name: clientVars.userName,
|
name: clientVars.userName,
|
||||||
|
@ -414,18 +454,60 @@ var pad = {
|
||||||
colorId: clientVars.userColor,
|
colorId: clientVars.userColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const postAceInit = () => {
|
||||||
|
padeditbar.init();
|
||||||
|
setTimeout(() => {
|
||||||
|
padeditor.ace.focus();
|
||||||
|
}, 0);
|
||||||
|
// if we have a cookie for always showing chat then show it
|
||||||
|
if (padcookie.getPref('chatAlwaysVisible')) {
|
||||||
|
chat.stickToScreen(true); // stick it to the screen
|
||||||
|
$('#options-stickychat').prop('checked', true); // set the checkbox to on
|
||||||
|
}
|
||||||
|
// if we have a cookie for always showing chat then show it
|
||||||
|
if (padcookie.getPref('chatAndUsers')) {
|
||||||
|
chat.chatAndUsers(true); // stick it to the screen
|
||||||
|
$('#options-chatandusers').prop('checked', true); // set the checkbox to on
|
||||||
|
}
|
||||||
|
if (padcookie.getPref('showAuthorshipColors') === false) {
|
||||||
|
pad.changeViewOption('showAuthorColors', false);
|
||||||
|
}
|
||||||
|
if (padcookie.getPref('showLineNumbers') === false) {
|
||||||
|
pad.changeViewOption('showLineNumbers', false);
|
||||||
|
}
|
||||||
|
if (padcookie.getPref('rtlIsTrue') === true) {
|
||||||
|
pad.changeViewOption('rtlIsTrue', true);
|
||||||
|
}
|
||||||
|
pad.changeViewOption('padFontFamily', padcookie.getPref('padFontFamily'));
|
||||||
|
$('#viewfontmenu').val(padcookie.getPref('padFontFamily')).niceSelect('update');
|
||||||
|
|
||||||
|
// Prevent sticky chat or chat and users to be checked for mobiles
|
||||||
|
const checkChatAndUsersVisibility = (x) => {
|
||||||
|
if (x.matches) { // If media query matches
|
||||||
|
$('#options-chatandusers:checked').click();
|
||||||
|
$('#options-stickychat:checked').click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const mobileMatch = window.matchMedia('(max-width: 800px)');
|
||||||
|
mobileMatch.addListener(checkChatAndUsersVisibility); // check if window resized
|
||||||
|
setTimeout(() => { checkChatAndUsersVisibility(mobileMatch); }, 0); // check now after load
|
||||||
|
|
||||||
|
$('#editorcontainer').addClass('initialized');
|
||||||
|
|
||||||
|
hooks.aCallAll('postAceInit', {ace: padeditor.ace, pad});
|
||||||
|
};
|
||||||
|
|
||||||
|
// order of inits is important here:
|
||||||
padimpexp.init(this);
|
padimpexp.init(this);
|
||||||
padsavedrevs.init(this);
|
padsavedrevs.init(this);
|
||||||
|
|
||||||
padeditor.init(postAceInit, pad.padOptions.view || {}, this);
|
padeditor.init(postAceInit, pad.padOptions.view || {}, this);
|
||||||
|
|
||||||
paduserlist.init(pad.myUserInfo, this);
|
paduserlist.init(pad.myUserInfo, this);
|
||||||
padconnectionstatus.init();
|
padconnectionstatus.init();
|
||||||
padmodals.init(this);
|
padmodals.init(this);
|
||||||
|
|
||||||
pad.collabClient = getCollabClient(padeditor.ace, clientVars.collab_client_vars, pad.myUserInfo, {
|
pad.collabClient = getCollabClient(
|
||||||
colorPalette: pad.getColorPalette(),
|
padeditor.ace, clientVars.collab_client_vars, pad.myUserInfo,
|
||||||
}, pad);
|
{colorPalette: pad.getColorPalette()}, pad);
|
||||||
pad.collabClient.setOnUserJoin(pad.handleUserJoin);
|
pad.collabClient.setOnUserJoin(pad.handleUserJoin);
|
||||||
pad.collabClient.setOnUpdateUserInfo(pad.handleUserUpdate);
|
pad.collabClient.setOnUpdateUserInfo(pad.handleUserUpdate);
|
||||||
pad.collabClient.setOnUserLeave(pad.handleUserLeave);
|
pad.collabClient.setOnUserLeave(pad.handleUserLeave);
|
||||||
|
@ -434,68 +516,27 @@ var pad = {
|
||||||
pad.collabClient.setOnInternalAction(pad.handleCollabAction);
|
pad.collabClient.setOnInternalAction(pad.handleCollabAction);
|
||||||
|
|
||||||
// load initial chat-messages
|
// load initial chat-messages
|
||||||
if (clientVars.chatHead != -1) {
|
if (clientVars.chatHead !== -1) {
|
||||||
const chatHead = clientVars.chatHead;
|
const chatHead = clientVars.chatHead;
|
||||||
const start = Math.max(chatHead - 100, 0);
|
const start = Math.max(chatHead - 100, 0);
|
||||||
pad.collabClient.sendMessage({type: 'GET_CHAT_MESSAGES', start, end: chatHead});
|
pad.collabClient.sendMessage({type: 'GET_CHAT_MESSAGES', start, end: chatHead});
|
||||||
} else // there are no messages
|
} else {
|
||||||
{
|
// there are no messages
|
||||||
$('#chatloadmessagesbutton').css('display', 'none');
|
$('#chatloadmessagesbutton').css('display', 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
function postAceInit() {
|
|
||||||
padeditbar.init();
|
|
||||||
setTimeout(() => {
|
|
||||||
padeditor.ace.focus();
|
|
||||||
}, 0);
|
|
||||||
if (padcookie.getPref('chatAlwaysVisible')) { // if we have a cookie for always showing chat then show it
|
|
||||||
chat.stickToScreen(true); // stick it to the screen
|
|
||||||
$('#options-stickychat').prop('checked', true); // set the checkbox to on
|
|
||||||
}
|
|
||||||
if (padcookie.getPref('chatAndUsers')) { // if we have a cookie for always showing chat then show it
|
|
||||||
chat.chatAndUsers(true); // stick it to the screen
|
|
||||||
$('#options-chatandusers').prop('checked', true); // set the checkbox to on
|
|
||||||
}
|
|
||||||
if (padcookie.getPref('showAuthorshipColors') == false) {
|
|
||||||
pad.changeViewOption('showAuthorColors', false);
|
|
||||||
}
|
|
||||||
if (padcookie.getPref('showLineNumbers') == false) {
|
|
||||||
pad.changeViewOption('showLineNumbers', false);
|
|
||||||
}
|
|
||||||
if (padcookie.getPref('rtlIsTrue') == true) {
|
|
||||||
pad.changeViewOption('rtlIsTrue', true);
|
|
||||||
}
|
|
||||||
pad.changeViewOption('padFontFamily', padcookie.getPref('padFontFamily'));
|
|
||||||
$('#viewfontmenu').val(padcookie.getPref('padFontFamily')).niceSelect('update');
|
|
||||||
|
|
||||||
// Prevent sticky chat or chat and users to be checked for mobiles
|
|
||||||
function checkChatAndUsersVisibility(x) {
|
|
||||||
if (x.matches) { // If media query matches
|
|
||||||
$('#options-chatandusers:checked').click();
|
|
||||||
$('#options-stickychat:checked').click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mobileMatch = window.matchMedia('(max-width: 800px)');
|
|
||||||
mobileMatch.addListener(checkChatAndUsersVisibility); // check if window resized
|
|
||||||
setTimeout(() => { checkChatAndUsersVisibility(mobileMatch); }, 0); // check now after load
|
|
||||||
|
|
||||||
$('#editorcontainer').addClass('initialized');
|
|
||||||
|
|
||||||
hooks.aCallAll('postAceInit', {ace: padeditor.ace, pad});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
dispose() {
|
dispose: () => {
|
||||||
padeditor.dispose();
|
padeditor.dispose();
|
||||||
},
|
},
|
||||||
notifyChangeName(newName) {
|
notifyChangeName: (newName) => {
|
||||||
pad.myUserInfo.name = newName;
|
pad.myUserInfo.name = newName;
|
||||||
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
||||||
},
|
},
|
||||||
notifyChangeColor(newColorId) {
|
notifyChangeColor: (newColorId) => {
|
||||||
pad.myUserInfo.colorId = newColorId;
|
pad.myUserInfo.colorId = newColorId;
|
||||||
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
||||||
},
|
},
|
||||||
changePadOption(key, value) {
|
changePadOption: (key, value) => {
|
||||||
const options = {};
|
const options = {};
|
||||||
options[key] = value;
|
options[key] = value;
|
||||||
pad.handleOptionsChange(options);
|
pad.handleOptionsChange(options);
|
||||||
|
@ -506,32 +547,30 @@ var pad = {
|
||||||
changedBy: pad.myUserInfo.name || 'unnamed',
|
changedBy: pad.myUserInfo.name || 'unnamed',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
changeViewOption(key, value) {
|
changeViewOption: (key, value) => {
|
||||||
const options = {
|
const options = {
|
||||||
view: {},
|
view: {},
|
||||||
};
|
};
|
||||||
options.view[key] = value;
|
options.view[key] = value;
|
||||||
pad.handleOptionsChange(options);
|
pad.handleOptionsChange(options);
|
||||||
},
|
},
|
||||||
handleOptionsChange(opts) {
|
handleOptionsChange: (opts) => {
|
||||||
// opts object is a full set of options or just
|
// opts object is a full set of options or just
|
||||||
// some options to change
|
// some options to change
|
||||||
if (opts.view) {
|
if (opts.view) {
|
||||||
if (!pad.padOptions.view) {
|
if (!pad.padOptions.view) {
|
||||||
pad.padOptions.view = {};
|
pad.padOptions.view = {};
|
||||||
}
|
}
|
||||||
for (const k in opts.view) {
|
for (const [k, v] of Object.entries(opts.view)) {
|
||||||
pad.padOptions.view[k] = opts.view[k];
|
pad.padOptions.view[k] = v;
|
||||||
padcookie.setPref(k, opts.view[k]);
|
padcookie.setPref(k, v);
|
||||||
}
|
}
|
||||||
padeditor.setViewOptions(pad.padOptions.view);
|
padeditor.setViewOptions(pad.padOptions.view);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getPadOptions() {
|
// caller shouldn't mutate the object
|
||||||
// caller shouldn't mutate the object
|
getPadOptions: () => pad.padOptions,
|
||||||
return pad.padOptions;
|
suggestUserName: (userId, name) => {
|
||||||
},
|
|
||||||
suggestUserName(userId, name) {
|
|
||||||
pad.collabClient.sendClientMessage(
|
pad.collabClient.sendClientMessage(
|
||||||
{
|
{
|
||||||
type: 'suggestUserName',
|
type: 'suggestUserName',
|
||||||
|
@ -539,31 +578,31 @@ var pad = {
|
||||||
newName: name,
|
newName: name,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleUserJoin(userInfo) {
|
handleUserJoin: (userInfo) => {
|
||||||
paduserlist.userJoinOrUpdate(userInfo);
|
paduserlist.userJoinOrUpdate(userInfo);
|
||||||
},
|
},
|
||||||
handleUserUpdate(userInfo) {
|
handleUserUpdate: (userInfo) => {
|
||||||
paduserlist.userJoinOrUpdate(userInfo);
|
paduserlist.userJoinOrUpdate(userInfo);
|
||||||
},
|
},
|
||||||
handleUserLeave(userInfo) {
|
handleUserLeave: (userInfo) => {
|
||||||
paduserlist.userLeave(userInfo);
|
paduserlist.userLeave(userInfo);
|
||||||
},
|
},
|
||||||
handleClientMessage(msg) {
|
handleClientMessage: (msg) => {
|
||||||
if (msg.type == 'suggestUserName') {
|
if (msg.type === 'suggestUserName') {
|
||||||
if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name) {
|
if (msg.unnamedId === pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name) {
|
||||||
pad.notifyChangeName(msg.newName);
|
pad.notifyChangeName(msg.newName);
|
||||||
paduserlist.setMyUserInfo(pad.myUserInfo);
|
paduserlist.setMyUserInfo(pad.myUserInfo);
|
||||||
}
|
}
|
||||||
} else if (msg.type == 'newRevisionList') {
|
} else if (msg.type === 'newRevisionList') {
|
||||||
padsavedrevs.newRevisionList(msg.revisionList);
|
padsavedrevs.newRevisionList(msg.revisionList);
|
||||||
} else if (msg.type == 'revisionLabel') {
|
} else if (msg.type === 'revisionLabel') {
|
||||||
padsavedrevs.newRevisionList(msg.revisionList);
|
padsavedrevs.newRevisionList(msg.revisionList);
|
||||||
} else if (msg.type == 'padoptions') {
|
} else if (msg.type === 'padoptions') {
|
||||||
const opts = msg.options;
|
const opts = msg.options;
|
||||||
pad.handleOptionsChange(opts);
|
pad.handleOptionsChange(opts);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dmesg(m) {
|
dmesg: (m) => {
|
||||||
if (pad.getIsDebugEnabled()) {
|
if (pad.getIsDebugEnabled()) {
|
||||||
const djs = $('#djs').get(0);
|
const djs = $('#djs').get(0);
|
||||||
const wasAtBottom = (djs.scrollTop - (djs.scrollHeight - $(djs).height()) >= -20);
|
const wasAtBottom = (djs.scrollTop - (djs.scrollHeight - $(djs).height()) >= -20);
|
||||||
|
@ -573,31 +612,30 @@ var pad = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleChannelStateChange(newState, message) {
|
handleChannelStateChange: (newState, message) => {
|
||||||
const oldFullyConnected = !!padconnectionstatus.isFullyConnected();
|
const oldFullyConnected = !!padconnectionstatus.isFullyConnected();
|
||||||
const wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
|
const wasConnecting = (padconnectionstatus.getStatus().what === 'connecting');
|
||||||
if (newState == 'CONNECTED') {
|
if (newState === 'CONNECTED') {
|
||||||
padeditor.enable();
|
padeditor.enable();
|
||||||
padeditbar.enable();
|
padeditbar.enable();
|
||||||
padimpexp.enable();
|
padimpexp.enable();
|
||||||
padconnectionstatus.connected();
|
padconnectionstatus.connected();
|
||||||
} else if (newState == 'RECONNECTING') {
|
} else if (newState === 'RECONNECTING') {
|
||||||
padeditor.disable();
|
padeditor.disable();
|
||||||
padeditbar.disable();
|
padeditbar.disable();
|
||||||
padimpexp.disable();
|
padimpexp.disable();
|
||||||
padconnectionstatus.reconnecting();
|
padconnectionstatus.reconnecting();
|
||||||
} else if (newState == 'DISCONNECTED') {
|
} else if (newState === 'DISCONNECTED') {
|
||||||
pad.diagnosticInfo.disconnectedMessage = message;
|
pad.diagnosticInfo.disconnectedMessage = message;
|
||||||
pad.diagnosticInfo.padId = pad.getPadId();
|
pad.diagnosticInfo.padId = pad.getPadId();
|
||||||
pad.diagnosticInfo.socket = {};
|
pad.diagnosticInfo.socket = {};
|
||||||
|
|
||||||
// we filter non objects from the socket object and put them in the diagnosticInfo
|
// we filter non objects from the socket object and put them in the diagnosticInfo
|
||||||
// this ensures we have no cyclic data - this allows us to stringify the data
|
// this ensures we have no cyclic data - this allows us to stringify the data
|
||||||
for (const i in socket.socket) {
|
for (const [i, value] of Object.entries(socket.socket || {})) {
|
||||||
const value = socket.socket[i];
|
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
|
|
||||||
if (type == 'string' || type == 'number') {
|
if (type === 'string' || type === 'number') {
|
||||||
pad.diagnosticInfo.socket[i] = value;
|
pad.diagnosticInfo.socket[i] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -613,11 +651,11 @@ var pad = {
|
||||||
padconnectionstatus.disconnected(message);
|
padconnectionstatus.disconnected(message);
|
||||||
}
|
}
|
||||||
const newFullyConnected = !!padconnectionstatus.isFullyConnected();
|
const newFullyConnected = !!padconnectionstatus.isFullyConnected();
|
||||||
if (newFullyConnected != oldFullyConnected) {
|
if (newFullyConnected !== oldFullyConnected) {
|
||||||
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
|
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleIsFullyConnected(isConnected, isInitialConnect) {
|
handleIsFullyConnected: (isConnected, isInitialConnect) => {
|
||||||
pad.determineChatVisibility(isConnected && !isInitialConnect);
|
pad.determineChatVisibility(isConnected && !isInitialConnect);
|
||||||
pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
|
pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
|
||||||
pad.determineAuthorshipColorsVisibility();
|
pad.determineAuthorshipColorsVisibility();
|
||||||
|
@ -625,7 +663,7 @@ var pad = {
|
||||||
padeditbar.toggleDropDown('none');
|
padeditbar.toggleDropDown('none');
|
||||||
}, 1000);
|
}, 1000);
|
||||||
},
|
},
|
||||||
determineChatVisibility(asNowConnectedFeedback) {
|
determineChatVisibility: (asNowConnectedFeedback) => {
|
||||||
const chatVisCookie = padcookie.getPref('chatAlwaysVisible');
|
const chatVisCookie = padcookie.getPref('chatAlwaysVisible');
|
||||||
if (chatVisCookie) { // if the cookie is set for chat always visible
|
if (chatVisCookie) { // if the cookie is set for chat always visible
|
||||||
chat.stickToScreen(true); // stick it to the screen
|
chat.stickToScreen(true); // stick it to the screen
|
||||||
|
@ -634,7 +672,7 @@ var pad = {
|
||||||
$('#options-stickychat').prop('checked', false); // set the checkbox for off
|
$('#options-stickychat').prop('checked', false); // set the checkbox for off
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
determineChatAndUsersVisibility(asNowConnectedFeedback) {
|
determineChatAndUsersVisibility: (asNowConnectedFeedback) => {
|
||||||
const chatAUVisCookie = padcookie.getPref('chatAndUsersVisible');
|
const chatAUVisCookie = padcookie.getPref('chatAndUsersVisible');
|
||||||
if (chatAUVisCookie) { // if the cookie is set for chat always visible
|
if (chatAUVisCookie) { // if the cookie is set for chat always visible
|
||||||
chat.chatAndUsers(true); // stick it to the screen
|
chat.chatAndUsers(true); // stick it to the screen
|
||||||
|
@ -643,7 +681,7 @@ var pad = {
|
||||||
$('#options-chatandusers').prop('checked', false); // set the checkbox for off
|
$('#options-chatandusers').prop('checked', false); // set the checkbox for off
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
determineAuthorshipColorsVisibility() {
|
determineAuthorshipColorsVisibility: () => {
|
||||||
const authColCookie = padcookie.getPref('showAuthorshipColors');
|
const authColCookie = padcookie.getPref('showAuthorshipColors');
|
||||||
if (authColCookie) {
|
if (authColCookie) {
|
||||||
pad.changeViewOption('showAuthorColors', true);
|
pad.changeViewOption('showAuthorColors', true);
|
||||||
|
@ -652,14 +690,14 @@ var pad = {
|
||||||
$('#options-colorscheck').prop('checked', false);
|
$('#options-colorscheck').prop('checked', false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleCollabAction(action) {
|
handleCollabAction: (action) => {
|
||||||
if (action == 'commitPerformed') {
|
if (action === 'commitPerformed') {
|
||||||
padeditbar.setSyncStatus('syncing');
|
padeditbar.setSyncStatus('syncing');
|
||||||
} else if (action == 'newlyIdle') {
|
} else if (action === 'newlyIdle') {
|
||||||
padeditbar.setSyncStatus('done');
|
padeditbar.setSyncStatus('done');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asyncSendDiagnosticInfo() {
|
asyncSendDiagnosticInfo: () => {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
$.ajax(
|
$.ajax(
|
||||||
{
|
{
|
||||||
|
@ -668,32 +706,29 @@ var pad = {
|
||||||
data: {
|
data: {
|
||||||
diagnosticInfo: JSON.stringify(pad.diagnosticInfo),
|
diagnosticInfo: JSON.stringify(pad.diagnosticInfo),
|
||||||
},
|
},
|
||||||
success() {},
|
success: () => {},
|
||||||
error() {},
|
error: () => {},
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
forceReconnect() {
|
forceReconnect: () => {
|
||||||
$('form#reconnectform input.padId').val(pad.getPadId());
|
$('form#reconnectform input.padId').val(pad.getPadId());
|
||||||
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
|
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
|
||||||
$('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
|
$('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
|
||||||
$('form#reconnectform input.missedChanges').val(JSON.stringify(pad.collabClient.getMissedChanges()));
|
$('form#reconnectform input.missedChanges')
|
||||||
|
.val(JSON.stringify(pad.collabClient.getMissedChanges()));
|
||||||
$('form#reconnectform').submit();
|
$('form#reconnectform').submit();
|
||||||
},
|
},
|
||||||
// this is called from code put into a frame from the server:
|
// this is called from code put into a frame from the server:
|
||||||
handleImportExportFrameCall(callName, varargs) {
|
handleImportExportFrameCall: (callName, varargs) => {
|
||||||
padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1));
|
padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1));
|
||||||
},
|
},
|
||||||
callWhenNotCommitting(f) {
|
callWhenNotCommitting: (f) => {
|
||||||
pad.collabClient.callWhenNotCommitting(f);
|
pad.collabClient.callWhenNotCommitting(f);
|
||||||
},
|
},
|
||||||
getCollabRevisionNumber() {
|
getCollabRevisionNumber: () => pad.collabClient.getCurrentRevisionNumber(),
|
||||||
return pad.collabClient.getCurrentRevisionNumber();
|
isFullyConnected: () => padconnectionstatus.isFullyConnected(),
|
||||||
},
|
addHistoricalAuthors: (data) => {
|
||||||
isFullyConnected() {
|
|
||||||
return padconnectionstatus.isFullyConnected();
|
|
||||||
},
|
|
||||||
addHistoricalAuthors(data) {
|
|
||||||
if (!pad.collabClient) {
|
if (!pad.collabClient) {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
pad.addHistoricalAuthors(data);
|
pad.addHistoricalAuthors(data);
|
||||||
|
@ -704,11 +739,9 @@ var pad = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function init() {
|
const init = () => pad.init();
|
||||||
return pad.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
var settings = {
|
const settings = {
|
||||||
LineNumbersDisabled: false,
|
LineNumbersDisabled: false,
|
||||||
noColors: false,
|
noColors: false,
|
||||||
useMonospaceFontGlobal: false,
|
useMonospaceFontGlobal: false,
|
||||||
|
@ -718,6 +751,7 @@ var settings = {
|
||||||
};
|
};
|
||||||
|
|
||||||
pad.settings = settings;
|
pad.settings = settings;
|
||||||
|
|
||||||
exports.baseURL = '';
|
exports.baseURL = '';
|
||||||
exports.settings = settings;
|
exports.settings = settings;
|
||||||
exports.randomString = randomString;
|
exports.randomString = randomString;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
exports.showCountDownTimerToReconnectOnModal = function ($modal, pad) {
|
'use strict';
|
||||||
|
|
||||||
|
exports.showCountDownTimerToReconnectOnModal = ($modal, pad) => {
|
||||||
if (clientVars.automaticReconnectionTimeout && $modal.is('.with_reconnect_timer')) {
|
if (clientVars.automaticReconnectionTimeout && $modal.is('.with_reconnect_timer')) {
|
||||||
createCountDownElementsIfNecessary($modal);
|
createCountDownElementsIfNecessary($modal);
|
||||||
|
|
||||||
|
@ -13,7 +15,7 @@ exports.showCountDownTimerToReconnectOnModal = function ($modal, pad) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var createCountDownElementsIfNecessary = function ($modal) {
|
const createCountDownElementsIfNecessary = ($modal) => {
|
||||||
const elementsDoNotExist = $modal.find('#cancelreconnect').length === 0;
|
const elementsDoNotExist = $modal.find('#cancelreconnect').length === 0;
|
||||||
if (elementsDoNotExist) {
|
if (elementsDoNotExist) {
|
||||||
const $defaultMessage = $modal.find('#defaulttext');
|
const $defaultMessage = $modal.find('#defaulttext');
|
||||||
|
@ -45,12 +47,13 @@ var createCountDownElementsIfNecessary = function ($modal) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var localize = function ($element) {
|
const localize = ($element) => {
|
||||||
html10n.translateElement(html10n.translations, $element.get(0));
|
html10n.translateElement(html10n.translations, $element.get(0));
|
||||||
};
|
};
|
||||||
|
|
||||||
var createTimerForModal = function ($modal, pad) {
|
const createTimerForModal = ($modal, pad) => {
|
||||||
const timeUntilReconnection = clientVars.automaticReconnectionTimeout * reconnectionTries.nextTry();
|
const timeUntilReconnection =
|
||||||
|
clientVars.automaticReconnectionTimeout * reconnectionTries.nextTry();
|
||||||
const timer = new CountDownTimer(timeUntilReconnection);
|
const timer = new CountDownTimer(timeUntilReconnection);
|
||||||
|
|
||||||
timer.onTick((minutes, seconds) => {
|
timer.onTick((minutes, seconds) => {
|
||||||
|
@ -68,23 +71,23 @@ var createTimerForModal = function ($modal, pad) {
|
||||||
return timer;
|
return timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
var disableAutomaticReconnection = function ($modal) {
|
const disableAutomaticReconnection = ($modal) => {
|
||||||
toggleAutomaticReconnectionOption($modal, true);
|
toggleAutomaticReconnectionOption($modal, true);
|
||||||
};
|
};
|
||||||
var enableAutomaticReconnection = function ($modal) {
|
const enableAutomaticReconnection = ($modal) => {
|
||||||
toggleAutomaticReconnectionOption($modal, false);
|
toggleAutomaticReconnectionOption($modal, false);
|
||||||
};
|
};
|
||||||
var toggleAutomaticReconnectionOption = function ($modal, disableAutomaticReconnect) {
|
const toggleAutomaticReconnectionOption = ($modal, disableAutomaticReconnect) => {
|
||||||
$modal.find('#cancelreconnect, .reconnecttimer').toggleClass('hidden', disableAutomaticReconnect);
|
$modal.find('#cancelreconnect, .reconnecttimer').toggleClass('hidden', disableAutomaticReconnect);
|
||||||
$modal.find('#defaulttext').toggleClass('hidden', !disableAutomaticReconnect);
|
$modal.find('#defaulttext').toggleClass('hidden', !disableAutomaticReconnect);
|
||||||
};
|
};
|
||||||
|
|
||||||
var waitUntilClientCanConnectToServerAndThen = function (callback, pad) {
|
const waitUntilClientCanConnectToServerAndThen = (callback, pad) => {
|
||||||
whenConnectionIsRestablishedWithServer(callback, pad);
|
whenConnectionIsRestablishedWithServer(callback, pad);
|
||||||
pad.socket.connect();
|
pad.socket.connect();
|
||||||
};
|
};
|
||||||
|
|
||||||
var whenConnectionIsRestablishedWithServer = function (callback, pad) {
|
const whenConnectionIsRestablishedWithServer = (callback, pad) => {
|
||||||
// only add listener for the first try, don't need to add another listener
|
// only add listener for the first try, don't need to add another listener
|
||||||
// on every unsuccessful try
|
// on every unsuccessful try
|
||||||
if (reconnectionTries.counter === 1) {
|
if (reconnectionTries.counter === 1) {
|
||||||
|
@ -92,11 +95,11 @@ var whenConnectionIsRestablishedWithServer = function (callback, pad) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var forceReconnection = function ($modal) {
|
const forceReconnection = ($modal) => {
|
||||||
$modal.find('#forcereconnect').click();
|
$modal.find('#forcereconnect').click();
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateCountDownTimerMessage = function ($modal, minutes, seconds) {
|
const updateCountDownTimerMessage = ($modal, minutes, seconds) => {
|
||||||
minutes = minutes < 10 ? `0${minutes}` : minutes;
|
minutes = minutes < 10 ? `0${minutes}` : minutes;
|
||||||
seconds = seconds < 10 ? `0${seconds}` : seconds;
|
seconds = seconds < 10 ? `0${seconds}` : seconds;
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ var updateCountDownTimerMessage = function ($modal, minutes, seconds) {
|
||||||
|
|
||||||
// store number of tries to reconnect to server, in order to increase time to wait
|
// store number of tries to reconnect to server, in order to increase time to wait
|
||||||
// until next try
|
// until next try
|
||||||
var reconnectionTries = {
|
const reconnectionTries = {
|
||||||
counter: 0,
|
counter: 0,
|
||||||
|
|
||||||
nextTry() {
|
nextTry() {
|
||||||
|
@ -119,8 +122,9 @@ var reconnectionTries = {
|
||||||
|
|
||||||
// Timer based on http://stackoverflow.com/a/20618517.
|
// Timer based on http://stackoverflow.com/a/20618517.
|
||||||
// duration: how many **seconds** until the timer ends
|
// duration: how many **seconds** until the timer ends
|
||||||
// granularity (optional): how many **milliseconds** between each 'tick' of timer. Default: 1000ms (1s)
|
// granularity (optional): how many **milliseconds**
|
||||||
var CountDownTimer = function (duration, granularity) {
|
// between each 'tick' of timer. Default: 1000ms (1s)
|
||||||
|
const CountDownTimer = function (duration, granularity) {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.granularity = granularity || 1000;
|
this.granularity = granularity || 1000;
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
@ -137,8 +141,7 @@ CountDownTimer.prototype.start = function () {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
const that = this;
|
const that = this;
|
||||||
let diff;
|
let diff;
|
||||||
|
const timer = () => {
|
||||||
(function timer() {
|
|
||||||
diff = that.duration - Math.floor((Date.now() - start) / 1000);
|
diff = that.duration - Math.floor((Date.now() - start) / 1000);
|
||||||
|
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
|
@ -149,7 +152,8 @@ CountDownTimer.prototype.start = function () {
|
||||||
that.tick(0);
|
that.tick(0);
|
||||||
that.expire();
|
that.expire();
|
||||||
}
|
}
|
||||||
}());
|
};
|
||||||
|
timer();
|
||||||
};
|
};
|
||||||
|
|
||||||
CountDownTimer.prototype.tick = function (diff) {
|
CountDownTimer.prototype.tick = function (diff) {
|
||||||
|
@ -184,9 +188,7 @@ CountDownTimer.prototype.cancel = function () {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
CountDownTimer.parse = function (seconds) {
|
CountDownTimer.parse = (seconds) => ({
|
||||||
return {
|
minutes: (seconds / 60) | 0,
|
||||||
minutes: (seconds / 60) | 0,
|
seconds: (seconds % 60) | 0,
|
||||||
seconds: (seconds % 60) | 0,
|
});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -22,25 +24,25 @@
|
||||||
|
|
||||||
const padmodals = require('./pad_modals').padmodals;
|
const padmodals = require('./pad_modals').padmodals;
|
||||||
|
|
||||||
const padconnectionstatus = (function () {
|
const padconnectionstatus = (() => {
|
||||||
let status = {
|
let status = {
|
||||||
what: 'connecting',
|
what: 'connecting',
|
||||||
};
|
};
|
||||||
|
|
||||||
const self = {
|
const self = {
|
||||||
init() {
|
init: () => {
|
||||||
$('button#forcereconnect').click(() => {
|
$('button#forcereconnect').click(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
connected() {
|
connected: () => {
|
||||||
status = {
|
status = {
|
||||||
what: 'connected',
|
what: 'connected',
|
||||||
};
|
};
|
||||||
padmodals.showModal('connected');
|
padmodals.showModal('connected');
|
||||||
padmodals.hideOverlay();
|
padmodals.hideOverlay();
|
||||||
},
|
},
|
||||||
reconnecting() {
|
reconnecting: () => {
|
||||||
status = {
|
status = {
|
||||||
what: 'reconnecting',
|
what: 'reconnecting',
|
||||||
};
|
};
|
||||||
|
@ -48,8 +50,8 @@ const padconnectionstatus = (function () {
|
||||||
padmodals.showModal('reconnecting');
|
padmodals.showModal('reconnecting');
|
||||||
padmodals.showOverlay();
|
padmodals.showOverlay();
|
||||||
},
|
},
|
||||||
disconnected(msg) {
|
disconnected: (msg) => {
|
||||||
if (status.what == 'disconnected') return;
|
if (status.what === 'disconnected') return;
|
||||||
|
|
||||||
status = {
|
status = {
|
||||||
what: 'disconnected',
|
what: 'disconnected',
|
||||||
|
@ -81,14 +83,10 @@ const padconnectionstatus = (function () {
|
||||||
padmodals.showModal(k);
|
padmodals.showModal(k);
|
||||||
padmodals.showOverlay();
|
padmodals.showOverlay();
|
||||||
},
|
},
|
||||||
isFullyConnected() {
|
isFullyConnected: () => status.what === 'connected',
|
||||||
return status.what == 'connected';
|
getStatus: () => status,
|
||||||
},
|
|
||||||
getStatus() {
|
|
||||||
return status;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}());
|
})();
|
||||||
|
|
||||||
exports.padconnectionstatus = padconnectionstatus;
|
exports.padconnectionstatus = padconnectionstatus;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2009 Google Inc.
|
* Copyright 2009 Google Inc.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -24,26 +26,26 @@ const Cookies = require('./pad_utils').Cookies;
|
||||||
const padcookie = require('./pad_cookie').padcookie;
|
const padcookie = require('./pad_cookie').padcookie;
|
||||||
const padutils = require('./pad_utils').padutils;
|
const padutils = require('./pad_utils').padutils;
|
||||||
|
|
||||||
const padeditor = (function () {
|
const padeditor = (() => {
|
||||||
let Ace2Editor = undefined;
|
let Ace2Editor = undefined;
|
||||||
let pad = undefined;
|
let pad = undefined;
|
||||||
let settings = undefined;
|
let settings = undefined;
|
||||||
|
|
||||||
var self = {
|
const self = {
|
||||||
ace: null,
|
ace: null,
|
||||||
// this is accessed directly from other files
|
// this is accessed directly from other files
|
||||||
viewZoom: 100,
|
viewZoom: 100,
|
||||||
init(readyFunc, initialViewOptions, _pad) {
|
init: (readyFunc, initialViewOptions, _pad) => {
|
||||||
Ace2Editor = require('./ace').Ace2Editor;
|
Ace2Editor = require('./ace').Ace2Editor;
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
settings = pad.settings;
|
settings = pad.settings;
|
||||||
|
|
||||||
function aceReady() {
|
const aceReady = () => {
|
||||||
$('#editorloadingbox').hide();
|
$('#editorloadingbox').hide();
|
||||||
if (readyFunc) {
|
if (readyFunc) {
|
||||||
readyFunc();
|
readyFunc();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
self.ace = new Ace2Editor();
|
self.ace = new Ace2Editor();
|
||||||
self.ace.init('editorcontainer', '', aceReady);
|
self.ace.init('editorcontainer', '', aceReady);
|
||||||
|
@ -57,7 +59,7 @@ const padeditor = (function () {
|
||||||
// view bar
|
// view bar
|
||||||
$('#viewbarcontents').show();
|
$('#viewbarcontents').show();
|
||||||
},
|
},
|
||||||
initViewOptions() {
|
initViewOptions: () => {
|
||||||
// Line numbers
|
// Line numbers
|
||||||
padutils.bindCheckboxChange($('#options-linenoscheck'), () => {
|
padutils.bindCheckboxChange($('#options-linenoscheck'), () => {
|
||||||
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($('#options-linenoscheck')));
|
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($('#options-linenoscheck')));
|
||||||
|
@ -74,8 +76,8 @@ const padeditor = (function () {
|
||||||
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($('#options-rtlcheck')));
|
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($('#options-rtlcheck')));
|
||||||
});
|
});
|
||||||
html10n.bind('localized', () => {
|
html10n.bind('localized', () => {
|
||||||
pad.changeViewOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
|
pad.changeViewOption('rtlIsTrue', ('rtl' === html10n.getDirection()));
|
||||||
padutils.setCheckbox($('#options-rtlcheck'), ('rtl' == html10n.getDirection()));
|
padutils.setCheckbox($('#options-rtlcheck'), ('rtl' === html10n.getDirection()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// font family change
|
// font family change
|
||||||
|
@ -87,9 +89,10 @@ const padeditor = (function () {
|
||||||
html10n.bind('localized', () => {
|
html10n.bind('localized', () => {
|
||||||
$('#languagemenu').val(html10n.getLanguage());
|
$('#languagemenu').val(html10n.getLanguage());
|
||||||
// translate the value of 'unnamed' and 'Enter your name' textboxes in the userlist
|
// translate the value of 'unnamed' and 'Enter your name' textboxes in the userlist
|
||||||
// this does not interfere with html10n's normal value-setting because html10n just ingores <input>s
|
// this does not interfere with html10n's normal value-setting because
|
||||||
// also, a value which has been set by the user will be not overwritten since a user-edited <input>
|
// html10n just ingores <input>s
|
||||||
// does *not* have the editempty-class
|
// also, a value which has been set by the user will be not overwritten
|
||||||
|
// since a user-edited <input> does *not* have the editempty-class
|
||||||
$('input[data-l10n-id]').each((key, input) => {
|
$('input[data-l10n-id]').each((key, input) => {
|
||||||
input = $(input);
|
input = $(input);
|
||||||
if (input.hasClass('editempty')) {
|
if (input.hasClass('editempty')) {
|
||||||
|
@ -106,17 +109,17 @@ const padeditor = (function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setViewOptions(newOptions) {
|
setViewOptions: (newOptions) => {
|
||||||
function getOption(key, defaultValue) {
|
const getOption = (key, defaultValue) => {
|
||||||
const value = String(newOptions[key]);
|
const value = String(newOptions[key]);
|
||||||
if (value == 'true') return true;
|
if (value === 'true') return true;
|
||||||
if (value == 'false') return false;
|
if (value === 'false') return false;
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
};
|
||||||
|
|
||||||
let v;
|
let v;
|
||||||
|
|
||||||
v = getOption('rtlIsTrue', ('rtl' == html10n.getDirection()));
|
v = getOption('rtlIsTrue', ('rtl' === html10n.getDirection()));
|
||||||
self.ace.setProperty('rtlIsTrue', v);
|
self.ace.setProperty('rtlIsTrue', v);
|
||||||
padutils.setCheckbox($('#options-rtlcheck'), v);
|
padutils.setCheckbox($('#options-rtlcheck'), v);
|
||||||
|
|
||||||
|
@ -137,29 +140,29 @@ const padeditor = (function () {
|
||||||
|
|
||||||
self.ace.setProperty('textface', newOptions.padFontFamily || '');
|
self.ace.setProperty('textface', newOptions.padFontFamily || '');
|
||||||
},
|
},
|
||||||
dispose() {
|
dispose: () => {
|
||||||
if (self.ace) {
|
if (self.ace) {
|
||||||
self.ace.destroy();
|
self.ace.destroy();
|
||||||
self.ace = null;
|
self.ace = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enable() {
|
enable: () => {
|
||||||
if (self.ace) {
|
if (self.ace) {
|
||||||
self.ace.setEditable(true);
|
self.ace.setEditable(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disable() {
|
disable: () => {
|
||||||
if (self.ace) {
|
if (self.ace) {
|
||||||
self.ace.setProperty('grayedOut', true);
|
self.ace.setProperty('grayedOut', true);
|
||||||
self.ace.setEditable(false);
|
self.ace.setEditable(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
restoreRevisionText(dataFromServer) {
|
restoreRevisionText: (dataFromServer) => {
|
||||||
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
|
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
|
||||||
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
|
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}());
|
})();
|
||||||
|
|
||||||
exports.padeditor = padeditor;
|
exports.padeditor = padeditor;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -20,24 +22,27 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const padimpexp = (function () {
|
const padimpexp = (() => {
|
||||||
// /// import
|
// /// import
|
||||||
let currentImportTimer = null;
|
let currentImportTimer = null;
|
||||||
|
|
||||||
function addImportFrames() {
|
const addImportFrames = () => {
|
||||||
$('#import .importframe').remove();
|
$('#import .importframe').remove();
|
||||||
const iframe = $('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>');
|
const iframe = $('<iframe>')
|
||||||
|
.css('display', 'none')
|
||||||
|
.attr('name', 'importiframe')
|
||||||
|
.addClass('importframe');
|
||||||
$('#import').append(iframe);
|
$('#import').append(iframe);
|
||||||
}
|
};
|
||||||
|
|
||||||
function fileInputUpdated() {
|
const fileInputUpdated = () => {
|
||||||
$('#importsubmitinput').addClass('throbbold');
|
$('#importsubmitinput').addClass('throbbold');
|
||||||
$('#importformfilediv').addClass('importformenabled');
|
$('#importformfilediv').addClass('importformenabled');
|
||||||
$('#importsubmitinput').removeAttr('disabled');
|
$('#importsubmitinput').removeAttr('disabled');
|
||||||
$('#importmessagefail').fadeOut('fast');
|
$('#importmessagefail').fadeOut('fast');
|
||||||
}
|
};
|
||||||
|
|
||||||
function fileInputSubmit() {
|
const fileInputSubmit = () => {
|
||||||
$('#importmessagefail').fadeOut('fast');
|
$('#importmessagefail').fadeOut('fast');
|
||||||
const ret = window.confirm(html10n.get('pad.impexp.confirmimport'));
|
const ret = window.confirm(html10n.get('pad.impexp.confirmimport'));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -64,13 +69,13 @@ const padimpexp = (function () {
|
||||||
$('#importstatusball').show();
|
$('#importstatusball').show();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
function importFailed(msg) {
|
const importFailed = (msg) => {
|
||||||
importErrorMessage(msg);
|
importErrorMessage(msg);
|
||||||
}
|
};
|
||||||
|
|
||||||
function importDone() {
|
const importDone = () => {
|
||||||
$('#importsubmitinput').removeAttr('disabled').val(html10n.get('pad.impexp.importbutton'));
|
$('#importsubmitinput').removeAttr('disabled').val(html10n.get('pad.impexp.importbutton'));
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
$('#importfileinput').removeAttr('disabled');
|
$('#importfileinput').removeAttr('disabled');
|
||||||
|
@ -78,16 +83,16 @@ const padimpexp = (function () {
|
||||||
$('#importstatusball').hide();
|
$('#importstatusball').hide();
|
||||||
importClearTimeout();
|
importClearTimeout();
|
||||||
addImportFrames();
|
addImportFrames();
|
||||||
}
|
};
|
||||||
|
|
||||||
function importClearTimeout() {
|
const importClearTimeout = () => {
|
||||||
if (currentImportTimer) {
|
if (currentImportTimer) {
|
||||||
window.clearTimeout(currentImportTimer);
|
window.clearTimeout(currentImportTimer);
|
||||||
currentImportTimer = null;
|
currentImportTimer = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function importErrorMessage(status) {
|
const importErrorMessage = (status) => {
|
||||||
let msg = '';
|
let msg = '';
|
||||||
|
|
||||||
if (status === 'convertFailed') {
|
if (status === 'convertFailed') {
|
||||||
|
@ -102,9 +107,11 @@ const padimpexp = (function () {
|
||||||
msg = html10n.get('pad.impexp.permission');
|
msg = html10n.get('pad.impexp.permission');
|
||||||
}
|
}
|
||||||
|
|
||||||
function showError(fade) {
|
const showError = (fade) => {
|
||||||
$('#importmessagefail').html(`<strong style="color: red">${html10n.get('pad.impexp.importfailed')}:</strong> ${msg || html10n.get('pad.impexp.copypaste', '')}`)[(fade ? 'fadeIn' : 'show')]();
|
$('#importmessagefail').html(
|
||||||
}
|
`<strong style="color: red">${html10n.get('pad.impexp.importfailed')}:</strong> ` +
|
||||||
|
`${msg || html10n.get('pad.impexp.copypaste', '')}`)[(fade ? 'fadeIn' : 'show')]();
|
||||||
|
};
|
||||||
|
|
||||||
if ($('#importexport .importmessage').is(':visible')) {
|
if ($('#importexport .importmessage').is(':visible')) {
|
||||||
$('#importmessagesuccess').fadeOut('fast');
|
$('#importmessagesuccess').fadeOut('fast');
|
||||||
|
@ -114,7 +121,7 @@ const padimpexp = (function () {
|
||||||
} else {
|
} else {
|
||||||
showError();
|
showError();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// /// export
|
// /// export
|
||||||
|
|
||||||
|
@ -134,16 +141,17 @@ const padimpexp = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///
|
// ///
|
||||||
var pad = undefined;
|
let pad = undefined;
|
||||||
const self = {
|
const self = {
|
||||||
init(_pad) {
|
init: (_pad) => {
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
|
|
||||||
// get /p/padname
|
// get /p/padname
|
||||||
// if /p/ isn't available due to a rewrite we use the clientVars padId
|
// if /p/ isn't available due to a rewrite we use the clientVars padId
|
||||||
const pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId;
|
const padRootPath = /.*\/p\/[^/]+/.exec(document.location.pathname) || clientVars.padId;
|
||||||
// get http://example.com/p/padname without Params
|
// get http://example.com/p/padname without Params
|
||||||
const pad_root_url = `${document.location.protocol}//${document.location.host}${document.location.pathname}`;
|
const dl = document.location;
|
||||||
|
const padRootUrl = `${dl.protocol}//${dl.host}${dl.pathname}`;
|
||||||
|
|
||||||
// i10l buttom import
|
// i10l buttom import
|
||||||
$('#importsubmitinput').val(html10n.get('pad.impexp.importbutton'));
|
$('#importsubmitinput').val(html10n.get('pad.impexp.importbutton'));
|
||||||
|
@ -152,32 +160,32 @@ const padimpexp = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
// build the export links
|
// build the export links
|
||||||
$('#exporthtmla').attr('href', `${pad_root_path}/export/html`);
|
$('#exporthtmla').attr('href', `${padRootPath}/export/html`);
|
||||||
$('#exportetherpada').attr('href', `${pad_root_path}/export/etherpad`);
|
$('#exportetherpada').attr('href', `${padRootPath}/export/etherpad`);
|
||||||
$('#exportplaina').attr('href', `${pad_root_path}/export/txt`);
|
$('#exportplaina').attr('href', `${padRootPath}/export/txt`);
|
||||||
|
|
||||||
// activate action to import in the form
|
// activate action to import in the form
|
||||||
$('#importform').attr('action', `${pad_root_url}/import`);
|
$('#importform').attr('action', `${padRootUrl}/import`);
|
||||||
|
|
||||||
// hide stuff thats not avaible if abiword/soffice is disabled
|
// hide stuff thats not avaible if abiword/soffice is disabled
|
||||||
if (clientVars.exportAvailable == 'no') {
|
if (clientVars.exportAvailable === 'no') {
|
||||||
$('#exportworda').remove();
|
$('#exportworda').remove();
|
||||||
$('#exportpdfa').remove();
|
$('#exportpdfa').remove();
|
||||||
$('#exportopena').remove();
|
$('#exportopena').remove();
|
||||||
|
|
||||||
$('#importmessageabiword').show();
|
$('#importmessageabiword').show();
|
||||||
} else if (clientVars.exportAvailable == 'withoutPDF') {
|
} else if (clientVars.exportAvailable === 'withoutPDF') {
|
||||||
$('#exportpdfa').remove();
|
$('#exportpdfa').remove();
|
||||||
|
|
||||||
$('#exportworda').attr('href', `${pad_root_path}/export/doc`);
|
$('#exportworda').attr('href', `${padRootPath}/export/doc`);
|
||||||
$('#exportopena').attr('href', `${pad_root_path}/export/odt`);
|
$('#exportopena').attr('href', `${padRootPath}/export/odt`);
|
||||||
|
|
||||||
$('#importexport').css({height: '142px'});
|
$('#importexport').css({height: '142px'});
|
||||||
$('#importexportline').css({height: '142px'});
|
$('#importexportline').css({height: '142px'});
|
||||||
} else {
|
} else {
|
||||||
$('#exportworda').attr('href', `${pad_root_path}/export/doc`);
|
$('#exportworda').attr('href', `${padRootPath}/export/doc`);
|
||||||
$('#exportpdfa').attr('href', `${pad_root_path}/export/pdf`);
|
$('#exportpdfa').attr('href', `${padRootPath}/export/pdf`);
|
||||||
$('#exportopena').attr('href', `${pad_root_path}/export/odt`);
|
$('#exportopena').attr('href', `${padRootPath}/export/odt`);
|
||||||
}
|
}
|
||||||
|
|
||||||
addImportFrames();
|
addImportFrames();
|
||||||
|
@ -185,7 +193,7 @@ const padimpexp = (function () {
|
||||||
$('#importform').unbind('submit').submit(fileInputSubmit);
|
$('#importform').unbind('submit').submit(fileInputSubmit);
|
||||||
$('.disabledexport').click(cantExport);
|
$('.disabledexport').click(cantExport);
|
||||||
},
|
},
|
||||||
handleFrameCall(directDatabaseAccess, status) {
|
handleFrameCall: (directDatabaseAccess, status) => {
|
||||||
if (directDatabaseAccess === 'undefined') directDatabaseAccess = false;
|
if (directDatabaseAccess === 'undefined') directDatabaseAccess = false;
|
||||||
if (status !== 'ok') {
|
if (status !== 'ok') {
|
||||||
importFailed(status);
|
importFailed(status);
|
||||||
|
@ -201,18 +209,18 @@ const padimpexp = (function () {
|
||||||
|
|
||||||
importDone();
|
importDone();
|
||||||
},
|
},
|
||||||
disable() {
|
disable: () => {
|
||||||
$('#impexp-disabled-clickcatcher').show();
|
$('#impexp-disabled-clickcatcher').show();
|
||||||
$('#import').css('opacity', 0.5);
|
$('#import').css('opacity', 0.5);
|
||||||
$('#impexp-export').css('opacity', 0.5);
|
$('#impexp-export').css('opacity', 0.5);
|
||||||
},
|
},
|
||||||
enable() {
|
enable: () => {
|
||||||
$('#impexp-disabled-clickcatcher').hide();
|
$('#impexp-disabled-clickcatcher').hide();
|
||||||
$('#import').css('opacity', 1);
|
$('#import').css('opacity', 1);
|
||||||
$('#impexp-export').css('opacity', 1);
|
$('#impexp-export').css('opacity', 1);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}());
|
})();
|
||||||
|
|
||||||
exports.padimpexp = padimpexp;
|
exports.padimpexp = padimpexp;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -23,13 +25,13 @@
|
||||||
const padeditbar = require('./pad_editbar').padeditbar;
|
const padeditbar = require('./pad_editbar').padeditbar;
|
||||||
const automaticReconnect = require('./pad_automatic_reconnect');
|
const automaticReconnect = require('./pad_automatic_reconnect');
|
||||||
|
|
||||||
const padmodals = (function () {
|
const padmodals = (() => {
|
||||||
let pad = undefined;
|
let pad = undefined;
|
||||||
const self = {
|
const self = {
|
||||||
init(_pad) {
|
init: (_pad) => {
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
},
|
},
|
||||||
showModal(messageId) {
|
showModal: (messageId) => {
|
||||||
padeditbar.toggleDropDown('none', () => {
|
padeditbar.toggleDropDown('none', () => {
|
||||||
$('#connectivity .visible').removeClass('visible');
|
$('#connectivity .visible').removeClass('visible');
|
||||||
$(`#connectivity .${messageId}`).addClass('visible');
|
$(`#connectivity .${messageId}`).addClass('visible');
|
||||||
|
@ -40,15 +42,15 @@ const padmodals = (function () {
|
||||||
padeditbar.toggleDropDown('connectivity');
|
padeditbar.toggleDropDown('connectivity');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showOverlay() {
|
showOverlay: () => {
|
||||||
// Prevent the user to interact with the toolbar. Useful when user is disconnected for example
|
// Prevent the user to interact with the toolbar. Useful when user is disconnected for example
|
||||||
$('#toolbar-overlay').show();
|
$('#toolbar-overlay').show();
|
||||||
},
|
},
|
||||||
hideOverlay() {
|
hideOverlay: () => {
|
||||||
$('#toolbar-overlay').hide();
|
$('#toolbar-overlay').hide();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}());
|
})();
|
||||||
|
|
||||||
exports.padmodals = padmodals;
|
exports.padmodals = padmodals;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2012 Peter 'Pita' Martischka
|
* Copyright 2012 Peter 'Pita' Martischka
|
||||||
*
|
*
|
||||||
|
@ -16,13 +18,14 @@
|
||||||
|
|
||||||
let pad;
|
let pad;
|
||||||
|
|
||||||
exports.saveNow = function () {
|
exports.saveNow = () => {
|
||||||
pad.collabClient.sendMessage({type: 'SAVE_REVISION'});
|
pad.collabClient.sendMessage({type: 'SAVE_REVISION'});
|
||||||
$.gritter.add({
|
$.gritter.add({
|
||||||
// (string | mandatory) the heading of the notification
|
// (string | mandatory) the heading of the notification
|
||||||
title: _('pad.savedrevs.marked'),
|
title: html10n.get('pad.savedrevs.marked'),
|
||||||
// (string | mandatory) the text inside the notification
|
// (string | mandatory) the text inside the notification
|
||||||
text: _('pad.savedrevs.timeslider') || 'You can view saved revisions in the timeslider',
|
text: html10n.get('pad.savedrevs.timeslider') ||
|
||||||
|
'You can view saved revisions in the timeslider',
|
||||||
// (bool | optional) if you want it to fade out on its own or just sit there
|
// (bool | optional) if you want it to fade out on its own or just sit there
|
||||||
sticky: false,
|
sticky: false,
|
||||||
time: 3000,
|
time: 3000,
|
||||||
|
@ -30,6 +33,6 @@ exports.saveNow = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.init = function (_pad) {
|
exports.init = (_pad) => {
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -22,13 +24,12 @@
|
||||||
|
|
||||||
const padutils = require('./pad_utils').padutils;
|
const padutils = require('./pad_utils').padutils;
|
||||||
const hooks = require('./pluginfw/hooks');
|
const hooks = require('./pluginfw/hooks');
|
||||||
|
const browser = require('./browser');
|
||||||
|
|
||||||
let myUserInfo = {};
|
let myUserInfo = {};
|
||||||
|
|
||||||
let colorPickerOpen = false;
|
let colorPickerOpen = false;
|
||||||
let colorPickerSetup = false;
|
let colorPickerSetup = false;
|
||||||
let previousColorId = 0;
|
|
||||||
|
|
||||||
|
|
||||||
const paduserlist = (function () {
|
const paduserlist = (function () {
|
||||||
const rowManager = (function () {
|
const rowManager = (function () {
|
||||||
|
@ -36,9 +37,7 @@ const paduserlist = (function () {
|
||||||
// their insertion, removal, and reordering. It manipulates TD height
|
// their insertion, removal, and reordering. It manipulates TD height
|
||||||
// and TD opacity.
|
// and TD opacity.
|
||||||
|
|
||||||
function nextRowId() {
|
const nextRowId = () => `usertr${nextRowId.counter++}`;
|
||||||
return `usertr${nextRowId.counter++}`;
|
|
||||||
}
|
|
||||||
nextRowId.counter = 1;
|
nextRowId.counter = 1;
|
||||||
// objects are shared; fields are "domId","data","animationStep"
|
// objects are shared; fields are "domId","data","animationStep"
|
||||||
const rowsFadingOut = []; // unordered set
|
const rowsFadingOut = []; // unordered set
|
||||||
|
@ -47,20 +46,67 @@ const paduserlist = (function () {
|
||||||
const ANIMATION_START = -12; // just starting to fade in
|
const ANIMATION_START = -12; // just starting to fade in
|
||||||
const ANIMATION_END = 12; // just finishing fading out
|
const ANIMATION_END = 12; // just finishing fading out
|
||||||
|
|
||||||
|
const animateStep = () => {
|
||||||
|
// animation must be symmetrical
|
||||||
|
for (let i = rowsFadingIn.length - 1; i >= 0; i--) { // backwards to allow removal
|
||||||
|
const row = rowsFadingIn[i];
|
||||||
|
const step = ++row.animationStep;
|
||||||
|
const animHeight = getAnimationHeight(step, row.animationPower);
|
||||||
|
const node = rowNode(row);
|
||||||
|
const baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
|
||||||
|
if (step <= -OPACITY_STEPS) {
|
||||||
|
node.find('td').height(animHeight);
|
||||||
|
} else if (step === -OPACITY_STEPS + 1) {
|
||||||
|
node.empty().append(createUserRowTds(animHeight, row.data))
|
||||||
|
.find('td').css('opacity', baseOpacity * 1 / OPACITY_STEPS);
|
||||||
|
} else if (step < 0) {
|
||||||
|
node.find('td').css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS)
|
||||||
|
.height(animHeight);
|
||||||
|
} else if (step === 0) {
|
||||||
|
// set HTML in case modified during animation
|
||||||
|
node.empty().append(createUserRowTds(animHeight, row.data))
|
||||||
|
.find('td').css('opacity', baseOpacity * 1).height(animHeight);
|
||||||
|
rowsFadingIn.splice(i, 1); // remove from set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = rowsFadingOut.length - 1; i >= 0; i--) { // backwards to allow removal
|
||||||
|
const row = rowsFadingOut[i];
|
||||||
|
const step = ++row.animationStep;
|
||||||
|
const node = rowNode(row);
|
||||||
|
const animHeight = getAnimationHeight(step, row.animationPower);
|
||||||
|
const baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
|
||||||
|
if (step < OPACITY_STEPS) {
|
||||||
|
node.find('td').css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS)
|
||||||
|
.height(animHeight);
|
||||||
|
} else if (step === OPACITY_STEPS) {
|
||||||
|
node.empty().append(createEmptyRowTds(animHeight));
|
||||||
|
} else if (step <= ANIMATION_END) {
|
||||||
|
node.find('td').height(animHeight);
|
||||||
|
} else {
|
||||||
|
rowsFadingOut.splice(i, 1); // remove from set
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getAnimationHeight(step, power) {
|
handleOtherUserInputs();
|
||||||
|
|
||||||
|
return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAnimationHeight = (step, power) => {
|
||||||
let a = Math.abs(step / 12);
|
let a = Math.abs(step / 12);
|
||||||
if (power == 2) a *= a;
|
if (power === 2) a **= 2;
|
||||||
else if (power == 3) a = a * a * a;
|
else if (power === 3) a **= 3;
|
||||||
else if (power == 4) a = a * a * a * a;
|
else if (power === 4) a **= 4;
|
||||||
else if (power >= 5) a = a * a * a * a * a;
|
else if (power >= 5) a **= 5;
|
||||||
return Math.round(26 * (1 - a));
|
return Math.round(26 * (1 - a));
|
||||||
}
|
};
|
||||||
const OPACITY_STEPS = 6;
|
const OPACITY_STEPS = 6;
|
||||||
|
|
||||||
const ANIMATION_STEP_TIME = 20;
|
const ANIMATION_STEP_TIME = 20;
|
||||||
const LOWER_FRAMERATE_FACTOR = 2;
|
const LOWER_FRAMERATE_FACTOR = 2;
|
||||||
const scheduleAnimation = padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR).scheduleAnimation;
|
const {scheduleAnimation} =
|
||||||
|
padutils.makeAnimationScheduler(animateStep, ANIMATION_STEP_TIME, LOWER_FRAMERATE_FACTOR);
|
||||||
|
|
||||||
const NUMCOLS = 4;
|
const NUMCOLS = 4;
|
||||||
|
|
||||||
|
@ -72,11 +118,9 @@ const paduserlist = (function () {
|
||||||
.css('border', 0)
|
.css('border', 0)
|
||||||
.css('height', `${height}px`);
|
.css('height', `${height}px`);
|
||||||
|
|
||||||
function isNameEditable(data) {
|
const isNameEditable = (data) => (!data.name) && (data.status !== 'Disconnected');
|
||||||
return (!data.name) && (data.status != 'Disconnected');
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceUserRowContents(tr, height, data) {
|
const replaceUserRowContents = (tr, height, data) => {
|
||||||
const tds = createUserRowTds(height, data);
|
const tds = createUserRowTds(height, data);
|
||||||
if (isNameEditable(data) && tr.find('td.usertdname input:enabled').length > 0) {
|
if (isNameEditable(data) && tr.find('td.usertdname input:enabled').length > 0) {
|
||||||
// preserve input field node
|
// preserve input field node
|
||||||
|
@ -93,7 +137,7 @@ const paduserlist = (function () {
|
||||||
tr.empty().append(tds);
|
tr.empty().append(tds);
|
||||||
}
|
}
|
||||||
return tr;
|
return tr;
|
||||||
}
|
};
|
||||||
|
|
||||||
const createUserRowTds = (height, data) => {
|
const createUserRowTds = (height, data) => {
|
||||||
let name;
|
let name;
|
||||||
|
@ -105,7 +149,7 @@ const paduserlist = (function () {
|
||||||
.attr('type', 'text')
|
.attr('type', 'text')
|
||||||
.addClass('editempty')
|
.addClass('editempty')
|
||||||
.addClass('newinput')
|
.addClass('newinput')
|
||||||
.attr('value', _('pad.userlist.unnamed'));
|
.attr('value', html10n.get('pad.userlist.unnamed'));
|
||||||
if (isNameEditable(data)) name.attr('disabled', 'disabled');
|
if (isNameEditable(data)) name.attr('disabled', 'disabled');
|
||||||
}
|
}
|
||||||
return $()
|
return $()
|
||||||
|
@ -131,19 +175,17 @@ const paduserlist = (function () {
|
||||||
.attr('id', id)
|
.attr('id', id)
|
||||||
.append(contents);
|
.append(contents);
|
||||||
|
|
||||||
function rowNode(row) {
|
const rowNode = (row) => $(`#${row.domId}`);
|
||||||
return $(`#${row.domId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRowData(row) {
|
const handleRowData = (row) => {
|
||||||
if (row.data && row.data.status == 'Disconnected') {
|
if (row.data && row.data.status === 'Disconnected') {
|
||||||
row.opacity = 0.5;
|
row.opacity = 0.5;
|
||||||
} else {
|
} else {
|
||||||
delete row.opacity;
|
delete row.opacity;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleOtherUserInputs() {
|
const handleOtherUserInputs = () => {
|
||||||
// handle 'INPUT' elements for naming other unnamed users
|
// handle 'INPUT' elements for naming other unnamed users
|
||||||
$('#otheruserstable input.newinput').each(function () {
|
$('#otheruserstable input.newinput').each(function () {
|
||||||
const input = $(this);
|
const input = $(this);
|
||||||
|
@ -156,12 +198,12 @@ const paduserlist = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).removeClass('newinput');
|
}).removeClass('newinput');
|
||||||
}
|
};
|
||||||
|
|
||||||
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
|
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
|
||||||
|
|
||||||
|
|
||||||
function insertRow(position, data, animationPower) {
|
const insertRow = (position, data, animationPower) => {
|
||||||
position = Math.max(0, Math.min(rowsPresent.length, position));
|
position = Math.max(0, Math.min(rowsPresent.length, position));
|
||||||
animationPower = (animationPower === undefined ? 4 : animationPower);
|
animationPower = (animationPower === undefined ? 4 : animationPower);
|
||||||
|
|
||||||
|
@ -177,7 +219,7 @@ const paduserlist = (function () {
|
||||||
handleRowData(row);
|
handleRowData(row);
|
||||||
rowsPresent.splice(position, 0, row);
|
rowsPresent.splice(position, 0, row);
|
||||||
let tr;
|
let tr;
|
||||||
if (animationPower == 0) {
|
if (animationPower === 0) {
|
||||||
tr = createRow(domId, createUserRowTds(getAnimationHeight(0), data), authorId);
|
tr = createRow(domId, createUserRowTds(getAnimationHeight(0), data), authorId);
|
||||||
row.animationStep = 0;
|
row.animationStep = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -185,41 +227,43 @@ const paduserlist = (function () {
|
||||||
tr = createRow(domId, createEmptyRowTds(getAnimationHeight(ANIMATION_START)), authorId);
|
tr = createRow(domId, createEmptyRowTds(getAnimationHeight(ANIMATION_START)), authorId);
|
||||||
}
|
}
|
||||||
$('table#otheruserstable').show();
|
$('table#otheruserstable').show();
|
||||||
if (position == 0) {
|
if (position === 0) {
|
||||||
$('table#otheruserstable').prepend(tr);
|
$('table#otheruserstable').prepend(tr);
|
||||||
} else {
|
} else {
|
||||||
rowNode(rowsPresent[position - 1]).after(tr);
|
rowNode(rowsPresent[position - 1]).after(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animationPower != 0) {
|
if (animationPower !== 0) {
|
||||||
scheduleAnimation();
|
scheduleAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOtherUserInputs();
|
handleOtherUserInputs();
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
}
|
};
|
||||||
|
|
||||||
function updateRow(position, data) {
|
const updateRow = (position, data) => {
|
||||||
const row = rowsPresent[position];
|
const row = rowsPresent[position];
|
||||||
if (row) {
|
if (row) {
|
||||||
row.data = data;
|
row.data = data;
|
||||||
handleRowData(row);
|
handleRowData(row);
|
||||||
if (row.animationStep == 0) {
|
if (row.animationStep === 0) {
|
||||||
// not currently animating
|
// not currently animating
|
||||||
const tr = rowNode(row);
|
const tr = rowNode(row);
|
||||||
replaceUserRowContents(tr, getAnimationHeight(0), row.data).find('td').css('opacity', (row.opacity === undefined ? 1 : row.opacity));
|
replaceUserRowContents(tr, getAnimationHeight(0), row.data)
|
||||||
|
.find('td')
|
||||||
|
.css('opacity', (row.opacity === undefined ? 1 : row.opacity));
|
||||||
handleOtherUserInputs();
|
handleOtherUserInputs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function removeRow(position, animationPower) {
|
const removeRow = (position, animationPower) => {
|
||||||
animationPower = (animationPower === undefined ? 4 : animationPower);
|
animationPower = (animationPower === undefined ? 4 : animationPower);
|
||||||
const row = rowsPresent[position];
|
const row = rowsPresent[position];
|
||||||
if (row) {
|
if (row) {
|
||||||
rowsPresent.splice(position, 1); // remove
|
rowsPresent.splice(position, 1); // remove
|
||||||
if (animationPower == 0) {
|
if (animationPower === 0) {
|
||||||
rowNode(row).remove();
|
rowNode(row).remove();
|
||||||
} else {
|
} else {
|
||||||
row.animationStep = -row.animationStep; // use symmetry
|
row.animationStep = -row.animationStep; // use symmetry
|
||||||
|
@ -231,65 +275,20 @@ const paduserlist = (function () {
|
||||||
if (rowsPresent.length === 0) {
|
if (rowsPresent.length === 0) {
|
||||||
$('table#otheruserstable').hide();
|
$('table#otheruserstable').hide();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// newPosition is position after the row has been removed
|
// newPosition is position after the row has been removed
|
||||||
|
|
||||||
|
|
||||||
function moveRow(oldPosition, newPosition, animationPower) {
|
const moveRow = (oldPosition, newPosition, animationPower) => {
|
||||||
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
|
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
|
||||||
const row = rowsPresent[oldPosition];
|
const row = rowsPresent[oldPosition];
|
||||||
if (row && oldPosition != newPosition) {
|
if (row && oldPosition !== newPosition) {
|
||||||
const rowData = row.data;
|
const rowData = row.data;
|
||||||
removeRow(oldPosition, animationPower);
|
removeRow(oldPosition, animationPower);
|
||||||
insertRow(newPosition, rowData, animationPower);
|
insertRow(newPosition, rowData, animationPower);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function animateStep() {
|
|
||||||
// animation must be symmetrical
|
|
||||||
for (var i = rowsFadingIn.length - 1; i >= 0; i--) { // backwards to allow removal
|
|
||||||
var row = rowsFadingIn[i];
|
|
||||||
var step = ++row.animationStep;
|
|
||||||
var animHeight = getAnimationHeight(step, row.animationPower);
|
|
||||||
var node = rowNode(row);
|
|
||||||
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
|
|
||||||
if (step <= -OPACITY_STEPS) {
|
|
||||||
node.find('td').height(animHeight);
|
|
||||||
} else if (step == -OPACITY_STEPS + 1) {
|
|
||||||
node.empty().append(createUserRowTds(animHeight, row.data))
|
|
||||||
.find('td').css('opacity', baseOpacity * 1 / OPACITY_STEPS);
|
|
||||||
} else if (step < 0) {
|
|
||||||
node.find('td').css('opacity', baseOpacity * (OPACITY_STEPS - (-step)) / OPACITY_STEPS).height(animHeight);
|
|
||||||
} else if (step == 0) {
|
|
||||||
// set HTML in case modified during animation
|
|
||||||
node.empty().append(createUserRowTds(animHeight, row.data))
|
|
||||||
.find('td').css('opacity', baseOpacity * 1).height(animHeight);
|
|
||||||
rowsFadingIn.splice(i, 1); // remove from set
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var i = rowsFadingOut.length - 1; i >= 0; i--) { // backwards to allow removal
|
|
||||||
var row = rowsFadingOut[i];
|
|
||||||
var step = ++row.animationStep;
|
|
||||||
var node = rowNode(row);
|
|
||||||
var animHeight = getAnimationHeight(step, row.animationPower);
|
|
||||||
var baseOpacity = (row.opacity === undefined ? 1 : row.opacity);
|
|
||||||
if (step < OPACITY_STEPS) {
|
|
||||||
node.find('td').css('opacity', baseOpacity * (OPACITY_STEPS - step) / OPACITY_STEPS).height(animHeight);
|
|
||||||
} else if (step == OPACITY_STEPS) {
|
|
||||||
node.empty().append(createEmptyRowTds(animHeight));
|
|
||||||
} else if (step <= ANIMATION_END) {
|
|
||||||
node.find('td').height(animHeight);
|
|
||||||
} else {
|
|
||||||
rowsFadingOut.splice(i, 1); // remove from set
|
|
||||||
node.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOtherUserInputs();
|
|
||||||
|
|
||||||
return (rowsFadingIn.length > 0) || (rowsFadingOut.length > 0); // is more to do
|
|
||||||
}
|
|
||||||
|
|
||||||
const self = {
|
const self = {
|
||||||
insertRow,
|
insertRow,
|
||||||
|
@ -302,7 +301,7 @@ const paduserlist = (function () {
|
||||||
const otherUsersInfo = [];
|
const otherUsersInfo = [];
|
||||||
const otherUsersData = [];
|
const otherUsersData = [];
|
||||||
|
|
||||||
function rowManagerMakeNameEditor(jnode, userId) {
|
const rowManagerMakeNameEditor = (jnode, userId) => {
|
||||||
setUpEditable(jnode, () => {
|
setUpEditable(jnode, () => {
|
||||||
const existingIndex = findExistingIndex(userId);
|
const existingIndex = findExistingIndex(userId);
|
||||||
if (existingIndex >= 0) {
|
if (existingIndex >= 0) {
|
||||||
|
@ -313,26 +312,26 @@ const paduserlist = (function () {
|
||||||
}, (newName) => {
|
}, (newName) => {
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
jnode.addClass('editempty');
|
jnode.addClass('editempty');
|
||||||
jnode.val(_('pad.userlist.unnamed'));
|
jnode.val(html10n.get('pad.userlist.unnamed'));
|
||||||
} else {
|
} else {
|
||||||
jnode.attr('disabled', 'disabled');
|
jnode.attr('disabled', 'disabled');
|
||||||
pad.suggestUserName(userId, newName);
|
pad.suggestUserName(userId, newName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function findExistingIndex(userId) {
|
const findExistingIndex = (userId) => {
|
||||||
let existingIndex = -1;
|
let existingIndex = -1;
|
||||||
for (let i = 0; i < otherUsersInfo.length; i++) {
|
for (let i = 0; i < otherUsersInfo.length; i++) {
|
||||||
if (otherUsersInfo[i].userId == userId) {
|
if (otherUsersInfo[i].userId === userId) {
|
||||||
existingIndex = i;
|
existingIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return existingIndex;
|
return existingIndex;
|
||||||
}
|
};
|
||||||
|
|
||||||
function setUpEditable(jqueryNode, valueGetter, valueSetter) {
|
const setUpEditable = (jqueryNode, valueGetter, valueSetter) => {
|
||||||
jqueryNode.bind('focus', (evt) => {
|
jqueryNode.bind('focus', (evt) => {
|
||||||
const oldValue = valueGetter();
|
const oldValue = valueGetter();
|
||||||
if (jqueryNode.val() !== oldValue) {
|
if (jqueryNode.val() !== oldValue) {
|
||||||
|
@ -350,16 +349,18 @@ const paduserlist = (function () {
|
||||||
jqueryNode.val(valueGetter()).blur();
|
jqueryNode.val(valueGetter()).blur();
|
||||||
});
|
});
|
||||||
jqueryNode.removeAttr('disabled').addClass('editable');
|
jqueryNode.removeAttr('disabled').addClass('editable');
|
||||||
}
|
};
|
||||||
|
|
||||||
var pad = undefined;
|
let pad = undefined;
|
||||||
var self = {
|
const self = {
|
||||||
init(myInitialUserInfo, _pad) {
|
init(myInitialUserInfo, _pad) {
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
|
|
||||||
self.setMyUserInfo(myInitialUserInfo);
|
self.setMyUserInfo(myInitialUserInfo);
|
||||||
|
|
||||||
if ($('#online_count').length === 0) $('#editbar [data-key=showusers] > a').append('<span id="online_count">1</span>');
|
if ($('#online_count').length === 0) {
|
||||||
|
$('#editbar [data-key=showusers] > a').append('<span id="online_count">1</span>');
|
||||||
|
}
|
||||||
|
|
||||||
$('#otheruserstable tr').remove();
|
$('#otheruserstable tr').remove();
|
||||||
|
|
||||||
|
@ -388,23 +389,24 @@ const paduserlist = (function () {
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
usersOnline() {
|
usersOnline: () => {
|
||||||
// Returns an object of users who are currently online on this pad
|
// Returns an object of users who are currently online on this pad
|
||||||
const userList = [].concat(otherUsersInfo); // Make a copy of the otherUsersInfo, otherwise every call to users modifies the referenced array
|
// Make a copy of the otherUsersInfo, otherwise every call to users
|
||||||
|
// modifies the referenced array
|
||||||
|
const userList = [].concat(otherUsersInfo);
|
||||||
// Now we need to add ourselves..
|
// Now we need to add ourselves..
|
||||||
userList.push(myUserInfo);
|
userList.push(myUserInfo);
|
||||||
return userList;
|
return userList;
|
||||||
},
|
},
|
||||||
users() {
|
users: () => {
|
||||||
// Returns an object of users who have been on this pad
|
// Returns an object of users who have been on this pad
|
||||||
const userList = self.usersOnline();
|
const userList = self.usersOnline();
|
||||||
|
|
||||||
// Now we add historical authors
|
// Now we add historical authors
|
||||||
const historical = clientVars.collab_client_vars.historicalAuthorData;
|
const historical = clientVars.collab_client_vars.historicalAuthorData;
|
||||||
for (const key in historical) {
|
for (const [key, {userId}] of Object.entries(historical)) {
|
||||||
var userId = historical[key].userId;
|
|
||||||
// Check we don't already have this author in our array
|
// Check we don't already have this author in our array
|
||||||
var exists = false;
|
let exists = false;
|
||||||
|
|
||||||
userList.forEach((user) => {
|
userList.forEach((user) => {
|
||||||
if (user.userId === userId) exists = true;
|
if (user.userId === userId) exists = true;
|
||||||
|
@ -416,7 +418,7 @@ const paduserlist = (function () {
|
||||||
}
|
}
|
||||||
return userList;
|
return userList;
|
||||||
},
|
},
|
||||||
setMyUserInfo(info) {
|
setMyUserInfo: (info) => {
|
||||||
// translate the colorId
|
// translate the colorId
|
||||||
if (typeof info.colorId === 'number') {
|
if (typeof info.colorId === 'number') {
|
||||||
info.colorId = clientVars.colorPalette[info.colorId];
|
info.colorId = clientVars.colorPalette[info.colorId];
|
||||||
|
@ -427,8 +429,8 @@ const paduserlist = (function () {
|
||||||
|
|
||||||
self.renderMyUserInfo();
|
self.renderMyUserInfo();
|
||||||
},
|
},
|
||||||
userJoinOrUpdate(info) {
|
userJoinOrUpdate: (info) => {
|
||||||
if ((!info.userId) || (info.userId == myUserInfo.userId)) {
|
if ((!info.userId) || (info.userId === myUserInfo.userId)) {
|
||||||
// not sure how this would happen
|
// not sure how this would happen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -438,7 +440,8 @@ const paduserlist = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
const userData = {};
|
const userData = {};
|
||||||
userData.color = typeof info.colorId === 'number' ? clientVars.colorPalette[info.colorId] : info.colorId;
|
userData.color = typeof info.colorId === 'number'
|
||||||
|
? clientVars.colorPalette[info.colorId] : info.colorId;
|
||||||
userData.name = info.name;
|
userData.name = info.name;
|
||||||
userData.status = '';
|
userData.status = '';
|
||||||
userData.activity = '';
|
userData.activity = '';
|
||||||
|
@ -460,12 +463,12 @@ const paduserlist = (function () {
|
||||||
const nameThis = (info.name || '').toLowerCase();
|
const nameThis = (info.name || '').toLowerCase();
|
||||||
const idN = infoN.userId;
|
const idN = infoN.userId;
|
||||||
const idThis = info.userId;
|
const idThis = info.userId;
|
||||||
return (nameN > nameThis) || (nameN == nameThis && idN > idThis);
|
return (nameN > nameThis) || (nameN === nameThis && idN > idThis);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existingIndex >= 0) {
|
if (existingIndex >= 0) {
|
||||||
// update
|
// update
|
||||||
if (existingIndex == newIndex) {
|
if (existingIndex === newIndex) {
|
||||||
otherUsersInfo[existingIndex] = info;
|
otherUsersInfo[existingIndex] = info;
|
||||||
otherUsersData[existingIndex] = userData;
|
otherUsersData[existingIndex] = userData;
|
||||||
rowManager.updateRow(existingIndex, userData);
|
rowManager.updateRow(existingIndex, userData);
|
||||||
|
@ -485,10 +488,10 @@ const paduserlist = (function () {
|
||||||
|
|
||||||
self.updateNumberOfOnlineUsers();
|
self.updateNumberOfOnlineUsers();
|
||||||
},
|
},
|
||||||
updateNumberOfOnlineUsers() {
|
updateNumberOfOnlineUsers: () => {
|
||||||
let online = 1; // you are always online!
|
let online = 1; // you are always online!
|
||||||
for (let i = 0; i < otherUsersData.length; i++) {
|
for (let i = 0; i < otherUsersData.length; i++) {
|
||||||
if (otherUsersData[i].status == '') {
|
if (otherUsersData[i].status === '') {
|
||||||
online++;
|
online++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,7 +500,7 @@ const paduserlist = (function () {
|
||||||
|
|
||||||
return online;
|
return online;
|
||||||
},
|
},
|
||||||
userLeave(info) {
|
userLeave: (info) => {
|
||||||
const existingIndex = findExistingIndex(info.userId);
|
const existingIndex = findExistingIndex(info.userId);
|
||||||
if (existingIndex >= 0) {
|
if (existingIndex >= 0) {
|
||||||
const userData = otherUsersData[existingIndex];
|
const userData = otherUsersData[existingIndex];
|
||||||
|
@ -510,11 +513,12 @@ const paduserlist = (function () {
|
||||||
// joins, or updates happen for this user in the
|
// joins, or updates happen for this user in the
|
||||||
// next N seconds, to remove the user from the list.
|
// next N seconds, to remove the user from the list.
|
||||||
const thisUserId = info.userId;
|
const thisUserId = info.userId;
|
||||||
var thisLeaveTimer = window.setTimeout(() => {
|
const thisLeaveTimer = window.setTimeout(() => {
|
||||||
const newExistingIndex = findExistingIndex(thisUserId);
|
const newExistingIndex = findExistingIndex(thisUserId);
|
||||||
if (newExistingIndex >= 0) {
|
if (newExistingIndex >= 0) {
|
||||||
const newUserData = otherUsersData[newExistingIndex];
|
const newUserData = otherUsersData[newExistingIndex];
|
||||||
if (newUserData.status == 'Disconnected' && newUserData.leaveTimer == thisLeaveTimer) {
|
if (newUserData.status === 'Disconnected' &&
|
||||||
|
newUserData.leaveTimer === thisLeaveTimer) {
|
||||||
otherUsersInfo.splice(newExistingIndex, 1);
|
otherUsersInfo.splice(newExistingIndex, 1);
|
||||||
otherUsersData.splice(newExistingIndex, 1);
|
otherUsersData.splice(newExistingIndex, 1);
|
||||||
rowManager.removeRow(newExistingIndex);
|
rowManager.removeRow(newExistingIndex);
|
||||||
|
@ -529,7 +533,7 @@ const paduserlist = (function () {
|
||||||
|
|
||||||
self.updateNumberOfOnlineUsers();
|
self.updateNumberOfOnlineUsers();
|
||||||
},
|
},
|
||||||
renderMyUserInfo() {
|
renderMyUserInfo: () => {
|
||||||
if (myUserInfo.name) {
|
if (myUserInfo.name) {
|
||||||
$('#myusernameedit').removeClass('editempty').val(myUserInfo.name);
|
$('#myusernameedit').removeClass('editempty').val(myUserInfo.name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -549,23 +553,20 @@ const paduserlist = (function () {
|
||||||
return self;
|
return self;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
function getColorPickerSwatchIndex(jnode) {
|
const getColorPickerSwatchIndex = (jnode) => $('#colorpickerswatches li').index(jnode);
|
||||||
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
|
|
||||||
return $('#colorpickerswatches li').index(jnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeColorPicker(accept) {
|
const closeColorPicker = (accept) => {
|
||||||
if (accept) {
|
if (accept) {
|
||||||
var newColor = $('#mycolorpickerpreview').css('background-color');
|
let newColor = $('#mycolorpickerpreview').css('background-color');
|
||||||
const parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
const parts = newColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||||
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"]
|
// parts now should be ["rgb(0, 70, 255", "0", "70", "255"]
|
||||||
if (parts) {
|
if (parts) {
|
||||||
delete (parts[0]);
|
delete (parts[0]);
|
||||||
for (let i = 1; i <= 3; ++i) {
|
for (let i = 1; i <= 3; ++i) {
|
||||||
parts[i] = parseInt(parts[i]).toString(16);
|
parts[i] = parseInt(parts[i]).toString(16);
|
||||||
if (parts[i].length == 1) parts[i] = `0${parts[i]}`;
|
if (parts[i].length === 1) parts[i] = `0${parts[i]}`;
|
||||||
}
|
}
|
||||||
var newColor = `#${parts.join('')}`; // "0070ff"
|
newColor = `#${parts.join('')}`; // "0070ff"
|
||||||
}
|
}
|
||||||
myUserInfo.colorId = newColor;
|
myUserInfo.colorId = newColor;
|
||||||
pad.notifyChangeColor(newColor);
|
pad.notifyChangeColor(newColor);
|
||||||
|
@ -577,10 +578,9 @@ function closeColorPicker(accept) {
|
||||||
|
|
||||||
colorPickerOpen = false;
|
colorPickerOpen = false;
|
||||||
$('#mycolorpicker').removeClass('popup-show');
|
$('#mycolorpicker').removeClass('popup-show');
|
||||||
}
|
};
|
||||||
|
|
||||||
function showColorPicker() {
|
const showColorPicker = () => {
|
||||||
previousColorId = myUserInfo.colorId;
|
|
||||||
$.farbtastic('#colorpicker').setColor(myUserInfo.colorId);
|
$.farbtastic('#colorpicker').setColor(myUserInfo.colorId);
|
||||||
|
|
||||||
if (!colorPickerOpen) {
|
if (!colorPickerOpen) {
|
||||||
|
@ -613,6 +613,6 @@ function showColorPicker() {
|
||||||
$('#colorpickerswatches li').removeClass('picked');
|
$('#colorpickerswatches li').removeClass('picked');
|
||||||
$($('#colorpickerswatches li')[myUserInfo.colorId]).addClass('picked'); // seems weird
|
$($('#colorpickerswatches li')[myUserInfo.colorId]).addClass('picked'); // seems weird
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
exports.paduserlist = paduserlist;
|
exports.paduserlist = paduserlist;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
* This code is mostly from the old Etherpad. Please help us to comment this code.
|
||||||
* This helps other people to understand this code better and helps them to improve it.
|
* This helps other people to understand this code better and helps them to improve it.
|
||||||
|
@ -20,8 +22,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const Security = require('./security');
|
const Security = require('./security');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue