Skip to content

Conversation

@n3ps
Copy link
Contributor

@n3ps n3ps commented Nov 25, 2025

Description

fixes #38222

Wraps the sidepanel context menu configuration with the remote feature flag

Open in GitHub Codespaces

Changelog

CHANGELOG entry: fix: feature flag sidepanel context menu

Related issues

Fixes:

Manual testing steps

  1. Go to this page...

Screenshots/Recordings

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Gates the sidepanel context menu behind a remote feature flag and refactors its setup into a dedicated module initialized after background startup.

  • Background:
    • Sidepanel context menu:
      • Extracted setup to app/scripts/lib/sidepanel-context-menu.ts with initSidePanelContextMenu(controller).
      • Creates/removes openSidePanel menu based on IS_SIDEPANEL and remoteFeatureFlags.extensionUxSidepanel; opens side panel on click.
      • Subscribes to RemoteFeatureFlagController:stateChange to toggle menu dynamically.
    • Initialization:
      • In app/scripts/background.js, register sidepanel context menu via lazyListener.once('runtime','onInstalled'), calling handleSidePanelContextMenu() after handleOnInstalled.
      • New handleSidePanelContextMenu waits for isInitialized then invokes initSidePanelContextMenu(controller).
      • Removes prior inline context menu registration logic.

Written by Cursor Bugbot for commit bc69ea7. This will update automatically on new commits. Configure here.

@github-actions
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-core-extension-ux Core Extension UX team label Nov 25, 2025
@n3ps n3ps requested a review from NidhiKJha November 25, 2025 00:01
@n3ps n3ps changed the title fix: feature flag sidepanel context menu fix: feature flag sidepanel context menu cp-13.10.3 Nov 25, 2025
@n3ps n3ps changed the title fix: feature flag sidepanel context menu cp-13.10.3 fix: feature flag sidepanel context menu cp-13.10.2 Nov 25, 2025
@metamaskbot
Copy link
Collaborator

