@@ -4,6 +4,13 @@ import {buildForInput} from '../wysiwyg-tinymce/config';
44import { el } from "../wysiwyg/utils/dom" ;
55
66import commentIcon from "@icons/comment.svg"
7+ import closeIcon from "@icons/close.svg"
8+
9+ /**
10+ * Track the close function for the current open marker so it can be closed
11+ * when another is opened so we only show one marker comment thread at one time.
12+ */
13+ let openMarkerClose : Function | null = null ;
714
815export class PageComment extends Component {
916
@@ -13,6 +20,8 @@ export class PageComment extends Component {
1320 protected deletedText : string ;
1421 protected updatedText : string ;
1522 protected viewCommentText : string ;
23+ protected jumpToThreadText : string ;
24+ protected closeText : string ;
1625
1726 protected wysiwygEditor : any = null ;
1827 protected wysiwygLanguage : string ;
@@ -35,6 +44,8 @@ export class PageComment extends Component {
3544 this . deletedText = this . $opts . deletedText ;
3645 this . updatedText = this . $opts . updatedText ;
3746 this . viewCommentText = this . $opts . viewCommentText ;
47+ this . jumpToThreadText = this . $opts . jumpToThreadText ;
48+ this . closeText = this . $opts . closeText ;
3849
3950 // Editor reference and text options
4051 this . wysiwygLanguage = this . $opts . wysiwygLanguage ;
@@ -130,7 +141,7 @@ export class PageComment extends Component {
130141
131142 await window . $http . delete ( `/comment/${ this . commentId } ` ) ;
132143 this . $emit ( 'delete' ) ;
133- this . container . closest ( '.comment-branch' ) . remove ( ) ;
144+ this . container . closest ( '.comment-branch' ) ? .remove ( ) ;
134145 window . $events . success ( this . deletedText ) ;
135146 }
136147
@@ -196,16 +207,22 @@ export class PageComment extends Component {
196207 }
197208
198209 protected showCommentAtMarker ( marker : HTMLElement ) : void {
199-
210+ // Hide marker and close existing marker windows
211+ if ( openMarkerClose ) {
212+ openMarkerClose ( ) ;
213+ }
200214 marker . hidden = true ;
201- const readClone = this . container . closest ( '.comment-branch' ) . cloneNode ( true ) as HTMLElement ;
215+
216+ // Build comment window
217+ const readClone = ( this . container . closest ( '.comment-branch' ) as HTMLElement ) . cloneNode ( true ) as HTMLElement ;
202218 const toRemove = readClone . querySelectorAll ( '.actions, form' ) ;
203219 for ( const el of toRemove ) {
204220 el . remove ( ) ;
205221 }
206222
207- const close = el ( 'button' , { type : 'button' } , [ 'x' ] ) ;
208- const jump = el ( 'button' , { type : 'button' } , [ 'Jump to thread' ] ) ;
223+ const close = el ( 'button' , { type : 'button' , title : this . closeText } ) ;
224+ close . innerHTML = ( closeIcon as string ) ;
225+ const jump = el ( 'button' , { type : 'button' , 'data-action' : 'jump' } , [ this . jumpToThreadText ] ) ;
209226
210227 const commentWindow = el ( 'div' , {
211228 class : 'content-comment-window'
@@ -214,19 +231,29 @@ export class PageComment extends Component {
214231 class : 'content-comment-window-actions' ,
215232 } , [ jump , close ] ) ,
216233 el ( 'div' , {
217- class : 'content-comment-window-content' ,
234+ class : 'content-comment-window-content comment-container-compact comment-container-super-compact ' ,
218235 } , [ readClone ] ) ,
219236 ] ) ;
220237
221- marker . parentElement . append ( commentWindow ) ;
238+ marker . parentElement ? .append ( commentWindow ) ;
222239
240+ // Handle interaction within window
223241 const closeAction = ( ) => {
224242 commentWindow . remove ( ) ;
225243 marker . hidden = false ;
244+ window . removeEventListener ( 'click' , windowCloseAction ) ;
245+ openMarkerClose = null ;
226246 } ;
227247
228- close . addEventListener ( 'click' , closeAction . bind ( this ) ) ;
248+ const windowCloseAction = ( event : MouseEvent ) => {
249+ if ( ! ( marker . parentElement as HTMLElement ) . contains ( event . target as HTMLElement ) ) {
250+ closeAction ( ) ;
251+ }
252+ } ;
253+ window . addEventListener ( 'click' , windowCloseAction ) ;
229254
255+ openMarkerClose = closeAction ;
256+ close . addEventListener ( 'click' , closeAction . bind ( this ) ) ;
230257 jump . addEventListener ( 'click' , ( ) => {
231258 closeAction ( ) ;
232259 this . container . scrollIntoView ( { behavior : 'smooth' } ) ;
@@ -235,7 +262,12 @@ export class PageComment extends Component {
235262 highlightTarget . addEventListener ( 'animationend' , ( ) => highlightTarget . classList . remove ( 'anim-highlight' ) )
236263 } ) ;
237264
238- // TODO - Position wrapper sensibly
239- // TODO - Movement control?
265+ // Position window within bounds
266+ const commentWindowBounds = commentWindow . getBoundingClientRect ( ) ;
267+ const contentBounds = document . querySelector ( '.page-content' ) ?. getBoundingClientRect ( ) ;
268+ if ( contentBounds && commentWindowBounds . right > contentBounds . right ) {
269+ const diff = commentWindowBounds . right - contentBounds . right ;
270+ commentWindow . style . left = `-${ diff } px` ;
271+ }
240272 }
241273}
0 commit comments