Sfoglia il codice sorgente

Fix docs panel placement and footnote backspace

Adjust Office Docs panel positioning so the find/comments panels align to the right edge and dynamically track the toolbar’s bottom as the ribbon resizes. Also add empty-footnote handling: pressing Backspace in a footnote that only contains its number now removes the footnote and all its references, restores caret position at the first reference, and refreshes document state/counters.
Toby Chui 16 ore fa
parent
commit
8b7229ada7
2 ha cambiato i file con 47 aggiunte e 4 eliminazioni
  1. 4 4
      src/web/Office/docs/docs.css
  2. 43 0
      src/web/Office/docs/docs.js

+ 4 - 4
src/web/Office/docs/docs.css

@@ -482,8 +482,8 @@ body.doc-show-boxes #editor > .col-span-all::after {
 /* ============ Find panel ============ */
 .of-find-panel {
     position: fixed;
-    top: 92px;
-    right: 26px;
+    top: 92px;   /* placeFindPanel() moves it to the ribbon's bottom edge */
+    right: 4px;
     z-index: 1000;
     background: var(--of-chrome-bg);
     border: 1px solid var(--of-border);
@@ -697,8 +697,8 @@ body.dark #editor span.doc-cmt { background: rgba(255, 213, 79, 0.22); }
 
 #docCmtPanel {
     position: fixed;
-    top: 92px;
-    right: 12px;
+    top: 92px;   /* placeFindPanel() moves it to the ribbon's bottom edge */
+    right: 4px;
     bottom: 40px;
     width: 270px;
     z-index: 850;

+ 43 - 0
src/web/Office/docs/docs.js

@@ -2044,8 +2044,18 @@
     }
 
     /* ================= find and replace ================= */
+    // the panel hangs from the bottom edge of the ribbon, whose height
+    // changes as it is collapsed, expanded or wraps
+    function placeFindPanel() {
+        var bar = document.getElementById("toolbar");
+        if (!bar) return;
+        document.getElementById("findPanel").style.top = Math.round(bar.getBoundingClientRect().bottom) + 4 + "px";
+    }
+    if (window.ResizeObserver) new ResizeObserver(placeFindPanel).observe(document.getElementById("toolbar"));
+    window.addEventListener("resize", placeFindPanel);
     function openFind(withReplace) {
         $("#findPanel").show();
+        placeFindPanel();
         if (withReplace) $("#replaceRow").show();
         var selTxt = savedRange ? savedRange.toString() : "";
         if (selTxt && selTxt.length <= 80 && selTxt.indexOf("\n") < 0) {
@@ -2460,6 +2470,33 @@
         fnMeasureEl.innerHTML = "";
         return h;
     }
+    // a note with nothing typed in it but its number
+    function footnoteIsEmpty(fn) {
+        var clone = fn.cloneNode(true);
+        var marks = clone.querySelectorAll(".doc-fnnum");
+        for (var m = 0; m < marks.length; m++) marks[m].parentNode.removeChild(marks[m]);
+        return !clone.textContent.replace(/[\s​]/g, "") &&
+            !clone.querySelector("img,svg,table,hr,video,iframe");
+    }
+    // Backspace in an empty note deletes it: its references leave the
+    // text and the caret goes back to where the first one was
+    function removeFootnote(id) {
+        var refs = editor.querySelectorAll('sup.doc-fnref[data-fn="' + id + '"]');
+        if (!refs.length) return;
+        var range = document.createRange();
+        range.setStartBefore(refs[0]);
+        range.collapse(true);
+        for (var i = 0; i < refs.length; i++) refs[i].parentNode.removeChild(refs[i]);
+        delete footnotes[id];
+        editor.focus();
+        var sel = window.getSelection();
+        sel.removeAllRanges();
+        sel.addRange(range);
+        savedRange = range.cloneRange();
+        afterEdit(true);
+        clearTimeout(countTimer);
+        updateCounts();
+    }
     function renderFootnoteAreas(pages, geo) {
         var old = pageEl.querySelectorAll(".doc-fn-area");
         for (var i = 0; i < old.length; i++) {
@@ -2481,6 +2518,12 @@
                     OfficeApp.markDirty();
                     undo.pushDebounced(snapshot, 600);
                 });
+                fn.addEventListener("keydown", function (e) {
+                    if (e.key !== "Backspace" || e.ctrlKey || e.metaKey || e.altKey) return;
+                    if (!footnoteIsEmpty(fn)) return;
+                    e.preventDefault();
+                    removeFootnote(fn.getAttribute("data-fn"));
+                });
             });
             pageEl.appendChild(area);
             runLayoutPasses(area);