Builds ready [d5bdc68]
UI Startup Metrics (1195 ± 106 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup11951008148910612391388
load101384912448910581186
domContentLoaded100784412388810491175
domInteractive2414116201980
firstPaint53676120439510051178
backgroundConnect2061912459210221
firstReactRender28185183246
getState321587103549
initialActions104112
loadScripts807646104086849976
setupStore1172941123
numNetworkReqs1257821575
BrowserifyPower User HomeuiStartup21431646281027722932739
load1034905156015710281497
domContentLoaded1020896155315710101490
domInteractive38191943532143
firstPaint58910415504019901088
backgroundConnect23220527616243261
firstReactRender924715922100142
getState18112827833205236
initialActions105112
loadScripts80669113271547871278
setupStore231092132646
numNetworkReqs1406339876177364
WebpackStandard HomeuiStartup822692111986852999
load64556082779706806
domContentLoaded64155782278702801
domInteractive2614106212189
firstPaint22275827168196734
backgroundConnect963851017
firstReactRender26204263139
getState251266113250
initialActions104112
loadScripts63855481277699792
setupStore1143051326
numNetworkReqs1257720573
WebpackPower User HomeuiStartup15141225244824616212016
load6735831031101666964
domContentLoaded6635751023102653958
domInteractive35181813031113
firstPaint295102974198355658
backgroundConnect1483551623
firstReactRender86471291594106
getState14412520517154176
initialActions103012
loadScripts6605731013100651949
setupStore211064132550
numNetworkReqs101612956295286
FirefoxBrowserifyStandard HomeuiStartup12111065159111012921432
load100591212487910601177
domContentLoaded100490712487910601177
domInteractive5230210317499
firstPaint------
backgroundConnect3321102123754
firstReactRender22174552237
getState14513322952
initialActions103112
loadScripts98589512267610371153
setupStore11578111028
numNetworkReqs1157015655
BrowserifyPower User HomeuiStartup24391919331426926372895
load1098916154014411311449
domContentLoaded1097911153914411311445
domInteractive1113150190121356
firstPaint------
backgroundConnect992672295100198
firstReactRender82371342092119
getState28754864222442767
initialActions218127
loadScripts1062901152113710811401
setupStore1277817186106638
numNetworkReqs99622475595243
WebpackStandard HomeuiStartup13901227170910414451657
load1180105214148612351361
domContentLoaded1179105214148612351361
domInteractive51261663273124
firstPaint------
backgroundConnect371791154171
firstReactRender26204252837
getState963041016
initialActions102012
loadScripts1157103913938312101334
setupStore1156081027
numNetworkReqs1156515660
WebpackPower User HomeuiStartup27392240345128529583220
load13451153191517213331802
domContentLoaded13441153191517213331802
domInteractive108304589598384
firstPaint------
backgroundConnect962845957109195
firstReactRender86451341796118
getState30463881241484819
initialActions3028437
loadScripts13091121179516113021682
setupStore1266770177103627
numNetworkReqs101612586278248
📊 Page Load Benchmark Results

Current Commit: d5bdc68 | Date: 11/25/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.05s (±39ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 732ms (±36ms) 🟢 | historical mean value: 718ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 80ms (±13ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.05s 39ms 1.03s 1.34s 1.08s 1.34s
domContentLoaded 732ms 36ms 712ms 1.00s 748ms 1.00s
firstPaint 80ms 13ms 64ms 196ms 88ms 196ms
firstContentfulPaint 80ms 13ms 64ms 196ms 88ms 196ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 659 Bytes (0.01%)
  • ui: 7.61 KiB (0.11%)
  • common: 22 Bytes (0%)

@gauthierpetetin gauthierpetetin changed the title fix: feature flag sidepanel context menu cp-13.10.2 fix: feature flag sidepanel context menu cp-13.10.3 Nov 25, 2025
@n3ps n3ps force-pushed the n3ps/sidepanel-contextmenu branch from 97662ec to 04eb620 Compare November 25, 2025 06:00
} else {
removeMenu();
}
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Missing state comparison causes duplicate context menu operations

The RemoteFeatureFlagController:stateChange subscription doesn't compare previous and current values of extensionUxSidepanel. Unlike other parts of the codebase that use previousValueComparator, this code calls createMenu() or removeMenu() on every state change event without checking if the flag actually changed. If the menu already exists (created initially at line 33-35) and any state change occurs while still enabled, browser.contextMenus.create will fail with "Cannot create item with duplicate id" error. Similarly, calling removeMenu() when the menu doesn't exist will also fail.

Additional Locations (1)

Fix in Cursor Fix in Web

NidhiKJha
NidhiKJha previously approved these changes Nov 25, 2025
@metamaskbot
Copy link
Collaborator

Builds ready [04eb620]
UI Startup Metrics (1130 ± 98 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup113092614269811691331
load9547871178859971137
domContentLoaded9487821171839901118
domInteractive2414100211886
firstPaint6127511873849831097
backgroundConnect1831702088187199
firstReactRender28185293445
getState28166193049
initialActions106113
loadScripts77261498781815933
setupStore1052641020
numNetworkReqs1257821573
BrowserifyPower User HomeuiStartup19791583266524521182515
load98288414461229781382
domContentLoaded96788014311219591370
domInteractive32161522929128
firstPaint57411014523889411247
backgroundConnect22320030715226252
firstReactRender88461382097127
getState16312625829178238
initialActions104112
loadScripts76268012241187541121
setupStore221079142553
numNetworkReqs103652865399270
WebpackStandard HomeuiStartup8987341193999571095
load69459490088754852
domContentLoaded68958989288748845
domInteractive2916140242497
firstPaint26293827173300623
backgroundConnect1153151225
firstReactRender3021223203241
getState271391133550
initialActions104112
loadScripts68558788386746841
setupStore1153951319
numNetworkReqs1257720572
WebpackPower User HomeuiStartup16061238221722917502026
load664583100994662952
domContentLoaded654578100295648947
domInteractive36181623031126
firstPaint271921008188246660
backgroundConnect1474461622
firstReactRender85451091593103
getState14712319515156179
initialActions106111
loadScripts65157699393646936
setupStore21962132450
numNetworkReqs1536741178198390
FirefoxBrowserifyStandard HomeuiStartup12581079170010913221438
load104692112437210891194
domContentLoaded104591812437210891189
domInteractive64311783485132
firstPaint------
backgroundConnect3720146213790
firstReactRender22184652235
getState12615620919
initialActions103012
loadScripts102390512157010611169
setupStore126193191026
numNetworkReqs1156413748
BrowserifyPower User HomeuiStartup24231866310926726202878
load1085931151613110841430
domContentLoaded1084925151613210811430
domInteractive1103149499107395
firstPaint------
backgroundConnect902347066102216
firstReactRender874216323100129
getState24560840201340643
initialActions2122237
loadScripts1056912149613010581406
setupStore1568733195169673
numNetworkReqs101592496179245
WebpackStandard HomeuiStartup14401276188812214651718
load1211108614538212601376
domContentLoaded1210108614518212601376
domInteractive57271823375128
firstPaint------
backgroundConnect42211712543103
firstReactRender27216862938
getState156183241345
initialActions104112
loadScripts1186106914217712361325
setupStore135134161233
numNetworkReqs1156916663
WebpackPower User HomeuiStartup27572203382428129233262
load14041183206416414421726
domContentLoaded14031183206416414421726
domInteractive11533546106104376
firstPaint------
backgroundConnect1173556774131204
firstReactRender88451762098123
getState24357926207294748
initialActions3142537
loadScripts13591163197715214021657
setupStore1616741190196629
numNetworkReqs101563085994243
📊 Page Load Benchmark Results

Current Commit: 04eb620 | Date: 11/25/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±40ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 716ms (±37ms) 🟢 | historical mean value: 726ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 75ms (±11ms) 🟢 | historical mean value: 80ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 40ms 1.01s 1.34s 1.04s 1.34s
domContentLoaded 716ms 37ms 697ms 998ms 725ms 998ms
firstPaint 75ms 11ms 56ms 164ms 84ms 164ms
firstContentfulPaint 75ms 11ms 56ms 164ms 84ms 164ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 913 Bytes (0.02%)
  • ui: 9.38 KiB (0.13%)
  • common: 131 Bytes (0%)

} else {
removeMenu();
}
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Context menu state changes cause duplicate creation errors

The state change subscription calls createMenu() or removeMenu() on every RemoteFeatureFlagController:stateChange event without tracking whether the menu already exists or comparing with the previous flag value. Since the state change event fires when ANY remote feature flag changes (not just extensionUxSidepanel), this will repeatedly try to create an already-existing menu item (causing "Cannot create item with duplicate id" error) or remove a non-existent menu. The codebase has an established previousValueComparator utility for this exact scenario that compares previous and current state before acting.

Additional Locations (1)

Fix in Cursor Fix in Web

if (info.menuItemId === MENU_ITEM_ID && tab?.windowId) {
browserWithSidePanel.sidePanel?.open({ windowId: tab.windowId });
}
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Context menu click handler only registered on install

The browser.contextMenus.onClicked listener is now registered inside initSidePanelContextMenu, which only runs when lazyListener.once('runtime', 'onInstalled') resolves. The onInstalled event only fires on fresh install, extension update, or browser update—not on regular browser restart or service worker wake-up. In the old code, the click listener was registered at module load time, ensuring it worked whenever the service worker started. Now, after a normal browser restart, the click handler won't be registered and clicking the context menu item will do nothing.

Additional Locations (1)

Fix in Cursor Fix in Web

@metamaskbot
Copy link
Collaborator

Builds ready [bc69ea7]
UI Startup Metrics (1257 ± 110 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup12571023158911013271446
load1066872142210111331246
domContentLoaded106086914149911261238
domInteractive2615109232293
firstPaint50585142840910201220
backgroundConnect21419424910220232
firstReactRender30206293547
getState331868113755
initialActions104112
loadScripts8536641196989251031
setupStore1273341319
numNetworkReqs1257921576
BrowserifyPower User HomeuiStartup20131572263427521952578
load97587914541329641360
domContentLoaded96187014411329451352
domInteractive35171643331129
firstPaint57510014673979291360
backgroundConnect21719924710221240
firstReactRender87431462295130
getState16712924125190209
initialActions1010113
loadScripts76166912381317441139
setupStore221065122647
numNetworkReqs1506937772184357
WebpackStandard HomeuiStartup8327071136878571028
load64656788275689801
domContentLoaded64256387774685794
domInteractive2515102212188
firstPaint23071819156214605
backgroundConnect95284917
firstReactRender2720110103238
getState251363113246
initialActions104113
loadScripts63956186973683785
setupStore1062541219
numNetworkReqs1257721575
WebpackPower User HomeuiStartup17051093221320218542030
load67059199293674935
domContentLoaded66058598293661929
domInteractive36181743133127
firstPaint29291974205299696
backgroundConnect1574261825
firstReactRender86451431693106
getState15012522215159178
initialActions104111
loadScripts65758296990659920
setupStore20959132252
numNetworkReqs1606738674201377
FirefoxBrowserifyStandard HomeuiStartup12181078183813812451469
load101189712557910571189
domContentLoaded101089312557910531189
domInteractive55292253471129
firstPaint------
backgroundConnect4021336463689
firstReactRender22174562135
getState155189251151
initialActions102122
loadScripts98888312387010351139
setupStore1053551020
numNetworkReqs1156716660
BrowserifyPower User HomeuiStartup25031967335628426693092
load1103947162813011051451
domContentLoaded1102947162713011051450
domInteractive1153250298113362
firstPaint------
backgroundConnect1002545565118220
firstReactRender86431812396129
getState28455864225437736
initialActions3132337
loadScripts1070930147012410681403
setupStore1277769172116638
numNetworkReqs103593146583260
WebpackStandard HomeuiStartup14321248181211514891674
load1213105915039512711416
domContentLoaded1213105915039512711415
domInteractive65262154182152
firstPaint------
backgroundConnect3621184194060
firstReactRender28218193041
getState146143221145
initialActions103122
loadScripts1191104214479112501380
setupStore1157591123
numNetworkReqs1156715654
WebpackPower User HomeuiStartup26432047338328027813187
load13591095194519114871783
domContentLoaded13591094194419114811783
domInteractive11230681118101403
firstPaint------
backgroundConnect1012746771117201
firstReactRender84402172294121
getState27059874235409782
initialActions3059637
loadScripts13181076192319014181747
setupStore114575417390644
numNetworkReqs986024448133234
📊 Page Load Benchmark Results

Current Commit: bc69ea7 | Date: 11/25/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±38ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 739ms (±36ms) 🟢 | historical mean value: 721ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 80ms (±11ms) 🟢 | historical mean value: 81ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 38ms 1.03s 1.34s 1.10s 1.34s
domContentLoaded 739ms 36ms 716ms 1.01s 777ms 1.01s
firstPaint 80ms 11ms 68ms 172ms 88ms 172ms
firstContentfulPaint 80ms 11ms 68ms 172ms 88ms 172ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 970 Bytes (0.02%)
  • ui: 9.38 KiB (0.13%)
  • common: 131 Bytes (0%)


const isEnabled = (state?: {
remoteFeatureFlags?: { extensionUxSidepanel?: boolean };
}) => state?.remoteFeatureFlags?.extensionUxSidepanel !== false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
}) => state?.remoteFeatureFlags?.extensionUxSidepanel !== false;
}) => state?.remoteFeatureFlags?.extensionUxSidepanel === true;

@ameliejyc ameliejyc added this pull request to the merge queue Nov 25, 2025
Merged via the queue into main with commit 67d4f18 Nov 25, 2025
176 checks passed
@ameliejyc ameliejyc deleted the n3ps/sidepanel-contextmenu branch November 25, 2025 09:30
@github-actions github-actions bot locked and limited conversation to collaborators Nov 25, 2025
@metamaskbot metamaskbot added the release-13.12.0 Issue or pull request that will be included in release 13.12.0 label Nov 25, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.12.0 Issue or pull request that will be included in release 13.12.0 size-S team-core-extension-ux Core Extension UX team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Sidepanel appears in Extension Context menu when feature flag is off

6 participants