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
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;
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<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: 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.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() {
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');
}
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) {
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 {