@@ -58,7 +58,7 @@ class FooterFile {
5858 private source : string ,
5959 ) { }
6060
61- public async appendBelowFiles ( version : number ) : Promise < void > {
61+ public async appendBelowFiles ( version : number , hasRealFiles : boolean ) : Promise < void > {
6262 // Skip if a newer render has already been requested
6363 if ( version !== renderVersion ) return
6464
@@ -72,13 +72,24 @@ class FooterFile {
7272 const container = document . createElement ( 'div' )
7373 container . id = CONTENT_ID
7474
75- // Insert after the file list table (try multiple selectors for NC 28-33)
7675 const anchor = document . querySelector ( '.files-list__table' )
7776 || document . querySelector ( '.files-filestable' )
7877 || document . querySelector ( '#filestable' )
7978
8079 if ( ! anchor ) return
8180
81+ const filesList = anchor . closest ( '.files-list' ) ?? anchor . parentElement
82+
83+ if ( ! hasRealFiles && filesList ) {
84+ // No real files — hide empty state and table headers
85+ filesList . classList . add ( 'sendent-no-files' )
86+ }
87+
88+ // Insert inside files-list, after the table. Mark files-list so we can
89+ // disable its internal scrolling and let only the page scroll.
90+ if ( filesList ) {
91+ filesList . classList . add ( 'sendent-has-securemail' )
92+ }
8293 anchor . insertAdjacentElement ( 'afterend' , container )
8394
8495 // Show loading spinner
@@ -98,6 +109,13 @@ class FooterFile {
98109
99110 // Replace loading spinner with iframe
100111 container . innerHTML = ''
112+
113+ // Add a "Message" header so it's clear this is the email body
114+ const header = document . createElement ( 'h3' )
115+ header . className = 'sendent-content__header'
116+ header . textContent = 'Message'
117+ container . appendChild ( header )
118+
101119 container . appendChild ( this . generateIframeElement ( content ) )
102120 } catch ( err ) {
103121 // eslint-disable-next-line no-console
@@ -127,20 +145,38 @@ class FooterFile {
127145
128146 private generateIframeElement ( content : string ) : HTMLIFrameElement {
129147 const iframe = document . createElement ( 'iframe' )
130- iframe . width = '0 '
131- iframe . height = '0'
132- iframe . addEventListener ( 'load' , ( ) => {
148+ iframe . scrolling = 'no '
149+
150+ const resizeIframe = ( ) => {
133151 const innerHeight = iframe . contentDocument ?. documentElement ?. scrollHeight
134- const innerWidth = iframe . contentDocument ?. documentElement ?. scrollWidth
135- if ( innerHeight ) iframe . height = String ( innerHeight )
136- if ( innerWidth ) iframe . width = String ( innerWidth )
152+ if ( innerHeight ) iframe . style . height = innerHeight + 'px'
153+ }
154+
155+ iframe . addEventListener ( 'load' , ( ) => {
156+ resizeIframe ( )
157+ // Re-measure after images finish loading
158+ const images = iframe . contentDocument ?. querySelectorAll ( 'img' )
159+ for ( const img of Array . from ( images ?? [ ] ) ) {
160+ if ( ! img . complete ) {
161+ img . addEventListener ( 'load' , resizeIframe )
162+ img . addEventListener ( 'error' , resizeIframe )
163+ }
164+ }
137165 } )
138166 iframe . srcdoc = content
139167 return iframe
140168 }
141169
142170}
143171
172+ /**
173+ * Restores the files-list to its default state.
174+ */
175+ function restoreFilesList ( ) {
176+ document . querySelector ( '.sendent-no-files' ) ?. classList . remove ( 'sendent-no-files' )
177+ document . querySelector ( '.sendent-has-securemail' ) ?. classList . remove ( 'sendent-has-securemail' )
178+ }
179+
144180let debounceTimer : ReturnType < typeof setTimeout > | null = null
145181let renderVersion = 0
146182
@@ -160,18 +196,29 @@ function processFileListDebounced(files: any[]) {
160196 */
161197function processFileList ( files : any [ ] ) {
162198 const version = ++ renderVersion
199+ let securemailFile : any = null
200+ let realFileCount = 0
201+
163202 for ( const file of files ?? [ ] ) {
164203 const basename = file . basename || file . name
165204 if ( file . type === 'file' && basename === FOOTER_NAME ) {
166- // Extract directory from full path (Node.dirname or manual extraction)
167- const dirPath = file . dirname
168- ?? ( file . path ? file . path . substring ( 0 , file . path . lastIndexOf ( '/' ) ) || '/' : '/' )
169- new FooterFile ( basename , dirPath , file . source ?? '' ) . appendBelowFiles ( version )
170- return
205+ securemailFile = file
206+ } else if ( file . type === 'file' ) {
207+ realFileCount ++
171208 }
172209 }
210+
211+ if ( securemailFile ) {
212+ const basename = securemailFile . basename || securemailFile . name
213+ const dirPath = securemailFile . dirname
214+ ?? ( securemailFile . path ? securemailFile . path . substring ( 0 , securemailFile . path . lastIndexOf ( '/' ) ) || '/' : '/' )
215+ new FooterFile ( basename , dirPath , securemailFile . source ?? '' ) . appendBelowFiles ( version , realFileCount > 0 )
216+ return
217+ }
218+
173219 // No securemail file in this directory — clean up stale preview
174220 document . getElementById ( CONTENT_ID ) ?. remove ( )
221+ restoreFilesList ( )
175222}
176223
177224/**
0 commit comments