9
9
10
10
// RWH Compose Module
11
11
12
- import { rwhLogger } from './logger.mjs' ;
12
+ import { rwhLogger } from './logger.mjs' ;
13
13
import * as rwhSettings from './settings.mjs' ;
14
14
import * as rwhI18n from './headers-i18n.mjs' ;
15
15
import * as rwhAccounts from './accounts.mjs' ;
@@ -25,33 +25,47 @@ export async function process(tab) {
25
25
26
26
let composeDetails = await messenger . compose . getComposeDetails ( tab . id ) ;
27
27
rwhLogger . debug ( composeDetails ) ;
28
+ if ( composeDetails . type === 'new' ) {
29
+ rwhLogger . debug ( 'New message getting composed' ) ;
30
+ return ;
31
+ }
28
32
33
+ // Check account level disable exists
29
34
let accountId = await rwhAccounts . findIdByIdentityId ( composeDetails . identityId ) ;
30
35
let isAccountEnabled = await rwhSettings . isAccountEnabled ( accountId ) ;
31
36
rwhLogger . debug ( 'AccountId' , accountId , 'isAccountEnabled' , isAccountEnabled ) ;
32
37
if ( ! isAccountEnabled ) {
33
- return ;
38
+ return ; // RWH stops here
39
+ }
40
+
41
+ // Check 10s disable exists on message level
42
+ let isMessageLevelDisabled = await rwhSettings . get ( `disable.${ accountId } .message_${ composeDetails . relatedMessageId } ` ) ;
43
+ rwhLogger . debug ( 'isMessageLevelDisabled' , isMessageLevelDisabled ) ;
44
+ if ( isMessageLevelDisabled ) {
45
+ return ; // RWH stops here
34
46
}
35
47
36
48
let fullMsg = await messenger . messages . getFull ( composeDetails . relatedMessageId ) ;
37
49
rwhLogger . debug ( fullMsg ) ;
38
50
39
- let rwh = new ReplyWithHeader ( composeDetails , fullMsg ) . init ( ) ;
51
+ let rwh = new ReplyWithHeader ( accountId , composeDetails , fullMsg ) . init ( ) ;
40
52
if ( ! ( rwh . isReply || rwh . isForward ) ) {
41
53
rwhLogger . warn ( `Unsupported compose type ${ rwh . composeType } ` ) ;
42
- return ;
54
+ return ; // RWH stops here
43
55
}
44
56
45
57
await rwh . process ( tab ) ;
46
58
}
47
59
48
60
class ReplyWithHeader {
61
+ #accountId
49
62
#composeDetails
50
63
#fullMessage
51
64
#document
52
65
#text
53
66
54
- constructor ( composeDetails , fullMessage ) {
67
+ constructor ( accountId , composeDetails , fullMessage ) {
68
+ this . #accountId = accountId ;
55
69
this . #composeDetails = composeDetails ;
56
70
this . #fullMessage = fullMessage ;
57
71
}
@@ -103,16 +117,10 @@ class ReplyWithHeader {
103
117
}
104
118
105
119
async process ( tab ) {
106
- let result = { isModified : false } ;
120
+ let result = { isModified : false } ;
107
121
108
122
if ( rwhSettings . isTransSubjectPrefix ( ) ) {
109
- let subject = this . #composeDetails. subject ;
110
- if ( this . isReply && subject . startsWith ( rwhSettings . replySubjectPrefix ) ) {
111
- result . subject = subject . replace ( rwhSettings . replySubjectPrefix , 'RE:' )
112
- }
113
- if ( this . isForward && subject . startsWith ( rwhSettings . forwardSubjectPrefix ) ) {
114
- result . subject = subject . replace ( rwhSettings . forwardSubjectPrefix , 'FW:' ) ;
115
- }
123
+ result . subject = this . _transformSubjectPrefix ( this . #composeDetails. subject ) ;
116
124
}
117
125
118
126
if ( this . isPlainText ) {
@@ -121,7 +129,7 @@ class ReplyWithHeader {
121
129
result = Object . assign ( { } , result , await this . _processPlainText ( ) ) ;
122
130
} else {
123
131
rwhLogger . debug ( 'HTML Content' , this . htmlBody ) ;
124
- this . #document = this . _createDocumentFromString ( this . htmlBody ) ;
132
+ this . #document = rwhUtils . createDocumentFromString ( this . htmlBody ) ;
125
133
result = Object . assign ( { } , result , await this . _processHtml ( ) ) ;
126
134
}
127
135
@@ -154,7 +162,7 @@ class ReplyWithHeader {
154
162
'cc' : await this . _extractHeader ( 'cc' , true , true ) ,
155
163
'date' : await this . _extractHeader ( 'date' , false , true ) ,
156
164
'reply-to' : await this . _extractHeader ( 'reply-to' , true , true ) ,
157
- 'subject' : await this . _extractHeader ( 'subject' , false , true ) ,
165
+ 'subject' : this . _transformSubjectPrefix ( await this . _extractHeader ( 'subject' , false , true ) ) ,
158
166
}
159
167
rwhLogger . debug ( headers ) ;
160
168
@@ -193,7 +201,7 @@ class ReplyWithHeader {
193
201
'cc' : await this . _extractHeader ( 'cc' , true , false ) ,
194
202
'date' : await this . _extractHeader ( 'date' , false , false ) ,
195
203
'reply-to' : await this . _extractHeader ( 'reply-to' , true , false ) ,
196
- 'subject' : await this . _extractHeader ( 'subject' , false , false ) ,
204
+ 'subject' : this . _transformSubjectPrefix ( await this . _extractHeader ( 'subject' , false , false ) ) ,
197
205
}
198
206
rwhLogger . debug ( headers ) ;
199
207
@@ -216,7 +224,7 @@ class ReplyWithHeader {
216
224
}
217
225
} else if ( this . isForward ) {
218
226
linesToDelete = rwhHeaders . length ;
219
- for ( let l of textLines ) {
227
+ for ( let l of textLines ) {
220
228
if ( l . trim ( ) . startsWith ( fwdHdrLookupString ) ) {
221
229
break ;
222
230
}
@@ -272,6 +280,7 @@ class ReplyWithHeader {
272
280
}
273
281
} , this ) ;
274
282
283
+ rwhHeaders += await this . _handleAllHeadersFlow ( false , true ) ;
275
284
rwhHeaders += '</div><br>' ;
276
285
277
286
return rwhHeaders ;
@@ -281,7 +290,6 @@ class ReplyWithHeader {
281
290
let locale = await rwhSettings . getHeaderLocale ( ) ;
282
291
let headerLabelSeq = await rwhSettings . getHeaderLabelSeqStyle ( ) ;
283
292
let headerLabelSeqValues = rwhSettings . headerLabelSeqStyleSettings [ headerLabelSeq ] ;
284
- let lineBreak = '\r\n' ;
285
293
286
294
let rwhHeaders = [ ] ;
287
295
if ( await rwhSettings . isHeaderPlainPrefixText ( ) ) {
@@ -309,6 +317,10 @@ class ReplyWithHeader {
309
317
}
310
318
} , this ) ;
311
319
320
+ let remainingHeaders = await this . _handleAllHeadersFlow ( false , false ) ;
321
+ if ( remainingHeaders . length > 0 ) {
322
+ rwhHeaders = [ ...rwhHeaders , ...remainingHeaders ] ;
323
+ }
312
324
rwhHeaders . push ( '' ) ;
313
325
314
326
return rwhHeaders ;
@@ -322,8 +334,8 @@ class ReplyWithHeader {
322
334
let includeTimezone = await rwhSettings . isHeaderTimeZone ( ) ;
323
335
324
336
rwhLogger . debug ( 'Date format: ' + ( dateFormat == 1 ? 'UTC' : 'Locale (' + locale + ')' )
325
- + ', Time format: ' + ( timeFormat == 1 ? '24-hour' : '12-hour' )
326
- + ( includeTimezone ? ', Include short timezone info' : '' ) )
337
+ + ', Time format: ' + ( timeFormat == 1 ? '24-hour' : '12-hour' )
338
+ + ( includeTimezone ? ', Include short timezone info' : '' ) )
327
339
328
340
let epoch = null ;
329
341
try {
@@ -373,9 +385,18 @@ class ReplyWithHeader {
373
385
return escape ? this . _escapeHtml ( pv . join ( ', ' ) ) : pv . join ( ', ' ) ;
374
386
}
375
387
388
+ async _extractRemainingHeaders ( clean , escape ) {
389
+ let remainingHeaders = { } ;
390
+ for ( let key of Object . keys ( this . #fullMessage. headers ) ) {
391
+ if ( rwhSettings . headerLabelSeqStyleSettings [ 0 ] . includes ( key ) ) { continue ; }
392
+ remainingHeaders [ key ] = await this . _extractHeader ( key , clean , escape ) ;
393
+ }
394
+ return remainingHeaders ;
395
+ }
396
+
376
397
_findPlainTextReplyInsertMarker ( textLines , lookupWord ) {
377
398
let startPos = 0 ;
378
- for ( let l of textLines ) {
399
+ for ( let l of textLines ) {
379
400
if ( l . trim ( ) . includes ( lookupWord ) ) {
380
401
return { found : true , startPos : startPos }
381
402
}
@@ -408,10 +429,6 @@ class ReplyWithHeader {
408
429
return ( v || '' ) . replaceAll ( '&' , '&' ) . replaceAll ( '<' , '<' ) . replaceAll ( '>' , '>' ) ;
409
430
}
410
431
411
- _createDocumentFromString ( s ) {
412
- return new DOMParser ( ) . parseFromString ( s , 'text/html' )
413
- }
414
-
415
432
_cleanNodesUpToClassName ( node , cssClassName ) {
416
433
while ( node . firstChild ) {
417
434
if ( node . firstChild ?. className ?. includes ( cssClassName ) ) {
@@ -420,4 +437,43 @@ class ReplyWithHeader {
420
437
node . removeChild ( node . firstChild ) ;
421
438
}
422
439
}
440
+
441
+ _transformSubjectPrefix ( subject ) {
442
+ if ( subject . startsWith ( rwhSettings . replySubjectPrefix ) ) {
443
+ return subject . replace ( rwhSettings . replySubjectPrefix , 'RE:' )
444
+ }
445
+ if ( subject . startsWith ( rwhSettings . forwardSubjectPrefix ) ) {
446
+ return subject . replace ( rwhSettings . forwardSubjectPrefix , 'FW:' ) ;
447
+ }
448
+ return subject ;
449
+ }
450
+
451
+ async _handleAllHeadersFlow ( clean , escape ) {
452
+ if ( this . isReply ) { return '' ; }
453
+
454
+ let prefName = `header.fwd.all.${ this . #accountId} .message_${ this . #composeDetails. relatedMessageId } ` ;
455
+ let isForwardAllHeaders = await rwhSettings . get ( prefName ) ;
456
+ rwhLogger . debug ( 'isForwardAllHeaders' , isForwardAllHeaders ) ;
457
+ if ( isForwardAllHeaders ) {
458
+ let remainingHeaders = await this . _extractRemainingHeaders ( clean , escape ) ;
459
+ rwhLogger . debug ( remainingHeaders ) ;
460
+
461
+ if ( this . isPlainText ) {
462
+ let rwhHeaders = [ ] ;
463
+ for ( let [ key , value ] of Object . entries ( remainingHeaders ) ) {
464
+ rwhHeaders . push ( rwhUtils . toPartialCanonicalFormat ( key ) + ': ' + value ) ;
465
+ }
466
+ return rwhHeaders ;
467
+ } else {
468
+ let rwhHeaders = '' ;
469
+ for ( let [ key , value ] of Object . entries ( remainingHeaders ) ) {
470
+ rwhHeaders += '<p style="margin:0cm;font-size:11.5pt"><span><b>'
471
+ + rwhUtils . toPartialCanonicalFormat ( key ) + ':</b> ' + value + '</span></p>' ;
472
+ }
473
+ return rwhHeaders ;
474
+ }
475
+ }
476
+
477
+ return '' ;
478
+ }
423
479
}
0 commit comments