mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-31 19:02:59 +01:00
lint: Fix some straightforward ESLint errors
This commit is contained in:
parent
e66e8a4eb2
commit
ca01856f94
3 changed files with 139 additions and 113 deletions
|
@ -20,13 +20,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
const Security = require('./security');
|
const Security = require('./security');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
|
* Generates a random String with the given length. Is needed to generate the Author, Group,
|
||||||
|
* readonly, session Ids
|
||||||
*/
|
*/
|
||||||
|
const randomString = (len) => {
|
||||||
function randomString(len) {
|
|
||||||
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||||
let randomstring = '';
|
let randomstring = '';
|
||||||
len = len || 20;
|
len = len || 20;
|
||||||
|
@ -35,41 +37,69 @@ function randomString(len) {
|
||||||
randomstring += chars.substring(rnum, rnum + 1);
|
randomstring += chars.substring(rnum, rnum + 1);
|
||||||
}
|
}
|
||||||
return randomstring;
|
return randomstring;
|
||||||
}
|
};
|
||||||
|
|
||||||
var padutils = {
|
const padutils = {
|
||||||
escapeHtml(x) {
|
escapeHtml: (x) => Security.escapeHTML(String(x)),
|
||||||
return Security.escapeHTML(String(x));
|
uniqueId: () => {
|
||||||
},
|
|
||||||
uniqueId() {
|
|
||||||
const pad = require('./pad').pad; // Sidestep circular dependency
|
const pad = require('./pad').pad; // Sidestep circular dependency
|
||||||
function encodeNum(n, width) {
|
// returns string that is exactly 'width' chars, padding with zeros and taking rightmost digits
|
||||||
// returns string that is exactly 'width' chars, padding with zeros
|
const encodeNum =
|
||||||
// and taking rightmost digits
|
(n, width) => (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
|
||||||
return (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
|
return [
|
||||||
}
|
pad.getClientIp(),
|
||||||
return [pad.getClientIp(), encodeNum(+new Date(), 7), encodeNum(Math.floor(Math.random() * 1e9), 4)].join('.');
|
encodeNum(+new Date(), 7),
|
||||||
|
encodeNum(Math.floor(Math.random() * 1e9), 4),
|
||||||
|
].join('.');
|
||||||
},
|
},
|
||||||
// e.g. "Thu Jun 18 2009 13:09"
|
// e.g. "Thu Jun 18 2009 13:09"
|
||||||
simpleDateTime(date) {
|
simpleDateTime: (date) => {
|
||||||
const d = new Date(+date); // accept either number or date
|
const d = new Date(+date); // accept either number or date
|
||||||
const dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
|
const dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
|
||||||
const month = (['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])[d.getMonth()];
|
const month = ([
|
||||||
|
'Jan',
|
||||||
|
'Feb',
|
||||||
|
'Mar',
|
||||||
|
'Apr',
|
||||||
|
'May',
|
||||||
|
'Jun',
|
||||||
|
'Jul',
|
||||||
|
'Aug',
|
||||||
|
'Sep',
|
||||||
|
'Oct',
|
||||||
|
'Nov',
|
||||||
|
'Dec',
|
||||||
|
])[d.getMonth()];
|
||||||
const dayOfMonth = d.getDate();
|
const dayOfMonth = d.getDate();
|
||||||
const year = d.getFullYear();
|
const year = d.getFullYear();
|
||||||
const hourmin = `${d.getHours()}:${(`0${d.getMinutes()}`).slice(-2)}`;
|
const hourmin = `${d.getHours()}:${(`0${d.getMinutes()}`).slice(-2)}`;
|
||||||
return `${dayOfWeek} ${month} ${dayOfMonth} ${year} ${hourmin}`;
|
return `${dayOfWeek} ${month} ${dayOfMonth} ${year} ${hourmin}`;
|
||||||
},
|
},
|
||||||
findURLs(text) {
|
findURLs: (text) => {
|
||||||
// copied from ACE
|
// copied from ACE
|
||||||
const _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
|
const _REGEX_WORDCHAR = new RegExp(`[${[
|
||||||
const _REGEX_URLCHAR = new RegExp(`(${/[-:@a-zA-Z0-9_.,~%+\/?=&#;()$]/.source}|${_REGEX_WORDCHAR.source})`);
|
'\u0030-\u0039',
|
||||||
const _REGEX_URL = new RegExp(`${/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|(about|geo|mailto|tel):)/.source + _REGEX_URLCHAR.source}*(?![:.,;])${_REGEX_URLCHAR.source}`, 'g');
|
'\u0041-\u005A',
|
||||||
|
'\u0061-\u007A',
|
||||||
|
'\u00C0-\u00D6',
|
||||||
|
'\u00D8-\u00F6',
|
||||||
|
'\u00F8-\u00FF',
|
||||||
|
'\u0100-\u1FFF',
|
||||||
|
'\u3040-\u9FFF',
|
||||||
|
'\uF900-\uFDFF',
|
||||||
|
'\uFE70-\uFEFE',
|
||||||
|
'\uFF10-\uFF19',
|
||||||
|
'\uFF21-\uFF3A',
|
||||||
|
'\uFF41-\uFF5A',
|
||||||
|
'\uFF66-\uFFDC',
|
||||||
|
].join('')}]`);
|
||||||
|
const _REGEX_URLCHAR = new RegExp(`([-:@a-zA-Z0-9_.,~%+/?=&#;()$]|${_REGEX_WORDCHAR.source})`);
|
||||||
|
const _REGEX_URL = new RegExp(
|
||||||
|
'(?:(?:https?|s?ftp|ftps|file|nfs)://|(about|geo|mailto|tel):)' +
|
||||||
|
`${_REGEX_URLCHAR.source}*(?![:.,;])${_REGEX_URLCHAR.source}`, 'g');
|
||||||
|
|
||||||
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
||||||
|
const _findURLs = (text) => {
|
||||||
|
|
||||||
function _findURLs(text) {
|
|
||||||
_REGEX_URL.lastIndex = 0;
|
_REGEX_URL.lastIndex = 0;
|
||||||
let urls = null;
|
let urls = null;
|
||||||
let execResult;
|
let execResult;
|
||||||
|
@ -81,34 +111,39 @@ var padutils = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
};
|
||||||
|
|
||||||
return _findURLs(text);
|
return _findURLs(text);
|
||||||
},
|
},
|
||||||
escapeHtmlWithClickableLinks(text, target) {
|
escapeHtmlWithClickableLinks: (text, target) => {
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
const pieces = [];
|
const pieces = [];
|
||||||
const urls = padutils.findURLs(text);
|
const urls = padutils.findURLs(text);
|
||||||
|
|
||||||
function advanceTo(i) {
|
const advanceTo = (i) => {
|
||||||
if (i > idx) {
|
if (i > idx) {
|
||||||
pieces.push(Security.escapeHTML(text.substring(idx, i)));
|
pieces.push(Security.escapeHTML(text.substring(idx, i)));
|
||||||
idx = i;
|
idx = i;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
if (urls) {
|
if (urls) {
|
||||||
for (let j = 0; j < urls.length; j++) {
|
for (let j = 0; j < urls.length; j++) {
|
||||||
const startIndex = urls[j][0];
|
const startIndex = urls[j][0];
|
||||||
const href = urls[j][1];
|
const href = urls[j][1];
|
||||||
advanceTo(startIndex);
|
advanceTo(startIndex);
|
||||||
// Using rel="noreferrer" stops leaking the URL/location of the pad when clicking links in the document.
|
// Using rel="noreferrer" stops leaking the URL/location of the pad when clicking links in
|
||||||
// Not all browsers understand this attribute, but it's part of the HTML5 standard.
|
// the document. Not all browsers understand this attribute, but it's part of the HTML5
|
||||||
// https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer
|
// standard. https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer
|
||||||
// Additionally, we do rel="noopener" to ensure a higher level of referrer security.
|
// Additionally, we do rel="noopener" to ensure a higher level of referrer security.
|
||||||
// https://html.spec.whatwg.org/multipage/links.html#link-type-noopener
|
// https://html.spec.whatwg.org/multipage/links.html#link-type-noopener
|
||||||
// https://mathiasbynens.github.io/rel-noopener/
|
// https://mathiasbynens.github.io/rel-noopener/
|
||||||
// https://github.com/ether/etherpad-lite/pull/3636
|
// https://github.com/ether/etherpad-lite/pull/3636
|
||||||
pieces.push('<a ', (target ? `target="${Security.escapeHTMLAttribute(target)}" ` : ''), 'href="', Security.escapeHTMLAttribute(href), '" rel="noreferrer noopener">');
|
pieces.push(
|
||||||
|
'<a ',
|
||||||
|
(target ? `target="${Security.escapeHTMLAttribute(target)}" ` : ''),
|
||||||
|
'href="',
|
||||||
|
Security.escapeHTMLAttribute(href),
|
||||||
|
'" rel="noreferrer noopener">');
|
||||||
advanceTo(startIndex + href.length);
|
advanceTo(startIndex + href.length);
|
||||||
pieces.push('</a>');
|
pieces.push('</a>');
|
||||||
}
|
}
|
||||||
|
@ -116,14 +151,14 @@ var padutils = {
|
||||||
advanceTo(text.length);
|
advanceTo(text.length);
|
||||||
return pieces.join('');
|
return pieces.join('');
|
||||||
},
|
},
|
||||||
bindEnterAndEscape(node, onEnter, onEscape) {
|
bindEnterAndEscape: (node, onEnter, onEscape) => {
|
||||||
// Use keypress instead of keyup in bindEnterAndEscape
|
// Use keypress instead of keyup in bindEnterAndEscape. Keyup event is fired on enter in IME
|
||||||
// Keyup event is fired on enter in IME (Input Method Editor), But
|
// (Input Method Editor), But keypress is not. So, I changed to use keypress instead of keyup.
|
||||||
// keypress is not. So, I changed to use keypress instead of keyup.
|
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox
|
||||||
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
|
// 3.6.10, Chrome 6.0.472, Safari 5.0).
|
||||||
if (onEnter) {
|
if (onEnter) {
|
||||||
node.keypress((evt) => {
|
node.keypress((evt) => {
|
||||||
if (evt.which == 13) {
|
if (evt.which === 13) {
|
||||||
onEnter(evt);
|
onEnter(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -131,18 +166,18 @@ var padutils = {
|
||||||
|
|
||||||
if (onEscape) {
|
if (onEscape) {
|
||||||
node.keydown((evt) => {
|
node.keydown((evt) => {
|
||||||
if (evt.which == 27) {
|
if (evt.which === 27) {
|
||||||
onEscape(evt);
|
onEscape(evt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
timediff(d) {
|
timediff: (d) => {
|
||||||
const pad = require('./pad').pad; // Sidestep circular dependency
|
const pad = require('./pad').pad; // Sidestep circular dependency
|
||||||
function format(n, word) {
|
const format = (n, word) => {
|
||||||
n = Math.round(n);
|
n = Math.round(n);
|
||||||
return (`${n} ${word}${n != 1 ? 's' : ''} ago`);
|
return (`${n} ${word}${n !== 1 ? 's' : ''} ago`);
|
||||||
}
|
};
|
||||||
d = Math.max(0, (+(new Date()) - (+d) - pad.clientTimeOffset) / 1000);
|
d = Math.max(0, (+(new Date()) - (+d) - pad.clientTimeOffset) / 1000);
|
||||||
if (d < 60) {
|
if (d < 60) {
|
||||||
return format(d, 'second');
|
return format(d, 'second');
|
||||||
|
@ -158,14 +193,14 @@ var padutils = {
|
||||||
d /= 24;
|
d /= 24;
|
||||||
return format(d, 'day');
|
return format(d, 'day');
|
||||||
},
|
},
|
||||||
makeAnimationScheduler(funcToAnimateOneStep, stepTime, stepsAtOnce) {
|
makeAnimationScheduler: (funcToAnimateOneStep, stepTime, stepsAtOnce) => {
|
||||||
if (stepsAtOnce === undefined) {
|
if (stepsAtOnce === undefined) {
|
||||||
stepsAtOnce = 1;
|
stepsAtOnce = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let animationTimer = null;
|
let animationTimer = null;
|
||||||
|
|
||||||
function scheduleAnimation() {
|
const scheduleAnimation = () => {
|
||||||
if (!animationTimer) {
|
if (!animationTimer) {
|
||||||
animationTimer = window.setTimeout(() => {
|
animationTimer = window.setTimeout(() => {
|
||||||
animationTimer = null;
|
animationTimer = null;
|
||||||
|
@ -181,43 +216,16 @@ var padutils = {
|
||||||
}
|
}
|
||||||
}, stepTime * stepsAtOnce);
|
}, stepTime * stepsAtOnce);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return {
|
|
||||||
scheduleAnimation,
|
|
||||||
};
|
};
|
||||||
|
return {scheduleAnimation};
|
||||||
},
|
},
|
||||||
makeShowHideAnimator(funcToArriveAtState, initiallyShown, fps, totalMs) {
|
makeShowHideAnimator: (funcToArriveAtState, initiallyShown, fps, totalMs) => {
|
||||||
let animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
|
let animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
|
||||||
const animationFrameDelay = 1000 / fps;
|
const animationFrameDelay = 1000 / fps;
|
||||||
const animationStep = animationFrameDelay / totalMs;
|
const animationStep = animationFrameDelay / totalMs;
|
||||||
|
|
||||||
const scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
|
const animateOneStep = () => {
|
||||||
|
if (animationState < -1 || animationState === 0) {
|
||||||
function doShow() {
|
|
||||||
animationState = -1;
|
|
||||||
funcToArriveAtState(animationState);
|
|
||||||
scheduleAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function doQuickShow() { // start showing without losing any fade-in progress
|
|
||||||
if (animationState < -1) {
|
|
||||||
animationState = -1;
|
|
||||||
} else if (animationState > 0) {
|
|
||||||
animationState = Math.max(-1, Math.min(0, -animationState));
|
|
||||||
}
|
|
||||||
funcToArriveAtState(animationState);
|
|
||||||
scheduleAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function doHide() {
|
|
||||||
if (animationState >= -1 && animationState <= 0) {
|
|
||||||
animationState = 1e-6;
|
|
||||||
scheduleAnimation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function animateOneStep() {
|
|
||||||
if (animationState < -1 || animationState == 0) {
|
|
||||||
return false;
|
return false;
|
||||||
} else if (animationState < 0) {
|
} else if (animationState < 0) {
|
||||||
// animate show
|
// animate show
|
||||||
|
@ -243,17 +251,37 @@ var padutils = {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const scheduleAnimation =
|
||||||
|
padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: doShow,
|
show: () => {
|
||||||
hide: doHide,
|
animationState = -1;
|
||||||
quickShow: doQuickShow,
|
funcToArriveAtState(animationState);
|
||||||
|
scheduleAnimation();
|
||||||
|
},
|
||||||
|
quickShow: () => { // start showing without losing any fade-in progress
|
||||||
|
if (animationState < -1) {
|
||||||
|
animationState = -1;
|
||||||
|
} else if (animationState > 0) {
|
||||||
|
animationState = Math.max(-1, Math.min(0, -animationState));
|
||||||
|
}
|
||||||
|
funcToArriveAtState(animationState);
|
||||||
|
scheduleAnimation();
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
if (animationState >= -1 && animationState <= 0) {
|
||||||
|
animationState = 1e-6;
|
||||||
|
scheduleAnimation();
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
_nextActionId: 1,
|
_nextActionId: 1,
|
||||||
uncanceledActions: {},
|
uncanceledActions: {},
|
||||||
getCancellableAction(actionType, actionFunc) {
|
getCancellableAction: (actionType, actionFunc) => {
|
||||||
let o = padutils.uncanceledActions[actionType];
|
let o = padutils.uncanceledActions[actionType];
|
||||||
if (!o) {
|
if (!o) {
|
||||||
o = {};
|
o = {};
|
||||||
|
@ -261,27 +289,27 @@ var padutils = {
|
||||||
}
|
}
|
||||||
const actionId = (padutils._nextActionId++);
|
const actionId = (padutils._nextActionId++);
|
||||||
o[actionId] = true;
|
o[actionId] = true;
|
||||||
return function () {
|
return () => {
|
||||||
const p = padutils.uncanceledActions[actionType];
|
const p = padutils.uncanceledActions[actionType];
|
||||||
if (p && p[actionId]) {
|
if (p && p[actionId]) {
|
||||||
actionFunc();
|
actionFunc();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
cancelActions(actionType) {
|
cancelActions: (actionType) => {
|
||||||
const o = padutils.uncanceledActions[actionType];
|
const o = padutils.uncanceledActions[actionType];
|
||||||
if (o) {
|
if (o) {
|
||||||
// clear it
|
// clear it
|
||||||
delete padutils.uncanceledActions[actionType];
|
delete padutils.uncanceledActions[actionType];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
makeFieldLabeledWhenEmpty(field, labelText) {
|
makeFieldLabeledWhenEmpty: (field, labelText) => {
|
||||||
field = $(field);
|
field = $(field);
|
||||||
|
|
||||||
function clear() {
|
const clear = () => {
|
||||||
field.addClass('editempty');
|
field.addClass('editempty');
|
||||||
field.val(labelText);
|
field.val(labelText);
|
||||||
}
|
};
|
||||||
field.focus(() => {
|
field.focus(() => {
|
||||||
if (field.hasClass('editempty')) {
|
if (field.hasClass('editempty')) {
|
||||||
field.val('');
|
field.val('');
|
||||||
|
@ -297,34 +325,28 @@ var padutils = {
|
||||||
clear,
|
clear,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getCheckbox(node) {
|
getCheckbox: (node) => $(node).is(':checked'),
|
||||||
return $(node).is(':checked');
|
setCheckbox: (node, value) => {
|
||||||
},
|
|
||||||
setCheckbox(node, value) {
|
|
||||||
if (value) {
|
if (value) {
|
||||||
$(node).attr('checked', 'checked');
|
$(node).attr('checked', 'checked');
|
||||||
} else {
|
} else {
|
||||||
$(node).removeAttr('checked');
|
$(node).removeAttr('checked');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bindCheckboxChange(node, func) {
|
bindCheckboxChange: (node, func) => {
|
||||||
$(node).change(func);
|
$(node).change(func);
|
||||||
},
|
},
|
||||||
encodeUserId(userId) {
|
encodeUserId: (userId) => userId.replace(/[^a-y0-9]/g, (c) => {
|
||||||
return userId.replace(/[^a-y0-9]/g, (c) => {
|
if (c === '.') return '-';
|
||||||
if (c == '.') return '-';
|
return `z${c.charCodeAt(0)}z`;
|
||||||
return `z${c.charCodeAt(0)}z`;
|
}),
|
||||||
});
|
decodeUserId: (encodedUserId) => encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, (cc) => {
|
||||||
},
|
if (cc === '-') { return '.'; } else if (cc.charAt(0) === 'z') {
|
||||||
decodeUserId(encodedUserId) {
|
return String.fromCharCode(Number(cc.slice(1, -1)));
|
||||||
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, (cc) => {
|
} else {
|
||||||
if (cc == '-') { return '.'; } else if (cc.charAt(0) == 'z') {
|
return cc;
|
||||||
return String.fromCharCode(Number(cc.slice(1, -1)));
|
}
|
||||||
} else {
|
}),
|
||||||
return cc;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let globalExceptionHandler = null;
|
let globalExceptionHandler = null;
|
||||||
|
@ -402,13 +424,13 @@ padutils.setupGlobalExceptionHandler = () => {
|
||||||
padutils.binarySearch = require('./ace2_common').binarySearch;
|
padutils.binarySearch = require('./ace2_common').binarySearch;
|
||||||
|
|
||||||
// https://stackoverflow.com/a/42660748
|
// https://stackoverflow.com/a/42660748
|
||||||
function inThirdPartyIframe() {
|
const inThirdPartyIframe = () => {
|
||||||
try {
|
try {
|
||||||
return (!window.top.location.hostname);
|
return (!window.top.location.hostname);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// This file is included from Node so that it can reuse randomString, but Node doesn't have a global
|
// This file is included from Node so that it can reuse randomString, but Node doesn't have a global
|
||||||
// window object.
|
// window object.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spys on socket.io messages and saves them into several arrays
|
* Spys on socket.io messages and saves them into several arrays
|
||||||
* that are visible in tests
|
* that are visible in tests
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
describe('timeslider follow', function () {
|
describe('timeslider follow', function () {
|
||||||
// create a new pad before each test run
|
// create a new pad before each test run
|
||||||
beforeEach(function (cb) {
|
beforeEach(function (cb) {
|
||||||
|
@ -23,7 +25,7 @@ describe('timeslider follow', function () {
|
||||||
helper.contentWindow().$('#playpause_button_icon').click();
|
helper.contentWindow().$('#playpause_button_icon').click();
|
||||||
|
|
||||||
let newTop;
|
let newTop;
|
||||||
return helper.waitForPromise(() => {
|
await helper.waitForPromise(() => {
|
||||||
newTop = helper.contentWindow().$('#innerdocbody').offset();
|
newTop = helper.contentWindow().$('#innerdocbody').offset();
|
||||||
return newTop.top < originalTop.top;
|
return newTop.top < originalTop.top;
|
||||||
});
|
});
|
||||||
|
@ -96,9 +98,9 @@ describe('timeslider follow', function () {
|
||||||
* @param {number} lineNum
|
* @param {number} lineNum
|
||||||
* @returns {boolean} scrolled to the lineOffset?
|
* @returns {boolean} scrolled to the lineOffset?
|
||||||
*/
|
*/
|
||||||
function hasFollowedToLine(lineNum) {
|
const hasFollowedToLine = (lineNum) => {
|
||||||
const scrollPosition = helper.contentWindow().$('#editorcontainerbox')[0].scrollTop;
|
const scrollPosition = helper.contentWindow().$('#editorcontainerbox')[0].scrollTop;
|
||||||
const lineOffset = helper.contentWindow().$('#innerdocbody').find(`div:nth-child(${lineNum})`)[0].offsetTop;
|
const lineOffset =
|
||||||
|
helper.contentWindow().$('#innerdocbody').find(`div:nth-child(${lineNum})`)[0].offsetTop;
|
||||||
return Math.abs(scrollPosition - lineOffset) < 1;
|
return Math.abs(scrollPosition - lineOffset) < 1;
|
||||||
}
|
};
|
||||||
|
|
Loading…
Reference in a new issue