Skip to content

Commit 1d92512

Browse files
committed
Enhance profile switching functionality: add origin parameter to limit UI updates for profile changes
1 parent 67dde75 commit 1d92512

File tree

3 files changed

+63
-36
lines changed

3 files changed

+63
-36
lines changed

buttons-init.js

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -175,31 +175,49 @@ window.MaxExtensionButtonsInit = {
175175

176176
/**
177177
* Updates all buttons and toggles in response to a profile change.
178-
* This refreshes both the floating panel and the original container.
178+
* Accepts an optional `origin` parameter:
179+
* - 'panel' => only update the floating panel UI
180+
* - 'inline' => only update the inline buttons UI
181+
* - null/undefined => update both (legacy behavior)
179182
*/
180-
updateButtonsForProfileChange: function () {
181-
// Update buttons in the original container
183+
updateButtonsForProfileChange: function (origin = null) {
184+
// If origin is 'panel', only update the floating panel
185+
if (origin === 'panel') {
186+
if (window.MaxExtensionFloatingPanel && window.MaxExtensionFloatingPanel.panelElement) {
187+
const panelContent = document.getElementById('max-extension-floating-panel-content');
188+
if (panelContent) {
189+
panelContent.innerHTML = '';
190+
this.generateAndAppendAllButtons(panelContent, true);
191+
logConCgp('[init] Updated buttons in floating panel for profile change (panel origin).');
192+
}
193+
}
194+
return;
195+
}
196+
197+
// If origin is 'inline', only update the inline/original container
198+
if (origin === 'inline') {
199+
const originalContainer = document.getElementById(window.InjectionTargetsOnWebsite.selectors.buttonsContainerId);
200+
if (originalContainer) {
201+
originalContainer.innerHTML = '';
202+
this.generateAndAppendAllButtons(originalContainer, false);
203+
logConCgp('[init] Updated buttons in original container for profile change (inline origin).');
204+
}
205+
return;
206+
}
207+
208+
// Legacy/default: update both containers
182209
const originalContainer = document.getElementById(window.InjectionTargetsOnWebsite.selectors.buttonsContainerId);
183210
if (originalContainer) {
184-
// Clear existing buttons and toggles
185211
originalContainer.innerHTML = '';
186-
187-
// Note: toggles are now appended within generateAndAppendAllButtons() at the very end
188212
this.generateAndAppendAllButtons(originalContainer, false); // Not panel
189-
190213
logConCgp('[init] Updated buttons in original container for profile change.');
191214
}
192-
193-
// Update buttons in the floating panel if it exists and is initialized
215+
194216
if (window.MaxExtensionFloatingPanel && window.MaxExtensionFloatingPanel.panelElement) {
195217
const panelContent = document.getElementById('max-extension-floating-panel-content');
196218
if (panelContent) {
197-
// Clear existing buttons and toggles
198219
panelContent.innerHTML = '';
199-
200-
// Note: toggles are now appended within generateAndAppendAllButtons() at the very end
201220
this.generateAndAppendAllButtons(panelContent, true); // This is the panel
202-
203221
logConCgp('[init] Updated buttons in floating panel for profile change.');
204222
}
205223
}
@@ -275,17 +293,18 @@ window.MaxExtensionButtonsInit.createInlineProfileSelector = async function () {
275293
select.addEventListener('change', (e) => {
276294
const selected = e.target.value;
277295
// Request switch and refresh immediately using service worker response for reliability.
278-
chrome.runtime.sendMessage({ type: 'switchProfile', profileName: selected }, (response) => {
296+
// Include origin so receiver can limit refresh scope to inline UI only.
297+
chrome.runtime.sendMessage({ type: 'switchProfile', profileName: selected, origin: 'inline' }, (response) => {
279298
if (response && response.config) {
280299
// Immediate local refresh; SW also broadcasts to other tabs
281300
if (typeof window.__OCP_partialRefreshUI === 'function') {
282-
window.__OCP_partialRefreshUI(response.config);
301+
window.__OCP_partialRefreshUI(response.config, 'inline');
283302
} else if (typeof window.__OCP_nukeAndRefresh === 'function') {
284-
window.__OCP_nukeAndRefresh(response.config);
303+
window.__OCP_nukeAndRefresh(response.config, 'inline');
285304
} else if (window.MaxExtensionButtonsInit && typeof window.MaxExtensionButtonsInit.updateButtonsForProfileChange === 'function') {
286305
// Fallback: partial refresh
287306
window.globalMaxExtensionConfig = response.config;
288-
window.MaxExtensionButtonsInit.updateButtonsForProfileChange();
307+
window.MaxExtensionButtonsInit.updateButtonsForProfileChange('inline');
289308
}
290309
}
291310
});

config.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,17 @@ async function loadProfileConfig(profileName) {
169169
}
170170

171171
// Function to switch to a different profile
172-
async function switchProfile(profileName, excludeTabId) {
172+
async function switchProfile(profileName, excludeTabId, origin = null) {
173173
logConfigurationRelatedStuff(`Switching to profile: ${profileName}`);
174174
try {
175175
const profile = await loadProfileConfig(profileName);
176176
if (profile) {
177177
await chrome.storage.local.set({ 'currentProfile': profileName });
178178
logConfigurationRelatedStuff(`Switched to profile: ${profileName}`);
179179

180-
// Broadcast profile change to all tabs except the initiator (if provided)
181-
broadcastProfileChange(profileName, profile, excludeTabId);
180+
// Broadcast profile change to all tabs except the initiator (if provided).
181+
// Include origin so content scripts can limit their refresh scope.
182+
broadcastProfileChange(profileName, profile, excludeTabId, origin);
182183

183184
return profile;
184185
} else {
@@ -192,7 +193,7 @@ async function switchProfile(profileName, excludeTabId) {
192193
}
193194

194195
// Function to broadcast profile change to all tabs
195-
async function broadcastProfileChange(profileName, profileData, excludeTabId) {
196+
async function broadcastProfileChange(profileName, profileData, excludeTabId, origin = null) {
196197
try {
197198
const tabs = await chrome.tabs.query({});
198199
tabs.forEach(tab => {
@@ -201,7 +202,8 @@ async function broadcastProfileChange(profileName, profileData, excludeTabId) {
201202
chrome.tabs.sendMessage(tab.id, {
202203
type: 'profileChanged',
203204
profileName: profileName,
204-
config: profileData
205+
config: profileData,
206+
origin: origin
205207
}).catch(error => {
206208
// Suppress errors when content script is not running on a tab
207209
logConfigurationRelatedStuff(`Could not send message to tab ${tab.id}: ${error.message}`);
@@ -357,8 +359,9 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
357359
return true;
358360
case 'switchProfile':
359361
// Identify the sender tab (if any) to avoid echoing a broadcast back immediately.
360-
switchProfile(request.profileName, sender?.tab?.id).then(config => {
361-
sendResponse({ config });
362+
switchProfile(request.profileName, sender?.tab?.id, request.origin).then(config => {
363+
// Echo the origin back to the initiator for clarity.
364+
sendResponse({ config, origin: request.origin || null });
362365
logConfigurationRelatedStuff('Profile switch request processed');
363366
});
364367
return true;

init.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ if (!window.__OCP_messageListenerRegistered_v2) {
4040
window.__OCP_nukeInProgress = false;
4141

4242
// Lightweight UI refresh that preserves the floating panel state
43-
window.__OCP_partialRefreshUI = function(optionalNewConfig) {
43+
// Accepts an optional `origin` parameter to limit refreshing to the initiator (e.g. 'panel' or 'inline').
44+
window.__OCP_partialRefreshUI = function(optionalNewConfig, origin = null) {
4445
try {
4546
if (optionalNewConfig) {
4647
window.globalMaxExtensionConfig = optionalNewConfig;
4748
}
4849
if (window.MaxExtensionButtonsInit && typeof window.MaxExtensionButtonsInit.updateButtonsForProfileChange === 'function') {
49-
window.MaxExtensionButtonsInit.updateButtonsForProfileChange();
50+
// Forward origin so updateButtonsForProfileChange can limit which container(s) are updated.
51+
window.MaxExtensionButtonsInit.updateButtonsForProfileChange(origin);
5052
}
5153
} catch (e) {
5254
// If anything goes wrong, fallback to full re-init on next call
@@ -55,21 +57,22 @@ if (!window.__OCP_messageListenerRegistered_v2) {
5557
};
5658

5759
// Expose a single entry to perform partial or full refresh depending on panel presence
58-
window.__OCP_nukeAndRefresh = function(optionalNewConfig) {
60+
// Accepts optional `origin` so partial refresh can be targeted when appropriate.
61+
window.__OCP_nukeAndRefresh = function(optionalNewConfig, origin = null) {
5962
if (window.__OCP_nukeInProgress) return;
6063
window.__OCP_nukeInProgress = true;
6164
try {
6265
const hasPanel = !!(window.MaxExtensionFloatingPanel && window.MaxExtensionFloatingPanel.panelElement);
63-
66+
6467
if (hasPanel) {
6568
// Preserve panel DOM/state; only refresh buttons/inline
66-
window.__OCP_partialRefreshUI(optionalNewConfig);
69+
window.__OCP_partialRefreshUI(optionalNewConfig, origin);
6770
} else {
6871
// Full re-init path (no panel in DOM)
6972
if (optionalNewConfig) {
7073
window.globalMaxExtensionConfig = optionalNewConfig;
7174
}
72-
75+
7376
// 1) Stop resiliency monitors and timers from previous run
7477
try {
7578
if (window.OneClickPropmts_currentResiliencyTimeout) {
@@ -81,20 +84,20 @@ if (!window.__OCP_messageListenerRegistered_v2) {
8184
window.OneClickPropmts_extendedMonitoringObserver = null;
8285
}
8386
} catch (e) {}
84-
87+
8588
// 2) Remove inline buttons container(s)
8689
try {
8790
const containerId = window?.InjectionTargetsOnWebsite?.selectors?.buttonsContainerId;
8891
if (containerId) {
8992
document.querySelectorAll('#' + CSS.escape(containerId)).forEach(node => node.remove());
9093
}
9194
} catch (e) {}
92-
95+
9396
// 3) Do NOT remove the panel here (it is already absent in this branch)
94-
97+
9598
// 4) Detach keyboard listener to avoid duplicates
9699
try { window.removeEventListener('keydown', manageKeyboardShortcutEvents); } catch (e) {}
97-
100+
98101
// 5) Re-run full initialization
99102
publicStaticVoidMain();
100103
}
@@ -108,11 +111,13 @@ if (!window.__OCP_messageListenerRegistered_v2) {
108111
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
109112
if (message && message.type === 'profileChanged') {
110113
logConCgp('[init] Received profileChanged. Refreshing UI.');
114+
// Pass origin along if provided to limit refresh scope.
115+
const origin = message.origin || null;
111116
// Prefer partial refresh to preserve panel state
112117
if (typeof window.__OCP_partialRefreshUI === 'function') {
113-
window.__OCP_partialRefreshUI(message.config);
118+
window.__OCP_partialRefreshUI(message.config, origin);
114119
} else {
115-
window.__OCP_nukeAndRefresh(message.config);
120+
window.__OCP_nukeAndRefresh(message.config, origin);
116121
}
117122
sendResponse?.({ ok: true });
118123
return true;

0 commit comments

Comments
 (0)