1- import { removeChildren } from "../../helpers/dom" ;
1+ import { forEachNodeList , removeChildren } from "../../helpers/dom" ;
2+ import { find } from "../../helpers/misc" ;
23import { Context , OverlayManagerClass } from "../../typing/context" ;
34import { OpenOverlay , OverlayChangeEvent } from "../../typing/open-overlay" ;
45import { WaterfallEntry } from "../../typing/waterfall" ;
@@ -9,8 +10,7 @@ class OverlayManager implements OverlayManagerClass {
910 /** Collection of currely open overlays */
1011 private openOverlays : OpenOverlay [ ] = [ ] ;
1112
12- // TODO: move `overlayHolder` to constructor
13- constructor ( private context : Context , private overlayHolder : SVGGElement ) {
13+ constructor ( private context : Context , private rowHolder : SVGGElement ) {
1414
1515 }
1616
@@ -19,8 +19,30 @@ class OverlayManager implements OverlayManagerClass {
1919 return this . openOverlays . reduce ( ( pre , curr ) => pre + curr . height , 0 ) ;
2020 }
2121
22- public getOpenOverlays ( ) {
23- return this . openOverlays ;
22+ /**
23+ * Get ref to Overlay SVG Element in DOM.
24+ *
25+ * _Item might be re-drawn, when another Overlay is changed_
26+ */
27+ public getOpenOverlayDomEl ( overlay : OpenOverlay ) {
28+ return this . rowHolder . querySelector ( `.overlay-index-${ overlay . index } ` ) as SVGGElement ;
29+ }
30+
31+ /**
32+ * Get ref to the last (DOM element wise) Overlay SVG Element in DOM.
33+ *
34+ * _Item might be re-drawn, when another Overlay is changed_
35+ */
36+ public getLastOpenOverlayDomEl ( ) {
37+ const overlays = this . rowHolder . querySelectorAll ( ".info-overlay-holder" ) ;
38+ return overlays . item ( overlays . length - 1 ) as SVGGElement ;
39+ }
40+
41+ /**
42+ * Are any overlays currently open?
43+ */
44+ public hasOpenOverlays ( ) {
45+ return this . openOverlays . length > 0 ;
2446 }
2547
2648 /**
@@ -42,6 +64,7 @@ class OverlayManager implements OverlayManagerClass {
4264 "openTabIndex" : 0 ,
4365 } ;
4466 this . openOverlays . push ( newOverlay ) ;
67+ this . openOverlays = this . openOverlays . sort ( ( a , b ) => a . index > b . index ? 1 : - 1 ) ;
4568
4669 this . renderOverlays ( detailsHeight ) ;
4770 this . context . pubSub . publishToOverlayChanges ( {
@@ -115,27 +138,47 @@ class OverlayManager implements OverlayManagerClass {
115138 * @param {SVGGElement } overlayHolder
116139 */
117140 private renderOverlays ( detailsHeight : number ) {
118- removeChildren ( this . overlayHolder ) ;
141+ // removeChildren(this.rowHolder );
119142
120143 let currY = 0 ;
121- this . openOverlays
122- . sort ( ( a , b ) => a . index > b . index ? 1 : - 1 )
123- . forEach ( ( overlay ) => {
124- let y = overlay . defaultY + currY ;
125- let infoOverlay = createRowInfoOverlay ( overlay , y , detailsHeight ) ;
126- // if overlay has a preview image show it
127- let previewImg = infoOverlay . querySelector ( "img.preview" ) as HTMLImageElement ;
128- if ( previewImg && ! previewImg . src ) {
129- previewImg . setAttribute ( "src" , previewImg . attributes . getNamedItem ( "data-src" ) . value ) ;
144+
145+ let updateHeight = ( overlay , y , currHeight ) => {
146+ currY += currHeight ;
147+ overlay . actualY = y ;
148+ overlay . height = currHeight ;
149+ } ;
150+
151+ let addNewOverlay = ( overlayHolder : SVGGElement , overlay : OpenOverlay ) => {
152+ let y = overlay . defaultY + currY ;
153+ let infoOverlay = createRowInfoOverlay ( overlay , y , detailsHeight ) ;
154+ // if overlay has a preview image show it
155+ let previewImg = infoOverlay . querySelector ( "img.preview" ) as HTMLImageElement ;
156+ if ( previewImg && ! previewImg . src ) {
157+ previewImg . setAttribute ( "src" , previewImg . attributes . getNamedItem ( "data-src" ) . value ) ;
158+ }
159+ overlayHolder . appendChild ( infoOverlay ) ;
160+ updateHeight ( overlay , y , infoOverlay . getBoundingClientRect ( ) . height ) ;
161+ } ;
162+
163+ const rowItems = this . rowHolder . getElementsByClassName ( "row-item" ) as NodeListOf < SVGAElement > ;
164+ forEachNodeList ( rowItems , ( rowItem , index ) => {
165+ const overlay = find ( this . openOverlays , ( o ) => o . index === index ) ;
166+ let overlayEl = rowItem . nextElementSibling . firstElementChild as SVGGElement ;
167+ if ( overlay === undefined ) {
168+ if ( overlayEl ) {
169+ // remove closed overlay
170+ removeChildren ( rowItem . nextElementSibling ) ;
130171 }
131- this . overlayHolder . appendChild ( infoOverlay ) ;
132-
133- let currHeight = infoOverlay . getBoundingClientRect ( ) . height ;
134- currY += currHeight ;
135- overlay . actualY = y ;
136- overlay . height = currHeight ;
137- return overlay ;
138- } ) ;
172+ return ; // not open
173+ }
174+ if ( overlayEl ) {
175+ updateHeight ( overlay , overlay . defaultY + currY , overlay . height ) ;
176+ const fo = overlayEl . getElementsByTagName ( "foreignObject" ) . item ( 0 ) as SVGForeignObjectElement ;
177+ fo . setAttribute ( "y" , overlay . actualY . toString ( ) ) ;
178+ return ;
179+ }
180+ addNewOverlay ( rowItem . nextElementSibling as SVGGElement , overlay ) ;
181+ } ) ;
139182 }
140183} ;
141184export {
0 commit comments