X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/e8f44186a8ebfac6789800211cb5a947991bf971..refs/heads/development:/resources/js/components/page-comment-reference.ts diff --git a/resources/js/components/page-comment-reference.ts b/resources/js/components/page-comment-reference.ts index 72e3dbe48..009e806c1 100644 --- a/resources/js/components/page-comment-reference.ts +++ b/resources/js/components/page-comment-reference.ts @@ -3,7 +3,9 @@ import {findTargetNodeAndOffset, hashElement} from "../services/dom"; import {el} from "../wysiwyg/utils/dom"; import commentIcon from "@icons/comment.svg"; import closeIcon from "@icons/close.svg"; -import {scrollAndHighlightElement} from "../services/util"; +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 {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,21 +30,53 @@ export class PageCommentReference extends Component { this.closeText = this.$opts.closeText; // Show within page display area if seen + this.showForDisplay(); + + // Handle editor view to show on comments toolbox view + window.addEventListener('editor-toolbox-change', ((event: CustomEvent) => { + 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: CustomEvent) => { + const sectionId = event.detail.showing; + if (!sectionId.startsWith('comment-tab-panel')) { + return; + } + + const panel = document.getElementById(sectionId); + if (panel?.contains(this.link)) { + this.showForDisplay(); + } else { + this.hideMarker(); + } + }) as EventListener); + } + + public showForDisplay() { const pageContentArea = document.querySelector('.page-content'); - if (pageContentArea instanceof HTMLElement) { + if (pageContentArea instanceof HTMLElement && this.link.checkVisibility()) { this.updateMarker(pageContentArea); } - - // 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(); - } - }); } protected showForEditor() { @@ -75,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'); } @@ -111,9 +137,10 @@ export class PageCommentReference extends Component { scrollAndHighlightElement(refEl); }); - window.addEventListener('resize', () => { + const debouncedReposition = debounce(() => { this.positionMarker(refEl, refRange); - }); + }, 50, false).bind(this); + window.addEventListener('resize', debouncedReposition); } protected positionMarker(targetEl: HTMLElement, range: string) { @@ -145,12 +172,13 @@ export class PageCommentReference extends Component { this.markerWrap.style.height = `${targetBounds.height}px`; } - protected hideMarker() { + public hideMarker() { // Hide marker and close existing marker windows if (openMarkerClose) { openMarkerClose(); } this.markerWrap?.remove(); + this.markerWrap = null; } protected showCommentAtMarker(marker: HTMLElement): void {