diff --git a/docker/etherpad/Dockerfile b/docker/etherpad/Dockerfile index 111b1dc5c5..4d2ac7d0d7 100644 --- a/docker/etherpad/Dockerfile +++ b/docker/etherpad/Dockerfile @@ -17,8 +17,17 @@ FROM docker.io/etherpad/etherpad:1.8.4 LABEL maintainer="infra-root@openstack.org" -# Install the headings plugin and fix css on 1.8.4. -# Newer etherpad shouldn't need the css fix. +USER root +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y patch && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* +USER etherpad +# Install the headings plugin and fix css and console logging on 1.8.4. +# Newer etherpad shouldn't need the css or console fixes. +COPY patches/ /patches/ RUN cd /opt/etherpad-lite && npm install ep_headings \ - && sed -i -e 's/padding: 6px 0 !important;/padding: 0 0 !important;/' \ - /opt/etherpad-lite/src/static/css/iframe_editor.css + && patch /opt/etherpad-lite/src/static/css/iframe_editor.css /patches/iframe_editor.css.patch \ + && patch /opt/etherpad-lite/src/static/js/ace.js /patches/ace.js.patch \ + && patch /opt/etherpad-lite/src/static/js/ace2_inner.js /patches/ace2_inner.js.patch diff --git a/docker/etherpad/patches/ace.js.patch b/docker/etherpad/patches/ace.js.patch new file mode 100644 index 0000000000..26ac5dd160 --- /dev/null +++ b/docker/etherpad/patches/ace.js.patch @@ -0,0 +1,11 @@ +--- a/src/static/js/ace.js ++++ b/src/static/js/ace.js +@@ -104,7 +104,7 @@ function Ace2Editor() + editor[fnName] = pendingInit(function(){ + if(fnName === "setAuthorInfo"){ + if(!arguments[0]){ +- top.console.warn("setAuthorInfo AuthorId not set for some reason", arguments); ++ // setAuthorInfo AuthorId not set for some reason + }else{ + info[prefix + fnName].apply(this, arguments); + } diff --git a/docker/etherpad/patches/ace2_inner.js.patch b/docker/etherpad/patches/ace2_inner.js.patch new file mode 100644 index 0000000000..e5acdf07a8 --- /dev/null +++ b/docker/etherpad/patches/ace2_inner.js.patch @@ -0,0 +1,247 @@ +--- a/src/static/js/ace2_inner.js ++++ b/src/static/js/ace2_inner.js +@@ -130,7 +130,6 @@ function Ace2Inner(){ + console = {}; + for (var i = 0; i < names.length; ++i) + console[names[i]] = noop; +- //top.console.error = function(str) { alert(str); }; + } + + var PROFILER = window.PROFILER; +@@ -265,7 +264,7 @@ function Ace2Inner(){ + { + if ((typeof author) != "string") + { +- top.console.error("Going to throw new error, potentially caused by: https://github.com/ether/etherpad-lite/issues/2802"); ++ // Potentially caused by: https://github.com/ether/etherpad-lite/issues/2802"); + throw new Error("setAuthorInfo: author (" + author + ") is not a string"); + } + if (!info) +@@ -370,7 +369,8 @@ function Ace2Inner(){ + + if (currentCallStack) + { +- top.console.error("Can't enter callstack " + type + ", already in " + currentCallStack.type); ++ // Do not uncomment this in production. It will break Etherpad being provided in iFrames. I'm leaving this in for testing usefulness. ++ // top.console.error("Can't enter callstack " + type + ", already in " + currentCallStack.type); + } + + var profiling = false; +@@ -378,7 +378,6 @@ function Ace2Inner(){ + function profileRest() + { + profiling = true; +- top.console.profile(); + } + + function newEditEvent(eventType) +@@ -468,7 +467,6 @@ function Ace2Inner(){ + documentAttributeManager: documentAttributeManager + }); + +- //top.console.log("Just did action for: "+type); + cleanExit = true; + } + catch (e) +@@ -484,7 +482,6 @@ function Ace2Inner(){ + finally + { + var cs = currentCallStack; +- //top.console.log("Finished action for: "+type); + if (cleanExit) + { + submitOldEvent(cs.editEvent); +@@ -518,7 +515,6 @@ function Ace2Inner(){ + } + } + currentCallStack = null; +- if (profiling) top.console.profileEnd(); + } + return result; + } +@@ -740,7 +736,6 @@ function Ace2Inner(){ + * See for reference: + * - https://github.com/ether/etherpad-lite/issues/3861 + */ +- top.console.warn('atext.text is an empty string(""). Replacing with "\\n". See issue #3861.'); + atext.text = "\n"; + } + +@@ -1056,7 +1051,6 @@ function Ace2Inner(){ + + function newTimeLimit(ms) + { +- //top.console.debug("new time limit"); + var startTime = now(); + var lastElapsed = 0; + var exceededAlready = false; +@@ -1067,7 +1061,6 @@ function Ace2Inner(){ + { + if ((!printedTrace)) + { // && now() - startTime - ms > 300) { +- //top.console.trace(); + printedTrace = true; + } + return true; +@@ -1076,8 +1069,6 @@ function Ace2Inner(){ + if (elapsed > ms) + { + exceededAlready = true; +- //top.console.debug("time limit hit, before was %d/%d", lastElapsed, ms); +- //top.console.trace(); + return true; + } + else +@@ -1176,7 +1167,6 @@ function Ace2Inner(){ + + var isTimeUp = newTimeLimit(250); + +- //top.console.time("idlework"); + var finishedImportantWork = false; + var finishedWork = false; + +@@ -1195,13 +1185,11 @@ function Ace2Inner(){ + + var visibleRange = scroll.getVisibleCharRange(rep); + var docRange = [0, rep.lines.totalWidth()]; +- //top.console.log("%o %o", docRange, visibleRange); + finishedImportantWork = true; + finishedWork = true; + } + finally + { +- //top.console.timeEnd("idlework"); + if (finishedWork) + { + idleWorkTimer.atMost(1000); +@@ -1284,7 +1272,6 @@ function Ace2Inner(){ + selectionNeedsResetting = true; + } + +- //if (timer()) top.console.dirxml(lineEntry.lineNode.dom); + if (firstLine === null) firstLine = lineIndex; + lastLine = lineIndex; + lineStart = lineEnd; +@@ -1295,7 +1282,6 @@ function Ace2Inner(){ + { + currentCallStack.selectionAffected = true; + } +- //top.console.debug("Recolored line range %d-%d", firstLine, lastLine); + } + + // like getSpansForRange, but for a line, and the func takes (text,class) +@@ -1364,7 +1350,6 @@ function Ace2Inner(){ + // (from how it looks in our representation) and record them in a way + // that can be used to "normalize" the document (apply the changes to our + // representation, and put the DOM in a canonical form). +- // top.console.log("observeChangesAroundNode(%o)", node); + var cleanNode; + var hasAdjacentDirtyness; + if (!isNodeDirty(node)) +@@ -1501,7 +1486,6 @@ function Ace2Inner(){ + observeSuspiciousNodes(); + p.mark("dirty"); + var dirtyRanges = getDirtyRanges(); +- //top.console.log("dirtyRanges: "+toSource(dirtyRanges)); + var dirtyRangesCheckOut = true; + var j = 0; + var a, b; +@@ -1535,8 +1519,6 @@ function Ace2Inner(){ + p.mark("getsel"); + var selection = getSelection(); + +- //top.console.log(magicdom.root.dom.innerHTML); +- //top.console.log("got selection: %o", selection); + var selStart, selEnd; // each one, if truthy, has [line,char] needed to set selection + var i = 0; + var splicesToDo = []; +@@ -1584,7 +1566,6 @@ function Ace2Inner(){ + // It could be SPAN or a DIV; basically this is any case where the contentCollector + // decides it isn't done. + // Note that this clean node might need to be there for the next dirty range. +- //top.console.log("inclusive of "+lastDirtyNode.next().dom.tagName); + b++; + var cleanLine = lastDirtyNode.nextSibling; + cc.collectContent(cleanLine); +@@ -1609,7 +1590,6 @@ function Ace2Inner(){ + // Firefox isn't quite so bad, but it's still pretty quirky. + var scrollToTheLeftNeeded = true; + } +- // top.console.log("Editor warning: " + linesWrapped + " long line" + (linesWrapped == 1 ? " was" : "s were") + " hard-wrapped into " + ccData.numLinesAfter + " lines."); + } + + if (ss[0] >= 0) selStart = [ss[0] + a + netNumLinesChangeSoFar, ss[1]]; +@@ -1673,7 +1653,6 @@ function Ace2Inner(){ + if(n.parentNode) n.parentNode.removeChild(n); + + //dmesg(htmlPrettyEscape(htmlForRemovedChild(n))); +- //top.console.log("removed: "+id); + }); + + if(scrollToTheLeftNeeded){ // needed to stop chrome from breaking the ui when long strings without spaces are pasted +@@ -1893,6 +1872,7 @@ function Ace2Inner(){ + { + var line = lineAndChar[0]; + var charsLeft = lineAndChar[1]; ++ // Do not uncomment this in production it will break iFrames. + //top.console.log("line: %d, key: %s, node: %o", line, rep.lines.atIndex(line).key, + //getCleanNodeByKey(rep.lines.atIndex(line).key)); + var lineEntry = rep.lines.atIndex(line); +@@ -2018,7 +1998,6 @@ function Ace2Inner(){ + n = parNode; + } + } +- if (n.id === "") top.console.debug("BAD"); + if (n.firstChild && isBlockElement(n.firstChild)) + { + col += 1; // lineMarker +@@ -2905,11 +2884,13 @@ function Ace2Inner(){ + } + + return true; ++ // Do not uncomment this in production it will break iFrames. + //top.console.log("selStart: %o, selEnd: %o, focusAtStart: %s", rep.selStart, rep.selEnd, + //String(!!rep.selFocusAtStart)); + } + return false; +- //top.console.log("%o %o %s", rep.selStart, rep.selEnd, rep.selFocusAtStart); ++ // Do not uncomment this in production it will break iFrames. ++ //top.console.log("%o %o %s", rep.selStart, rep.selEnd, rep.selFocusAtStart); + } + + function isPadLoading(eventType) +@@ -3142,14 +3123,13 @@ function Ace2Inner(){ + // returns whether line was already correctly assigned (i.e. correctly + // clean or dirty, according to cleanRanges, and if clean, correctly + // attached or not attached (i.e. in the same range as) the prev and next lines). +- //top.console.log("correctly assigning: %d", line); + var rng = rangeForLine(line); + var lineClean = isClean(line); + if (rng < 0) + { + if (lineClean) + { +- top.console.debug("somehow lost clean line"); ++ // somehow lost clean line + } + return true; + } +@@ -3229,7 +3209,6 @@ function Ace2Inner(){ + detectChangesAroundLine(N - 1, 1); + + p.mark("obs"); +- //top.console.log("observedChanges: "+toSource(observedChanges)); + for (var k in observedChanges.cleanNodesNearChanges) + { + var key = k.substring(1); +@@ -4708,10 +4687,6 @@ function Ace2Inner(){ + // can handle "backwards"-oriented selection, shift-arrow-keys move start + // of selection + browserSelection.collapse(end.container, end.offset); +- //top.console.trace(); +- //top.console.log(htmlPrettyEscape(rep.alltext)); +- //top.console.log("%o %o", rep.selStart, rep.selEnd); +- //top.console.log("%o %d", start.container, start.offset); + browserSelection.extend(start.container, start.offset); + } + else diff --git a/docker/etherpad/patches/iframe_editor.css.patch b/docker/etherpad/patches/iframe_editor.css.patch new file mode 100644 index 0000000000..8b2442f360 --- /dev/null +++ b/docker/etherpad/patches/iframe_editor.css.patch @@ -0,0 +1,11 @@ +--- iframe_editor.css 2020-07-17 10:26:43.835522898 -0700 ++++ iframe_editor.css.fixed 2020-07-17 10:26:59.972181257 -0700 +@@ -51,7 +51,7 @@ + + #innerdocbody span { + line-height: 125%; +- padding: 6px 0 !important; ++ padding: 0 0 !important; + } + + option {