From 95fd66b31f55dd3ca02e288dc73f46f0e3d9049d Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 22 Nov 2024 15:50:51 +0800 Subject: [PATCH 01/10] add "secure reply" option in Gmail actions menu --- extension/css/webmail.css | 17 ++++++++++++++ extension/js/common/xss-safe-factory.ts | 9 ++++---- .../webmail/gmail/gmail-element-replacer.ts | 23 +++++++++++++++++-- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/extension/css/webmail.css b/extension/css/webmail.css index 09a2869c620..5efb7caa2fa 100644 --- a/extension/css/webmail.css +++ b/extension/css/webmail.css @@ -202,6 +202,23 @@ body.cryptup_gmail .inserted div.reply_message_button { } } +body.cryptup_gmail div.menu_reply_message_button { + display: flex; + cursor: pointer; + align-items: center; + padding: 4px; +} + +body.cryptup_gmail div.menu_reply_message_button:hover { + background-color: #eee; /* mimic Gmail hover. uses exact color pallete from Gmail */ +} + +body.cryptup_gmail div.menu_reply_message_button > img { + height: 22px; + width: 20px; + padding: 0 12px; +} + body.cryptup_gmail.firefox .inserted div.reply_message_button { padding-top: 16px; } diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index 676158c75e0..058bd3450a9 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -261,11 +261,10 @@ export class XssSafeFactory { } }; - public btnSecureReply = () => { - return `
- + public btnSecureReply = (placement: 'menu' | 'toolbar' = 'toolbar') => { + const msgBtnClassName = placement === 'toolbar' ? 'reply_message_button' : 'menu_reply_message_button'; + return `
+ ${placement === 'menu' ? 'Secure Reply' : ''}
`; }; diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index a691c7be657..48ed6ae5d8c 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -51,6 +51,8 @@ export class GmailElementReplacer extends WebmailElementReplacer { msgInner: 'div.a3s:visible:not(.undefined), .message_inner_body:visible', msgInnerText: 'table.cf.An', msgInnerContainingPgp: "div.a3s:not(.undefined):contains('" + PgpArmor.headers('null').begin + "')", + msgActionsBtn: '.J-J5-Ji.aap', + msgActionsMenu: '.b7.J-M', attachmentsContainerOuter: 'div.hq.gt', attachmentsContainerInner: 'div.aQH', translatePrompt: '.adI, .wl4W9b', @@ -147,6 +149,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { this.replaceArmoredBlocks().catch(Catch.reportErr); this.replaceAttachments().catch(Catch.reportErr); this.replaceComposeDraftLinks(); + this.replaceActionsMenu(); this.replaceConvoBtns(); this.replaceStandardReplyBox().catch(Catch.reportErr); this.evaluateStandardComposeRecipients().catch(Catch.reportErr); @@ -276,6 +279,17 @@ export class GmailElementReplacer extends WebmailElementReplacer { return !!$('iframe.pgp_block').filter(':visible').length; }; + private replaceActionsMenu = () => { + const gmailReplyMenuBtn = $(this.sel.msgActionsMenu); + if ($('.menu_reply_message_button').length <= 0) { + const menuSecureReplyBtn = $(this.factory.btnSecureReply('menu')).prependTo(gmailReplyMenuBtn); // xss-safe-factory + menuSecureReplyBtn.on( + 'click', + Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) + ); + } + }; + private replaceConvoBtns = (force = false) => { const convoUpperIconsContainer = $('div.hj:visible'); const convoUpperIcons = $('span.pYTkkf-JX-ank-Rtc0Jf'); @@ -293,7 +307,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { for (const elem of convoReplyBtnsArr) { $(elem).addClass('inserted'); const gmailReplyBtn = $(elem).find('.aaq.L3'); - const secureReplyBtn = $(this.factory.btnSecureReply()).insertAfter(gmailReplyBtn); // xss-safe-factory + const secureReplyBtn = $(this.factory.btnSecureReply('toolbar')).insertAfter(gmailReplyBtn); // xss-safe-factory secureReplyBtn.addClass(gmailReplyBtn.attr('class') || ''); secureReplyBtn.off(); secureReplyBtn.on( @@ -346,12 +360,13 @@ export class GmailElementReplacer extends WebmailElementReplacer { private actionActivateSecureReplyHandler = async (btn: HTMLElement, event: JQuery.Event) => { event.stopImmediatePropagation(); + const secureReplyInvokedFromMenu = btn.className.includes('menu_reply_message_button'); if ($('#switch_to_encrypted_reply').length) { $('#switch_to_encrypted_reply').trigger('click'); return; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const messageContainer = $(btn.closest('.h7')!); + const messageContainer = secureReplyInvokedFromMenu ? $('.T-I-JO.T-I-Kq').closest('.h7') : $(btn.closest('.h7')!); if (messageContainer.is(':last-child')) { if (this.isEncrypted()) { await this.setReplyBoxEditable(); @@ -361,6 +376,10 @@ export class GmailElementReplacer extends WebmailElementReplacer { } else { this.insertEncryptedReplyBox(messageContainer); } + if (secureReplyInvokedFromMenu) { + $(this.sel.msgActionsBtn).removeClass('T-I-JO T-I-Kq'); + $(this.sel.msgActionsMenu).hide(); + } }; private replaceComposeDraftLinks = () => { From cc8b7823e525b5135367f27fd5b0507c6df6ec9d Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 23 Nov 2024 14:06:49 +0800 Subject: [PATCH 02/10] add base ui for secure forward --- extension/css/webmail.css | 9 +++++---- extension/img/svgs/forward-icon.svg | 9 +++++++++ extension/js/common/xss-safe-factory.ts | 13 +++++++++---- .../webmail/gmail/gmail-element-replacer.ts | 15 ++++++++++----- 4 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 extension/img/svgs/forward-icon.svg diff --git a/extension/css/webmail.css b/extension/css/webmail.css index 5efb7caa2fa..5089268c0a7 100644 --- a/extension/css/webmail.css +++ b/extension/css/webmail.css @@ -202,18 +202,19 @@ body.cryptup_gmail .inserted div.reply_message_button { } } -body.cryptup_gmail div.menu_reply_message_button { +body.cryptup_gmail div.action_menu_message_button { display: flex; - cursor: pointer; align-items: center; + text-transform: capitalize; + cursor: pointer; padding: 4px; } -body.cryptup_gmail div.menu_reply_message_button:hover { +body.cryptup_gmail div.action_menu_message_button:hover { background-color: #eee; /* mimic Gmail hover. uses exact color pallete from Gmail */ } -body.cryptup_gmail div.menu_reply_message_button > img { +body.cryptup_gmail div.action_menu_message_button > img { height: 22px; width: 20px; padding: 0 12px; diff --git a/extension/img/svgs/forward-icon.svg b/extension/img/svgs/forward-icon.svg new file mode 100644 index 00000000000..bd9a30e1ec8 --- /dev/null +++ b/extension/img/svgs/forward-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index 058bd3450a9..7ee0e7612a5 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -261,10 +261,15 @@ export class XssSafeFactory { } }; - public btnSecureReply = (placement: 'menu' | 'toolbar' = 'toolbar') => { - const msgBtnClassName = placement === 'toolbar' ? 'reply_message_button' : 'menu_reply_message_button'; - return `
- ${placement === 'menu' ? 'Secure Reply' : ''} + public btnSecureReply = () => { + return `
+ +
`; + }; + + public actionsMenuBtn = (action: 'reply' | 'forward') => { + return `
+ secure ${action}
`; }; diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index 48ed6ae5d8c..3fc463bc120 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -280,13 +280,18 @@ export class GmailElementReplacer extends WebmailElementReplacer { }; private replaceActionsMenu = () => { - const gmailReplyMenuBtn = $(this.sel.msgActionsMenu); - if ($('.menu_reply_message_button').length <= 0) { - const menuSecureReplyBtn = $(this.factory.btnSecureReply('menu')).prependTo(gmailReplyMenuBtn); // xss-safe-factory + const gmailActionsMenuContainer = $(this.sel.msgActionsMenu); + if ($('.action_menu_message_button').length <= 0) { + const menuSecureReplyBtn = $(this.factory.actionsMenuBtn('reply')).insertAfter($(gmailActionsMenuContainer).find('#r')); // xss-safe-factory + const menuSecureForwardBtn = $(this.factory.actionsMenuBtn('forward')).insertAfter($(gmailActionsMenuContainer).find('#r3')); // xss-safe-factory menuSecureReplyBtn.on( 'click', Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) ); + menuSecureForwardBtn.on( + 'click', + Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) + ); } }; @@ -307,7 +312,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { for (const elem of convoReplyBtnsArr) { $(elem).addClass('inserted'); const gmailReplyBtn = $(elem).find('.aaq.L3'); - const secureReplyBtn = $(this.factory.btnSecureReply('toolbar')).insertAfter(gmailReplyBtn); // xss-safe-factory + const secureReplyBtn = $(this.factory.btnSecureReply()).insertAfter(gmailReplyBtn); // xss-safe-factory secureReplyBtn.addClass(gmailReplyBtn.attr('class') || ''); secureReplyBtn.off(); secureReplyBtn.on( @@ -360,7 +365,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { private actionActivateSecureReplyHandler = async (btn: HTMLElement, event: JQuery.Event) => { event.stopImmediatePropagation(); - const secureReplyInvokedFromMenu = btn.className.includes('menu_reply_message_button'); + const secureReplyInvokedFromMenu = btn.className.includes('action_reply_message_button'); if ($('#switch_to_encrypted_reply').length) { $('#switch_to_encrypted_reply').trigger('click'); return; From f02b6f02c4b6387a9ab98940fd02b55456ae8bb0 Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 23 Nov 2024 14:37:02 +0800 Subject: [PATCH 03/10] fix forward icon --- extension/css/webmail.css | 3 ++- extension/img/svgs/forward-icon.svg | 35 +++++++++++++++++++++-------- extension/manifest.json | 1 + 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/extension/css/webmail.css b/extension/css/webmail.css index 5089268c0a7..cc45985f285 100644 --- a/extension/css/webmail.css +++ b/extension/css/webmail.css @@ -215,9 +215,10 @@ body.cryptup_gmail div.action_menu_message_button:hover { } body.cryptup_gmail div.action_menu_message_button > img { - height: 22px; + height: 20px; width: 20px; padding: 0 12px; + object-fit: contain; } body.cryptup_gmail.firefox .inserted div.reply_message_button { diff --git a/extension/img/svgs/forward-icon.svg b/extension/img/svgs/forward-icon.svg index bd9a30e1ec8..e0702a6462f 100644 --- a/extension/img/svgs/forward-icon.svg +++ b/extension/img/svgs/forward-icon.svg @@ -1,9 +1,26 @@ - - - - - - - - - + + reply-icon-svg + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extension/manifest.json b/extension/manifest.json index 34c0e03f66c..8c57be8e8c8 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -78,6 +78,7 @@ "resources": [ "/css/webmail.css", "/img/svgs/reply-icon.svg", + "/img/svgs/forward-icon.svg", "/img/svgs/spinner-white-small.svg", "/img/svgs/spinner-green-small.svg", "/img/svgs/unlock.svg", From 3084d140e3ef33c2d6cee238a90bcf060a022548 Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 23 Nov 2024 15:30:41 +0800 Subject: [PATCH 04/10] add secure forward functionality --- .../generic/webmail-element-replacer.ts | 3 ++- .../webmail/gmail/gmail-element-replacer.ts | 21 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts index ed5fbf06606..db51b273ac9 100644 --- a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts @@ -1,5 +1,6 @@ /* ©️ 2016 - present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com */ +import { ReplyOption } from '../../../../chrome/elements/compose-modules/compose-reply-btn-popover-module'; import { ContentScriptWindow } from '../../../common/browser/browser-window'; import { notifyMurdered } from './setup-webmail-content-script'; @@ -9,7 +10,7 @@ export abstract class WebmailElementReplacer { private replacePgpElsInterval: number; public abstract getIntervalFunctions: () => IntervalFunction[]; - public abstract setReplyBoxEditable: () => Promise; + public abstract setReplyBoxEditable: (replyOption?: ReplyOption) => Promise; public abstract reinsertReplyBox: (replyMsgId: string) => void; public abstract scrollToReplyBox: (replyMsgId: string) => void; public abstract scrollToCursorInReplyBox: (replyMsgId: string, cursorOffsetTop: number) => void; diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index 3fc463bc120..f3967eeb0fd 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -87,10 +87,12 @@ export class GmailElementReplacer extends WebmailElementReplacer { ]; }; - public setReplyBoxEditable = async () => { + public setReplyBoxEditable = async (replyOption?: ReplyOption) => { const replyContainerIframe = $('.reply_message_iframe_container > iframe').last(); if (replyContainerIframe.length) { - $(replyContainerIframe).replaceWith(this.factory.embeddedReply(this.getLastMsgReplyParams(this.getConvoRootEl(replyContainerIframe[0])), true)); // xss-safe-value + $(replyContainerIframe).replaceWith( + this.factory.embeddedReply(this.getLastMsgReplyParams(this.getConvoRootEl(replyContainerIframe[0]), replyOption), true) + ); // xss-safe-value } else { await this.replaceStandardReplyBox(undefined, true); } @@ -365,7 +367,8 @@ export class GmailElementReplacer extends WebmailElementReplacer { private actionActivateSecureReplyHandler = async (btn: HTMLElement, event: JQuery.Event) => { event.stopImmediatePropagation(); - const secureReplyInvokedFromMenu = btn.className.includes('action_reply_message_button'); + const secureReplyInvokedFromMenu = btn.className.includes('action_menu_message_button'); + const replyOption: ReplyOption = btn.className.includes('reply') ? 'a_reply' : 'a_forward'; if ($('#switch_to_encrypted_reply').length) { $('#switch_to_encrypted_reply').trigger('click'); return; @@ -374,12 +377,12 @@ export class GmailElementReplacer extends WebmailElementReplacer { const messageContainer = secureReplyInvokedFromMenu ? $('.T-I-JO.T-I-Kq').closest('.h7') : $(btn.closest('.h7')!); if (messageContainer.is(':last-child')) { if (this.isEncrypted()) { - await this.setReplyBoxEditable(); + await this.setReplyBoxEditable(replyOption); } else { await this.replaceStandardReplyBox(undefined, true); } } else { - this.insertEncryptedReplyBox(messageContainer); + this.insertEncryptedReplyBox(messageContainer, replyOption); } if (secureReplyInvokedFromMenu) { $(this.sel.msgActionsBtn).removeClass('T-I-JO T-I-Kq'); @@ -613,18 +616,18 @@ export class GmailElementReplacer extends WebmailElementReplacer { return from ? Str.parseEmail(from) : undefined; }; - private getLastMsgReplyParams = (convoRootEl: JQuery): FactoryReplyParams => { - return { replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()) }; + private getLastMsgReplyParams = (convoRootEl: JQuery, replyOption?: ReplyOption): FactoryReplyParams => { + return { replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()), replyOption }; }; private getConvoRootEl = (anyInnerElement: HTMLElement) => { return $(anyInnerElement).closest('div.if, div.aHU, td.Bu').first(); }; - private insertEncryptedReplyBox = (messageContainer: JQuery) => { + private insertEncryptedReplyBox = (messageContainer: JQuery, replyOption: ReplyOption) => { const msgIdElement = messageContainer.find('[data-legacy-message-id], [data-message-id]'); const msgId = msgIdElement.attr('data-legacy-message-id') || msgIdElement.attr('data-message-id'); - const replyParams: FactoryReplyParams = { replyMsgId: msgId, removeAfterClose: true }; + const replyParams: FactoryReplyParams = { replyMsgId: msgId, removeAfterClose: true, replyOption }; const secureReplyBoxXssSafe = /* xss-safe-factory */ `
${this.factory.embeddedReply( replyParams, true, From 5d3d915a576ccd0c250dfabf44b7ac4c5a7fd1ef Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 23 Nov 2024 16:34:12 +0800 Subject: [PATCH 05/10] add test --- extension/js/common/xss-safe-factory.ts | 2 +- test/source/tests/gmail.ts | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index 7ee0e7612a5..483dbe53746 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -268,7 +268,7 @@ export class XssSafeFactory { }; public actionsMenuBtn = (action: 'reply' | 'forward') => { - return `
+ return `
secure ${action}
`; }; diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index fa6e659ceee..06c1bfae1cb 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -457,6 +457,30 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test }) ); + test( + 'mail.google.com - secure reply and forward in dot menu', + testWithBrowser(async (t, browser) => { + await BrowserRecipe.setUpCommonAcct(t, browser, 'ci.tests.gmail'); + const gmailPage = await openGmailPage(t, browser); + await gotoGmailPage(gmailPage, '/FMfcgzGtwgfMhWTlgRwwKWzRhqNZzwXz'); // go to encrypted convo + await Util.sleep(5); + const actionsMenuSelector = '.J-J5-Ji.aap'; + await gmailPage.waitAndClick(actionsMenuSelector); + expect(await gmailPage.isElementPresent('@action-reply-message-button')); + await gmailPage.waitAndClick('@action-reply-message-button'); + await Util.sleep(3); + const replyBox = await gmailPage.getFrame(['/chrome/elements/compose.htm'], { sleep: 5 }); + await Util.sleep(3); + await replyBox.waitForContent('@input-body', ''); + await gmailPage.waitAndClick(actionsMenuSelector); + expect(await gmailPage.isElementPresent('@action-forward-message-button')); + await Util.sleep(3); + await gmailPage.waitAndClick('@action-forward-message-button'); + await Util.sleep(3); + await replyBox.waitForContent('@input-body', '---------- Forwarded message ---------'); + }) + ); + // convo-sensitive, draft-sensitive test test.serial( 'mail.google.com - plain reply draft', From 05ae4d1bc924468261e9b038590e9671fe207bbd Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 23 Nov 2024 16:42:16 +0800 Subject: [PATCH 06/10] revert unneeded changes --- extension/js/common/xss-safe-factory.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index 483dbe53746..e5699ddd68d 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -262,9 +262,11 @@ export class XssSafeFactory { }; public btnSecureReply = () => { - return `
- -
`; + return `
+ +
`; }; public actionsMenuBtn = (action: 'reply' | 'forward') => { From 79b76d121c4c3277bda9589e94639cdc2eced4ad Mon Sep 17 00:00:00 2001 From: martgil Date: Sun, 24 Nov 2024 12:35:12 +0800 Subject: [PATCH 07/10] update test --- test/source/tests/gmail.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 06c1bfae1cb..54607676df8 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -466,15 +466,15 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await Util.sleep(5); const actionsMenuSelector = '.J-J5-Ji.aap'; await gmailPage.waitAndClick(actionsMenuSelector); + await Util.sleep(3); expect(await gmailPage.isElementPresent('@action-reply-message-button')); await gmailPage.waitAndClick('@action-reply-message-button'); - await Util.sleep(3); const replyBox = await gmailPage.getFrame(['/chrome/elements/compose.htm'], { sleep: 5 }); await Util.sleep(3); await replyBox.waitForContent('@input-body', ''); await gmailPage.waitAndClick(actionsMenuSelector); - expect(await gmailPage.isElementPresent('@action-forward-message-button')); await Util.sleep(3); + expect(await gmailPage.isElementPresent('@action-forward-message-button')); await gmailPage.waitAndClick('@action-forward-message-button'); await Util.sleep(3); await replyBox.waitForContent('@input-body', '---------- Forwarded message ---------'); From c37fa3eea1dd213815c0d29040261856c3fd0f53 Mon Sep 17 00:00:00 2001 From: martgil Date: Sun, 24 Nov 2024 12:36:35 +0800 Subject: [PATCH 08/10] update test --- test/source/tests/gmail.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/source/tests/gmail.ts b/test/source/tests/gmail.ts index 54607676df8..b360f2d0df8 100644 --- a/test/source/tests/gmail.ts +++ b/test/source/tests/gmail.ts @@ -476,8 +476,9 @@ export const defineGmailTests = (testVariant: TestVariant, testWithBrowser: Test await Util.sleep(3); expect(await gmailPage.isElementPresent('@action-forward-message-button')); await gmailPage.waitAndClick('@action-forward-message-button'); + const replyBox2 = await gmailPage.getFrame(['/chrome/elements/compose.htm'], { sleep: 5 }); await Util.sleep(3); - await replyBox.waitForContent('@input-body', '---------- Forwarded message ---------'); + await replyBox2.waitForContent('@input-body', '---------- Forwarded message ---------'); }) ); From 18564f0080c55ab7b02f1f63cb1dde04f21e2f66 Mon Sep 17 00:00:00 2001 From: martgil Date: Tue, 26 Nov 2024 16:39:16 +0800 Subject: [PATCH 09/10] remove unneeded attributes --- extension/js/common/xss-safe-factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/js/common/xss-safe-factory.ts b/extension/js/common/xss-safe-factory.ts index e5699ddd68d..686435c749e 100644 --- a/extension/js/common/xss-safe-factory.ts +++ b/extension/js/common/xss-safe-factory.ts @@ -270,7 +270,7 @@ export class XssSafeFactory { }; public actionsMenuBtn = (action: 'reply' | 'forward') => { - return `
+ return `
secure ${action}
`; }; From 4af70f14f8c9516ab834f7433eb5550d2652b378 Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 29 Nov 2024 17:32:26 +0800 Subject: [PATCH 10/10] pr reviews: make code concise --- .../webmail/gmail/gmail-element-replacer.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index f3967eeb0fd..f2775edc7f4 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -281,19 +281,19 @@ export class GmailElementReplacer extends WebmailElementReplacer { return !!$('iframe.pgp_block').filter(':visible').length; }; + private addMenuButton = (action: 'reply' | 'forward', selector: string) => { + const gmailActionsMenuContainer = $(this.sel.msgActionsMenu).find(selector); + const button = $(this.factory.actionsMenuBtn(action)).insertAfter(gmailActionsMenuContainer); // xss-safe-factory + button.on( + 'click', + Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) + ); + }; + private replaceActionsMenu = () => { - const gmailActionsMenuContainer = $(this.sel.msgActionsMenu); if ($('.action_menu_message_button').length <= 0) { - const menuSecureReplyBtn = $(this.factory.actionsMenuBtn('reply')).insertAfter($(gmailActionsMenuContainer).find('#r')); // xss-safe-factory - const menuSecureForwardBtn = $(this.factory.actionsMenuBtn('forward')).insertAfter($(gmailActionsMenuContainer).find('#r3')); // xss-safe-factory - menuSecureReplyBtn.on( - 'click', - Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) - ); - menuSecureForwardBtn.on( - 'click', - Ui.event.handle((el, ev: JQuery.Event) => this.actionActivateSecureReplyHandler(el, ev)) - ); + this.addMenuButton('reply', '#r'); + this.addMenuButton('forward', '#r3'); } };