]> BookStack Code Mirror - bookstack/blobdiff - resources/js/components/page-comment-reference.ts
Images: Added testing to cover animated avif handling
[bookstack] / resources / js / components / page-comment-reference.ts
index edf24354b3ba663f3a73f3c1557bd01beb9c0893..009e806c104d429cfa2451f4af68b20b26f803db 100644 (file)
@@ -4,6 +4,8 @@ import {el} from "../wysiwyg/utils/dom";
 import commentIcon from "@icons/comment.svg";
 import closeIcon from "@icons/close.svg";
 import {debounce, scrollAndHighlightElement} from "../services/util";
+import {EditorToolboxChangeEventData} from "./editor-toolbox";
+import {TabsChangeEvent} from "./tabs";
 
 /**
  * Track the close function for the current open marker so it can be closed
@@ -12,13 +14,13 @@ import {debounce, scrollAndHighlightElement} from "../services/util";
 let openMarkerClose: Function|null = null;
 
 export class PageCommentReference extends Component {
-    protected link: HTMLLinkElement;
-    protected reference: string;
+    protected link!: HTMLLinkElement;
+    protected reference!: string;
     protected markerWrap: HTMLElement|null = null;
 
-    protected viewCommentText: string;
-    protected jumpToThreadText: string;
-    protected closeText: string;
+    protected viewCommentText!: string;
+    protected jumpToThreadText!: string;
+    protected closeText!: string;
 
     setup() {
         this.link = this.$el as HTMLLinkElement;
@@ -28,36 +30,53 @@ export class PageCommentReference extends Component {
         this.closeText = this.$opts.closeText;
 
         // Show within page display area if seen
-        const pageContentArea = document.querySelector('.page-content');
-        if (pageContentArea instanceof HTMLElement && this.link.checkVisibility()) {
-            this.updateMarker(pageContentArea);
-        }
+        this.showForDisplay();
 
         // Handle editor view to show on comments toolbox view
-        window.addEventListener('editor-toolbox-change', (event) => {
-             const tabName: string = (event as {detail: {tab: string, open: boolean}}).detail.tab;
-             const isOpen = (event as {detail: {tab: string, open: boolean}}).detail.open;
-             if (tabName === 'comments' && isOpen) {
-                 this.showForEditor();
-             } else {
-                 this.hideMarker();
-             }
-        });
+        window.addEventListener('editor-toolbox-change', ((event: CustomEvent<EditorToolboxChangeEventData>) => {
+            const tabName: string = event.detail.tab;
+            const isOpen = event.detail.open;
+            if (tabName === 'comments' && isOpen && this.link.checkVisibility()) {
+                this.showForEditor();
+            } else {
+                this.hideMarker();
+            }
+        }) as EventListener);
+
+        // Handle visibility changes within editor toolbox archived details dropdown
+        window.addEventListener('toggle', event => {
+            if (event.target instanceof HTMLElement && event.target.contains(this.link)) {
+                window.requestAnimationFrame(() => {
+                    if (this.link.checkVisibility()) {
+                        this.showForEditor();
+                    } else {
+                        this.hideMarker();
+                    }
+                });
+            }
+        }, {capture: true});
 
         // Handle comments tab changes to hide/show markers & indicators
-        window.addEventListener('tabs-change', event => {
-            const sectionId = (event as {detail: {showing: string}}).detail.showing;
-            if (!sectionId.startsWith('comment-tab-panel') || !(pageContentArea instanceof HTMLElement)) {
+        window.addEventListener('tabs-change', ((event: CustomEvent<TabsChangeEvent>) => {
+            const sectionId = event.detail.showing;
+            if (!sectionId.startsWith('comment-tab-panel')) {
                 return;
             }
 
             const panel = document.getElementById(sectionId);
             if (panel?.contains(this.link)) {
-                this.updateMarker(pageContentArea);
+                this.showForDisplay();
             } else {
                 this.hideMarker();
             }
-        });
+        }) as EventListener);
+    }
+
+    public showForDisplay() {
+        const pageContentArea = document.querySelector('.page-content');
+        if (pageContentArea instanceof HTMLElement && this.link.checkVisibility()) {
+            this.updateMarker(pageContentArea);
+        }
     }
 
     protected showForEditor() {
@@ -90,15 +109,7 @@ export class PageCommentReference extends Component {
             return;
         }
 
-        const refCloneToAssess = refEl.cloneNode(true) as HTMLElement;
-        const toRemove = refCloneToAssess.querySelectorAll('[data-lexical-text]');
-        refCloneToAssess.removeAttribute('style');
-        for (const el of toRemove) {
-            el.after(...el.childNodes);
-            el.remove();
-        }
-
-        const actualHash = hashElement(refCloneToAssess);
+        const actualHash = hashElement(refEl);
         if (actualHash !== refHash) {
             this.link.classList.add('outdated');
         }