Skip to content

Commit f70e382

Browse files
authored
Merge pull request #149 from jeevatkm/rwh-v3-beta2
RWH v3 beta2 updates
2 parents d38863e + 448b839 commit f70e382

File tree

7 files changed

+217
-60
lines changed

7 files changed

+217
-60
lines changed

manifest.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifest_version": 2,
33
"name": "ReplyWithHeader",
44
"description": "Outlook style headers and few goodies for Thunderbird",
5-
"version": "3.0.0.beta1",
5+
"version": "3.0.0.beta2",
66
"author": "Jeevanandam M.",
77
"homepage_url": "https://myjeeva.com/replywithheader-mozilla",
88
"browser_specific_settings": {
@@ -26,6 +26,15 @@
2626
"messagesRead",
2727
"accountsRead"
2828
],
29+
"message_display_action": {
30+
"default_title": "RWH",
31+
"type": "menu",
32+
"default_icon": {
33+
"16": "images/rwh.svg",
34+
"24": "images/rwh.svg",
35+
"32": "images/rwh.svg"
36+
}
37+
},
2938
"background": {
3039
"page": "background.html"
3140
},

modules/compose.mjs

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
// RWH Compose Module
1111

12-
import { rwhLogger} from './logger.mjs';
12+
import { rwhLogger } from './logger.mjs';
1313
import * as rwhSettings from './settings.mjs';
1414
import * as rwhI18n from './headers-i18n.mjs';
1515
import * as rwhAccounts from './accounts.mjs';
@@ -25,33 +25,47 @@ export async function process(tab) {
2525

2626
let composeDetails = await messenger.compose.getComposeDetails(tab.id);
2727
rwhLogger.debug(composeDetails);
28+
if (composeDetails.type === 'new') {
29+
rwhLogger.debug('New message getting composed');
30+
return;
31+
}
2832

33+
// Check account level disable exists
2934
let accountId = await rwhAccounts.findIdByIdentityId(composeDetails.identityId);
3035
let isAccountEnabled = await rwhSettings.isAccountEnabled(accountId);
3136
rwhLogger.debug('AccountId', accountId, 'isAccountEnabled', isAccountEnabled);
3237
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
3446
}
3547

3648
let fullMsg = await messenger.messages.getFull(composeDetails.relatedMessageId);
3749
rwhLogger.debug(fullMsg);
3850

39-
let rwh = new ReplyWithHeader(composeDetails, fullMsg).init();
51+
let rwh = new ReplyWithHeader(accountId, composeDetails, fullMsg).init();
4052
if (!(rwh.isReply || rwh.isForward)) {
4153
rwhLogger.warn(`Unsupported compose type ${rwh.composeType}`);
42-
return;
54+
return; // RWH stops here
4355
}
4456

4557
await rwh.process(tab);
4658
}
4759

4860
class ReplyWithHeader {
61+
#accountId
4962
#composeDetails
5063
#fullMessage
5164
#document
5265
#text
5366

54-
constructor(composeDetails, fullMessage) {
67+
constructor(accountId, composeDetails, fullMessage) {
68+
this.#accountId = accountId;
5569
this.#composeDetails = composeDetails;
5670
this.#fullMessage = fullMessage;
5771
}
@@ -103,16 +117,10 @@ class ReplyWithHeader {
103117
}
104118

105119
async process(tab) {
106-
let result = {isModified: false};
120+
let result = { isModified: false };
107121

108122
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);
116124
}
117125

118126
if (this.isPlainText) {
@@ -121,7 +129,7 @@ class ReplyWithHeader {
121129
result = Object.assign({}, result, await this._processPlainText());
122130
} else {
123131
rwhLogger.debug('HTML Content', this.htmlBody);
124-
this.#document = this._createDocumentFromString(this.htmlBody);
132+
this.#document = rwhUtils.createDocumentFromString(this.htmlBody);
125133
result = Object.assign({}, result, await this._processHtml());
126134
}
127135

@@ -154,7 +162,7 @@ class ReplyWithHeader {
154162
'cc': await this._extractHeader('cc', true, true),
155163
'date': await this._extractHeader('date', false, true),
156164
'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)),
158166
}
159167
rwhLogger.debug(headers);
160168

@@ -193,7 +201,7 @@ class ReplyWithHeader {
193201
'cc': await this._extractHeader('cc', true, false),
194202
'date': await this._extractHeader('date', false, false),
195203
'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)),
197205
}
198206
rwhLogger.debug(headers);
199207

@@ -216,7 +224,7 @@ class ReplyWithHeader {
216224
}
217225
} else if (this.isForward) {
218226
linesToDelete = rwhHeaders.length;
219-
for(let l of textLines) {
227+
for (let l of textLines) {
220228
if (l.trim().startsWith(fwdHdrLookupString)) {
221229
break;
222230
}
@@ -272,6 +280,7 @@ class ReplyWithHeader {
272280
}
273281
}, this);
274282

283+
rwhHeaders += await this._handleAllHeadersFlow(false, true);
275284
rwhHeaders += '</div><br>';
276285

277286
return rwhHeaders;
@@ -281,7 +290,6 @@ class ReplyWithHeader {
281290
let locale = await rwhSettings.getHeaderLocale();
282291
let headerLabelSeq = await rwhSettings.getHeaderLabelSeqStyle();
283292
let headerLabelSeqValues = rwhSettings.headerLabelSeqStyleSettings[headerLabelSeq];
284-
let lineBreak = '\r\n';
285293

286294
let rwhHeaders = [];
287295
if (await rwhSettings.isHeaderPlainPrefixText()) {
@@ -309,6 +317,10 @@ class ReplyWithHeader {
309317
}
310318
}, this);
311319

320+
let remainingHeaders = await this._handleAllHeadersFlow(false, false);
321+
if (remainingHeaders.length > 0) {
322+
rwhHeaders = [...rwhHeaders, ...remainingHeaders];
323+
}
312324
rwhHeaders.push('');
313325

314326
return rwhHeaders;
@@ -322,8 +334,8 @@ class ReplyWithHeader {
322334
let includeTimezone = await rwhSettings.isHeaderTimeZone();
323335

324336
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' : ''))
327339

328340
let epoch = null;
329341
try {
@@ -373,9 +385,18 @@ class ReplyWithHeader {
373385
return escape ? this._escapeHtml(pv.join(', ')) : pv.join(', ');
374386
}
375387

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+
376397
_findPlainTextReplyInsertMarker(textLines, lookupWord) {
377398
let startPos = 0;
378-
for(let l of textLines) {
399+
for (let l of textLines) {
379400
if (l.trim().includes(lookupWord)) {
380401
return { found: true, startPos: startPos }
381402
}
@@ -408,10 +429,6 @@ class ReplyWithHeader {
408429
return (v || '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
409430
}
410431

411-
_createDocumentFromString(s) {
412-
return new DOMParser().parseFromString(s, 'text/html')
413-
}
414-
415432
_cleanNodesUpToClassName(node, cssClassName) {
416433
while (node.firstChild) {
417434
if (node.firstChild?.className?.includes(cssClassName)) {
@@ -420,4 +437,43 @@ class ReplyWithHeader {
420437
node.removeChild(node.firstChild);
421438
}
422439
}
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+
}
423479
}

0 commit comments

Comments
 (0)